Teams
Manage dynamic teams of domain-specific agents with tracking framework.
Arguments: $ARGUMENTS
Prompt contract
Position 1 of $ARGUMENTS is a free-form prompt (RU/EN) — the mode and the [name] positional are
optional and may follow in any order. Nobody types keys: resolve mode + team name FROM the prompt.
| Mode | EN keywords | RU keywords | Mutates? |
|---|---|---|---|
status |
(empty), status, show, list, check |
статус, покажи, что, проверь |
no |
install |
install, create, setup, new team, build |
установи, создай, настрой, новая команда |
yes |
upgrade |
upgrade, update, tune, improve, retune |
обнови, улучши, настрой лучше |
yes |
enable |
enable, on, turn on, activate, restore |
включи, активируй, верни, восстанови |
yes |
disable |
disable, off, turn off, pause, park |
выключи, отключи, пауза, приостанови |
yes |
uninstall |
uninstall, remove, delete, clean up, tear down |
удали, убери, сними, очисти |
yes, destructive |
purge |
purge, wipe, nuke, delete everything, remove all |
снеси, удали всё, вычисти, полностью удали |
yes, destructive |
- Strip flags (
--skip-review,--review). An explicit mode token anywhere wins outright, no scoring. - Else score modes by distinct whole-word keyword hits (table above). Highest unique score wins.
Tie with a destructive mode ->
AskUserQuestion; tie withstatus->status; tie of two mutating modes -> the keyword appearing first; all zero -> the documented default:statusif the named team already exists, elseinstall(detect-mode.shalready applies this default when the input is empty or the first word is not a canonical mode). - Empty arguments -> the same default.
statusasks nothing;installand the other mutating defaults ask ONE scoping question only when the answer changes what gets written. - Outcome-changing ambiguity -> ONE
AskUserQuestion(max 4 questions) BEFORE any work. - A prompt that is not a bare
mode [name]pair is still input, never an error: extract the team NAME (and, forinstall, the team description) from the prose. Never treat the first word of a sentence as the positional[name]—"disable the payments team"names teampayments, notdisable;detect-mode.sh's literal first-word parse is only correct for a baremode [name]shape, see Error Handling below for the prose case.
Then print this block ONCE, before the first action (## Universal Prelude Step 0.4):
PLAN — brewcode:teams-setup
INPUT: <arguments verbatim, or "(empty)">
MODE: <resolved> — <explicit | matched keyword: X | default>
SCOPE: <team name, agent count/roster, paths under .claude/teams/{name}/ and .claude/agents/>
DO: <2-5 imperative bullets>
RESULT: <what the user ends up holding>
Labels are literal; values follow the conversation language. status still prints it — asks nothing.
Phase 1: Parse Arguments
EXECUTE using Bash tool:
bash "${CLAUDE_SKILL_DIR}/scripts/detect-mode.sh" "$ARGUMENTS" && echo "OK" || echo "FAILED"
Output: MODE:, TEAM_NAME:, PROMPT: (optional), plus the artifact-metadata scalars
PLUGIN_VERSION:, CONTENT_VERSION:, GENERATED_BY:, LAST_UPDATED:. Store all of them.
Artifact metadata — every file this skill writes.
team.mdand every generated domain agent carryversion=PLUGIN_VERSION:,generated_by=GENERATED_BY:(brewcode:teams-setup),last_updated=LAST_UPDATED:, anddoc_type: llmon the agents.team.md's header table ALSO carriescontent_version=CONTENT_VERSION:, right afterVersion— self-located bydetect-mode.shfrom THIS skill's ownSKILL.mdline-1brewcode-meta:marker (the onebump-version.shstamps at release), never copied fromPLUGIN_VERSION:and never invented. Take the values from the output above — never hardcode a version, never calldatea second time with a different format, and never stamp a "template version": the plugin version replaces it..claude/agents/intent-guard.mdis the ONE exception:generate.sh emit-agentstamps it withgenerated_by: brewcode:superreview-setup, and teams never touches those keys.
Resolve INTENT_GUARD_POLICY before a write: a new team defaults to required; an existing team.md
with |Intent guard|required| or |Intent guard|legacy-absent| keeps that exact value. When the row
predates this field, presence of an intent-guard roster member migrates to required; absence migrates
to legacy-absent. These are the only values. required requires the fixed review-only row;
legacy-absent forbids that row and MUST NOT add the role during upgrade.
Resolve REPORT_ROOT from the applicable project guidance before every team.md write. The narrowest
durable project instruction wins (for example, Dusk's Codex guidance requires .codex/reports even when
this Claude workflow performs the write); otherwise use .claude/reports. Store a normalized project-relative
path with no trailing slash. Reject absolute paths, ~, .. segments, backslashes, whitespace, doubled
slashes, unresolved {...} tokens, control characters, or shell metacharacters. Every slash-separated
segment MUST match ^[A-Za-z0-9._-]+$ and MUST NOT equal . or ..; this rejects $(), backticks,
;, &, and | by construction. If equally specific applicable guidance declares two distinct report
roots, STOP on the conflict instead of selecting either. Never infer the report root from this plugin's
own defaults when project guidance declares one.
MODE is one of the canonical seven, in this order: status | install | upgrade | enable | disable | uninstall | purge. On any ERROR: line: report it verbatim and STOP. Never guess a mode, and
never treat a canonical verb as a team name — install enable creates a team NAMED enable, so the
verb always comes first and the optional [name] positional after it.
How a team is enabled or disabled. Claude Code discovers a project agent only through
.claude/agents/<name>.md.disablerenames each member to<name>.md.disabled;enablerenames it back. The file body,team.md,trace.jsonl,trace-archive.jsonland the cursor are untouched either way, so the toggle is fully reversible and loses no configuration and no history. It is NOT an uninstall: nothing is deleted. Underrequired,intent-guardis never parked — it is shared with/brewcode:superreview-setup, exactly as in UNINSTALL and PURGE. Underlegacy-absent, no guard file or roster row is introduced.
Universal Prelude (every mode)
Step 0: Init + Validate + Confirm
Output:
Mode: {MODE}, Team: {TEAM_NAME}Load environment:
| Action | Command / Path |
|---|---|
| Read agent template | ${CLAUDE_SKILL_DIR}/references/agent-template.md |
| Read framework templates | ${CLAUDE_SKILL_DIR}/references/framework-files.md |
| Check team dir | .claude/teams/{TEAM_NAME}/ -- exists? |
| Check existing agents | .claude/agents/ -- list all |
| If team.md exists | Read, show current roster |
| If trace.jsonl exists | Show entry counts via trace-ops.sh read |
An absent trace.jsonl is valid before the first event or after cleanup: status reports zero events,
verification stays read-only, and trace-ops.sh add creates it safely on the first write. A present
trace target must be a non-symlink regular file.
Preflight the durable tokenizer without network or mutation:
python3 -I -S "${CLAUDE_SKILL_DIR}/scripts/prepare-tokenizer.py" checkIf it is missing, retain the emitted
REPAIR: ... preparecommand.statusreports the missing prerequisite and does not run team verification. A mutating mode waits for step 5 approval before preparation. If the preflight passes and the team exists, verify:bash "${CLAUDE_SKILL_DIR}/scripts/verify-team.sh" "TEAM_NAME_HERE" && echo "PASS" || echo "FAIL"Print the PLAN block (
## Prompt contractabove) — once, before step 5's confirmation and before any mutation.statusprints it too, then skips straight to its report — no AskUserQuestion.Mutating modes only — ASK using AskUserQuestion: "PLAN above. Continue?" Options: "Yes, continue" | "No, I want changes" | "Cancel"
- "changes" -> AskUserQuestion for details, revise the PLAN and reprint it
- "Cancel" -> STOP
After approval, prepare the isolated tokenizer when step 3 reported it missing, then preflight it again. This explicit step is the only tokenizer install/network path; it downloads the exact platform wheel and BPE into the user cache, verifies both SHA-256 values, creates a dedicated venv, and installs the wheel with
--no-deps --no-index:python3 -I -S "${CLAUDE_SKILL_DIR}/scripts/prepare-tokenizer.py" prepare \ && python3 -I -S "${CLAUDE_SKILL_DIR}/scripts/prepare-tokenizer.py" checkSTOP on failure.
verify-team.shandcount-tokens.pynever install, download, or use a temporary runtime; they fail closed with the same repair command.
Delegation (applies to EVERY Task spawn in this skill)
A big task handed to one agent = an agent gone for an hour: you cannot observe it, cannot correct it, and it usually drifts off-target. One subagent = ONE bounded unit — one deliverable (here: ONE agent file), ~<=5 files, ~<=10 steps. Bigger MUST be split into N tasks, all spawned in ONE message. That is why agents are created one-per-spawn and reviews are fanned out.
Every spawn prompt MUST carry:
| Field | Content |
|---|---|
| GOAL | the overall task and why it exists — the point beyond the file edit |
| ROLE | what this agent owns; what it must NOT touch |
| SCOPE | exact paths/commands in bounds + explicit out-of-bounds |
| CONTEXT | what is already done, by whom, what runs in parallel — trimmed to what THIS agent needs |
| CONSUMER | who or what uses the result next, and the shape it must fit |
| DONE | acceptance criteria + the exact report shape you want back |
A bare one-line task is never enough. See C8 for the canonical spawn shape. Every code/test brief MUST make the agent find the closest well-built counterpart in the repo and follow its principles - IN ADDITION to conventions/rules/docs, never instead.
Mode: INSTALL (9 phases)
C1: Project Analysis
Spawn 3-5 Explore agents in ONE message via Task tool:
| # | Focus |
|---|---|
| 1 | Code structure: modules, packages, domains, architectural layers |
| 2 | Existing agents (.claude/agents/, brewcode/agents/, ~/.claude/agents/) + Claude Code infrastructure |
| 3 | Tech stack: build files, frameworks, dependencies, languages |
| 4 | CI/CD, testing, deploy, infrastructure |
| 5 (optional) | Domain boundaries: business logic, API, data layer, UI |
All via Task(subagent_type="Explore"). Consolidate into single analysis document.
For the new team's default required policy, also harvest the intent-guard facts (agent #1 and #4
cover most of these; add explicit asks to their prompts).
These fill the placeholders of the shared intent-guard.md.template in C3 — an unharvested fact must be recorded
as none / not present in this project, never invented:
| Fact | Fills | Where to look |
|---|---|---|
| Project name | {PROJECT_NAME} |
repo dir, root CLAUDE.md, package.json/build file |
| Where original requirements live (tracker, issues, Slack, "chat only") | {TRACKER_LABEL} |
CLAUDE.md, .github/, issue templates, CI links |
| Spec / design-doc paths or globs | {SPEC_LOCATION} |
.claude/specs/**, docs/, adr/ |
| Plan / task-board / task-graph paths | {PLAN_LOCATION} |
.claude/features/**, TASKS.md, board files |
Policy paths: root + nested CLAUDE.md, rules, conventions |
{POLICY_LOCATION} |
CLAUDE.md, .claude/rules/** |
| Planned scale / user count, testing policy, dependency policy, file-layout policy, architecture stance | {PROJECT_INVARIANTS_TABLE} |
CLAUDE.md, rules, test dirs, manifests, module layout |
| 3-6 plausible drift instances in this repo's vocabulary | {DRIFT_EXAMPLES_TABLE} |
derived from the invariants above |
| Cheap evidence commands (diffstat, manifest diff, test-file count, new-file list) for this stack | {EVIDENCE_COMMANDS_BASH} |
build/test tooling found by agent #3 and #4 |
Also resolve and store REPORT_ROOT from applicable root/nested project guidance using the prelude rule.
An exact durable project path wins; guidance silence falls back to .claude/reports. Equal-specificity
conflicting report-root directives -> STOP. Validate the winning path before C2.6.
C2: Team Proposal (interactive)
Based on analysis + PROMPT (if provided), propose 3 variants via AskUserQuestion.
New installs use INTENT_GUARD_POLICY=required: intent-guard is a fixed review-only anti-drift
member (asked-vs-delivered), outside the domain-agent count. The 5 / 10-12 / 15-20 counts describe
DOMAIN agents only. Show it as fixed in every new-install variant:
Fixed member (every variant, not counted):
| Agent | Domain | Mission |
| intent-guard | -- (review-only) | Compares what was ASKED vs what was DELIVERED; explicit invocation only |
Minimal (5 domain agents + intent-guard):
| Agent | Domain | Mission |
Balanced (10-12 domain agents + intent-guard) -- Recommended:
| Agent | Domain | Mission |
Maximum (15-20 domain agents + intent-guard):
| Agent | Domain | Mission |
Options: "Minimal (5)" | "Balanced (recommended)" | "Maximum (15-20)" | "Custom -- I'll specify"
If "Custom" -- second AskUserQuestion for free input; the new-install required policy stays fixed.
Final confirmation of agent list before proceeding. Existing legacy-absent teams are handled only by
UPGRADE and retain their explicit policy without adding intent-guard.
If
.claude/agents/intent-guard.mdalready exists (e.g./brewcode:superreview-setupcreated it), label the fixed rowreuse (already present)— C3-IG'semit-agentcall will reportREUSEand leave the file untouched.
Agent names are globally unique across teams — REJECT a name another team already owns. Two teams
listing the same agent share one file: one team's upgrade rewrites the other's member, and the other's
uninstall/purge is then blocked by the ownership check (cleanup-flow.md Step 3 step 0c), leaving
an undeletable roster row. Before showing the variants, run from the project root for every proposed name
(intent-guard excluded — it is shared BY DESIGN and exempt from this check):
for a in {PROPOSED_NAMES}; do
o=$(bash "${CLAUDE_SKILL_DIR}/scripts/agent-owners.sh" "$a") && echo "TAKEN $a <- $o"
done; echo "OK"
- exit 0 (any owner printed) -> the name is TAKEN. Drop it from the variant and propose a distinct
one — a domain-qualified rename such as
{name}-{TEAM_NAME}or a different domain word. Never reuse, never "join" the other team's agent. - exit 2 (no owner) -> free, use it.
- exit 1 (refusal, reason on stderr) -> treat the name as TAKEN until the reason is fixed; report the stderr line, do not guess.
Say which names were renamed and why in the confirmation before C3.
C2.5: Model Selection (AskUserQuestion)
"Default model for domain agents: Opus (most reliable)."
| Model | Best for | Cost |
|---|---|---|
| opus | Complex domains, architecture, critical logic | High |
| sonnet | Standard domains, CRUD, testing, utilities | Medium |
| haiku | Simple utility agents, formatting, validation | Low |
Options: "Opus (recommended)" | "Sonnet" | "Haiku" | "Mixed -- I'll choose per agent"
If "Mixed" -- ask model per agent in C3. Store as DEFAULT_MODEL (default: opus).
DEFAULT_MODELapplies to DOMAIN agents only.intent-guardkeeps themodel: sonnetits shared template ships — do not ask about it, do not override it.
C2.6: Shared Contract Bootstrap (before agent discovery)
This gate MUST finish before any team-owned .claude/agents/{name}.md is written. An interrupted install
may leave a partial roster, but no discoverable compact profile may ever point at a missing shared contract.
- Create
.claude/teams/{TEAM_NAME}/. - Read
${CLAUDE_SKILL_DIR}/references/framework-files.md; writeteam.mdwith substituted metadata, validatedREPORT_ROOT,INTENT_GUARD_POLICY=required, the byte-faithful## Shared Agent Contract, exact "intent-guardis review-only, keeps its own output contract, and never implements." substitution, the## Agentsheader, and only the required fixedintent-guardrow. Do not add domain-agent rows yet; C4 finalizes the successfully created roster. - Create empty
trace.jsonl; copy the project-localtrace-ops.shand make it executable. - Gate before C3:
team.mdexists, contains## Shared Agent Contract, the project-local tracer path, andA task traced \took` ends with exactly one terminal track: `completed` or `failed`.`
STOP on any failure. Do not spawn or write an agent. Resume by repairing this bootstrap first; never
strip shared rules from a profile until its target team.md passes the gate.
C3: Agent Creation (agent-creator x N)
Read
${CLAUDE_SKILL_DIR}/references/agent-template.md1a. Confirm C2.6 completed..claude/teams/{TEAM_NAME}/team.mdis already written and gated; if missing or incomplete, STOP before the first spawn and repair the bootstrap. 1b. Re-run the C2 uniqueness check on the FINAL confirmed roster, immediately before the first spawn — the user may have typed names in the "Custom" branch that never passed it. Same script, same exit-code reading. AnyTAKENname -> do not spawn; go back and rename it with the user first. Also refuse a name whose.claude/agents/{name}.md.disabledexists with no live file: that is another install's parked agent, and writing the live path recreates the dual-copy state bothenableanddisablerefuse.For each agent, spawn
Task(subagent_type="brewcode:agent-creator")— ONE agent file per spawn, never a whole team. Prompt carries GOAL (build this one{TEAM_NAME}roster member; siblings own other domains), ROLE (owns.claude/agents/{name}.mdonly), SCOPE (that file; other agents,team.md, project source out), CONTEXT (settled mission/domain/project analysis, selected model, 3-4 sibling names; no trigger/domain overlap; the gated shared contract already exists), CONSUMER (C4 adds the final roster row; C5 reviews; the roster routes work), DONE:description<=100 chars (optimal ~80), single-line role + 2-3 triggers, no<example>;- body <=3200 bytes and <=800 exact
tiktoken==0.13.0o200k_basetokens, with exactly these ordered headings and no others:## Mission,## Owned surfaces,## Exclusions,## Must-load references,## Unique invariants,## Unique verification; ## Must-load referencesnames.claude/teams/{TEAM_NAME}/team.mdfirst;- profile contains only domain-unique facts.
Task Acceptance Protocol,Return Contract,Trace Instructions,Colleagues,Scope Fit, shared routing, and shared output rules stay only inteam.md; - placeholders substituted; return file path + description line.
Every spawn prompt MUST also carry the template path and the four metadata lines, resolved — the subagent cannot see Phase 1's output, so replace
{PLUGIN_VERSION}and{LAST_UPDATED}below with the literal values from the Phase 1PLUGIN_VERSION:/LAST_UPDATED:lines before you send the prompt. A token that reaches the subagent ships verbatim into the agent file, andsetup-statusthen reports that agentpartialforever. Those two spellings are the only sanctioned ones — never an angle form, never a double brace:CONTEXT (cont.): structure from ${CLAUDE_SKILL_DIR}/references/agent-template.md — read it first. DONE (cont.): the frontmatter ends with exactly these four keys, in this order, AFTER the agent's own keys (name, description, model, tools — leave those byte-untouched, `tools` above all): doc_type: llm version: "{PLUGIN_VERSION}" generated_by: "brewcode:teams-setup" last_updated: "{LAST_UPDATED}"verify-team.shre-reads every generated agent's frontmatter and FAILS on a wrong order, a missing key or wrong quoting, so a prompt that shipped a token does not pass C4.Batch 3-4 agents in parallel per message
After each batch, optimize without changing the six-heading contract:
Task(subagent_type="brewtools:text-optimizer", prompt="Light-optimize .claude/agents/{agent-name}.md; preserve its exact six ordered headings, team.md reference, names/numbers/negations/scope. Output metrics.")brewtoolsnot installed (text-optimizerunavailable) — skip the pass, agents stay as written. Never run the optimizer on.claude/agents/intent-guard.md. Its frontmatterdescriptionis deliberately short and review-only; an optimizer pass may reword, lengthen or reflow it into a normal domain-agent description, which would make it compete for auto-activation. Excluded.
C3-IG: intent-guard (required policy, exactly once)
.claude/agents/intent-guard.md has exactly ONE writer: generate.sh emit-agent, shared with
/brewcode:superreview-setup. Never author this file from the template yourself, and never spawn an agent
to author it — that would fork the file into two divergent pipelines. agent-creator appears in this
phase only as a post-processor that replaces three seeded BLOCKs.
Step 1 — emit. Run from the project root, exporting the C1 facts. Unharvested fact -> none /
not present in this project; never invent a tracker, a path or a ticket id.
EXECUTE using Bash tool (substitute the C1 values first):
PROJECT_NAME="PROJECT_NAME_HERE" \
TRACKER_LABEL="TRACKER_LABEL_HERE" \
SPEC_LOCATION="SPEC_LOCATION_HERE" \
PLAN_LOCATION="PLAN_LOCATION_HERE" \
POLICY_LOCATION="POLICY_LOCATION_HERE" \
bash "${CLAUDE_SKILL_DIR}/../superreview-setup/scripts/generate.sh" emit-agent && echo "OK" || echo "FAILED"
It creates-or-reuses ONLY .claude/agents/intent-guard.md (superreview does not need to have run) and
prints exactly one INTENT_GUARD: line on STDOUT: INTENT_GUARD: CREATED <path>,
INTENT_GUARD: REUSE <path> or INTENT_GUARD: MIGRATED <path> (a pre-standard file of ours, restamped
in place — metadata only, tailored body preserved). Diagnostics (e.g. "recreating from template") go to
stderr and never add a second status line.
STOP if FAILED -- report the script output; do not fall back to hand-authoring the file.
Step 2 — sanity-check the emitted file (a pre-existing file may be empty, truncated or
placeholder-laden; -f alone proves nothing). This runs on the REUSE path too, where $f is somebody's
already-adapted agent whose evidence block legitimately holds shell expansions — so strip ${VAR} FIRST
and match bare tokens on what is left. Without the strip a ${BASE} scores as an unresolved placeholder,
and this step's remedy is rm -f: it would delete a tailored file.
f=.claude/agents/intent-guard.md
[ -s "$f" ] && grep -q '^name: intent-guard' "$f" \
&& ! sed 's/\${[A-Z_][A-Z_]*}//g' "$f" | grep -q '{[A-Z_]\{2,\}}' && echo "SANE" || echo "CORRUPT"
grep -qF '<!-- generated_by: brewcode:superreview-setup' "$f" 2>/dev/null && echo "OURS" || echo "FOREIGN"
CORRUPT+OURS-> the file came out of this pipeline, sorm -f .claude/agents/intent-guard.md, re-run Step 1 once (a fresh emit is now aCREATED), re-check. StillCORRUPT-> STOP and report; do not patch it by hand.CORRUPT+FOREIGN-> STOP. Neverrmit. An unstamped file is the project's own agent and its{TOKENS}may be its own convention; deleting it is the data loss this check exists to prevent (emit-agentalready REUSED it byte-untouched and printed the tokens as a conflict on stderr). Report the path and the tokens and let the user decide.
Step 3 — adapt the seeded BLOCKs. Only on INTENT_GUARD: CREATED. On REUSE or MIGRATED skip this
step entirely: the existing file is already project-adapted and must not be rewritten or "refreshed".
emit-agent seeds three BLOCKs with GENERIC marked defaults. Spawn ONE
Task(subagent_type="brewcode:agent-creator"), alone (not batched with the domain agents), to replace
them with project-specific content:
Task(subagent_type="brewcode:agent-creator", prompt="
GOAL: team '{TEAM_NAME}' has its fixed review-only member intent-guard — the anti-drift check that
compares what was ASKED against what was DELIVERED. The file is ALREADY WRITTEN by
superreview-setup/scripts/generate.sh emit-agent with generic placeholder content in three BLOCKs.
Your only job is to tailor those three BLOCKs to this project.
ROLE: you own exactly three marked BLOCKs inside .claude/agents/intent-guard.md:
PROJECT_INVARIANTS_TABLE, DRIFT_EXAMPLES_TABLE, EVIDENCE_COMMANDS_BASH.
You do NOT author this agent and you do NOT re-instantiate it from any template.
SCOPE: Edit only the content of those three BLOCKs, in place.
EACH REPLACEMENT MUST CONSUME ITS MARKER. Every seeded BLOCK ends in its own
`<!-- SEEDED-DEFAULT: ... -->` line. Key each Edit on that marker: `old_string` = the
seeded block PLUS its marker line, `new_string` = your project-specific replacement
WITHOUT any marker. A surviving marker is what makes a skipped adaptation detectable —
`generate.sh validate` reports any file that still carries one as UNTAILORED.
HARD out of bounds — a single byte changed here is a failed task:
- the frontmatter (name, description, model: sonnet, tools, color, maxTurns). The
description is <= 100 chars, review-only, explicitly-invoked BY DESIGN; do NOT rewrite,
lengthen or 'improve' it. This overrides any default description-authoring habit.
- the file header, every heading, and every other section of the file
- the shared template, other agent files, team.md, trace.jsonl, project source
CONTEXT: C1 project analysis is settled — use these facts, invent nothing:
PROJECT_INVARIANTS_TABLE = from C1: planned scale/user count, testing policy, dependency
policy, file-layout policy, architecture stance
DRIFT_EXAMPLES_TABLE = 3-6 drift instances in THIS repo's vocabulary
EVIDENCE_COMMANDS_BASH = cheap evidence commands for THIS stack (diffstat, manifest diff,
test-file count, new-file list)
Unknown fact -> write 'none' / 'not present in this project'. Never fabricate a tracker,
a path or a ticket id. Do not add a Scope Fit block, Task Acceptance Protocol, trace
instructions or a Domain Instructions section — this agent has no code domain.
CONSUMER: /brewcode:superreview-setup spawns this same file by name during review, and C4 adds its row to
.claude/teams/{TEAM_NAME}/team.md — the file name and agent name stay exactly 'intent-guard'.
DONE: three BLOCKs project-specific, all three SEEDED-DEFAULT markers gone (consumed by the
replacements), everything else byte-identical to what emit-agent wrote.
Report: path + the three BLOCK contents + confirmation that frontmatter and header are untouched.
")
Step 4 — verify. FOUR counts, one grep per line, in this order. Each pattern matches the ARTIFACT,
never prose ABOUT it: the emitted agent legitimately keeps a tail comment that NAMES the stripped
TEMPLATE HEADER, so an unanchored grep -c 'TEMPLATE HEADER' reports 1 on every healthy file and
turns this gate into an unpassable loop. Match the header's opening line, not the phrase. Same reason the
placeholder count strips ${VAR} first: {PROJECT_NAME} is a token, ${CLAUDE_PLUGIN_ROOT} in an adapted
evidence command is not, and only a strip-then-match tells them apart — a $-guard inside the pattern
mis-handles adjacent tokens. || true on every line: zero matches is the happy path for three of the four
counts (repo rule avoid#7), and a count must still PRINT under set -o pipefail, especially when it is the
one going red.
f=.claude/agents/intent-guard.md
sed 's/\${[A-Z_][A-Z_]*}//g' "$f" | grep -c '{[A-Z_]\{2,\}}' || true # 0 — unresolved placeholder
grep -c '^<!-- TEMPLATE HEADER' "$f" || true # 0 — header comment not stripped by emit
grep -c '^name: intent-guard' "$f" || true # 1 — frontmatter name key intact
grep -cF '<!-- SEEDED-DEFAULT:' "$f" || true # 0 — every seeded BLOCK marker consumed
Must print 0, 0, 1, 0. A non-zero last count means an adaptation left its marker (or skipped
the block) and generate.sh validate will report the agent UNTAILORED.
STOP if not -- re-spawn Step 3 once with the offending lines named.
Report intent-guard: created (adapted) or intent-guard: reused (already present) and continue to
C4. Either way a required team gets its team.md row. This phase is skipped for an existing
legacy-absent team; never emit or adapt the agent merely to upgrade that team.
C4: Roster Finalization + Verification
Re-check the C2.6 bootstrap before editing the roster. Missing/malformed shared contract, unsafe or unresolved report root, or wrong policy-conditional intent-guard sentence -> STOP; never finalize discoverable agents against an absent authority.
Finalize
team.mdfrom${CLAUDE_SKILL_DIR}/references/framework-files.md: preserve the bootstrapped Shared Agent Contract byte-faithful, add one compact domain row per successfully created agent, and apply the explicit intent policy (requiredretains the fixed row;legacy-absenthas no row). Thentouch trace.jsonl. No confirmed-but-unwritten agent enters the roster.Then install the project-local tracer the generated agents call. A
.claude/agents/*.mdfile is not plugin-owned, so${CLAUDE_PLUGIN_ROOT}is NOT substituted inside it and no*_PLUGIN_ROOTenv var exists — the only path an agent can rely on is a repo-relative one:cp "${CLAUDE_SKILL_DIR}/scripts/trace-ops.sh" ".claude/teams/TEAM_NAME_HERE/trace-ops.sh" && \ chmod +x ".claude/teams/TEAM_NAME_HERE/trace-ops.sh" && echo "OK" || echo "FAILED"STOP if FAILED — without it every agent's trace call is a no-op, STATUS reports 0 tasks and UPGRADE misclassifies the whole roster as
Inactive. Re-copy it in UPGRADE too (cpis idempotent) so a team created by an older version gains it.team.mdMUST carry|Intent guard|required|plus anintent-guardrow (trailingKindcolumn =review-only, trailingVersioncolumn =PLUGIN_VERSION:), whether C3-IG created or reused it. Underlegacy-absent, it MUST carry|Intent guard|legacy-absent|and no such row.Agents | {N}counts DOMAIN agents only.The header table MUST carry these four rows, adjacent and in exactly this order, filled from the Phase 1
PLUGIN_VERSION:/CONTENT_VERSION:/GENERATED_BY:/LAST_UPDATED:lines:| Version | {PLUGIN_VERSION} | | Content version | {CONTENT_VERSION} | | Generated by | brewcode:teams-setup | | Last update | {LAST_UPDATED} |No placeholder token may survive into the written file — a literal
{PLUGIN_VERSION}inteam.mdmeans substitution never happened.Add
|Agent defaults|active;{LAST_UPDATED};domain;{PLUGIN_VERSION}|. A domain row using all four defaults keeps the seven-column shape but leaves those cells empty:|name|domain|mission|||||. Write all four cells only for an override; the fixed review-onlyintent-guardrow stays explicit.Keep roster
Domain/Missioncells terse; agent profiles own detail. For up to 13 domain agents, the complete writtenteam.md(metadata + shared contract + every row) MUST be <=2800 characters and <=700 exacttiktoken==0.13.0o200k_basetokens.verify-team.shfails closed when the approved durable runtime or hash-verified cache is absent/mismatched; only Universal Prelude step 6 prepares it. Measure the full substituted file, not the empty template; if over, compress only roster wording without dropping members, columns, policy, or contract facts.Verify:
bash "${CLAUDE_SKILL_DIR}/scripts/verify-team.sh" "TEAM_NAME_HERE" && echo "PASS" || echo "FAIL"STOP if FAIL -- fix missing files before continuing.
AskUserQuestion: final report + suggest
/brewcode:teams-setup status {TEAM_NAME}
C5: Quorum Review
Spawn 3 reviewer agents in ONE message via Task tool. REVIEWER (here and in C7/C9) = the
project's reviewer agent from .claude/agents/, else general-purpose.
intent-guardis never theREVIEWER. It is not a general reviewer: it only compares asked-vs-delivered on a real delivery, and it has no code domain. Never select it for the C5/C7/C9 pipeline role, and never as an implementation owner in C8 or U4.
| # | Focus |
|---|---|
| 1 | Profile contract: body only (frontmatter excluded) <=3200 bytes / <=800 exact tiktoken==0.13.0 o200k_base tokens; exactly six ordered body headings (Mission, Owned surfaces, Exclusions, Must-load references, Unique invariants, Unique verification); .claude/teams/{TEAM_NAME}/team.md loaded first; no repeated shared-contract heading/rule |
| 2 | Domain accuracy: correct scope, tool selection, model fit, description triggers |
| 3 | Architecture: no domain overlaps; owned surfaces/exclusions/routing agree with the roster; acceptance/tracing/returns/colleagues/scope-fit exist once in team.md |
.claude/agents/intent-guard.md is reviewed under DIFFERENT criteria — it is an instantiated shared
template, not an authored domain agent. Judge only: placeholders all resolved, template header stripped,
frontmatter identical to the template (short review-only description, model: sonnet, read-only tools),
project facts accurate and not invented. Do NOT judge it on the six-heading domain profile, domain fit/scope,
description triggers, acceptance, scope-fit, shared return or tracing — it has none by design, and
"add the missing sections" is a FALSE POSITIVE here. Never propose lengthening its description.
Each reads ALL agent files in .claude/agents/ and outputs:
FILE: .claude/agents/{name}.md
SEVERITY: critical/important/minor
ISSUE: description
FIX: suggested fix
C6: Consensus Filter
Quorum threshold: 2/3 agreement = confirmed. Match criteria: same file + same area (+/- 5 lines or same section) + same category (instruction/domain/architecture/trigger).
| Outcome | Action |
|---|---|
| 2/3+ confirm | Mark confirmed, keep severity from highest reporter |
| 1/3 only | Log as unconfirmed, skip |
| Minor severity (all reporters) | Log but skip fix |
C7: Verification
Task(subagent_type=REVIEWER, prompt="
Verify these findings against actual agent files. For each:
1. Read the agent file
2. Check if the issue actually exists
3. Mark: VERIFIED or FALSE_POSITIVE
{confirmed_findings}
")
Filter out false positives. Final list = verified critical + important issues.
C8: Fix
For each verified critical/important issue:
Task(subagent_type="brewcode:agent-creator", prompt="
GOAL: team '{TEAM_NAME}' was just generated and quorum-reviewed; this task clears ONE
confirmed defect so the roster ships clean.
ROLE: you own {agent_file} only. Do NOT touch other agent files, team.md, trace.jsonl,
CLAUDE.md, or project source.
SCOPE: {agent_file}. Out of bounds: everything else.
CONTEXT: C3 already wrote the whole roster and C5-C7 quorum-reviewed it; this finding is
verified (2/3 reviewers + C7 double-check) — do NOT re-litigate it. Up to 3 sibling
agent-creators fix other agent files in this same batch; team.md already lists the final
roster, so do not rename the agent or change its domain.
Read `${CLAUDE_SKILL_DIR}/references/agent-template.md` first; it is the canonical domain-profile
shape. For a domain agent, preserve exactly its six ordered body headings and shared-team reference.
ISSUE: {description}
FIX: {suggested_fix}
SEVERITY: {severity}
CONSUMER: C9 re-verifies your file for "issue resolved + no regression", and the team
manifest .claude/teams/{TEAM_NAME}/team.md must stay accurate — keep name, domain and
description shape intact so its roster row still matches.
DONE: fix applied and validated. Domain-agent body (frontmatter excluded) <=3200 bytes, exactly the
canonical six ordered headings, team.md loaded first, no shared contract duplicated. Report:
file | what changed | validation result.
")
Batch: up to 3 parallel per message. Minor issues skipped.
If
{agent_file}is.claude/agents/intent-guard.md, add to the ROLE: frontmatter is frozen — the description stays short and review-only, tools stay read-only,model: sonnetstays. Only placeholder content (project facts, invariants, drift examples, evidence commands) may be fixed.
C9: Re-verify
Task(subagent_type=REVIEWER, prompt="
Re-verify these fixes. For each:
1. Read the fixed agent file
2. Check original issue is resolved
3. Check no regression introduced
4. For every domain agent, hard-gate exactly one single-line description <=100 characters and the
body only (frontmatter excluded): <=3200 bytes; exactly
`Mission`, `Owned surfaces`, `Exclusions`, `Must-load references`, `Unique invariants`,
`Unique verification` in order with no other headings; team.md first; no shared rule duplicated.
`intent-guard` is exempt from this six-heading gate and keeps its frozen review-only contract.
Mark: FIXED or REGRESSION
{fixes_applied}
")
| Outcome | Action |
|---|---|
| All FIXED | Pipeline complete, proceed to Epilogue |
| REGRESSION found | Return to C8 for that file (max 2 cycles) |
| Still failing after 2 cycles | Log as unresolved, proceed to Epilogue |
To skip review pipeline: add
--skip-reviewtoinstallarguments. To run review on existing team:/brewcode:teams-setup upgrade {TEAM_NAME} --review
Mode: STATUS (read-only)
No modifications. Read + report only.
- Read
.claude/teams/{TEAM_NAME}/team.md - Read trace data:
Parse JSONL: group bybash "${CLAUDE_SKILL_DIR}/scripts/trace-ops.sh" read ".claude/teams/{TEAM_NAME}" && echo "OK" || echo "FAILED"src(agent) andk(kind). Compute per-agent stats fromk=track(took/refused/completed/failed counts), issues fromk=issue, insights fromk=insight.
Output:
# Team Status: {TEAM_NAME}
## Summary
| Metric | Value |
|--------|-------|
| Agents | {N} |
| Tasks tracked | {N} |
| Success rate | {%} |
| Open issues | {N} (high: {N}, critical: {N}) |
| Insights | {N} |
| Last activity | {date} |
## Per Agent
| Agent | Tasks | Success | Refused | Issues | Insights | Health |
|-------|-------|---------|---------|--------|----------|--------|
## Recommendations
Health:
| Label | Criteria |
|---|---|
| Healthy | >70% success, active |
| Needs tuning | 30-70% success or many refusals |
| Underperforming/Inactive | <30% success or inactive |
Recommendations: underperformers -> suggest /brewcode:teams-setup upgrade; >200 trace rows -> suggest uninstall; 0 activity -> suggest review.
No AskUserQuestion -- pu
…(truncated)