Files
Skills/specify/SKILL.md
T
Brummel 08bc2aa027 refactor(pipeline): specs/plans are gitignored working files, never committed
Per-cycle specs and plans stop being git-tracked commit-then-git-rm
artefacts and become git-ignored working files: created on disk for the
active cycle, read across sessions from the working tree, and shell-rm'd
at cycle close by audit. Nothing is committed, so there is no
git-history copy — the durable record of a cycle's intent is the design
ledger only, and no durable artefact (code, test, doc, ledger) may cite
a spec/plan by number or path.

- conventions/pipeline/design/README: invert the git-tracked -> git-rm
  -> git-history-recovery model to gitignored -> shell-rm -> ledger-only.
- naming: drop the NNNN file counter; files are slug.md (fieldtest specs
  keep a fieldtest- prefix as the cycle-close discriminator).
- cycle number: separated from the (now-gone) file number, sourced from
  the feat(NNNN)/audit(NNNN) commit subjects, which cycle commits carry.
- specify/planner/fieldtest/fieldtester: no commit step; fieldtest splits
  fixtures (committed as code) from its spec (gitignored), with the
  cross-cycle rule that a fieldtest- spec belongs to the next cycle.
- boss: auto-sign auditability moves from the (boss-signed) commit
  subject to the run's reference issue; rollback reverts only code.
- audit: new Step 5 shell-rm's the cycle spec+plan after the architect
  reads them, sparing fieldtest- specs.

Companion machine config (outside this repo): the global git excludes
(~/.config/git/ignore) gains docs/specs/ and docs/plans/ so the ignore
applies to every project at once.
2026-07-02 11:35:06 +02:00

565 lines
31 KiB
Markdown

