Team Architecture
A deep dive into how Team is built. Skim it for the mental model, or read it in full to contribute. The high-level pipeline overview lives on the home page.
Source of truth: the artifacts in
docs/plans/<id>/*.mdand the in-session TodoWrite ledger.
Contents
- 1. Design philosophy
- 2. Artifact layout & frontmatter
- 3. Pipeline (QRSPI)
- 4. Agent roster
- 5. Phase-table orchestrator
- 6. Skills
- OpenCode adapter
- 7. Hooks
- 8. Behavioral evals
- 9. State management
- 10. Nested sub-agents
1. Design philosophy
Agents are decoupled microservices. Each agent consumes a predecessor
artifact on disk, does work, and produces its own artifact under
docs/plans/<id>/. The orchestrator is the main session: it
walks a linear phase table, dispatches the right specialist for each phase,
seeds and updates a TodoWrite ledger, and runs the gates.
Principles:
- Files on disk are the durable record. Every artifact under
docs/plans/<id>/carries YAML frontmatter that describes its phase and revision metadata. Phase progression is inferred by scanning artifacts. - TodoWrite is the live coordination ledger. It is session-scoped.
Re-invoking any
/team-*command rebuilds the ledger by scanning artifacts on entry. - Registry is a phase-tagged inventory.
skills/team/registry.jsonlists the 13 specialist agents and the QRSPI phase each serves. The orchestrator dispatches through the phase table inskills/team/SKILL.md, not through the registry. - File artifacts survive compaction. Agents communicate through
files in
docs/plans/<id>/. These survive context-window compaction, can be re-read by any agent in any session, and live in git history. - Research isolation. The researcher and file-finder never receive
the user’s original task description. Enforcement is two-layer.
Structural: the orchestrator only passes the
2-questions.mdpath to the research agents. Procedural: the research agents’ system prompts forbid reading1-task.md. - No mid-run human gates. The design (~200-line alignment doc) is
gated by an adversarial design review. A fresh-context subagent audits
it, and the orchestrator records its verdict to
design-review-<n>.md. The artifacts are thus self-describing. The Structure (~2-page vertical-slice breakdown) and the Plan are not gated. They advance autonomously. The human’s checkpoint is the PR review at the end. - Hooks enforce discipline mechanically. LLMs forget instructions ~20% of the time. Hooks are deterministic.
Trust boundary. The single human checkpoint, the end-of-run PR
review, is a code checkpoint, and it happens after the run has
already executed. Local Bash execution (implementer, verifier, hooks),
branch creation, pushes to remotes, and any multi-repo worktree effects
all occur before a human sees the PR. The PR review contains the diff,
the design’s recorded assumptions, and the deferred ## Review notes. It
does not contain the run’s local side effects. The pipeline also
assumes that repository content the researcher reads is trusted: a repo
that accepts untrusted contributions feeds untrusted text into agent
context. Merging remains human-only: nothing in the pipeline marks a PR
ready for review or merges it.
2. Artifact layout & frontmatter
Runtime canon: the schema below is carried for agents by artifact schema. This section is the doc-surface copy. The executable
ID_RE/PHASE_FILESdefinitions live inhooks/session-start-recover.mjs.
All phase artifacts live in docs/plans/<id>/, where <id> is one of:
- Ticket-prefixed:
<TICKET>-<kebab-topic>(e.g.,ENG-1234-add-rate-limiting) - Date-prefixed:
<YYYY-MM-DD>-<kebab-topic>(e.g.,2026-05-01-add-rate-limiting)
Every artifact opens with YAML frontmatter. Common fields:
---
topic: <kebab-case>
date: 2026-04-30
phase: design # task | questions | prd | repos | research | design | structure | plan
---
Per-phase additions:
| Phase | Extra frontmatter |
|---|---|
| task | ticketId: <id> (or null) |
| questions | (none) |
| prd | (none. Not gated. The questioner writes it conditionally.) |
| repos | (none. Written conditionally in multi-repo mode.) |
| research | (none) |
| design | revision: 0 |
| structure | (none. Not gated. It advances to PLAN once it exists.) |
| plan | (none. Derived mechanically from the structure.) |
Design-review record (design-review-<n>.md): each review round the
orchestrator writes docs/plans/<id>/design-review-<n>.md (<n> 1-based
per round) with frontmatter topic, date, phase: design-review, and
verdict: <APPROVE|REQUEST CHANGES|COMMENT>. The body carries the
reviewer’s findings verbatim. The verdict field is the deterministic
read for hooks and resume detection. A design has passed review when the
highest-<n> file carries APPROVE or COMMENT.
Review loop (REQUEST CHANGES): the design-author re-drafts with the
reviewer’s findings verbatim. The orchestrator increments
revision: <n+1> in the new draft’s frontmatter.
Phase inference (orchestrator + hooks):
| Latest artifact present | Current phase |
|---|---|
worktree exists for <id>, no 1-task.md yet |
WORKTREE (next up) |
1-task.md + 2-questions.md only |
RESEARCH (next up) |
5-research.md |
DESIGN (next up) |
6-design.md alone (no passing design review) |
DESIGN (review next) |
6-design.md + passing design-review-<n>.md |
STRUCTURE (next up) |
7-structure.md |
PLAN (next up) |
8-plan.md + ≥1 commit on <id> since merge-base |
IMPLEMENT |
8-plan.md (no commit on <id> yet) |
PLAN (next up) |
| topic branch has slice commits + verifier passed | PR (next up) |
| PR opened or commit shipped | SHIPPED |
Worktree presence: git worktree list --porcelain | grep -q <id>.
IMPLEMENT is confirmed only once there is
≥1 commit on <id> since merge-base with the default branch, so
git log <merge-base>..<id> is non-empty. A present 8-plan.md with no
commit means the run is still pre-IMPLEMENT.
Two non-phase sibling outputs exist. Discovery keys only on the six
PHASE_FILES names, so both are invisible to hooks and skills, and IMPLEMENT
still declares no phase artifact.
docs/plans/<id>/screenshots/ (PNGs plus manifest.md) is written by
ux-reviewer during IMPLEMENT for UI-touching changes and consumed by team-pr.
The upload itself, and every mechanic it needs, lives in
skills/pr-screenshots/.
docs/plans/<id>/cross-model-notes.md is written by the orchestrator at
the DESIGN review gate and the IMPLEMENT aggregate gate — one
### Cross-model disposition block appended per review round, at either
gate, in which the cross-model pass ran — and consumed by team-pr
for the PR’s ## Review notes section. It is created only on the first
round that runs the pass, so a repo where the pass never runs gains no
artifact. Beside it, docs/plans/<id>/cross-model-raw.md is the design
path’s raw transcript — the orchestrator appends each vendor call’s
result line and fenced output at capture time. Like the notes file, it is
invisible to discovery: neither is a phase artifact, and neither is ever
read back as state. Both frontmatter schemas
(phase: cross-model-review and phase: cross-model-raw, no verdict)
live in artifact schema.
3. Pipeline (QRSPI)
The pipeline has eight phases. The orchestrator walks them in order. Each phase needs the prior phase’s artifact on disk.
WORKTREE → QUESTION → RESEARCH → DESIGN → STRUCTURE → PLAN → IMPLEMENT → PR → SHIPPED
Phase 1: Worktree
Action: orchestrator-emit (the leading phase) Predecessor: none. The description arrives in ``.
Before QUESTION, the orchestrator creates the home worktree on branch
<id> off origin/HEAD using Claude Code’s native worktree support, and
authors docs/plans/<id>/ inside it. Because the artifact directory
is born in the worktree, no copy is ever needed and the home checkout’s
git status stays clean for the whole run. The orchestrator computes the
worktree’s absolute path once and threads it into every downstream
dispatch (the main session does not cd).
Single-repo (default): 4-repos.md is absent. One home worktree at
<repo>/.claude/worktrees/<id>.
Multi-repo: the questioner writes 4-repos.md autonomously at
QUESTION, one phase after WORKTREE. The design-author writes it at DESIGN
when the questioner missed the multi-repo signals. Only the home worktree
is created here. Secondary worktrees are created
after the design review, one per listed repo. Each repo path must
first pass the containment check: its realpath must be a direct child of
the home repo’s parent directory.
git -C <repo-path> worktree add .claude/worktrees/<id> -b <id> origin/HEAD
At that point the orchestrator writes a ## Worktrees section to
4-repos.md. It back-records the home worktree path plus each secondary
path. Any later /team-* invocation can thus rediscover all paths from
one file. Only the home repo’s worktree carries docs/plans/<id>/. Other
repos’ worktrees do not duplicate the artifacts. See
skills/team-worktree/playbooks/worktree.md for full topology.
Fallback: if home-worktree creation fails (shallow clone, certain CI
systems, permissions), the orchestrator reports it and falls back to
in-place for the entire run: docs/plans/<id>/ lives at the home-repo
root and the threaded path is the home-repo root.
Phase 2: Question
Agent: questioner
Predecessor: worktree prepared (+ description in $ARGUMENTS)
Artifacts: docs/plans/<id>/{task,questions}.md
Decomposes the user’s intent into two artifacts. Only the questioner ever
sees the user’s description. There is no separate brief.md. Neutral
codebase context lives in a “Codebase context” section at the top of
2-questions.md.
Phase 3: Research
Agents: file-finder and researcher (parallel, isolated)
Predecessor: 2-questions.md (orchestrator passes only the
2-questions.md path to the research agents)
Artifact: docs/plans/<id>/5-research.md
Orchestrator waits for both agents to return, then writes the combined research artifact with the necessary frontmatter.
Phase 4: Design
Agent: design-author (resolves its own open questions, recording
each as an auditable assumption) Predecessor: 5-research.md
Artifact: docs/plans/<id>/6-design.md Gate: REVIEW. The
orchestrator dispatches a fresh-context, read-only Explore subagent
with the ## Review brief from skills/eng-design-doc-review/references/design-reviewer.md.
The subagent holds no Write or Edit tools, so the reviewer cannot touch
the artifacts it judges. The orchestrator records the verdict to
design-review-<n>.md. APPROVE and COMMENT advance. On REQUEST CHANGES
the agent re-drafts with the findings verbatim and increments revision.
Phase 5: Structure
Agent: structure-planner
Predecessor: 6-design.md + passing design-review-<n>.md
Artifact: docs/plans/<id>/7-structure.md
Gate: NONE (autonomous). Once 7-structure.md exists the pipeline
advances to PLAN.
Phase 6: Plan
Agent: planner
Predecessor: 7-structure.md
Artifact: docs/plans/<id>/8-plan.md
No gate. The plan is mechanically derived from the structure.
Phase 7: Implement
Sub-pipeline:
- Test-first.
test-architectwrites failing acceptance tests. - Mechanical gate. The orchestrator runs the suite and the project’s static checks. All tests must fail with assertion errors, not crashes, and every static check must pass — a runner that transpiles without type-checking leaves a red type checker behind a green suite. A change whose stated contract is zero behavior change inverts both steps: step 1 is skipped with a recorded reason, since the current suite is already the acceptance suite, and the gate becomes “the checks reproduce the baseline captured before any file moved”. Green is the correct state throughout.
- Slice execution.
implementerworks through the plan one slice at a time, committing each atomically. - Code review. 5 reviewers in parallel:
code-reviewer,security-reviewer,technical-writer,ux-reviewer,verifier. - Aggregate gate. The orchestrator sorts every finding into a
severity tier: Blocking, Major, or Minor-and-below. See
skills/code-review/references/findings.md. Each round in which the code-reviewer’s report carries a### Cross-model dispositionblock, the orchestrator appends that block — altered only by the blockquote wrap (every line prefixed with>) — todocs/plans/<id>/cross-model-notes.md(see section 2). While any Blocking or Major finding remains, it dispatches the implementer to fix the typed failure class. It then re-runs all 5 reviewers automatically. It never consults the user. This is the no-consult rule. Once Blocking and Major are clean, any remaining Minor-and-below findings are recorded in the PR body’s## Review notesfor the human’s PR review.
The orchestrator tracks the round count by appending
Review round <n+1> (<b> Blocking, <m> Major open) items to the
TodoWrite ledger. The count is that round’s open Blocking and Major
total, so an operator watching the ledger can tell a converging loop
from a stuck one.
Recovery after an operator stop, a context-exhausted session, or a
fail-closed halt: a human re-invokes the same /team-* command bare.
Each command runs its own phase and names the next one to run. What
the human can fix first differs by gate.
The design-review gate writes every round’s findings to
design-review-<n>.md, so they are on disk to read before editing
6-design.md. The aggregate gate persists none of its findings. So
/team-implement resumes at the reviewer-dispatch step, and the five
reviewers re-derive the open set at the cost of one round. The aggregate
round counter is session-scoped through TodoWrite and starts fresh on
re-invocation. The design revision counter persists in 6-design.md
frontmatter.
Phase 8: PR
Action: orchestrator-emit Predecessor: aggregate gate passed
Update an existing CHANGELOG.md (filter for user-facing commits since last
release); if the root file is absent, leave it absent unless the user explicitly
requested one. Push the branch and open a draft PR automatically with
gh pr create --draft. The PR phase never waits for approval. Then
surface the tracking ticket, if 1-task.md carries ticketId. When the
branch impacts a UI, the PR body also gets a ## Screenshots section,
populated by one delegated call to the pr-screenshots skill, which attaches
the PNGs and rewrites the body. UI impact is decided from the full branch diff;
when ux-reviewer produced no capture manifest (docs/plans/<id>/screenshots/,
see the artifact-layout note in section 2), the PR phase captures per the
ux-reviewer brief before rendering the section.
When docs/plans/<id>/cross-model-notes.md exists, its body (frontmatter stripped) is copied into the PR’s
## Review notes section, replacing the final round’s inline disposition
block so every round appears exactly once. The worktree stays in place
after the PR opens. Teardown is deferred until the PR merges or the user
asks, so the branch remains available for iteration. The final report points at the
standalone /pr-watch-as-author utility for watching the PR once it is
ready for review.
4. Agent roster
13 specialist agents, organized by phase:
| Phase | Agents |
|---|---|
| QUESTION | questioner |
| RESEARCH | file-finder, researcher (parallel) |
| DESIGN | design-author |
| STRUCTURE | structure-planner |
| PLAN | planner |
| IMPLEMENT | test-architect, implementer, code-reviewer, security-reviewer, |
technical-writer, ux-reviewer, verifier (last 5 parallel) |
Each agent’s QRSPI phase is recorded in skills/team/registry.json.
Agent frontmatter uses only Claude Code’s supported fields.
The dev hook .claude/hooks/check-registry-sync.mjs validates that
the inventory in registry.json and the files under agents/ agree by
name.
Checks and balances
The roster splits into two roles with deliberately non-overlapping powers. Producers write artifacts and code. Reviewers cast verdicts. No agent holds both powers, and neither role can complete a review cycle alone.
| Role | Agents | Tools | permissionMode |
Power |
|---|---|---|---|---|
| Producer | questioner, design-author, structure-planner, planner, test-architect, implementer |
include Write/Edit |
acceptEdits |
Changes the tree. Casts no verdict. |
| Reviewer | code-reviewer, security-reviewer, technical-writer, ux-reviewer, verifier |
read-only | plan |
Blocks the line. Changes nothing. |
This is enforced by frontmatter, not by prompt text. A reviewer that could
edit could fix the defect it found and then approve its own fix, which collapses
the generator and the evaluator into one role. Read-only tool grants plus
permissionMode: plan make that impossible at the harness layer.
One path steps outside that enforcement: the cross-model pass
(skills/team/references/cross-model-review.md) shells out to external vendor CLIs
— the code-reviewer on the code path, the orchestrator on the design
path — and an external process is beyond the harness’s tool grants. On
that path the reviewer invariant is trusted, not enforced:
codex and agy run with their full-access
flags in the repo cwd — unsandboxed, with the invoking user’s permissions —
and with a vendor CLI installed, diff and design-document content leaves
the machine. What
bounds the path is the pinned argv the bundled script hardcodes, the per-vendor
env allowlist, the machine-wide
TEAM_DISABLE_CROSS_MODEL kill-switch that disables both paths
when set, the untrusted-output rules on everything a vendor
returns, and the post-pass git status check that reports any vendor
write as a blocking finding.
researcher and file-finder are also read-only, for a different reason:
research isolation (see Phase 3). Read-only does not by
itself mean reviewer.
Three more balances bound the checks themselves:
- The veto ends on agreement, not on a count. The review loop runs until no
Blocking or Major finding is left. A check that can never be satisfied grinds
until a person stops the run. See
skills/code-review/references/findings.md. - The check has a check. The optional skeptic pass is default-keep. An inconclusive refutation leaves the finding standing, so the pass removes false positives only.
- The orchestrator cannot punt. The no-consult rule forbids escalation of a Blocking or Major finding to the user mid-run.
Model tiering
The principle:
complex work runs on opus. Bounded judgment runs on sonnet.
Mechanical checks run on haiku. fable (Fable 5) is the tier above
opus: an agent runs there on a demonstrated, concrete need opus
cannot meet. The tier is empty.
opus(complex work, the default):researcher,design-author,structure-planner,planner,test-architect,implementer,code-reviewer, andsecurity-reviewer. Security review is complex work, so it runs on this rung like the rest. What is particular tosecurity-revieweris that it must never be overridden up tofable, and never down offopus; the override recipe below carries that constraint and its reason.sonnet(bounded single-pass judgment):questioner,ux-reviewer,technical-writer.haiku(mechanical checks):file-finder,verifier.
Notes:
- Overriding up to fable. After the flip,
fableis the override tier andopusis the shipped default, so a user without fable access needs no override at all. What thefableoverride requires of plugin users: Claude Code ≥ v2.1.170 and Fable access. Fable 5 is not available under zero data retention (30-day retention is necessary), and on Bedrock/Vertex/FoundryANTHROPIC_DEFAULT_FABLE_MODELmust be pinned.- The recommended mechanism is a per-agent file copy: copy the
agent file into the
.claude/agents/directory of the session that runs it, with the one-line editmodel: fable, one file per agent. Never copysecurity-reviewer. This is a named, load-bearing constraint on the recipe, and here is the fact behind it: Fable 5’s cybersecurity safety classifiers flag security-review content, and in a non-interactive subagent context a flagged request ends the turn with a refusal rather than a fallback, so the review dies mid-run.opusis a floating alias — it resolves to Claude Code’s current Opus (Opus 5 today) — and riding the latest Opus rather than a dated one is deliberate: the constraint is about Fable’s classifiers, not about freezing a specific Opus. Opus-tier models carry cybersecurity safeguards of their own (far milder than Fable’s), so if security reviews ever start ending in refusals after an Opus upgrade, overriding to the prior Opus is the escape hatch. - Placement is part of the recommendation. An override takes
effect only where the host looks for it, and a
/teamrun has two candidate directories: the orchestrating session keeps its own directory at the primary repo root and dispatches each agent into.claude/worktrees/<id>by absolute path (skills/team/SKILL.md). The worktree is a fresh checkout that carries no untracked files unless the root.worktreeincludenames them (and only files that are also gitignored are copied), and no repo surface pins which of the two directories the host’s project-agent resolution follows — unpinned host behavior, like the frontmatter-read timing hedged below. The rule splits by run mode and holds under either answer. For an autonomous/teamrun, add.claude/agents/to the repository’s.gitignoreand to its root.worktreeinclude, then keep the untracked override copy at.claude/agents/<name>.md: the copy stays present at the primary repo root and worktree creation carries it into each new worktree on its own, so the override is in place whichever directory resolution follows — and/teamopens no window to place a file after the worktree exists. The gitignore half is not optional — only files that are also gitignored get copied. For a phase-by-phase or manual session, an untracked copy inside the directory that session opens works with no repo change, because the user places it before dispatching. The committed alternative, for a team that wants one shared repository-wide override: commit.claude/agents/<name>.mdon the repository’s default branch and push it — never on a run’s feature branch — which needs permission to push to that branch. The observable that an override took effect is the manual routing check: spawn the agent from a fresh headless session and read back the model it reports, valid only against an install of the plugin version under test (against a stale install it is a false pass). One residual holds under either route: a worktree that already exists misses the override, because reuse runs no checkout and no.worktreeincludecopy. The fix is by hand — drop the copy into that worktree’s own.claude/agents/, or let the next new worktree pick it up. - Parity: a user who moves
implementerup to fable movestest-architectandcode-reviewerwith it — the scope fence and the correctness evaluator must not run on a weaker model than the implementer they gate. The parity set is exactly those three agents and stops there. - Freeze and resync: a copied file is a whole agent definition,
not a model patch. It shadows the plugin’s prompt,
tools,effort, andpermissionMode, and it keeps shadowing them after plugin updates, so re-copy overridden agents after each plugin upgrade and re-apply the one-line model edit. Skill content is not frozen: theskills:field lists names, and the bodies load from the installed plugin. - Do not use
CLAUDE_CODE_SUBAGENT_MODELfor this. The variable applies to every subagent, so any value flattens the five sonnet/haiku agents onto that tier’s price — and=fablealso dragssecurity-revieweronto the model whose classifier refusals end a security review mid-run. - An override takes effect no later than the next session: a restart, or a copy placed before a session opens, applies it whether the host reads frontmatter once at session start or live-loads it.
- The re-pin bar. An agent returns to
fablein the shipped defaults on a differential: a recorded opus failure on the agent’s own task that reproduces across at least two independent runs, and a matched fable success on the same task. The bar’s qualifications and limits are part of the bar:- No instrument for producing that matched pair ships with this change. Its requirements sit on #139. Until that instrument lands, a re-pin proposal rests on recorded production failures plus operator judgment — weak evidence the maintainer weighs, never a cleared bar. The bar is an evidential target, not a procedure to improvise: the design that specifies one has not been done.
- Reach. The bar starts from a recorded failure on the agent’s
own task, and only three agents produce one:
design-author(the adversarial design-review verdict),test-architect(the mechanical test gate), andimplementer(acceptance tests plus the 5-reviewer verify). It does not reachresearcher,structure-planner,planner, orcode-reviewer, because nothing evaluates the artifact or verdict they produce.code-reviewer’s one live route is the coupled reviewer set below. Forresearcher,structure-planner, andplannerthe routes are two, and both are future work: the deferred work on #139 produces per-agent evidence and the bar’s terms are extended to admit it (a future decision, recorded then), or a per-task failure signal for them comes into existence. Until one of those opens, the shipped opus default holds for them. The deferred aggregate comparison is neither route: it observes the flip in aggregate, which cannot meet a bar written per agent and per task. - The bar’s unit is a coupled set of pins. Most sets hold one
member. The reviewer set holds three: if
implementerclears the bar, the re-pin movestest-architectandcode-reviewerwith it onimplementer’s evidence alone. Never re-pinimplementersolo — a scope fence or evaluator on a weaker model than the implementer it gates is the defect the 0.14.1 fence rationale forbids. The cost is stated: one agent’s evidence triples the pin count, and with it the permanent spend. - What counts as recorded evidence is defined per agent, because
each agent’s gate detects its own class of failure.
test-architect’s gate detects mechanical faults (a crash, a failing static check, a new test that does not fail with an assertion error), not a scope fence that runs green and covers too little. Its recorded failure is evidence for that class, which is what puts it on the reached list, and its practical route back is the coupled reviewer set above. - The multi-repo limit: the route for a failure in a multi-repo run is future work too, and the aggregate comparison cannot host it — the Golden Master is pinned to one repository, and #139 models a run with no repository axis — so the deferred instrument work must state its own repository scope.
- The evidence venue: whatever evidence a re-pin proposal rests on lives in a GitHub issue on the project board, linking the runs it cites.
Even for the three reached agents, nobody can complete a case today, because the matched fable half needs the instrument this change defers. And “a matched fable success on the same task” is the evidential target, not proof on its own that the tier caused a difference — two opus failures alone prove the task is hard, not that the tier caused it.
- The recommended mechanism is a per-agent file copy: copy the
agent file into the
- 1M context window comes for free at the opus tier. The current
Opus models (Opus 5, like 4.8 before it) always run with the 1M window
on the Anthropic API. Max, Team, and Enterprise plans include
the 1M upgrade with the subscription, and Pro degrades gracefully to
200K. These agents thus need no
[1m]suffix. The sonnet agents stay at 200K, because their bounded single-pass work is nowhere near the ceiling. Haiku does not support 1M. -
Users can override any agent’s model with
CLAUDE_CODE_SUBAGENT_MODEL(applies to all subagents — see the env-var warning in the override note above), or copy an agent file into.claude/agents/with a differentmodel:. - Four agents (
researcher,implementer,code-reviewer,security-reviewer) additionally hold theAgenttool and may spawn read-only nested sub-agents. See 10. Nested sub-agents.
Effort tiering
Effort tracks the work the agent does, on its own four-rung ladder:
low (mechanical), medium and high (judgment — the band spans both
rungs), and xhigh (strategic artifact authors). The xhigh tier holds
design-author and structure-planner, whose artifacts set the
direction everything downstream inherits. The ladder runs alongside the
model ladder rather than off it, so an agent on sonnet at high is
inside the rule: questioner is the live case, doing judgment work in a
bounded single pass. Methodology skills carry no
effort. They inherit it from the loading agent.
User-facing skills use the same ladder. The full /team orchestrator runs at
high because it maintains state and applies gates across all eight phases.
Single-phase orchestrators stay at medium; their specialist agents perform
the complex work. Mechanical worktree setup runs at low, while entry points
that directly perform complex analysis or conflict resolution run at high.
5. Phase-table orchestrator
The orchestrator (the main session) drives /team by
walking the phase table in skills/team/SKILL.md. Pseudocode:
setup:
resolve $ARGUMENTS (issue URL → gh issue view; ticket → use as prefix).
derive <id> = "<TICKET>-<topic>" or "<YYYY-MM-DD>-<topic>".
create docs/plans/<id>/ if needed.
seed TodoWrite ledger with one item per phase.
on resume: scan docs/plans/<id>/, fast-forward the ledger.
loop:
1. Inspect TodoWrite. If all phases completed → exit.
2. Identify the in_progress phase. Look up agent(s) and predecessor
artifact path(s) in the phase table.
3. Make sure that predecessors exist on disk. For STRUCTURE that includes
a `design-review-<n>.md` with a passing verdict. If one is missing, the
run is desynced. Suggest the bare /team-* command again. Its three-tier
discovery resolves docs/plans/<id>/ without an explicit arg.
4. Dispatch the agent(s) — pass them the artifact directory
`docs/plans/<id>/`.
5. Write returned artifacts to docs/plans/<id>/<name>.md with the
YAML frontmatter the agent specifies.
6. Run the gate for this phase (HUMAN | MECHANICAL | ORCHESTRATOR-EMIT
| AGGREGATE).
7. Mark current TodoWrite item complete and the next one in_progress.
8. Goto loop.
6. Skills
Skills live under skills/. There are two flavors:
Entry-point skills (slash commands)
Every entry-point skill carries an argument-hint field in its
frontmatter (Claude Code skills frontmatter)
that documents the expected $ARGUMENTS shape.
Each downstream skill (team-research and beyond) treats $ARGUMENTS as
an artifact directory, typically the path printed by the previous phase’s
completion message. For the 8 directory-consuming skills
(team-research, team-design, team-structure, team-plan,
team-worktree, team-implement, team-pr, eng-design-doc-review)
the docs/plans/<id>/ argument is optional. Each skill resolves the
directory through a three-tier chain: explicit $ARGUMENTS →
newest-mtime convention discovery → AskUserQuestion. The middle tier
filters by ID_RE and PHASE_FILES, ported from
hooks/session-start-recover.mjs as a POSIX ERE translation, and by the
skill’s necessary predecessor artifact. The orchestrator or entry-point
skill calls AskUserQuestion itself, never a subagent. Subagents never
pause for user input. Standalone modes still exist. A partial skill
invoked with no resolvable directory, or with a free-form description,
bootstraps the missing upstream artifacts inline rather than hard-error.
Shared discovery helper. The 8 directory-consuming skills invoke the
bundled skills/team/discover-topic.sh helper with their predecessor
filename. team-structure also passes --require-passing-review. Each
skill resolves <team-skill-dir> to the absolute directory containing
skills/team/SKILL.md, then runs the helper from the repository root.
The helper reads no host-specific environment variable or relative import.
It owns ID_RE, PHASE_FILES, macOS/Linux mtime lookup, explicit-path
precedence, and empty-success output when no candidate matches. The optional
review filter accepts only APPROVE or COMMENT from the highest-numbered
design-review-<n>.md YAML frontmatter. Line 1 and a closing marker within
60 lines must both be ---; malformed or over-cap input fails closed.
Methodology skills (loaded by agents, not directly invoked)
Methodology skills carry no argument-hint. Agents load them through one
of two mechanisms. The first is a skills: YAML block list in the
agent’s frontmatter, one indented - <name> per line.
After the playbook-and-verification consolidation, no methodology skill
remains registered: the last two (running-quality-checks and
verifying-ux) moved into the verify playbook
and the ux reviewer brief.
The block form is the contract: three
test parsers read it, and the one-line inline flow form parses to zero
names, so it is an offender rather than a second shape.
The second is an inline prose load instruction in the agent body. All
methodology content is now an ordinary resource rather than a registered
skill: it lives in ordinary references such as the
code standards
and writing standards,
which consumers read by path before work.
Principles are the third flavor. A principle is a guarded command: it
sets disable-model-invocation: true, so the model never applies it on its
own, and it carries no argument-hint. It stays user-invocable through /,
and a consuming procedure reads it through its installed path — the same
citation form ordinary references use. The catalog files it under
## Principles, and a read of its SKILL.md is a Uses edge in the catalog
just as a load is. principle-fix-root-causes
is read by the bug-fix playbook;
its agents/openai.yaml declares allow_implicit_invocation: false for Codex.
Two reference forms, and the form is the contract. Every skill-to-skill reference is one of two kinds, and each has its own encoding:
| Kind | Reads | Encoded as |
|---|---|---|
| Load — the reader must go execute that skill | Call the Skill tool with `<name>` |
bare name |
| Citation — a schema lookup, a “see also”, a rule restated nearby | skills/<name>/SKILL.md |
path |
The citation row splits. A reference to a skill’s own SKILL.md is also an
edge in the docs/skills.md Uses/Used by graph — the consuming
procedure reads the skill, so it uses it. A reference to any other file in that
skill’s directory is a citation only and draws no edge, and so does a reference
that only locates a skill’s install directory (for example, “the directory
containing skills/team/SKILL.md”, read to run a script beside it).
The imperative phrasing on a load is what makes a model actually issue the tool call. “Load X”, “see X”, and “per X” all read as citations, and a model that treats a load as a citation proceeds on the summary in its own context instead of the skill’s actual content — a slice ships without the commit conventions applied, a review runs without its severity table, and nothing announces either.
A load carries no path. The bare name is what the Skill tool takes, and a
path sitting beside it reintroduces the ambiguity the imperative exists to
remove: it reads as a file to go open. Name resolution is what replaces the
path’s rename-detection, and it is strictly stronger — it catches a rename
and a typo, where a path assertion only ever confirmed a string was
present. skills/git-commmit/SKILL.md passed the old check.
Shared principles use six ordinary documents under skills/team/principles/. Artifact and operational rules use scoped references, outside registration.
Consumers explicitly read their installed paths before work; missing files stop the consuming operation with the resolved path.
The dispatch contract supplies definition and resource paths for named, body-loaded, and standalone agents.
The load form applies only where the other skill is genuinely needed. A
citation keeps its path and its ordinary wording: a schema lookup, a “see
also”, and a pointer to a skill the frontmatter already preloaded. Turning one of those into a tool call would spend a call
and a slice of context on content nobody asked for. A citation to a skill’s
SKILL.md still draws a Uses edge — the procedure reads the skill — even
though it is not a load.
The phrase is load-bearing as the encoding. Changing the convention means changing every reference that carries it, deliberately.
Because they are reference material rather than user actions, methodology
skills set user-invocable: false in their frontmatter. This keeps them
out of the / slash-command menu. They stay fully loadable by their two
mechanisms above. Neither the skills: preload nor a by-path load is affected by
the field, which governs only menu visibility. Setting
disable-model-invocation is a separate per-skill call with its own
recorded reason, and no methodology skill has one: the model auto-loading
a methodology skill when relevant is how it reaches one at all. When you
add a new methodology skill, set user-invocable: false. When you add a
new entry-point skill, leave it unset, so it registers as a slash
command.
The field is honored by Claude Code only. Codex reads no invocability
field at all, so it lists every registered methodology skill in
its $ picker and a user can invoke any of them. Principles avoid that leak
with disable-model-invocation: true plus allow_implicit_invocation: false
in their agents/openai.yaml, which keeps them out of Codex’s implicit
catalog. There is no fix on
Team’s side, and the workarounds that look plausible all fail — see
cross-host-portability.md
before spending time on it.
The consolidated writing standards
carry the former unslop and writing-prose content as one ordinary
reference. Its Team-authored categories separate AI-pattern detection from
sentence mechanics within one file.
The author scans the untouched draft with the exact-text and semantic guard before applying style edits. Exact source text stays byte-identical. The semantic guard protects normative force, permission, real uncertainty, and meaningful time relations. It outranks style substitutions.
Every agent and entry point reads the writing standards before finalizing prose. Agents audit only text they author. Orchestrators store and relay completed agent and vendor reports unchanged. The fresh design reviewer can use Read, Grep, Glob, and Skill, but no mutating tool. The technical writer uses the semantic guard to veto a readability finding that would change meaning.
Claude Code may retain the writing standards for later utilities in the same context before compaction. Compaction can evict that retained content. A recovered pipeline phase uses its phase entry and reloads the writing standards explicitly.
The trigger-phrase convention keys on the user-invocable field —
not on argument-hint, which docs/skills.md uses to sort skill
flavor. A skill that does not set user-invocable: false must state,
in its description, at least one double-quoted natural-language phrase
(one that does not start with /) plus its own literal /<name>,
normally as a final Trigger on "…", "…", or "/<name>". sentence. A
side-effecting or irreversible entry-point skill MUST carry
shipit-style explicit-intent guard wording (“Invoke ONLY on explicit …
intent — … never infer …”) beside or instead of the plain carrier, and
still state the quoted phrases and the slash name.
Which skills are in that class is a complement pair over every write an
invocation authorizes, so it returns one answer per skill. Out of
class: the invocation reads only, or writes only (1) files under
docs/plans/ and (2) invocation-local scratch files — untracked, created
and consumed inside the same run, carried by no commit, and read by no
later phase. In class: everything else — a change to any file the repo
tracks, or to an untracked file the change is meant to deliver; a git
write to history or refs (a commit, a branch, a rebase, a push, a branch
delete); or a change on a host outside the checkout (a PR opened,
approved, or merged; a ticket or issue moved, filed, or closed; a
deploy). The verb list this replaced — commits, pushes, opens a PR, moves
a ticket, merges, deploys, or deletes — still reads as an illustration of
the in-class half. A write the invocation never authorized, such as an
unsandboxed vendor CLI mutating the tree during a cross-model pass, moves
no skill into the class: the caller detects that write and reverts it
rather than authoring it.
Second tier: a skill that gates every mutation on its own in-run
approval carries the guard there instead, which is where
human-control rules puts it. groom-backlog is
the worked example — it presents each irreversible close and waits.
Setting disable-model-invocation is a further per-skill call with its
own recorded reason, never a property of this class. An in-class skill
stays listed as a command, and its routing-map line in AGENTS.md states
the explicit intent, so the map never invites it on a plain request. The
guard wording is the author’s and reviewer’s responsibility, and its absence
on a side-effecting skill is a review-blocking defect.
No methodology skill is user-invocable. When a methodology also wants a
user-facing command, the answer is a front door, not an exception:
the methodology keeps user-invocable: false and a separate entry-point
skill carries the slash command. The review procedures moved off the
methodology list entirely: each reviewer brief is now an ordinary
reference file owned by its entry point, so the front-door pair collapsed
to one skill carrying a references/ file beside it.
code-review owns the code reviewer brief
(skills/code-review/references/code-reviewer.md), the separate security
and documentation briefs (security-reviewer.md,
documentation-reviewer.md), and the shared finding format
(findings.md). The code-reviewer, security-reviewer, ux-reviewer,
and technical-writer agents read those briefs from the installed
plugin; code-review carries argument-hint and effort like any other
entry point and is catalogued under Standalone utilities. What stays on
the front door is the one thing a user runs: “review this diff”.
eng-design-doc-review owns the design reviewer brief
(skills/eng-design-doc-review/references/design-reviewer.md), and
team, team-design, and the front door all read it by path.
no-comments owns the comment reviewer brief
(skills/no-comments/references/reviewer.md): a read-only Explore
reviewer classifies comments, then the invoking producer applies accepted
findings and gates constraint encodings on approval.
A front door is a second kind of entry point, and both kinds are
ordinary. One runs its own procedure; a front door owes the reviewer’s
own rules and routes the work to whoever may do it. The main session
shares conversation history with whatever wrote the code, so it is not a
valid reviewer. code-review therefore dispatches the code-reviewer
agent and relays the verdict rather than reviewing inline, then reads
code-reviewer.md for the methodology that reviewer applies.
eng-design-doc-review does the same with a read-only Explore
subagent and the design-reviewer.md brief. no-comments uses that dispatch
pattern but returns accepted findings to the invoking producer for edits.
(This is separate from the entry-point skills, which are user-invocable by
definition. Some of those, e.g. team-worktree and team-pr, are also
referenced by path from team/SKILL.md, but those are procedural
cross-links in the orchestrator’s prose, not a parent loading the skill as
a building block. The reviewer briefs are how a composed review keeps a
user-facing entry point without becoming a methodology skill of its own.)
For the full per-skill reference (all skills, each with the skills it loads, which is the skill-to-skill dependency graph), see skills.md.
Design guidelines
Skill sources follow six rules: assert without arguing; state invariants instead
of exhaustive case lists; define shared rules once; keep SKILL.md as a router
to references/ and scripts; use descriptions only for capability and trigger;
and test commands, numbers, names, paths, or behavior rather than prose wording.
Source budgets remain 80 lines for methodology and 150 for entry points. Descriptions are at most 200 characters, or 150 for methodology. An overage requires a reviewed reason stating its exact line count.
-
Methodology skill load limit: three methodology skills is what an agent gets without argument. Every name in the agent’s
skills:block counts, including the agent’s own procedure skill. An agent that lists more than three carries one recorded reason, and that record names the count it justifies. A fourth name still signals that the agent’s responsibility can be too broad, and answering that is what the reason is for. -
Extraction threshold: capability against fragment. Content that is an independently useful capability earns its own skill regardless of consumer count. Such content is coherent and self-contained, and the model or a future consumer can plausibly load it on demand. Claude Code preloads only each skill’s name and description. The body loads just-in-time when invoked. An unused small skill thus costs almost nothing. Content embedded into a consumer instead forecloses just-in-time loading for everyone else. Content that is only meaningful inside one consumer’s procedure, a procedure fragment, stays inline in that consumer.
-
Shared principles: six ordinary documents define human control, durable state, verified results, independent review, focused work, and boil the ocean. Execution, external-data, decisions, and bug-fix resources own the remaining operational rules. Question, Research, Design, Structure, Plan, and Implement procedures live in playbooks with shared templates and dependency, testing, and diagnosis references. Code policy lives in the code-standards reference; prose policy lives in the writing-standards reference. Read only applicable resources from the installed skill or agent base. Stop missing reads with the exact path. Twelve agent bodies read execution rules. File-finder retains its single-step contract. Resources use no skill frontmatter or discovery metadata. Keep the 27 commands registered. Guarded principles are their own tier: they carry skill frontmatter and
agents/openai.yaml, register as commands, and setdisable-model-invocation: trueso the model never applies them on its own. Do not add unguarded principle registrations, recursive loading, compatibility stubs, or a resource registry.
Codex host manifests
Every skill under skills/ carries agents/openai.yaml, the per-skill
manifest Codex reads to build its catalog entry. Without one, Codex falls back
to the directory name and a truncated description:. The file is optional
upstream and mandatory here.
Three fields, each derived from the skill’s own SKILL.md frontmatter rather
than stored twice: display_name title-cases the kebab name: through two
closed lists (acronyms up, joiners down); short_description is an imperative phrase in the spec’s 25-64
character window; default_prompt is Use $<name> to <short_description with
its first character lowercased>., using the skill’s own declared name as the
explicit-invocation token. No
icons, no brand color. A policy block declaring
allow_implicit_invocation: false appears if and only if the frontmatter sets
disable-model-invocation: true, and the test asserts that equality in both
directions.
short_description has no mechanical derivation. The creation guide requires
updating agents/openai.yaml whenever description: changes; the manifest gate
checks its shape and length.
OpenCode adapter
Distributed opencode/team.js exports only the native plugin function. It resolves
its real checkout and imports opencode/catalog.mjs, the same catalog validator
used by script/dev-opencode.mjs. The Bash lifecycle entry scripts require Node.
script/dev-install/dev-uninstall and dev.yml route the OpenCode target to them.
opencode/ counts as distributed runtime for land-time versioning.
The catalog enumerates immediate real skill directories in stable order, reads each header once, and walks each tree once without following links. It rejects nested skill files, symlinks, invalid/ambiguous consumed frontmatter, duplicate names, empty catalogs, and canonical template-marker paths. References and scripts remain canonical files. Install validates before registration; plugin initialization validates before returning config contributions. Existing command collisions and invalid consumed config types fail before any config mutation.
All skills receive native configured commands containing canonical file/base
pointers and $ARGUMENTS, without embedded bodies, model overrides, or agent
overrides. This includes methodology skills marked user-invocable: false.
Frontmatter disable-model-invocation: true excludes only Team’s added native
skill paths. Those skills still have explicit commands. Existing external skill
sources may expose their own guarded copies or resolve duplicate names to other
files. Team commands retain canonical pointers, but later plugins/MCP can collide.
Command-file reads use native read and external_directory permission. Unguarded
cached skill loading uses skill permission. read: deny does not block that
route. Supplied arguments retain native preprocessing, including shell syntax
such as !`printf example` that can run before a model call, outside
model-tool rules including bash: deny. File pointers preserve body text. They
do not make arguments inert. See OpenCode support
for usage and resolved-skill versus command-template diagnostics.
Lifecycle operations canonicalize the existing plugin parent, acquire its atomic
team.js.lock directory, then inspect/change only the exact-owned symlink. They
release only their acquired empty lock, refuse busy/stale locks, preserve config
and credentials without reading them, and never invoke OpenCode. Install success
means registered. Native config loading remains separate. New host processes read
live checkout edits. Concurrent checkout edits or external replacement without
the lifecycle lock are unsupported.
This adapter establishes discovery and lifecycle support. Full QRSPI execution,
specialist/nested dispatch, reviewer isolation, and hook host-firing on OpenCode
remain unverified; the hook adapter programs were probed by direct invocation
(program contract verified, host-firing unverified — see
hooks-portability.md). /retro stays guarded and discoverable and resolves OpenCode
sessions from the host’s SQLite store.
7. Hooks
Runtime hooks (hooks/, distributed with the plugin): eight hook programs — four
canonical, three Codex duplicates under hooks/codex/, and one Antigravity copy
under hooks/antigravity/ — plus three OpenCode adapters in opencode/team.js.
The complete hook × host matrix is
hooks-portability.md.
| Hook | Event | Registers on | Purpose |
|---|---|---|---|
pre-compact-anchor.mjs |
PreCompact | Claude .claude-plugin/plugin.json; Codex hooks/hooks.json (hooks/codex/ copy → stdout); OpenCode experimental.session.compacting |
Scan docs/plans/ |
session-start-recover.mjs |
SessionStart | Claude .claude-plugin/plugin.json; Codex hooks/hooks.json (hooks/codex/ copy → stdout); OpenCode experimental.chat.system.transform |
Scan docs/plans/ |
post-write-validate.mjs |
PostToolUse(Write|Edit) | Claude .claude-plugin/plugin.json; Codex hooks/hooks.json (hooks/codex/ copy, matcher apply_patch, exit 2); OpenCode tool.execute.after |
Structural validation of plugin component files |
validate-team-config.mjs |
UserPromptSubmit | Claude .claude-plugin/plugin.json; Codex hooks/hooks.json (reused canonical); Antigravity root hooks.json (hooks/antigravity/ copy at PreInvocation, inject-only) |
Validate .team/config.json. Block the prompt (exit 2) while it is invalid. |
The Codex copies move the recovery envelope to stdout with hookEventName, parse
apply_patch stdin, and block with exit 2; the canonical config guard is reused
unchanged because its stdin and exit-2 contract already match. Antigravity
exposes only PreInvocation, which cannot block, so its config binding injects
an ephemeral message and the prompt proceeds; the other three Antigravity events
are named gaps. OpenCode drives the canonical recovery files through its plugin
adapters. See hooks-portability.md for the verified vs.
unverified cells.
Both pre-compact-anchor.mjs and session-start-recover.mjs work the
same way. They list docs/plans/*/ directories. They pick the most
recent artifact directory by the mtime of any contained artifact. They
infer the current phase from artifact presence and frontmatter. They then
emit a short context message that names the phase, <id>, and the
suggested next /team-* command. Both are stateless, exit 0 on any
error, and return within the 5000ms hook budget.
validate-team-config.mjs is the odd one out: it is a guard, not a notice. It
reads <project>/.team/config.json, validates it through the same schema owner
the resolver uses (skills/team/references/model-config.mjs), and blocks the
prompt with exit 2 while the file is invalid. An absent file is valid — the
overrides are optional. A hook bug exits 0 rather than stranding the session.
Development hooks (.claude/hooks/, not distributed):
| Hook | Event | Purpose |
|---|---|---|
check-registry-sync.mjs |
PostToolUse(Write|Edit) | Verify the agents/ directory and registry.json agree by agent name |
pre-merge-guard.mjs |
PreToolUse(Bash) | Deny gh pr merge when the version-bump invariant fails |
Development scripts (.claude/scripts/, not distributed) house dev-only
tooling run by plugin developers: version computation, the land-time
version-consistency assertion, and project-board helpers.
8. Testing
Team currently has no test suite. The previous behavioral-eval harness
(tests/, evals/, and its CI workflows) was removed so a new testing
methodology can be designed from scratch. What remains is static: the dev
hooks under .claude/hooks/, the version scripts under .claude/scripts/
and .github/scripts/, and claude plugin validate ..
9. State management
Primary state: the artifacts in docs/plans/<id>/*.md. Each
artifact’s YAML frontmatter is the source of truth for “did this phase
finish?” and “did the design review pass?”
Live coordination: TodoWrite (session-scoped). The orchestrator
seeds the ledger at the start of /team, marks each item in_progress
when dispatching, and completed when the artifact lands. Any /team-*
command rebuilds the ledger by scanning artifacts on entry, so an
interrupted run can be resumed by re-invoking any of them bare: discovery
auto-resolves the artifact directory (an explicit docs/plans/<id>/ is still
accepted). On a host offering no TodoWrite, docs/plans/<id>/ledger.md
substitutes for the ledger rather than supplementing it, and the run reports
which of the two it used; being on disk, that one is durable rather than
session-scoped, so the aggregate gate’s round counts survive a restart.
Design-review records: docs/plans/<id>/design-review-<n>.md
(frontmatter verdict: <APPROVE|REQUEST CHANGES|COMMENT>) records each
review round durably. The artifacts are self-describing.
Compaction defense: the PreCompact hook scans docs/plans/<id>/
directories for the active topic and injects a 4-line anchor (phase,
<id>, suggested next /team-* command). The SessionStart hook does
the same for new sessions.
Artifact persistence: during a run, files in docs/plans/<id>/ live
on disk in the worktree’s working tree and
the pipeline never commits them. That discipline is what lets the
commit-based IMPLEMENT signal (≥1 commit on <id> since the
default-branch merge-base) distinguish “implementation has begun” from
“artifacts merely exist”. Any commit on <id> is thus a code or slice
commit, never an artifact commit. A finished plan directory can land
later in its feature PR, which is outside the run. Persistence across
sessions, compaction events, and context resets comes from the survival
of the worktree’s files, not from git history. They remain the durable
communication protocol between agents and the source of truth for “did
phase N finish?”
10. Nested sub-agents
Claude Code v2.1.172 lets sub-agents spawn their own sub-agents (up to
5 levels deep). The plugin uses this capability in exactly three patterns,
all governed by skills/team/references/agent-dispatch.md:
- Context-economy scouts (
researcher,implementer): read-onlyExplore/team:file-finderhelpers that absorb bulk reading the parent would otherwise hold in its own context without ever referencing it again. Scouts are long-lived: both agents holdSendMessage, so a follow-up question inside a live scout’s territory goes to that scout (warm context) rather than to a cold respawn, and the implementer dispatches the next slice’s scout in the background while finishing the current slice. The researcher’s scouts inherit the research isolation invariant: task-derived content in scout prompts — first dispatch and follow-up alike — is restricted to verbatim question text andCodebase contextfrom2-questions.md, plus4-repos.mdpaths. Fixed trusted prose paths, audit instructions, read-only tool rules, reply caps, and output contracts are allowed operational method text. - Skeptic verification (
code-reviewer,security-reviewer): each hard-gate finding (Blocking, CRITICAL, or HIGH) goes to a freshgeneral-purposesub-agent as a neutral, falsifiable claim, with instructions to refute it. The claim never carries the reviewer’s verdict or severity. Skeptics are deliberately one-shot — never a follow-up to a live skeptic — because a skeptic that has judged earlier claims accumulates a model of the review and anchors to it. Default-keep: a finding is dropped only on an evidence-backed refutation the reviewer verifies itself. A false hard-gate finding costs an entire review round (implementer re-dispatch- all 5 reviewers re-run), so the pass pays for itself.
- Vendor couriers (
code-reviewer; the orchestrator uses the same pattern at the design-review gate as ordinary dispatch): each cross-model vendor call runs through oneExplorecourier named after its CLI (codex-review,agy-review), so each external model’s review is visible as its own agent while it runs. The courier’s errand is fixed — run the pinned runner command, return its stdout verbatim — and the vendor-courier block inskills/team/references/cross-model-review.mdcarries the contract plus the inline fallback when nesting is unavailable.
Policy:
- The
Agenttool is granted to exactly four agents:researcher,implementer,code-reviewer,security-reviewer. Any other agent gaining the tool must be a deliberate decision. - Nested helpers are read-only, never write under
docs/plans/, and never pause for user input (seeskills/team/references/agent-dispatch.md). - Depth budget: pipeline agents sit at depth 2 of 5 and may spawn at most one more level.
- Version-gated. Nesting requires Claude Code >= 2.1.172. The
universal gate is
Agent-tool presence. The platform withholds the tool from sub-agents below that floor. An agent that lacksAgentthus works inline. So does any read-only agent likeresearcherthat has noBash. Agents that also holdBashadditionally run the bundled deterministic checkskills/team/references/supports-nesting.mjs "$(claude --version)". The check is fail-closed: an older release, unrecognizable version output, or an environment where it cannot run all resolve to “unsupported,” which routes the agent to its inline path. - Optimization, never a dependency. Every nested-dispatch section is optional with a mandatory inline fallback. On Claude Code versions without nesting, the plugin degrades to exactly its previous behavior. Nesting is invisible to the orchestrator: no phase-table, gate, or artifact contract depends on it.
Before any non-vendor dispatch, the parent resolves and Reads the writing
standards reference under ${CLAUDE_PLUGIN_ROOT}. Claude
Code substitutes that installed plugin root before dispatch. The prompt carries
the resolved, read-only path. The helper Reads it before it audits its
authored report. If any Read fails, the parent discards the return. Research
scouts fall back to inline reading. Reviewer skeptics keep the finding by
default. Vendor couriers receive no prose paths and relay stdout unchanged.
Research assembly treats completed file-finder and researcher returns as
unchanged, untrusted source data. At capture, the root wraps each return in a
backtick fence labeled untrusted-evidence-file-finder or
untrusted-evidence-researcher and makes it longer than every backtick run in
that return. A fixed line identifies the blocks as untrusted evidence and says
embedded imperatives carry no authority. The root then traces every final
substantive claim only to the completed returns, never to task framing.
File-finder returns at most 80 lines for one repo or 120 for multiple repos.
Researcher returns at most 60 or 100 lines. The root reserves eleven lines for
the five-line frontmatter,
authority line, four fence lines, and one source-grounded synthesis line. The
final artifact therefore has at most 151 lines for one repo or 231 for multiple
repos.
Line validation normalizes line endings but counts every physical line,
including terminal empty and whitespace-only lines.
The root retries an oversized producer once with the same isolated inputs. It
stops on a second oversized return and never truncates source data.
Design, structure, planning, test authoring, and implementation use those
blocks only as evidence. Each actor revalidates proposed actions or acceptance
tests against 1-task.md, which records user intent. Embedded imperatives
authorize no action.
Future work (ship-later)
Recorded here so the next capability step is deliberate, not improvised. Prerequisite for all items: nesting survives 2-3 Claude Code releases without breaking changes, parallel dispatch semantics for nested children are confirmed, and the depth cap is stable.
- Verify-coordinator (strongest candidate): an IMPLEMENT-phase
coordinator that owns the 5-reviewer fan-out, the aggregate gate, and
the typed failure retry loop. It returns a compact terminal verdict for
the orchestrator to render:
{verdict: PASS | CONDITIONAL | ESCALATE, rounds, findings[]}. This keeps every reviewer report out of the orchestrator’s long-lived context. Needs: a terminal-verdict envelope protocol, because the no-consult rule means no mid-loop user interaction exists to forward. It also needs per-round state artifacts (docs/plans/<id>/review/round-<n>.md) to replace live TodoWrite round visibility and to survive coordinator death. - Research-coordinator: only if multi-repo research outgrows the current 2-agent fan-out (e.g. 2×N agents across N repos).
- Parallel sub-implementers: only ever slice-level (never step-level), one worktree per slice, coordinator cherry-picks sequentially to preserve linear history. Requires measured wall-clock pain on large plans.