Subagent Authoring Guide
Subagents are named roles with isolated context, narrowed tools, and explicit budgets.
File location
User-defined subagents live under:
.picasso/agents/<name>.mdThe shipped roles live under apps/cli/agents/ as YAML files (<name>.yaml).
YAML definition
A subagent is a YAML document. The role instructions live in a system_prompt field rather than a markdown body.
name: security_auditor
invocation: "@security_auditor"
model: claude-opus-4-8
tools:
- read_file
- grep
- glob
- find_symbol
- query_memory
deny:
- create_file
- edit_file
- delete_file
memory: read-only
hooks:
skip:
- post-act
max_steps: 30
max_depth: 0
output_schema: security-audit
system_prompt: |
You are a security auditor. Work from evidence. Return findings as structured JSON.Required fields
name: stable snake-case identifier.invocation:@namestring used in the TUI.model: default model route.tools: narrowed tool list.max_steps: hard step cap.max_depth: nested subagent cap.
Recommended fields
output_schema: expected structured result.description: one-line role description.when_to_use: dispatch guidance.
Spawn policy fields (T4.7)
Role files are self-contained spawn policy. These keys map onto the spawn request's ToolRestriction (the engine's toolFilter shape):
deny: denylist of tool names removed from the child's tool surface
(tools: stays the allowlist). tools: and deny: may coexist only when disjoint — declaring the same tool in both refuses the role file at load.
hooks: per-role hook opt-outs.hooks: none(orhooks: all) as a
scalar, or an object hooks: { skip: [<hook-name>...] } listing hook names the subagent run does not fire.
memory: memory scoping —none,read-only, orsession. The engine's spawn
request has no memory-scope field, so the spawn layer enforces it through the deny list: none refuses query_memory + write_memory, read-only refuses write_memory, and session stamps a session-scoped namespace into the spawn metadata. A memory: scope that denies a tool also in tools: is refused the same way an explicit deny: collision is.
- Unknown frontmatter keys warn to stderr but never fail the load.
Tool narrowing
Give each role only what it needs:
codebase_investigator: read, grep, glob, find symbol.security_auditor: read, grep, dependency and secret checks.test_writer: read, edit, run tests.doc_writer: read and edit docs.migration_planner: read, grep, plan mode.
Invocation
Inside the TUI:
@security_auditor review the auth changes for token leakageProgrammatically:
spawn_subagent --role=security_auditor --prompt="review auth changes"Isolation rules
- A named subagent receives a fresh role prompt.
- A fork subagent receives a snapshot of parent context.
- Subagents do not talk directly to each other.
- Parent only receives structured results.
- Step and wall-time budgets are enforced.
Output schema
Return:
{
"status": "ok",
"findings": [
{
"severity": "high",
"file": "src/auth/token.ts",
"line": 42,
"message": "Token is logged before redaction.",
"recommendation": "Redact before logging."
}
]
}