| name | agent-builder |
| description | Author new subagent definition. |
| user-invocable | true |
| allowed-tools | ["Bash","Read","Edit","Write","Glob","Grep"] |
agent-builder — author a new subagent definition (extend-first)
Create — or, preferably, reuse — a .claude/agents/<name>.md custom subagent
definition for a skill's fan-out step. This is skill-builder's counterpart for
the other kind of file this repo ships: a persistent, harness-registered
subagent persona, not a user-invocable workflow. The prime directive
mirrors skill-builder's: don't scaffold a new agent until you've confirmed
no existing agent should be reused instead, and a persistent agent file only
earns its keep when a plain inline Agent() prompt in the calling skill isn't
enough.
When this fires
- "build an agent", "create a subagent", "make a new agent", "add an agent",
"agent-builder"
- While authoring or extending a heavy, fan-out-shaped skill (see
when-to-orchestrate.md) and the per-item worker needs a fixed, narrower
tool boundary than the calling skill itself has — e.g. a detection or audit
pass that must not be able to mutate anything, even by accident.
- Proactively, the same way
spot-skill-opportunities proposes a new skill:
notice the pattern, propose scaffolding an agent, don't build one unasked.
Step 0 — Reuse or extend before you create (do this FIRST, always)
- List the existing agents and read their roles:
ls .claude/agents/
Each one pairs 1:1 with a skill (dependency-auditor → check-dependency-updates,
hallucination-detector → purge-hallucinations, community-demand-scout →
opposition-research). Check whether an existing role already covers this
concern under a different target — often the fix is parameterizing the
calling skill's prompt to the existing agent, not building a new persona.
- Ask whether this needs a persistent file at all. An inline
Agent() /
agent() prompt (see skill-builder's "If the skill fans out to subagents"
section) is enough unless: (a) more than one skill would spawn the same
persona, or (b) the harness-enforced tool restriction is itself load-bearing
— e.g. guaranteeing a detection pass can't accidentally write, which an
inline prompt can't guarantee (the calling skill's own tools still apply).
- Check open PRs too — another session may already have an in-progress
draft agent that never landed as a local branch you'd see. See
check-open-prs-before-duplicating.
- State explicitly: reuse, extend, or new — and why — before writing a line.
Anatomy of an agent definition
.claude/agents/<name>.md
---
name: <name>
description: <what it audits/detects/scouts>, what it lacks (Edit/Write/Bash)
and why, and which skill spawns it as its fan-out worker
tools: Bash, Read, Grep, Glob, WebFetch
---
Body shape: an opening line "You are the <role> half of the <skill> skill.",
a numbered procedure for what to check/verify/mine, an explicit output-shape
spec (what to return, in what order), and a closing reminder of exactly which
mutating tools are absent and why avoiding shell-based writes with the tools it
does have is instruction-level discipline, not harness-enforced. Match the tone
and structure of the three existing agents — they read almost as a template.
Conventions (match the existing family)
- Naming:
<domain>-<role> compound noun (dependency-auditor,
hallucination-detector, community-demand-scout) — not a verb phrase, not
a generic name like helper or worker.
- Default to read-only. Omit
Edit and Write from tools: unless the
agent's entire purpose is to mutate files (rare — none of the three existing
agents do). If Bash is present without Edit/Write, say explicitly in the
description that Bash could still write and that avoiding write-capable
shell commands is instruction-level, not harness-enforced — dependency-auditor
and hallucination-detector both carry this caveat (they have Bash).
community-demand-scout sidesteps the issue entirely by omitting Bash from
tools: — prefer that when the agent's job doesn't need shell access at all.
- Pair 1:1 with the skill that spawns it. Name that skill in the opening
clause of
description ("Read-only audit pass for check-dependency-updates
(cdu)").
- Write the prompt as if the calling skill's
SKILL.md doesn't exist — a
spawned agent never sees it. Restate every needed discipline (the exact
query, source priorities, output shape) inside the agent file itself, the
same rule skill-builder's subagent-fanning section states for inline
prompts.
- No registry to update. Agents are auto-discovered from
.claude/agents/
(mirrors skills' auto-discovery from skills/) — adding the file is enough
for the harness to expose it as a subagent_type. There is currently no
validate-skills.py-equivalent lint for .claude/agents/, so hand-check:
name: matches the filename, tools: is a comma-separated string (not a
YAML list), and description states the role, its tool limits, and the
calling skill.
Worker-role archetypes (beyond the read-only default)
The six existing agents are all one archetype — a scout: read-only,
reports back to the calling session, no authority to act on its own
findings. That's still the right default (see Conventions above), but three
other roles are legitimate reasons to deviate from it:
- Bounded worker — granted
Edit/Write to perform one scoped
implementation task, not just an investigation. Still rare (see
Conventions), but when a task genuinely needs it: name the exact file(s) or
path glob it may touch in the description, state what it must NOT touch,
and have it report back what it changed — the same output-shape discipline
a scout uses for findings.
- Critic --- reviews another agent's (or the coordinator's own) output instead of investigating the repo fresh.
adversarial-reviewer is this repo's one named critic, and it cleared the promotion bar below because every self-review routes to it --- push, ardi, and the fallback review in self-review-fallback (adversarial-self-review).
A Workflow script's pipeline()/parallel() verify stage (see when-to-orchestrate.md) is the other way this repo gets adversarial review --- an inline prompt, not a named persona.
Promote a new critic to a .claude/agents/*.md file only once more than one skill wants that same critic behavior --- Step 0's reuse-first rule applies here too.
- Paranoid reviewer — a critic deliberately run at higher cost/effort
(see
select-model and when-to-orchestrate.md's model/effort routing
section) for consequential or subtle work, where a same-family second pass
risks repeating the first pass's own blind spot. For the highest-stakes
case, run the critic on a genuinely different model family via
delegate-to-codex instead of another
Claude subagent — that skill's "verify" step already covers reviewing
Claude's own prior output, not just fresh investigation.
None of this changes the tools: frontmatter schema (there is no
model/effort field there, and there shouldn't be — pin the model/effort
choice in the calling skill's agent()/Agent() invocation instead, so
the same persona file stays reusable across tiers).
Can an agent build another agent?
Mechanically, yes: any subagent granted Edit/Write (the default
general-purpose agent, or a custom agent you don't restrict) can write a new
.claude/agents/*.md file exactly like any other file — nothing in the harness
singles out agent-definition files as unwritable. But this repo doesn't
delegate agent-authoring that way. Building an agent is an authoring task,
and every authoring task in this corpus — including skill-builder itself —
runs in the main session, not a spawned worker, so a human-in-the-loop
stays on the naming, tool-scoping, and reuse-check decisions in Step 0. The
fan-out workers this skill creates are deliberately read-only in part so they
can't self-modify or spawn siblings unsupervised. Keep authoring inline;
reserve spawned agents for the narrow, read-only, single-purpose jobs the
existing three model.
Register the new agent with its calling skill
There's no central agent list to update (see above) — "registering" a new
agent means updating the one skill that spawns it, via one of two
mechanisms:
- Inline fan-out call, when the skill only needs the agent for one
step and continues afterward in the calling session --- add
Agent(subagent_type: "<name>", ...) in that step, or inside a
Workflow script, agent(prompt, {agentType: "<name>"}).
- Declarative
context: fork, when the agent's own procedure covers
the skill's entire body end to end --- add context: fork,
agent: <name>, and (usually) background: false to the skill's own
frontmatter, per the
Run skills in a subagent
docs section.
See skill-audit/find-overlap for the pattern.
The two are not interchangeable, and picking the wrong one silently
breaks a write step. With context: fork, tool access comes from the
agent: type, not the skill's own allowed-tools --- the whole skill body
becomes the forked subagent's task, so there is no way to fork only a
sub-step.
A skill whose procedure mixes a read-only detect phase with a
main-session-only write/PR/interactive-confirmation follow-through
(reproducibility-audit, purge-hallucinations, fact-check-prose,
check-info-quality all do this --- see #914) cannot use mechanism 2
without restructuring into two skills first: forking the whole thing to a
read-only custom agent would strip the write access the follow-through
needs, not replace it declaratively.
Reach for mechanism 2 only when every step in the skill needs no more
than the agent's own tools: list --- confirm this by reading the
skill's full procedure, not by assuming a skill that already pairs with a
read-only agent is automatically eligible.
Either way:
- Name the
.claude/agents/<name>.md path explicitly in the skill body (grep
check-dependency-updates, purge-hallucinations, or opposition-research
for the inline pattern; skill-audit or find-overlap for the
declarative one).
- If the skill's procedure names a GitHub MCP tool the agent will call,
register it in
tool-mappings.yml per skill-builder's rule — the same
possible-hallucination risk applies to agent-spawning skills.
Ship it
Agent files and skills both live in the ai-config repo — never local-only.
Branch + PR + ARDI, the same flow as skill-builder.
In a worktree session, the same hazard applies as in skill-builder's
ship-it: the repo toplevel below is the MAIN checkout, not your worktree.
~/.claude/skills symlinks into the main ai-config checkout, so git -C ~/.claude/skills/… rev-parse --show-toplevel returns the main repo root —
often on another session's branch. Don't cd there and don't pass that path
to Write/Edit. Author .claude/agents/<name>.md and the calling skill's
SKILL.md in your worktree's own checkout instead, and confirm with
git branch --show-current before committing. See skill-builder's ship-it
section for the full explanation.
cd "$(git -C ~/.claude/skills/agent-builder rev-parse --show-toplevel)"
git fetch origin main && git checkout -b add-<name>-agent origin/main
python3 scripts/validate-skills.py
python3 scripts/check-links.py
python3 scripts/check-vendored-drift.py
npx --yes markdownlint-cli2@0.22.1
git add .claude/agents/<name>.md skills/<calling-skill>/SKILL.md
git commit -m "agents: add <name> — <summary>"
git push -u origin HEAD && gh pr create --fill
Then, as explicit steps:
- Request the reviewer:
gh pr edit --add-reviewer <reviewer> (EDIT_PR; see
request-pr-review).
- Drive to clean: run
ardi on the new PR until the verdict has zero
findings.
A second consumer: agent-team teammate roles
An agent definition has a use beyond the fan-out subagent it is built for: it
also doubles as an agent-team teammate role.
When a user asks a team lead to spawn a teammate "using the <name> agent
type", the definition's tools allowlist and model apply and its body is
appended to the teammate's system prompt --- but its skills and mcpServers
frontmatter are not applied (a teammate loads those from project and user
settings), and SendMessage plus the task-management tools are always available
regardless of tools.
So write the persona and tool boundary to stand on their own, and don't rely on
a definition's skills reaching a teammate.
See agent-teams for when a team is the
right primitive at all --- it is user-gated and experimental, so this is a reuse
property of the file, never a thing this skill or its agents spawn.
Relationship to other skills
skill-builder — the skill-authoring sibling; this is its subagent-file
counterpart. Use skill-builder when the new capability is a user-invocable
workflow; use this one when it's a read-only fan-out worker a skill spawns.
spot-skill-opportunities — recognizes when a skill is needed; the
same in-the-moment recognition applies to noticing a heavy skill's fan-out
step would benefit from a dedicated persona instead of an inline prompt —
hand off here for that case.
ums / record-learnings — when a session reveals that a fan-out step
needs a tighter, reusable worker persona (not just a skill gap), route here
instead of, or alongside, skill-builder.
heal-skill — repairs a skill that misfired; if the root cause is
actually the spawned agent's prompt or tool-scoping (wrong persona, too-loose
tools), fix the .claude/agents/*.md file via this skill's conventions
rather than editing the calling skill.
link-skills — the cross-link auditor for skills, though it currently
scans only skills/ and doesn't check .claude/agents/. Until it's extended
to cover agent files, manually verify that a skill naming a custom agent is
named back in that agent's description.
config-ai — the broader router this skill is one destination for: when
a request names a capability but not a mechanism, config-ai decides
whether it's a subagent (→ here), a skill, a memory, a hook, or a gha
capability, then hands off accordingly.
Anti-patterns
- ❌ Creating a new agent when an existing persona, parameterized differently,
would do.
- ❌ Not checking open PRs → building a second draft of an agent someone
already pushed and opened a PR for, instead of redirecting to it.
- ❌ Giving a read-only fan-out worker
Edit/Write "just in case."
- ❌ Writing the agent's system prompt assuming it inherits the calling
skill's text — restate every needed discipline explicitly.
- ❌
tools: written as a YAML list — agent frontmatter uses a plain
comma-separated string, unlike skills' allowed-tools:.
- ❌ Delegating the authoring itself to a spawned agent instead of doing it in
the main session — naming, tool-scoping, and the reuse-check need a
human-in-the-loop.
- ❌ Leaving the new agent unreferenced by any skill — an orphaned
.claude/agents/*.md file with nothing to spawn it.
- ❌ Leaving the change local-only, or pushing straight to main.