brainstorm-toolkit
AGENTS.md0 starsChanged 39 days agoMITView on GitHub
Instructions for AI coding agents (Claude Code, GitHub Copilot, Cursor, Codex, etc.) working in this repo. brainstorm-toolkit is a cross-tool plugin: a collection of SKILL.md-style slash commands that work in both Claude Code and GitHub Copilot. The design goal is low token weight — each skill is a focused, single-purpose file, and skills share a unified AGENTS.md / TASKS.md / project.json contract rather than embedding templates and checklists inline. Both hold .md reference material; they differ in who reads them…
Where files are headingNew AGENTS.md files have more rules about keeping secrets out of the code, and fewer about code style.
Of the AGENTS.md files we read, the 31,774 first seen in the last six months, against the older ones: the kind of rule that gained most share, and the kind that lost most. About files like this in general, not this one, and an estimate, since a kind is a pattern in the words.
In this repository14 other files it gives its agents.
- brainstormSkill
- brainstorm-teamSkill
- code-tourSkill
- dead-code-reviewSkill
- docstring-syncSkill
- flowsimSkill
- gotchaSkill
- plan-htmlSkill
- repo-healthSkill
- repo-onboardingSkill
- sdlcSkill
- sdlc-statusSkill
- taskSkill
- test-checkSkill
The file
Show its rules and text
We split this AGENTS.md into the rules it gives an agent
13 rules. About 0 are common, 4 are distinctive, and 9 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈4
Distinctive · estimate
This author's own choices. Worth a look.
9
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Very specific: line 79
If the line says Read skills/sdlc/templates/<x>.md now, the paragraph after it is a gate, not a summary.
- Distinctive: line 124
Every skill's name + description loads into every session on every turn, whether or not the skill ever fires, on all three runtimes.
- Very specific: line 133
Keep the whole set under 7,500 characters (measured, not estimated — parse the frontmatter, don't grep -c).
- Very specific: line 191
Read the affected skill's SKILL.md fully before editing.
- Very specific: line 192
If changing a contract (e.g., where a skill writes files), update the consumers too — grep across skills/, copilot/skills/, and README.md.
- Very specific: line 193
If a skill exists in both skills/ (canonical) and copilot/skills/ (override), changes may need to be reflected in both.
- Distinctive: line 194
Avoid adding Claude-only features to cross-tool skills unless the skill also has a Copilot override.
- Very specific: line 214
Every skill is prose. There is one expression of each pipeline stage (the canonical skills/<name>/SKILL.md) plus per-tool overlays where a …
- Distinctive: line 283
Before promoting a rule from prose to a hook, ask:
- Very specific: line 307
Add the skill's directory path to .claude-plugin/marketplace.json under plugins[0].skills.
- Distinctive: line 309
Update the skills table in README.md.
- Very specific: line 345
tools:is an allowlist the harness tops up: Treat it as "no Write/Edit", not as an exact set. - Very specific: line 365
If you do add or edit one: name must match the filename stem, register it in .claude-plugin/marketplace.json under plugins[].agents, and …
≈ “Common” is an estimate: at least 1 in 5 of the 40,246 AGENTS.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
AGENTS.md — brainstorm-toolkit
Instructions for AI coding agents (Claude Code, GitHub Copilot, Cursor, Codex, etc.) working in this repo.
What this repo is
brainstorm-toolkit is a cross-tool plugin: a collection of SKILL.md-style slash commands that work in both Claude Code and GitHub Copilot. The design goal is low token weight — each skill is a focused, single-purpose file, and skills share a unified AGENTS.md / TASKS.md / project.json contract rather than embedding templates and checklists inline.
Layout
.claude-plugin/ # Plugin + marketplace manifests
skills/<name>/SKILL.md # Canonical skills (source of truth, Claude-first)
skills/<name>/references/ # Runtime reference a skill LOADS — shipped into consumers by setup.sh
copilot/skills/<name>/ # Copilot overrides (only skills that differ from canonical)
codex/skills/<name>/ # Codex overrides (sequential; falls through to copilot/ then canonical)
agents/ # Claude-only sub-agent definitions
scripts/ # Shared helpers (eval-runner.py, check_docker_logs.py)
templates/ # AGENTS.md / TASKS.md / project.json templates for consumer repos
docs/ # Maintainer/architecture docs + see-also targets — NOT installed into consumers
examples/ # GOTCHAS.md.example
setup.sh # Installer — copies skills into a target repo (Claude / Copilot / Codex)
README.md # User-facing docsdocs/ vs skills/<name>/references/ — the placement rule
Both hold .md reference material; they differ in who reads them and whether they ship:
docs/— maintainer/architecture docs, and any doc a skill merely cites / see-also's (FLOW.md,CONVENTIONS.md,REVIEW-FIX-STAGE.md,PHASE-1-STATE-ENVELOPE.md).setup.shdoes not copydocs/, so these are zero token weight in consumer repos. A citation is a one-line pointer (naming per docs/CONVENTIONS.md) — the reader jumps to the plugin repo.skills/<name>/references/— material a skill's prompt instructs the agent to open and load at runtime (sdlc/templates/review checklists — e.g. the correctness/security lens rubrics).setup.shcopies the whole skill tree, so this ships into every consumer that installs the skill — and pays its weight only there.
Placement test: does the skill LOAD the file to do its job (→ references/), or merely
CITE it (→ docs/)? A citation is a pointer, not a payload. Never move a maintainer/see-also doc
into references/ — that ships it (installed once per tool — up to three identical copies under
--tools all) to every consumer for readers who never open it.
Per-tool overlays replace the canonical SKILL.md, not the canonical resources. setup.sh
installs the overlay's files and then fills in any of templates/, references/, scripts/, assets/
the overlay does not carry from the canonical skill (install_overlay). So an overlay cites the same
skills/<name>/templates/<file> paths the canonical does and never inlines a body; it ships its own
copy of a directory only when the content must genuinely differ for that tool.
Rationale prose — two kinds, one of which ships
The house style attaches a reason to most rules. That is deliberate and it stays. But two very different things wear the same coat, and only one of them earns a place in a file that loads on every run:
- Failure-mode rationale — KEEP. It names what the model will do wrong and
why, and it is the enforcement. "You will be tempted to run the tests inline —
shell traffic was ~53% of main-thread tokens on an audited run"; "this is the
step that keeps getting skipped, which leaves the loop dead"; "guessing here
compounds through the entire
/sdlcrun"; "a dispatch with nomodelbypasses the cap with zero log line". Strip the reason from any of these and the rule reads as a preference the model overrides the first time it is inconvenient. - Design-history rationale — MOVE to
docs/. It records what the design used to be or why a maintainer chose it. "This replaces the former Stages 5, 5.5 and 5.6"; "it now coexists instead of racing"; "the dogfood showed exactly this"; the/sdlc-litemerge changelog; the Workflow autopsy. Every one of these is true, useful to a maintainer, and paid for on every consumer run.docs/is not shipped bysetup.sh, so a citation there costs nothing.
The test: does the sentence change what the model does on this run, or does
it explain to a person why the file looks like this? The second belongs in
docs/LOOP-HYGIENE.md, docs/MODEL-AXES.md, docs/PROSE-FIDELITY.md,
docs/CONFIG.md, or docs/CONVENTIONS.md (Migration policy) — all of which
already exist for exactly this.
Two corollaries, both already violated at least once:
- A skill must not restate a template it also tells the model to read now.
If the line says
**Read skills/sdlc/templates/<x>.md now**, the paragraph after it is a gate, not a summary. This is the same "gate in the skill, body in the template" rule stated from the reader's side. - A runtime note addressed to Copilot/Codex belongs in the Copilot/Codex
overlay, not in a shared template. A shared template is read by all three
runtimes; a "no sub-agent seam?" callout in one is dead text on Claude and
costs on every run. The overlay
SKILL.mdis the only file guaranteed loaded on the runtime that needs it —--resumecan skip any given template.
What is NOT a violation: the same rule stated in several skills that never
load each other (Sonnet by default appears across ~20 files). Progressive
disclosure means a rule stated once in a file nobody else opens propagates
nowhere. Each of those sites should be a one-line pointer to
skills/sdlc/templates/models.md, not a re-derivation of the contract — but the
repetition itself is required, not redundant.
Skill authoring rules
- Frontmatter must include toolkit routing metadata under
metadata.brainstorm-toolkit-applies-to. Useclaudefor Claude-only skills orclaude copilotfor dual-tool skills. Example:--- name: status description: ... metadata: brainstorm-toolkit-applies-to: claude copilot ---setup.shuses this metadata to decide whether the skill is copied to.github/skills/<name>/(Copilot) in addition to.claude/skills/<name>/(Claude). The installer still accepts the legacy top-levelapplies-to:key for backward compatibility, but new edits in this repo should usemetadata. - Claude-only features (Plan mode, sub-agents via the Agent tool, hooks) → mark the skill
claudeonly inskills/. If the skill is still useful on Copilot in a simplified form, create a Copilot-optimized override incopilot/skills/<name>/SKILL.md(see rule 9). Keep each SKILL.md under 500 lines. That is the ceiling in the open Agent Skills spec (https://agentskills.io/specification), which Claude Code, Copilot and Codex all honor, and this repo adopts it unchanged rather than maintaining a stricter house number. Nothing here is close — run
wc -l skills/*/SKILL.mdfor current sizes rather than trusting a number here, since the largest file changes as skills grow. Note that 500 is a documented recommendation, not a validator-enforced hard error — no tool in the chain rejects a longer file.Length is not the real signal — duplication is. Past ~300 lines, ask whether a stage body belongs in
skills/sdlc/templates/instead. A skill that restates a template it also tells the model to read now is a finding at any line count; a skill whose prose is the product (code-tour's fabrication warnings and its "what bad output looks like" rubric are the output spec, not a wrapper around a template) is not a finding at any length. Judge on duplication, not on the count.Frontmatter
description— a hard budget, because it is always resident. Every skill's name + description loads into every session on every turn, whether or not the skill ever fires, on all three runtimes. Codex caps the whole discovery listing at 8,000 characters (or 2% of context) and silently shortens descriptions from the end — dropping skills entirely when over. Claude Code truncates each description at 1,536 chars and caps the listing at ~1% of context.setup.shinstalls every skill underskills/, so this repo's descriptions are measured against those ceilings as a set.- Target ≤550 characters per description; 600 is the ceiling.
- Keep the whole set under 7,500 characters (measured, not estimated —
parse the frontmatter, don't
grep -c). - Front-load trigger keywords in the first ~15 words. Codex truncates from the end; a description whose distinctive phrases are in its last sentence loses them first, silently.
- Explanation, neighbour-routing and "what this skill is NOT" belong in the
body, never the description.
gotcha(464 chars) is the reference shape: what it does + one clear when. - Enforced, not just documented:
scripts/ci/check_contracts.py'sdescription-budgetcheck measures everyskills/*/SKILL.mddescription with a real frontmatter parse. Set total ≤7,500 chars and per-skill ≤600 chars are hard failures; per-skill >550 is a printed warning that does not fail the check.
- No inline templates or long checklists. Reference
templates/*.templatefiles instead. - Graceful skip on missing config — read
.claude/project.jsonkeys with fallbacks; skills must work with an empty or missingproject.json. - Copilot uses Agent Skills, not prompt-file shims. Consumer repos should receive
.github/skills/<name>/SKILL.md, including any bundled resources referenced by the skill. - Claude helper agents stay in
.claude/agents/. VS Code can discover Claude-format agents there, so this repo does not maintain a duplicate.github/agents/tree for the current Claude-only helper agents. - Copilot overlay pattern.
copilot/skills/<name>/SKILL.mdoverrides the canonicalskills/<name>/SKILL.mdfor Copilot distribution. Use this when a skill needs Claude-specific features (Plan mode, agents) in its canonical version but can still provide value as a simplified Copilot slash command.setup.shprefers the override when it exists; otherwise falls through to the canonical version. Overrides must setmetadata.brainstorm-toolkit-applies-to: copilotand passvalidate_skills.pyindependently. Portable frontmatter subset. The open Agent Skills spec (https://agentskills.io/specification), which GitHub Copilot and OpenAI Codex both implement, defines
name,description,license,metadata,compatibility,allowed-toolsonly. A strict spec validator — and Anthropic's own Skills API upload — hard-errors on any other key; Copilot and Codex as shipped are more lenient (they log "unknown field ignored" and load anyway). Write to the strict set regardless: leniency is a current implementation detail, not a contract. Claude-only keys (argument-hint,disable-model-invocation, ...) may appear on the canonicalskills/<name>/SKILL.md(the Claude install source);setup.shstrips them for the.github/skills/and.agents/skills/installs.copilot/skills/<name>/SKILL.mdandcodex/skills/<name>/SKILL.mdoverlays must never declare them by hand —check_contracts.py'sportable-frontmattercheck enforces this.<!-- assert-manual: recheck-by 2027-03-15 "Copilot and Codex load an unknown SKILL.md frontmatter key leniently (log + continue) rather than hard-erroring" -->
Unified contracts
AGENTS.md— repo-wide agent instructions.setup.shwrites it fromtemplates/AGENTS.md.template, then writesCLAUDE.mdas a plain-file copy of it — deliberately not a symlink, since WSL/NTFS and Windows git both struggle with symlinks (indexing failures, IDE edits silently following the link). Consumers keep the two files in sync by hand after that.TASKS.md— markdown checkbox list at repo root; the portable, durable task tracker. It is the only cross-tool backlog:/sdlc-status, the--queueloop and the Stop hooks all read it, and it survives the session (/repo-healthdoes not read it today). Claude Code's native task list (TaskCreate/TaskUpdate) is a separate, session-scoped progress indicator —/taskmirrors its one item and/sdlcmirrors its stage list, both Claude-only and both skipped silently elsewhere. Never let a decision depend on the native list, and never treat it as a substitute for aTASKS.mdrow: it is a view, not a record.GOTCHAS.md— project-specific pitfalls; consulted by/gotchaand the sanity-check stage of/sdlc..claude/project.json— optional per-project config (test commands, eval runner, modules list); every key is optional, missing keys are skipped.- Gotcha flywheel — the loop-exit capture protocol is centralized in
skills/gotcha/SKILL.md("Capture at loop-exit")./taskand/sdlcauto-draft a gotcha only on an objective trigger (a fix-loop that failed-then-recovered, or the user voicing surprise), routed through gotcha's dedup — never a vibe-gate. When capture is declined, both drop a/gotcha <text>.next-actionsentinel; the seam is Stop-hook-backed on all three runtimes, with an inlineNext:fallback for when no hook is wired/trusted yet — full contract atdocs/SEAM.md(also the home of the separatestop-gate.shtest-rerun hook and its mutual-exclusion rule with the sentinel)./brainstorminjects area-scoped gotchas at Step 2 (entry), not only at validation. - Model tiers — two independent axes, canonical contract in
skills/sdlc/templates/models.md. Read it before touching any dispatch site; do not restate it here.- Axis 1 (fan-out tier):
.claude/project.jsonmodels.<role>> built-in default, thenmodels.capas a ceiling. There is no CLI flag; every dispatch role has its own key.models.capis a ceiling, never a target, and absent = no ceiling. The fan-out is Sonnet-first by default everywhere — Opus is an explicit opt-up. Keep it that way when adding a dispatch (and give it amodels.<role>key). - Axis 2 (reviewer model,
/sdlconly):models.code_review, defaultopus, stage permanently opt-in (pipeline.review_fix.enabled). Not on the haiku<sonnet<opus ladder;models.capnever lowers it. Its cost is bounded by fan-out width (agents.code_review_lenses,agents.code_review_max_lenses, default 4) instead. An explicitmodels.code_reviewis always the dispatched value — a reviewer that lands on the implementer's tier marks the runindependence: degradedrather than being bumped to a higher tier. - Keep the two axes mechanically separate in any future edit. Prose is
the default enforcement surface: each dispatch resolves its tier and
prints
model: <tier> (cap: <cap|none>)before dispatching. The opt-inpipeline.enforce_capPreToolUse hook (scripts/hooks/enforce-model-cap.sh, Claude only) makes Axis 1 deterministic by rewriting an over-cap dispatchmodel, exemptingreview:-prefixed dispatches (Axis 2). - Adding or rewording a fan-out dispatch is a two-leg edit: canonical
prose, then the Copilot/Codex overlays.
validate_skills.pysoft-warns if a fan-out skill drops themodels.mdpointer.
- Axis 1 (fan-out tier):
When modifying skills
- Read the affected skill's
SKILL.mdfully before editing. - If changing a contract (e.g., where a skill writes files), update the consumers too — grep across
skills/,copilot/skills/, andREADME.md. - If a skill exists in both
skills/(canonical) andcopilot/skills/(override), changes may need to be reflected in both. The Copilot override is a separate file, not a patch. - Avoid adding Claude-only features to cross-tool skills unless the skill also has a Copilot override.
Renaming or deleting a skill — never s|/old|/new|g
A global substitution rewrites every sentence that talks about the name, not just the
name. It has silently corrupted this repo six times: a FLOW.md diagram showing /sdlc
doing "branch → commit → push → PR" (it does no git writes), `sdlc`, `sdlc`, or `task`,
and three table rows collapsing into one command are all artifacts of it. Nothing catches
this — validate_skills.py and check_install_refs.py only prove paths resolve.
Grep first, read every hit, edit by hand. Attribution sentences ("absorbed from the former
X", "replaces X") must keep the OLD name — that is the whole point of the sentence. Then run
two checks: one for the same command named twice in one sentence (the shape of a collapsed
pair), and one for the fact the rename invalidated — after the pipeline merge that was
grep -rn "opens a PR\|touches git history", which found wrong-fact prose no token check
could see. Both commands, with the six case studies, are written out under "Migration policy" in
docs/CONVENTIONS.md.
Execution model — prose only
Every skill is prose. There is one expression of each pipeline stage (the canonical
skills/<name>/SKILL.md) plus per-tool overlays where a runtime genuinely differs.
Nothing in this repo runs a Workflow. The one that existed (sdlc-pipeline.workflow.js,
1,398 lines mirroring the prose, plus a smaller one in /brainstorm-deep) was deleted because
the prose↔Workflow sync leg had no automated guard and drifted. Do not add one back for the
same reason — see docs/PROSE-FIDELITY.md for the full case history.
So a stage-contract change is now a two-leg edit: the canonical prose, then the
Copilot/Codex overlays (which have no Workflow and never did — the prose is all they run).
validate_skills.py guards the prose↔overlay parity leg with a soft warning.
Where the canonical stage prose lives: skills/sdlc/templates/
skills/sdlc/ holds the skill and templates/, the shared stage bodies that
/sdlc and its Copilot/Codex overlays all load. setup.sh ships that tree to every
tool root in step 1b (install_shared_templates()) and rewrites the citation prefix, so
an overlay opens the same file the canonical skill does — the overlays must point at
the templates, never inline them. scripts/ci/check_install_refs.py runs in CI and
fails the build if any cited template does not resolve in a fresh install.
Each stage's body lives in one template there — output-verbosity, resumption,
stage-1.5-sanity-check, stage-2-gate, stage-2-implement, stage-2a/2b/2c,
stage-3-evals, fix-loop, stage-5-validate, stage-5.7-review-fix, stage-5.9-cleanup,
stage-6-handoff, secret-scan, stage-5-skill-repo, changed-files-gate, scope-gate,
convention-grounding, envelope-staleness, models, state-schema, operator-gate — and
skills/sdlc/SKILL.md stays thin per stage: a short
framing paragraph, the gate/skip rule that decides whether to run, and a
**Read skills/sdlc/templates/<x>.md now** pointer.
Two rules follow, and both are load-bearing:
- Edit the template, not the skill. A stage-contract change is one edit in
skills/sdlc/templates/plus the overlays. Copying a stage body into aSKILL.mdre-creates the canonical↔overlay drift the split exists to prevent. - The gate goes in the skill, the body goes in the template. A stage that self-skips
(no
eval.runner, review not opted in, no plan target, not a skill repo) must be able to decide that without opening the template it is skipping. That is where most of the saving comes from: a default run never loadsstage-5.7-review-fix.mdat all.
/sdlc absorbed the former /sdlc-lite — the two duplicated every stage, so keeping both
cost more than the merge did. The survivor took the /sdlc name, does no git writes, and
hands you a validated tree; the rename is recorded under Migration policy in docs/CONVENTIONS.md.
Two flags gate whole templates rather than sections — --queue (queue-mode.md) and the
review stage's opt-in. Keep it that way: a flag nobody passed should cost nothing.
Keeping the shell install in parity
scripts/sync-global.sh is the third install route (plugin, setup.sh, shell). It reads
hooks/hooks.json at run time and copies scripts/, templates/ and plugin.json into
~/.claude/brainstorm-toolkit/. So a change to hooks/hooks.json, or to which repo-root
scripts/ or templates/ paths skills call, must keep sync-global.sh in parity: never list
hook scripts in it (CI's shell-install-parity check enforces the hook half), and extend its
runtime copy when a skill starts citing a new repo-root directory. scripts/ci/setup-roundtrip.sh
exercises the full install/re-run/uninstall round trip against a scratch HOME.
When a rule earns a hook, not just prose
A skill is an advisory control — it can only ask the model to follow it. The hooks in
scripts/hooks/ exist because sometimes that isn't enough — the policy controls are
enforce-model-cap.sh, ask-gate.sh, stop-gate.sh and next-action.sh, and the context/observability hooks are
reseed-context.sh and run-cost-report.sh, which is the distinction this section cares
about: a skill is an advisory control while a hook is the deterministic layer behind it.
The failure that motivates
this is measured, not hypothetical: an audited /sdlc run said **Read
skills/sdlc/templates/<x>.md now** at nine points, the model read zero of them (795 lines of
stage contract unread), and nothing detected it.
Before promoting a rule from prose to a hook, ask:
- Does the rule need to hold even when the model forgets, not just when it cooperates? Prose only works on a model that reads it; a rule that fails silently when skipped (a model tier, a rewritten test file) is the candidate — a rule that only needs a nudge is not.
- Can the check itself be expressed deterministically — reading structured input (stdin
JSON,
project.json, a file hash) and returning a decision with no interpretation? If the check needs judgment, it stays prose regardless of how important the rule is. - Can
scripts/ci/test-hooks.shexercise it with scratch input and assert on stdout, the way it already does forenforce-model-cap.sh,stop-gate.sh, andprotect-tests.sh? A control nothing tests is a liability, not a control. - Is a preventer actually enforceable, or only a detector? A
PreToolUsematcher can be routed around (aBash-drivensed -iskips aWrite|Editmatcher);scripts/protect-tests.shanswers "deterministic, yes — but a detector, not a hook" for exactly this reason.
Weigh this against the cost honestly: a hook is also a second expression of the same rule,
and this repo deleted a 1,398-line Workflow that mirrored the prose exactly because that second
expression drifted with no automated guard. Pay the cost only when the second expression stays
small, mechanical, and testable — the shipped hooks run a few hundred lines each, an order of
magnitude under the Workflow's 1,398. Worked examples: docs/ENFORCEMENT.md.
When adding a new skill
- Copy the shape of a similar existing skill; don't invent new conventions.
- Add the skill's directory path to
.claude-plugin/marketplace.jsonunderplugins[0].skills. - Set
metadata.brainstorm-toolkit-applies-tohonestly. - Update the skills table in
README.md.
When adding a sub-agent (agents/) — usually: don't
Sub-agent definitions are a different artifact from skills, with their own failure mode.
An earlier four-agent set went almost entirely undispatched: every dispatch site named
subagent_type: general-purpose and pasted the role prompt in from a template, so the agent
files sat there costing maintenance and buying nothing. The ones that survive
(test-runner, e2e-test-runner, plan-conformance-validator, question-advisor) are each named at a real
site — check that before adding a fourth.
The rule:
Create an agent definition when and only when you need an enforced
tools:restriction, on a Claude-only agent whose prose has explicitly exempted it from the model-cap axis. Otherwise: a role prompt intemplates/+subagent_type: general-purpose+ an explicitmodel:at the dispatch site.
Frontmatter buys exactly three things nothing else can, and two of them are usually dead here:
| Field | Unique capability | Usually |
description: | auto-delegation — Claude picks the agent unprompted | Dead — every skill names its agent explicitly, and auto-delegation is unreliable in practice |
tools: | an enforced boundary; prose saying "you are read-only" is advisory | The real win — verified enforced: a declared allowlist omits Bash/Write entirely |
model: | pins a default tier | A default, not an override — since v2.1.251 the dispatch site's per-invocation model outranks frontmatter (order: per-invocation > frontmatter > CLAUDE_CODE_SUBAGENT_MODEL > session). So it does NOT bypass the ladder. Still prefer pinning at the dispatch site — that is where the models.<role> + models.cap resolution is printed and auditable — but a frontmatter tier is a safe floor for an agent that must never run hot (test-runner pins haiku) |
Also weigh, before adding one:
- Cross-tool blindness.
setup.shcopiesagents/for Claude only. Copilot and Codex have no agent-definition concept, so anything encoded in frontmatter is invisible to two of three runtimes. - Restart, but only sometimes. Claude Code watches
.claude/agents/and picks up an added or edited file within seconds, no restart needed. Three cases still need one, and the first is the one that bites a consumer: creating a scope's first agent file in a newagents/directory (i.e. a freshsetup.shinstall), an agents dir under--add-dir, and a session started with--disable-slash-commands. Editing an existing agent is live. tools:is an allowlist the harness tops up. Treat it as "no Write/Edit", not as an exact set. Accepts a comma- or space-separated string or a YAML list. Command-scoped forms likeBash(git log:*)are not a documented value here — if the agent needs git, it needs plainBash. The one documented scoped form isAgent(type-a, type-b), restricting which subagents may be spawned. A misspelled tool name is silently dropped; if every entry resolves to nothing the dispatch fails outright with "would be spawned with zero tools".- Plugin agents ignore three fields.
hooks,mcpServersandpermissionModeare dropped when an agent loads from a plugin — which is how this repo ships. Don't encode behaviour in them. Plugin agents are addressedbrainstorm-toolkit:<name>; the bare name works only for a vendored copy (a project agent under.claude/agents/), which is why the dispatch sites say "or bare<name>when vendored".
The one standing exception, recorded rather than hidden: e2e-test-runner declares no
tools: and no model:, so by the rule above it earns nothing and should be an inline role
prompt. It needs the full tool set to run a browser suite and apply fixes, so there is no
boundary to enforce. It is kept because it is dispatched by name at two real sites and its
prompt is long enough to be worth a file — but it is the exception, not the pattern. A fourth
agent without a tools: restriction should be an inline role prompt instead;
scripts/validate_skills.py warns on one.
If you do add or edit one: name must match the filename stem, register it in
.claude-plugin/marketplace.json under plugins[].agents, and never let the prose claim a
tier or a read-only posture that the frontmatter doesn't enforce. scripts/validate_skills.py
checks all of this.
Testing changes
This repo runs three tiers of testing, cheapest first — see docs/EVALS.md: static
prose/contract checks (below, free, every push), scripts/eval-runner.py's fixture-based
pytest evals, and scripts/ci/skill-eval.py's headless outcome evals on a fixture repo
(costs real money — nightly/on-demand only, never per push). Verify manually by:
- Running
python scripts/validate_skills.pyfrom the repo root — this covers skills andagents/frontmatter (missingname/description, a prose model-tier or read-only claim the frontmatter doesn't enforce, marketplace registration drift). - Running
python scripts/ci/check_contracts.py— checks proving the prose, the config and the shipped plugin agree: everyproject.jsonkey a skill names exists intemplates/project.json.example; every repo-path citation resolves (and adocs/file a skill says to load is a placement error); no forbidden (rename-invalidated) phrase survives; no sentence names the same command twice; no Copilot/Codex overlay declares a Claude-only frontmatter key; no shipped line invokes a barepython3(the Windows Store-stub trap) and nohooks.jsoncommand lacks an interpreter token; every skill's frontmatterdescriptionstays inside its budget (description-budget: 600-char per-skill / 7,500-char set-total fail, 550-char per-skill warn); and.claude-plugin/plugin.json'sversionmoved when shipped content did — an unmoved version leaves every consumer on a stale cached plugin, silently.--self-testexercises each one against a synthetic tree. - Running
bash scripts/ci/test-hooks.sh— the regression harness for the deterministic controls that back policy instead of prose — the two wired hooks (scripts/hooks/enforce-model-cap.sh,scripts/hooks/stop-gate.sh) and thescripts/protect-tests.shdetector CLI: scratch project dirs, sample stdin JSON, assertions on stdout. Exits 1 on the first failing case. - Running
bash setup.sh --target /tmp/test-repo --tools bothagainst a scratch repo. - Invoking the changed skill in both Claude Code and Copilot when the skill targets both tools.
- Confirming the skill runs without referencing removed files or broken paths.
For the Python helpers in scripts/, run them against the examples or a known input and check output.
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

