Add `pipeline.boss.spec_auto_sign` (default off). With it on, a /boss run may sign a spec in the user's place — but only through a gate built to never rely on the orchestrator's own confidence: all objective gates green (precondition, parse, grounding-check PASS with no human override) AND a unanimous five-lens adversarial spec-skeptic panel (criterion, grounding, scope-fork, ambiguity, plan-readiness). Any single BLOCK falls back to the human sign-off pause. On a clean sign the orchestrator commits the spec ((boss-signed) in the subject), fires a mandatory informational-with-veto notify, and proceeds to planner without stopping. A later veto is a forward correction, never a history rewind. - new agent: specify/agents/spec-skeptic.md (read-only, one lens per dispatch) - specify Step 6 + Iron Law: approval may come from the auto-sign gate, never from model self-confidence - boss: third notify category, §"Spec auto-sign", rationalisations, red flags - profile-schema + template: the opt-in slot - pipeline.md, agent-template.md, README: the auto-sign path documented
24 KiB
name: specify description: Use when the design is already settled — a long in-context design discussion, an exhaustive tracker issue, or a ratified design handed over by brainstorm — and a spec must be produced from those sources with review but without an interview. The spec-production core: applies the feature-acceptance criterion, writes the spec under paths.spec_dir, runs the parse and grounding-check gates, takes user sign-off, hands off to planner. Bounces to brainstorm the moment the sources do not resolve a load-bearing design decision. Co-equal third entry path alongside brainstorm and tdd.
specify — spec-production entry path
Violating the letter of these rules is violating the spirit.
Overview
specify is where a settled design becomes an approved spec. It
takes given sources — a long in-context design discussion, an
exhaustive tracker issue, settled design docs, or a ratified design
narrative handed over by brainstorm — and produces the spec the
planner consumes: with review, but without an interview.
It is the sole home of the spec-production gates: the
feature-acceptance criterion, the write-spec step, the
parse-every-block self-review, the grounding-check hard-gate, and
the user-review gate. Whichever way design work enters — fresh
through brainstorm's discovery, or directly from sources that
already resolve the design — it passes through specify to become a
spec. specify carries the universal invariant no plan without an
approved spec.
specify is the producing half of a deliberate split. brainstorm
owns deciding — interview, approaches, ratification. specify owns
producing — rendering that decision into the canonical artefact and
clearing the gates. The split is the toolchain's deepest discipline
applied one level up: tdd → implement and debug → implement split
RED from GREEN across two dispatches so the spec stays honest;
specify splits deciding from producing so the producing phase reads
the decision as a source rather than making it inline.
This skill is not opt-in. Unlike tdd (a profile-gated bypass),
specify is a core pipeline node: it is the gate before planner on
every design path that is not a bug fix or a test-specifiable feature.
When to Use / Skipping
Triggers:
- The design is settled in the sources and a spec must be written:
an exhaustive issue body, a long in-context design discussion, or
a ratified design
brainstormjust handed over. - A cycle-scope spec is missing for settled work and one is needed.
Use the named alternative instead for:
- A genuine design fork — the sources do not resolve a
load-bearing decision. Use
brainstorm(its discovery is what resolves the fork).specifyitself bounces here the moment it detects this (see The Iron Law and Step 1.5). - A test-specifiable feature, on a profile that enables
tdd— the RED executable-spec is the spec. Usetdddirectly. - An observed bug — use
debugdirectly (RED-first). - A tidy iteration — use
auditdirectly. - A trivial mechanical edit — per the project's CLAUDE.md carve-out.
Skipping a gate is never permitted. The interview is brainstorm's,
and its absence here is the whole point — but the production gates
(criterion, parse-every-block, grounding-check, user-review) are
non-negotiable regardless of how the work entered. "The issue looks
exhaustive, skip the grounding-check" is the reactive-deference failure
this skill must not reintroduce.
The Iron Law
THE SOURCES MUST RESOLVE EVERY LOAD-BEARING DESIGN DECISION BEFORE THE SPEC IS WRITTEN.
IF WRITING THE SPEC FORCES A CHOICE BETWEEN PLAUSIBLE DESIGNS THE SOURCES DO NOT RESOLVE,
STOP AND BOUNCE TO brainstorm. DO NOT SILENTLY PICK ONE.
THE PRODUCTION GATES — ACCEPTANCE CRITERION, PARSE-EVERY-BLOCK, GROUNDING-CHECK, USER-REVIEW —
ARE NON-NEGOTIABLE REGARDLESS OF ENTRY PATH.
NO PLAN, SCAFFOLDING, OR DOWNSTREAM SKILL UNTIL THE SPEC IS APPROVED — BY THE USER, OR
(ONLY UNDER /boss WITH spec_auto_sign ENABLED) BY THE AUTO-SIGN GATE: ALL OBJECTIVE GATES GREEN
AND A UNANIMOUS ADVERSARIAL spec-skeptic PANEL. MODEL SELF-CONFIDENCE ALONE IS NEVER APPROVAL.
Every clause is non-negotiable. The precondition gate is what makes
the no-interview path legitimate rather than merely convenient: it is
the honest fork-check that tdd's "is this test-specifiable?" is for
test work.
The Process
Step 1 — Explore / re-ground context
Before producing anything, establish what the sources actually say:
- Direct entry (from sources): read the sources in full — the
tracker issue body, the in-context design discussion, any settled
design docs. This IS the design input. Then
git log -5 --format=fullfor the current state of the project. - Chain entry (from
brainstorm): the ratified design narrative is already in-context. Re-ground lightly — freshgit log, the files the design touches — rather than re-deriving it. - If the project has a design ledger under
paths.design_ledger, walk to the contracts the work touches. Note anystatus: aspirationalsource: its code is a target, not verified fact — track it for the Step-4 parse gate.
Step 1.5 — Precondition gate (bounce-back)
Enumerate the load-bearing design decisions the spec must encode — the choices that, decided differently, would change what ships. For each, ask the honest question:
Do the sources resolve this, or am I about to pick it myself?
If every load-bearing decision is resolved by the sources, proceed to
Step 2. If even one is unresolved — the sources leave a genuine fork
between plausible designs with real trade-offs — STOP and bounce to
brainstorm (see Error handling / The Bounce-Back). Do not silently
pick one and bake it into the spec; a guessed design ratified into a
spec is harder to dislodge than an open question, and it is exactly
the reactive-deference failure the gate exists to prevent.
Genuine doubt about whether the sources resolve a decision is itself the fork signal — it resolves to a bounce, not to a guess.
Step 2 — Apply the project's feature-acceptance criterion
The project's CLAUDE.md declares the criterion a feature must
satisfy to ship. Apply it now, prospectively. The typical shape is
some combination of:
- the project's intended audience naturally reaches for the feature,
- the feature measurably improves correctness or removes redundancy,
- the feature reintroduces no class of failure the project's core constraint exists to eliminate.
If the project declares no criterion, the default is "the feature solves a real user-facing problem and does not contradict a stated design commitment". The orchestrator applies the criterion; do not delegate it to the user.
The criterion is unjudgeable without concrete code. For any cycle with authoring or consumer surface, the spec MUST contain the actual program / invocation / configuration a user would write — and that example is the criterion's empirical evidence. A prose assertion ("a user naturally reaches for X") with no shown code is the unfalsifiable hand-wave the criterion exists to prevent: write the code the user would write, then judge whether it is what the criterion demands. For an infrastructure cycle with no user surface there is still concrete code: show the code the cycle delivers — frequently a test fixture whose correct behaviour is rejection — plus a minimal, honest slice of the north-star program the infrastructure serves. "No surface so no code to show" is the rationalisation to refuse.
Code lifted from an aspirational source is a hypothesis, not
evidence. If the concrete code here is lifted from a design_models
file (or any status: aspirational source, per Step 1), it carries no
validation by default. Treat it as the spec's most suspect bytes: it
must clear the Step-4 parse-every-block gate before PASS.
Step 3 — Write the spec
Path: under paths.spec_dir, with a name per the project's
naming.policy (see profile schema). Determine the next slot per the
policy.
Structure:
# <Title> — Design Spec
**Date:** YYYY-MM-DD
**Status:** Draft — awaiting user spec review
**Authors:** orchestrator + Claude
## Goal
## Architecture
## Concrete code shapes
## Components
## Data flow
## Error handling
## Testing strategy
## Acceptance criteria
## Concrete code shapes is mandatory and leads with the
user-facing program: the worked author example for a surface cycle
(= the Step-2 empirical evidence), or — for a no-surface infra cycle —
the code the cycle delivers (often a must-fail fixture) plus a
minimal honest north-star slice. The before → after implementation
shape (struct / signature / match-arm) for each load-bearing change
follows as an explicitly secondary subsection, never first. Prose may
explain code, never replace it. Exact bytes / line-numbers remain
the planner's job — the spec owns the shape, shown.
Step 4 — Self-review
Inline checklist (not a subagent dispatch):
- Placeholder scan: any "TBD", "TODO", incomplete sections, vague requirements? Fix.
- Internal consistency: sections must not contradict. Architecture must match component descriptions.
- Scope check: focused enough for one plan, or does it need sub-cycle decomposition?
- Ambiguity check: could any requirement be read two ways? Pick one and make it explicit.
- Concrete-code check: does
## Concrete code shapesexist and carry before → after code for every load-bearing change (plus the worked user-facing example for a surface cycle)? A load-bearing change described only in prose is a self-review failure to fix. - Parse-every-block gate. Extract every fenced code block and run
it through the
spec_validationgate defined indocs/profile-schema.md(which owns the parser-invocation protocol, the no-parser skip, the malformed-entry failure, and the no-op when the profile declares nospec_validation). A parse failure is a self-review failure — fix the spec; do not pass unparsed bytes downstream. Paste the parse-trace into the chat: a visible trace attests the gate fired; its absence means it was skipped.
Fix issues inline.
Step 5 — Grounding-check (hard-gate)
Dispatch the read-only grounding-check agent. The agent reads the
just-written spec with fresh context, extracts its load-bearing
assumptions about current behaviour of the codebase, and for each
searches the workspace for a currently-green test that ratifies it.
Dispatch carrier — the fields spec_path and iteration_scope,
defined authoritatively under Carrier contract in
agents/grounding-check.md (note spec_path is an absolute path).
That table is the single source for those fields; it is deliberately
not restated here, so the two files cannot drift.
The agent returns PASS / BLOCK / INFRA_ERROR. Interpretation:
| Agent status | Orchestrator action |
|---|---|
PASS |
Proceed to Step 6. The report goes into the chat for the record. |
BLOCK |
Present the report to the user. User either: (a) accepts discard → execute the failure-mode procedure below; or (b) overrides in free chat ("Test <path>::<name> ratifies that") → log the override note and proceed to Step 6. |
INFRA_ERROR |
Abort. The spec stays as-is on disk; debug the workspace out-of-band and re-dispatch the agent. |
Failure-mode procedure (no-override BLOCK):
-
Delete the just-written spec file from the working tree (
rm <spec_path>— a shell delete, NOTgit rm; never committed). -
Open a backlog issue (via the project's issue-tracker create command) pointing forward to a future re-design. Include:
- Title: one-line identity of the deferred work
- Label: matching the project's vocabulary (
feature/bug/idea; promote toBLOCKERif the unratified mechanism is on a core-functionality path) - Body: short description plus two structured lines:
depends on: <name of the unratified mechanism>context: <why this is deferred>
If the deferred work needs its own spec on resumption (multi-iteration, cross-subsystem), file it as a milestone container instead of a single issue.
-
Tell the user the spec was retired and which backlog entry was filed. No commit is needed — the issue tracker is the live store.
After the failure-mode procedure runs, the session ENDS. There is no Step 6, no Step 7. The idea is parked until the dependency ships.
Re-dispatch on any post-PASS edit. The PASS report is bound to the
exact bytes of the spec at dispatch time. Any subsequent edit — polish,
a user-requested change, a wording tighten — invalidates the PASS
report and requires a fresh dispatch of grounding-check before the
Step-6 sign-off and commit. Step 5 is the last step that touches the
spec file; nothing slips between it and the commit.
Step 6 — User-review gate
The spec sits in the working tree as an unstaged file. Tell the user:
Spec written to
<path>(uncommitted). Please review it and let me know if you want changes before we start the implementation plan. The orchestrator will commit it once you approve.
Wait for the user's response. If they request changes, edit the file in place (still uncommitted), re-run Step 4 AND re-dispatch Step 5 (the previous PASS report no longer covers the edited bytes), then return here. Only proceed after approval AND a fresh Step 5 PASS.
The orchestrator commits the approved spec after sign-off (suggested
commit subject: spec: <cycle> <topic>). The skill does not perform
the commit itself.
In /boss (autonomous): specify is dispatched autonomously —
it is bounded (no interview). It runs the criterion, parse, and
grounding-check gates without a checkpoint. What happens at this
gate then depends on the profile slot pipeline.boss.spec_auto_sign:
-
Slot absent or
false(default):specifypauses here as a problem-state notify ("spec X ready, please sign off") and waits for the user. This is the final sign-off pause, not a pre-dispatch checkpoint — the distinction frombrainstorm, which/bossbounces before dispatch. This is the conservative default; the user's signature is mandatory. -
Slot
true: the orchestrator MAY sign in the user's place, but only through the auto-sign gate below. The gate exists because the orchestrator that wrote the spec is the worst-placed party to judge it — so the gate is built to not rely on the orchestrator's own confidence. Run it in two stages:-
Objective gates (all must already hold — these are facts, not judgements):
- Step 1.5 precondition gate passed cleanly — no load-bearing
fork was silently picked (if one had been,
specifywould have bounced, so reaching here is the evidence; do not re-decide it). - Step 4 self-review clean, including the placeholder scan (no
TBD/TODO/ incomplete section) and a pasted parse-trace for every configured-label block. - Step 5
grounding-checkreturnedPASS— not an overriddenBLOCK. An override needs a human; with no human in the loop aBLOCKcan never be overridden, so any non-PASSgrounding result denies auto-sign outright.
If any objective gate is not green, do not run the panel — fall straight to the human sign-off pause (the default-slot behaviour above), carrying the failing gate in the notify.
- Step 1.5 precondition gate passed cleanly — no load-bearing
fork was silently picked (if one had been,
-
Adversarial panel (unanimous-or-nothing): dispatch the read-only
spec-skepticagent five times in parallel, once per lens —criterion,grounding,scope-fork,ambiguity,plan-readiness. Carrier per dispatch:spec_path(absolute),iteration_scope, and the singlelens. Each juror tries to refute the spec along its lens and returnsSOUND/BLOCK/INFRA_ERROR.Panel outcome Orchestrator action All five SOUNDAuto-sign. Commit the spec yourself (subject spec: <cycle> <topic> (boss-signed)), send the informational auto-sign notify (seeboss§ Notifications — names the capability in user terms and states the plan is proceeding and a reply vetoes), then proceed to Step 7. No pause.Any BLOCKorINFRA_ERRORNo auto-sign. Fall back to the human sign-off pause; the notify carries which lens(es) blocked and their findings, so the user sees why it routed to them.
The fall-back is not a failure — it is the panel correctly routing a spec to the human who was going to review it anyway. A unanimous
SOUNDis the only thing that lets the orchestrator sign; "the spec looks good to me" never is.Auto-sign commits on
mainare forward-only like every other commit. A later user veto is a forward correction (revert / revised spec /git checkoutof downstream working-tree work), never a history rewind — same discipline as any other orchestrator call (seeboss§ Direction freedom). -
Step 7 — Hand off to planner
The terminal state of specify is invoking planner. NO other skill
is invoked from specify. NO direct jump to implement.
Hand off carries:
- path to the spec under
paths.spec_dir - iteration scope ("the first iteration covers section X+Y of the spec")
The Bounce-Back
specify returns to brainstorm whenever the precondition fails — the
sources do not resolve a load-bearing design decision (Step 1.5), or a
grounding-check BLOCK reveals an unratified mechanism the user does
not override (Step 5 failure-mode routes to a re-design). On a
precondition bounce:
- Nothing was written yet (the gate fires before Step 3), so there is no working-tree artefact to discard.
- Invoke
brainstormwith the unresolved design question as the cycle request. From there the normalbrainstorm → specify → plannerpath runs.
The bounce-back is not a failure of this skill; it is the skill
correctly refusing to ratify an un-chosen design into a spec — the same
discipline tdd applies when behaviour is not test-specifiable.
Handoff Contract
| Direction | Carrier |
|---|---|
user / issue (design settled) → specify |
the sources: issue body, in-context design discussion, design docs |
brainstorm → specify |
ratified design narrative (approaches chosen, constraints, sections approved) — in-context; brainstorm writes no spec file |
specify → grounding-check (Step 5) |
spec_path (absolute) + iteration_scope |
specify → spec-skeptic panel (Step 6, /boss + spec_auto_sign only) |
spec_path (absolute) + iteration_scope + one lens per dispatch, five in parallel |
specify → planner (Step 7, on PASS or overridden BLOCK) |
path to spec + iteration scope |
specify → brainstorm (precondition bounce) |
the unresolved design question as a cycle request; no spec written |
specify → issue backlog (Step 5, no-override BLOCK) |
new issue naming the unratified dependency; spec file deleted from the working tree |
Common Rationalisations
| Excuse | Reality |
|---|---|
| "The issue looks exhaustive — skip the grounding-check / criterion too" | The interview is what specify skips, by design. The production gates are not the interview; they are what keeps the spec honest no matter how it entered. Skipping a gate because the sources look thorough is the exact reactive-deference failure this skill must not reintroduce. |
| "There's a small open fork but the sources mostly decide it — I'll pick the rest" | "Mostly decided" with one real fork left is an unresolved design, and a guessed design baked into a spec is harder to dislodge than an open question. That is the bounce-back trigger — stop and go to brainstorm. |
| "Genuine doubt whether the sources resolve this — but bouncing feels like overkill" | Doubt about whether the sources resolve a decision is the fork signal. It resolves to a bounce, not a guess. The bounce is cheap (nothing is written yet); a wrong guess in a ratified spec is not. |
| "The shape is clear from the prose, I don't need to paste the code" | If it's clear, pasting it is free; if pasting it is hard, it wasn't clear. The acceptance criterion is unjudgeable without the worked code. |
| "The block obviously parses — I wrote it carefully" | Careful authoring is not a parse. A spec's code blocks are hypotheses until the live tool accepts them. If a parser is configured for the fence label, run it and paste the trace. |
| "Just polishing a wording after PASS, no need to re-dispatch" | The grounding-check report attests to specific bytes. A polish edit changes the bytes; the attestation no longer covers them. Re-dispatch is cheap. |
| "It's in a model doc / the design ledger, so it's canonical" | A models / RFC / proposal doc holds aspirational code — a target, not verified fact. Code lifted from a status: aspirational source must clear the Step-4 parse gate like any other block. |
"In /boss with auto-sign on, this spec looks solid — I'll sign and move on" |
Your sense that it looks solid is the exact signal the auto-sign gate refuses to trust. Signing requires all objective gates green AND a unanimous spec-skeptic panel. If you find yourself wanting to sign on confidence, that is the cue to run the gate, not to skip it. |
| "One lens blocked on something minor — I'll sign anyway since the rest passed" | The panel is unanimous-or-nothing by design. One BLOCK routes the spec to the human who was going to review it regardless. You do not get to overrule a juror; that is the whole point of replacing your eye with five independent ones. |
Red Flags — STOP
- An unresolved design fork silently picked instead of bounced (any flavour)
- "The sources are thorough, skip a gate" thoughts (any flavour)
- A load-bearing change described in prose with no before → after code block; a surface cycle with no worked user-facing example
- A spec carrying a code block whose fence label has a configured
spec_validationparser, committed without a parse-trace in the chat - Lifting code verbatim from a
status: aspirationalsource without flagging it for the Step-4 parse gate - Editing the spec file after a Step 5 PASS without re-dispatching
- (auto-sign) About to sign a spec in the user's place on confidence —
without all objective gates green AND a unanimous
spec-skepticpanel; or overruling a single juror'sBLOCK - (auto-sign) Running the panel before the objective gates are green,
or running it at all when
spec_auto_signis not enabled - Jumping straight from spec to
implement(must go viaplanner) - Running an interview here (that is
brainstorm's job — if the work needs one, bounce)
Cross-references
- Output target:
../planner/SKILL.md— only valid next skill. - Discovery front-end / bounce-back target:
../brainstorm/SKILL.md— produces the ratified designspecifyconsumes on the chain path, and reclaims the work when the sources do not resolve a design fork. - Sibling fast path:
../tdd/SKILL.md— the same bounce-to-brainstorm-on-fork discipline, for test-specifiable work; its RED executable-spec is the spec, so it skips bothspecifyandplanner. - Agent dispatched:
agents/grounding-check.md— dispatched in Step 5 as a hard-gate. Reads the spec with fresh context and reports PASS / BLOCK / INFRA_ERROR. - Agent dispatched (auto-sign only):
agents/spec-skeptic.md— dispatched in Step 6 five times in parallel (one per lens) ONLY under a/bosssession withpipeline.boss.spec_auto_signenabled. Each juror tries to refute the spec along its lens; a unanimousSOUNDis what lets the orchestrator sign in the user's place. AnyBLOCKfalls back to the human sign-off pause. - Ad-hoc dispatch. The orchestrator MAY also ad-hoc dispatch
../planner/agents/plan-recon.mdduring Step 1 when the work enters code territory not recently read; opt-in, not part of the standard process. - Project feature-acceptance criterion: declared in the project's
CLAUDE.md. Applied prospectively in Step 2.