# Agent Compilation: YAML to XML
What the compiler auto-injects. **DO NOT duplicate these in your YAML.**
## Compilation Pipeline
```
agent.yaml → Handlebars processing → XML generation → frontmatter.md
```
Source: `tools/cli/lib/agent/compiler.js`
## File Naming Convention
**CRITICAL:** Agent filenames must be ROLE-BASED, not persona-based.
**Why:** Users can customize the agent's persona name via `customize.yaml` config. The filename provides stable identity.
**Correct:**
```
presentation-master.agent.yaml ← Role/function
tech-writer.agent.yaml ← Role/function
code-reviewer.agent.yaml ← Role/function
```
**Incorrect:**
```
caravaggio.agent.yaml ← Persona name (users might rename to "Pablo")
paige.agent.yaml ← Persona name (users might rename to "Sarah")
rex.agent.yaml ← Persona name (users might rename to "Max")
```
**Pattern:**
- Filename: `{role-or-function}.agent.yaml` (kebab-case)
- Metadata ID: `.bmad/{module}/agents/{role-or-function}.md`
- Persona Name: User-customizable in metadata or customize.yaml
**Example:**
```yaml
# File: presentation-master.agent.yaml
agent:
metadata:
id: '.bmad/cis/agents/presentation-master.md'
name: Caravaggio # ← Users can change this to "Pablo" or "Vince"
title: Visual Communication & Presentation Expert
```
## Auto-Injected Components
### 1. Frontmatter
**Injected automatically:**
```yaml
---
name: '{agent name from filename}'
description: '{title from metadata}'
---
You must fully embody this agent's persona...
```
**DO NOT add** frontmatter to your YAML source.
### 2. Activation Block
**Entire activation section is auto-generated:**
```xml
Load persona from this current agent file
Load config to get {user_name}, {communication_language}
Remember: user's name is {user_name}
ALWAYS communicate in {communication_language}
Show greeting + numbered menu
STOP and WAIT for user input
Input resolution rules
```
**DO NOT create** activation sections - compiler builds it from your critical_actions.
### 3. Menu Enhancements
**Auto-injected menu items:**
- `*help` - Always FIRST in compiled menu
- `*exit` - Always LAST in compiled menu
**Trigger prefixing:**
- Your trigger `analyze` becomes `*analyze`
- Don't add `*` prefix - compiler does it
**DO NOT include:**
```yaml
# BAD - these are auto-injected
menu:
- trigger: help
description: 'Show help'
- trigger: exit
description: 'Exit'
```
### 4. Menu Handlers
Compiler detects which handlers you use and ONLY includes those:
```xml
...
...
...
...
```
**DO NOT document** handler behavior - it's injected.
### 5. Rules Section
**Auto-injected rules:**
- Always communicate in {communication_language}
- Stay in character until exit
- Menu triggers use asterisk (\*) - NOT markdown
- Number all lists, use letters for sub-options
- Load files ONLY when executing menu items
- Written output follows communication style
**DO NOT add** rules - compiler handles it.
## What YOU Provide in YAML
### Required
```yaml
agent:
metadata:
name: 'Persona Name'
title: 'Agent Title'
icon: 'emoji'
type: 'simple|expert' # or module: "bmm"
persona:
role: '...'
identity: '...'
communication_style: '...'
principles: [...]
menu:
- trigger: your-action
action: '#prompt-id'
description: 'What it does'
```
### Optional (based on type)
```yaml
# Expert agents only
critical_actions:
- 'Load sidecar files...'
- 'Restrict access...'
# Simple/Expert with embedded logic
prompts:
- id: prompt-id
content: '...'
# Simple/Expert with customization
install_config:
questions: [...]
```
## Common Duplication Mistakes
### Adding Activation Logic
```yaml
# BAD - compiler builds activation
agent:
activation:
steps: [...]
```
### Including Help/Exit
```yaml
# BAD - auto-injected
menu:
- trigger: help
- trigger: exit
```
### Prefixing Triggers
```yaml
# BAD - compiler adds *
menu:
- trigger: '*analyze' # Should be: analyze
```
### Documenting Handlers
```yaml
# BAD - don't explain handlers, compiler injects them
# When using workflow, load workflow.xml...
```
### Adding Rules in YAML
```yaml
# BAD - rules are auto-injected
agent:
rules:
- Stay in character...
```
## Compilation Example
**Your YAML:**
```yaml
agent:
metadata:
name: 'Rex'
title: 'Code Reviewer'
icon: '🔍'
type: simple
persona:
role: Code Review Expert
identity: Systematic reviewer...
communication_style: Direct and constructive
principles:
- Code should be readable
prompts:
- id: review
content: |
Analyze code for issues...
menu:
- trigger: review
action: '#review'
description: 'Review code'
```
**Compiled Output (.md):**
```markdown
---
name: 'rex'
description: 'Code Reviewer'
---
You must fully embody...
\`\`\`xml
Load persona...
Load config...
Remember user...
Communicate in language...
Show greeting + menu...
STOP and WAIT...
Input resolution...
action="#id" → Find prompt, execute
action="text" → Execute directly
- Stay in character...
- Number lists...
- Load files when executing...
Code Review Expert
Systematic reviewer...
Direct and constructive
Code should be readable
Analyze code for issues...
\`\`\`
```
## Key Takeaways
1. **Compiler handles boilerplate** - Focus on persona and logic
2. **Critical_actions become activation steps** - Just list your agent-specific needs
3. **Menu items are enhanced** - Help/exit added, triggers prefixed
4. **Handlers auto-detected** - Only what you use is included
5. **Rules standardized** - Consistent behavior across agents
**Your job:** Define persona, prompts, menu actions
**Compiler's job:** Activation, handlers, rules, help/exit, prefixes