---
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 docs/specs, 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
`grounding-check` hard-gate, and the sign-off 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* — discovery (a grounded synthetic-user swarm), 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.
`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.
Where `tdd` is one entry path among three (chosen when behaviour is
test-specifiable), `specify` sits on every prose-design path — it is
not bypassed for those.
## 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 `brainstorm` just 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). `specify` itself bounces here the moment it
detects this (see The Iron Law and Step 1.5).
- A test-specifiable feature — the RED executable-spec is the spec.
Use `tdd` directly.
- An observed bug — use `debug` directly (RED-first).
- A tidy iteration — use `audit` directly.
- 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, grounding-check, sign-off) 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. (Under `/boss` the sign-off gate is the
`grounding-check` `PASS` itself — see Step 6.)
## The Iron Law
```
EVERY LOAD-BEARING DESIGN DECISION MUST BE RESOLVED BEFORE THE SPEC IS WRITTEN — BUT
"RESOLVED" INCLUDES A FORK THE ORCHESTRATOR CAN DERIVE AN ANSWER FOR (FROM THE SOURCES,
THE CODE, EXISTING-DESIGN CONSISTENCY, OR RISK). A DERIVABLE FORK -> DECIDE IT BOLDLY AND
RECORD THE DECISION IN THE REFERENCE ISSUE. ONLY A FORK THAT HANGS ON PURE USER PREFERENCE
WITH NO DERIVABLE BETTER -> STOP AND BOUNCE / PAUSE. DO NOT BOUNCE A FORK YOU CAN DECIDE.
THE PRODUCTION GATES — ACCEPTANCE CRITERION, GROUNDING-CHECK, SIGN-OFF —
ARE NON-NEGOTIABLE REGARDLESS OF ENTRY PATH.
NO PLAN, SCAFFOLDING, OR DOWNSTREAM SKILL UNTIL THE SPEC IS APPROVED — BY THE USER, OR
(UNDER /boss) BY A grounding-check PASS. MODEL SELF-CONFIDENCE ALONE IS NEVER APPROVAL;
THE grounding-check IS AN INDEPENDENT FRESH-CONTEXT AGENT, NOT THE PRODUCER'S CONFIDENCE.
```
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. Its bar is *decidability*, not *pre-settlement*: a fork the
orchestrator can ground an answer for is resolved by deciding it; only a
fork that turns on the user's own preference, with no derivable better,
is the one that bounces.
## 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=full` for the current state of the project.
- **Chain entry** (from `brainstorm`): the ratified design narrative
is already in-context. Re-ground lightly — fresh `git log`, the
files the design touches — rather than re-deriving it.
- If the project has a design ledger (its CLAUDE.md project facts),
walk to the contracts the work touches. Note any `status:
aspirational` source: its code is a target, not verified fact.
### 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:
> Can I **derive** an answer for this fork — from the sources, the
> code, consistency with the existing design, or relative risk — or
> does it turn on a **preference only the user holds**?
This is a *decidability* test, not a *pre-settlement* test, and the
default is **decide, not bounce**:
- **Derivable fork → decide it boldly.** If there is a groundable
reason to prefer one option — it fits the existing design better, it
is simpler, it carries less risk, the sources lean that way — the
orchestrator decides it and proceeds. It does **not** bounce a fork it
can actually answer. When unsure whether its own leaning is bias
rather than judgement, it pulls **one** independent opinion — an
ad-hoc `spec-skeptic` lens (see Step 6) — and weighs it; the lens
informs the decision, it does not veto. Every derived decision is
**recorded in the reference issue** (below) with its rationale.
- **Pure-preference fork → bounce / pause.** Only when the fork turns on
something the orchestrator cannot derive — roadmap order, product
taste, two genuinely equivalent paths whose trade-off only the user
can weigh — is it a real bounce. Then **STOP and bounce to
`brainstorm`** (see The Bounce-Back), or under `/boss` route to the
human sign-off pause. A guessed *preference* baked into a spec is the
reactive-overreach this gate still prevents.
The old "genuine doubt *is* the fork signal → bounce" reflex is
**retired**: doubt about whether you can derive an answer resolves to an
honest attempt to derive it (with a bias-breaker if needed), not to a
reflexive bounce. Being wrong on a derived call is allowed — the net is
the user's veto and, under `/boss`, the rollback sandbox
(`../boss/SKILL.md` § Direction freedom). What is *not* allowed is
dressing a pure-preference guess as a derived decision.
**Every `/boss` run carries a reference issue.** The run is always
anchored to a tracker issue — an existing one that seeded the cycle, or
one the orchestrator creates when the work was settled in pure chat with
no prior issue (the mechanic below). That issue is the run's **decision
log**: as the orchestrator derives fork answers, it comments each one
there, so the user can audit and veto after the fact and the orchestrator
has a cross-run "issue memory". Because a `/boss` dead-end is recovered
by hard-dropping the autonomous commits (no attempt branch survives), the
issue's comment thread is also the **only surviving trace** of an
abandoned attempt — which is the second reason it is mandatory, not
optional.
A comment records one of two distinct things, and the distinction is
load-bearing:
- A **user decision** the conversation settled — minuted with
**provenance** (a verbatim user statement, or explicit attribution +
date). Legitimate: you are recording what the user chose.
- A **derived orchestrator decision** — recorded with its **rationale**
(why one option is groundably better). Legitimate under the new stance,
but it must be labelled as what it is: a derived call, never disguised
as a user decision. If you cannot state a rationale, the fork was not
derivable — that is a pure-preference bounce, not a comment.
**Reconciliation comment (lagging-issue case).** A fork can be resolved
— by a user decision in the discussion, or derived by the orchestrator —
yet still be listed *open* by the tracker issue that seeded the cycle.
When that holds, record the resolution as an auditable issue comment
**before** writing the spec, via the project's issue-tracker comment
command (`tea comment <idx>` for Gitea; a heredoc body per the `issue`
skill's conventions). One comment, this shape:
```
## Design reconciliation (specify)
Spec: <spec-name>. The fork(s) below are still listed open on this
issue; this records their resolution.
- **Fork: <name>** → <decision>.
Basis: <verbatim user statement + attribution, OR "derived:" + the
groundable rationale>.
```
`Basis:` carries either provenance (user decision) or rationale (derived
decision) — both are auditable, neither is a bare `decision: X` with no
support. The comment is *persistent and auditable* (author + timestamp,
in the forward queue) — which is exactly why it, and not your ephemeral
confidence, is what the user reads to understand and veto a call made
without them. Recording it keeps the forward queue honest in either run
mode.
Gitea writes are pre-authorized (per `~/.claude/CLAUDE.md`); post the
comment without a confirmation prompt.
**Issue-less in-context entry.** If the cycle has *no* tracker issue —
the design was settled in pure chat — there is no existing artefact to
comment on, so *create one*: open a new tracker issue that records the
resolved fork(s) under the same discipline as the reconciliation comment
above. The body takes this shape:
```
## Design record (specify, issue-less in-context entry)
This issue seeds <one-line identity of the work>. The design was settled
in an in-context discussion with no prior tracker issue; this records it.
Load-bearing fork(s) resolved:
- **Fork: <name>** → <decision>.
Basis: <verbatim user statement + attribution, OR "derived:" + rationale>.
```
The body names the *work*, not the spec file — the spec does not exist
yet at Step 1.5 (its number is assigned only in Step 3). This new issue
is the run's reference issue from here on: the orchestrator comments
later derived decisions on it as the run proceeds, and a downstream
ad-hoc `spec-skeptic` can read it via the project's issue show command if
the orchestrator pulls one. A *new issue* is the right artefact where a
provenance note *inside the spec* would be the wrong one — a note inside
the spec is self-referential (the spec asserting its own sources settle
it) and stays banned, but a separate issue is independent (author +
timestamp, in the forward queue, readable without opening the spec).
Create it via the project's issue-create command (the `issue` skill's
mechanics — `tea issues create` for Gitea), title and label per the
project's vocabulary. Gitea writes are pre-authorized, so create it
without a confirmation prompt. **Capture the new issue's index** the
moment it is created — it is the run's reference issue, the target for
every later decision comment.
### 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: flag
it as a target, not verified fact.
### Step 3 — Write the spec
Path: under `docs/specs`, named `slug.md` per the fixed naming
convention (see `docs/conventions.md` § Naming) — a short kebab-case
topic slug, no numeric prefix. The directory is git-ignored; the spec is
created there and never `git add`'d.
Structure:
```markdown
# <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):
1. **Placeholder scan:** any "TBD", "TODO", incomplete sections,
vague requirements? Fix.
2. **Internal consistency:** sections must not contradict.
Architecture must match component descriptions.
3. **Scope check:** focused enough for one plan, or does it need
sub-cycle decomposition?
4. **Ambiguity check:** could any requirement be read two ways? Pick
one and make it explicit.
5. **Concrete-code check:** does `## Concrete code shapes` exist 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.
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`):**
1. Delete the just-written spec file from the working tree
(`rm <spec_path>` — a shell delete, NOT `git rm`; never committed).
2. 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 to `BLOCKER` if 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.
3. 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 — Sign-off gate
Outside `/boss` the signature is the user's; under `/boss` it is the
Step-5 `grounding-check` `PASS` (the `/boss` subsection below).
The spec sits in the working tree as a git-ignored working file. Tell
the user:
> Spec written to `<path>` (git-ignored, never committed). Please review
> it and let me know if you want changes before we start the
> implementation plan.
Wait for the user's response. If they request changes, edit the file
in place, **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 spec is **never committed**: it is a git-ignored active-cycle working
file that lives on disk only for its own cycle and is shell-`rm`'d at
cycle close by `audit` (see `docs/conventions.md` § Lifecycle). The
durable record of its design intent is the design ledger, lifted during
audit — not the spec file.
**In `/boss` (autonomous):** `specify` is dispatched autonomously — it
is bounded (no interview), so there is no user at this gate to take the
signature. The signature comes from the **Step-5 `grounding-check`
`PASS`**: an independent fresh-context agent's verdict against
currently-green tests, not the producing orchestrator's confidence — and
that is what the bold stance trusts in the user's place. There is **no
adversarial panel**, no objective-gates-then-panel staging, no
self-correction loop; those were retired in favour of decide-upstream +
recover-downstream (baseline tag `pre-autosign-rework`).
- On a Step-5 **`PASS`**: the spec is signed by the PASS — leave it as a
git-ignored working file (never committed). Record the autonomous sign
on the run's reference issue (a decision-log comment: which capability,
that the `grounding-check` PASS was the signature, that no human
signed), fire the auto-sign notify (see `boss` § Notifications — it
names the capability in user terms and states the plan is proceeding
and a reply vetoes), then proceed to Step 7. No pause.
- On a Step-5 no-override **`BLOCK`** or **`INFRA_ERROR`**: there is no
human to override it, so it routes to the human sign-off pause — a
problem-state notify ("spec X needs your sign-off") — exactly as the
Step-5 failure mode describes. A no-override grounding `BLOCK` is the
one objective denial of an autonomous sign and is never signed over.
The judgement that used to live in the panel now lives **upstream**, in
Step 1.5's bold-decide stance: a load-bearing fork is *decided* there
(with an ad-hoc `spec-skeptic` bias-breaker if the orchestrator wants
one) and recorded in the reference issue, or — if it is a pure-preference
fork — bounced before the spec is ever written. By the time a spec
reaches this gate the only thing left to verify is the objective one the
`grounding-check` already verifies. Editorial defects the old panel would
have caught (a clumsy worked example, a two-way-readable sentence) are
allowed through **deliberately**: they are cheap to patch inline
downstream, and catching them was never worth an obligatory five-juror
panel on every spec.
**Bias-breaker (optional, the orchestrator's call).** When deciding a
fork in Step 1.5 the orchestrator MAY dispatch the read-only
`spec-skeptic` agent ad hoc — one lens, or a few, whichever fork it is
unsure about — for an independent refutation to weigh against its own
leaning. This is a *tool it reaches for*, not a gate it must clear: the
lens returns a finding, the orchestrator decides. Carrier and lenses are
defined in `agents/spec-skeptic.md`.
**Auto-signed CODE commits on `main` are forward-only — with one `/boss`
exception.** The spec itself is never a commit (it is a git-ignored
working file), so a later user veto is a forward correction: shell-`rm`
(or edit) the git-ignored spec, and `git revert` / `git checkout` only
the downstream **code** it produced. The `/boss` rollback sandbox is the
exception: within an autonomous run the orchestrator may hard-reset its
own *unpushed* autonomous code commits back toward (never below) the
session anchor when it has run into a dead end — its own work only, and
it shell-`rm`s the git-ignored spec/plan of the abandoned line. See
`boss` § Direction freedom for the exact boundary.
### 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 `docs/specs`
- iteration scope ("the first iteration covers section X+Y of the
spec")
## The Bounce-Back
`specify` returns to `brainstorm` whenever the precondition fails — a
load-bearing fork turns on **pure user preference** the orchestrator
cannot derive (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). A fork the orchestrator *can* derive an answer
for is **not** a bounce — it is decided and recorded in the reference
issue. On a precondition bounce:
1. Nothing was written yet (the gate fires *before* Step 3), so there
is no working-tree artefact to discard.
2. Invoke `brainstorm` with the unresolved design question as the
cycle request. From there the normal `brainstorm → specify →
planner` path runs.
The bounce-back is not a failure of this skill; it is the skill
correctly refusing to ratify a *pure-preference guess* into a spec — the
same discipline `tdd` applies when behaviour is not test-specifiable. It
is narrow by design: only the user's-call forks bounce, not every fork.
## 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` bias-breaker (Step 1.5, optional, orchestrator's call) | `spec_path` (absolute) + `iteration_scope` + one `lens` + `seeding_issue` (or `none`); dispatched ad hoc for a fork the orchestrator is deciding, never as a gate |
| `specify` → reference issue (Step 1.5) | a derived-decision comment (rationale) or user-decision comment (provenance); a freshly created seeding issue if the cycle had none |
| `specify``planner` (Step 7, on PASS or overridden BLOCK) | path to spec + iteration scope |
| `specify``brainstorm` (precondition bounce, pure-preference fork) | 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 an open fork left — I should bounce to `brainstorm` to be safe" | Only if it is a *pure-preference* fork. If you can derive an answer — sources, code, consistency, risk — decide it boldly, record the rationale in the reference issue, and proceed. Bouncing a fork you can actually decide is the reactive-deference reflex the new stance retired. |
| "I can derive an answer but I'm not 100% sure it's right — safer to bounce" | Being wrong on a *derived* call is allowed: the net is the user's veto and the `/boss` rollback sandbox. If you're unsure your leaning is judgement not bias, pull one ad-hoc `spec-skeptic` lens and weigh it — then decide. Reserve the bounce for forks only the user's preference can settle. |
| "This is pure product taste but one option seems fine — I'll just pick it" | A fork with no derivable better is the user's call; picking it is the pure-preference guess the gate still forbids. Bounce it, or under `/boss` route to the human sign-off pause. The line is *derivable vs. preference*, not *small vs. large*. |
| "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. |
| "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. Flag code lifted from a `status: aspirational` source as such; it is not ratified contract. |
| "In `/boss` this spec looks solid — I'll sign and move on" | Your sense that it looks solid is not the signature. Under `/boss` the signature is the Step-5 `grounding-check` `PASS` — an independent agent's verdict, not your confidence. Run the grounding-check; a no-override `BLOCK` routes to the human, never auto-signed over. |
| "A grounding `BLOCK` looks like a false alarm — I'll sign over it" | With no human in the loop there is no override. A no-override grounding `BLOCK` is the one objective denial of an autonomous sign; it routes to the human sign-off pause. The whole point of trusting grounding-PASS as the signature is that you also honour its `BLOCK`. |
## Red Flags — STOP
- A *pure-preference* fork silently picked instead of bounced — or its
inverse: a *derivable* fork bounced to `brainstorm` instead of decided
(the reactive-deference reflex the new stance retired)
- A derived fork decision made but **not recorded** in the reference
issue (no rationale comment, or no reference issue at all on a `/boss` run)
- "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
- Lifting code verbatim from a `status: aspirational` source without
flagging it as a target, not verified fact
- 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 —
rather than on the Step-5 `grounding-check` `PASS` that is the
autonomous signature; or signing over a no-override grounding `BLOCK`
/ `INFRA_ERROR` instead of routing it to the human sign-off pause
- (auto-sign) Treating the retired `spec-skeptic` panel as still a gate
— re-introducing a unanimous five-juror pass as a sign precondition,
rather than using `spec-skeptic` only as the optional Step-1.5
bias-breaker; or running any auto-sign path outside a `/boss` session
(interactive runs take the user's signature directly)
- Jumping straight from spec to `implement` (must go via `planner`)
- 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 design `specify` consumes 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 both `specify` and
`planner`.
- **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 (optional bias-breaker):** `agents/spec-skeptic.md`
— an ad-hoc tool, **not** a gate. Under `/boss`, when the orchestrator
is deciding a load-bearing fork in Step 1.5 and is unsure whether its
leaning is judgement or bias, it MAY dispatch one (or a few)
`spec-skeptic` lens(es) for an independent refutation to weigh. The
lens returns a finding; the orchestrator decides. The former obligatory
unanimous five-lens auto-sign panel is retired (baseline tag
`pre-autosign-rework`); the autonomous signature is now the Step-5
`grounding-check` `PASS`.
- **Ad-hoc dispatch.** The orchestrator MAY also ad-hoc dispatch
`../planner/agents/plan-recon.md` during Step 1 when the work enters
code territory not recently read; discretionary, not part of the
standard process.
- **Project feature-acceptance criterion:** declared in the project's
`CLAUDE.md`. Applied prospectively in Step 2.