fe5ca8f8c0
Implements the three efficiency findings from the #310 pipeline measurement (refs #35): ~691k subagent tokens / ~3.5 h for a deliberately small cycle, with recon duplication as the single biggest obligatory per-cycle cost. 1. Cycle recon (pipeline.md § Cycle recon; specify, planner, brainstorm, boss, plan-recon): recon fan-out is budgeted per cycle, not per phase. One full plan-recon dispatch — normally specify Step 1, in a new pre-spec sources/recon_scope carrier form — serves both the spec's concrete code shapes and the plan's file-map. planner Step 2 becomes reuse-first (freshness / quotability / coverage conditions) with narrowly-bounded delta dispatches (new Delta dispatch contract in plan-recon.md); broad Explore-type grounding sweeps are banned in every mode. Field evidence: 151k (Explore) + 99k (plan-recon) with ~40 % overlap in one bounded cycle. 2. Fieldtest probe tier (fieldtest, fieldtester, pipeline.md, agent-template.md § model rule 2): a cycle whose user-visible delta is a single narrow axis dispatches the per-cycle fieldtest at tier: probe — 1-2 examples on exactly that axis, ~200-word report, explicit model:sonnet dispatch override (no dispatch-level effort override exists; frontmatter effort applies). Probe is a tier, not a skip; the milestone fieldtest always runs full tier on the frontmatter model, keeping the milestone-close gate's >=2-example floor unconditional. 3. Assumption economy (specify Step 3 + self-review item 6): grounding-check cost scales with the spec's assumption count, so specs state current-behaviour claims only where the change relies on them (the gate's own falsity test), demote context-only mentions to ledger citations, and keep iteration scope tight — fewer restatements, never fewer reliances. The gate itself is unchanged. Design reviewed pre-implementation (opus plan review); diff adversarially verified by a 3-lens review workflow (consistency, operability, cross-reference), confirmed findings folded in. refs #35
629 lines
35 KiB
Markdown
629 lines
35 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.
|
|
The side paths that carry no fresh prose design — `compiler-driven`,
|
|
the harvest sweep — bypass it (`../docs/pipeline.md` § Skip rules).
|
|
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.
|
|
- Settled single-issue backlog drained as a batch — the harvest
|
|
sweep's issue bodies are the ratified spec source; no new spec is
|
|
written. See `../docs/pipeline.md` § Harvest sweep.
|
|
|
|
**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.
|
|
|
|
**Grounding fan-out — the cycle recon.** When the work enters code
|
|
territory the orchestrator has not recently read, dispatch
|
|
`../planner/agents/plan-recon.md` **once**, in its pre-spec form —
|
|
carrier fields (`sources`, `recon_scope`, optional `focus_hint`)
|
|
defined authoritatively under its **Pre-spec dispatch (cycle
|
|
recon)** heading. When the sources already settle the change shape
|
|
(a signature change, a variant add / remove, a symbol removal, a
|
|
content-pin perturbation), name it in `recon_scope`: that arms the
|
|
compile-driven enumeration inside the cycle recon and saves
|
|
`planner` a mandatory delta later. The returned file-map grounds
|
|
Step 2's criterion evidence and Step 3's `## Concrete code
|
|
shapes`, and is reused downstream by `planner` — budget, reuse
|
|
conditions, and delta triggers are defined once in
|
|
`../docs/pipeline.md` § Cycle recon. A `brainstorm`-fired dispatch
|
|
that meets that section's coverage condition IS the cycle recon —
|
|
do not dispatch again. Do NOT ground a spec with a broad
|
|
Explore-type sweep (§ Cycle recon's ban; field evidence on issue
|
|
#35: a 151k-token Explore sweep here, ~40 % duplicated by the
|
|
later plan-recon).
|
|
|
|
### 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** (the user's decision intent stated in English + explicit
|
|
attribution + date; a verbatim quote only where the exact wording is
|
|
load-bearing, and then translated — `../issue/SKILL.md` rule 4).
|
|
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: <user decision intent in English + 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: <user decision intent in English + 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 via the
|
|
project's committed `docs/.gitignore`; if that file does not yet ignore
|
|
`specs/`, create it first (`docs/conventions.md` § File layout) so the
|
|
spec can never be committable. The spec is created under `docs/specs` 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.
|
|
|
|
**Assumption economy — fewer restatements, never fewer reliances.**
|
|
Every assertion the spec makes about *current* codebase behaviour is
|
|
a load-bearing-assumption candidate the Step-5 `grounding-check`
|
|
must extract and ratify — the gate's cost scales with the count, and
|
|
it BLOCKs an over-broad spec outright (`agents/grounding-check.md`).
|
|
So: state a current-behaviour claim only where the change actually
|
|
relies on it (the gate's test: its falsity would make the change
|
|
fail or cost additional work), and render context-only mentions of
|
|
existing mechanisms as a design-ledger contract citation instead of
|
|
restating their behaviour. This trims *restatements*, never *reliances*: a
|
|
mechanism the change builds on remains an assumption — explicit, or
|
|
the implicit form the gate extracts anyway — and writing it as a
|
|
bare citation does not exempt it; hiding a reliance is exactly the
|
|
failure the gate exists to catch. The same economy applies to scope:
|
|
a tightly-cut iteration makes fewer claims than a sprawling one
|
|
(field evidence on issue #35: gate cost tracks the spec's assumption
|
|
count near-linearly).
|
|
|
|
### 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.
|
|
6. **Assumption economy:** scan every claim about current codebase
|
|
behaviour. The gate's own criterion decides which stay: a claim
|
|
is a *reliance* iff its being false would make the proposed
|
|
change fail or require additional work
|
|
(`agents/grounding-check.md` § What "load-bearing assumption"
|
|
means). Non-reliances are gate cost with no return — delete
|
|
them, or demote them to a citation that carries no behaviour
|
|
claim. Never demote a reliance: a bare citation does not ratify
|
|
it, and the gate BLOCKs on it unratified (Step 3's
|
|
restatements-vs-reliances line).
|
|
|
|
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 are forward-only once ratified — 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` → `plan-recon` (Step 1, the cycle recon — skipped when a brainstorm-fired dispatch meets the coverage condition) | `sources` + `recon_scope` + optional `focus_hint`; defined authoritatively under **Pre-spec dispatch (cycle recon)** in `../planner/agents/plan-recon.md` |
|
|
| `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. |
|
|
| "Fewer assumptions = a cheaper grounding-check, so I'll phrase the reliances as vague citations" | Economy cuts *restatements*, not *reliances*. A mechanism the change builds on stays a claim — vague phrasing merely converts it to the implicit form the gate extracts anyway, or worse, hides a false premise until a downstream iteration BLOCKs on it. Trim what the change does not rest on; never what it does. |
|
|
| "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)
|
|
- Grounding the spec with a broad Explore-type sweep — or a second
|
|
full recon dispatch when a cycle recon already exists
|
|
(`../docs/pipeline.md` § Cycle recon)
|
|
|
|
## 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`.
|
|
- **Cycle recon (Step 1).** `../planner/agents/plan-recon.md` in its
|
|
pre-spec form is the cycle's ONE full recon dispatch when the work
|
|
enters code territory not recently read; its report also serves
|
|
`planner` downstream. Budget, reuse conditions, and delta triggers:
|
|
`../docs/pipeline.md` § Cycle recon.
|
|
- **Project feature-acceptance criterion:** declared in the project's
|
|
`CLAUDE.md`. Applied prospectively in Step 2.
|