feat(boss): opt-in spec auto-sign via adversarial spec-skeptic panel

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
This commit is contained in:
2026-06-09 18:19:28 +02:00
parent 8d375d5622
commit cbd460e242
8 changed files with 395 additions and 15 deletions
+73 -5
View File
@@ -73,7 +73,9 @@ IF WRITING THE SPEC FORCES A CHOICE BETWEEN PLAUSIBLE DESIGNS THE SOURCES DO NOT
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 HAS BEEN PRESENTED AND THE USER HAS APPROVED IT.
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
@@ -287,10 +289,62 @@ 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, then **pauses here** as a
problem-state notify ("spec X ready, please sign off"). This is the
final sign-off pause, not a pre-dispatch checkpoint — the distinction
from `brainstorm`, which `/boss` bounces *before* dispatch.
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):** `specify` **pauses 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 from `brainstorm`, which `/boss` bounces
*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:
1. **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, `specify` would 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-check` returned **`PASS`** — *not* an
overridden `BLOCK`. An override needs a human; with no human in
the loop a `BLOCK` can never be overridden, so any non-`PASS`
grounding 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.
2. **Adversarial panel (unanimous-or-nothing):** dispatch the
read-only `spec-skeptic` agent **five times in parallel**, once
per lens — `criterion`, `grounding`, `scope-fork`, `ambiguity`,
`plan-readiness`. Carrier per dispatch: `spec_path` (absolute),
`iteration_scope`, and the single `lens`. Each juror tries to
*refute* the spec along its lens and returns `SOUND` / `BLOCK` /
`INFRA_ERROR`.
| Panel outcome | Orchestrator action |
|---------------|---------------------|
| All five `SOUND` | **Auto-sign.** Commit the spec yourself (subject `spec: <cycle> <topic> (boss-signed)`), send the informational auto-sign notify (see `boss` § 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 `BLOCK` or `INFRA_ERROR` | **No 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
`SOUND` is the *only* thing that lets the orchestrator sign;
"the spec looks good to me" never is.
**Auto-sign commits on `main` are forward-only like every other
commit.** A later user veto is a forward correction (revert / revised
spec / `git checkout` of downstream working-tree work), never a
history rewind — same discipline as any other orchestrator call (see
`boss` § Direction freedom).
### Step 7 — Hand off to `planner`
@@ -328,6 +382,7 @@ discipline `tdd` applies when behaviour is not test-specifiable.
| 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 |
@@ -343,6 +398,8 @@ discipline `tdd` applies when behaviour is not test-specifiable.
| "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
@@ -355,6 +412,11 @@ discipline `tdd` applies when behaviour is not test-specifiable.
- Lifting code verbatim from a `status: aspirational` source 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-skeptic`
panel; or overruling a single juror's `BLOCK`
- (auto-sign) Running the panel before the objective gates are green,
or running it at all when `spec_auto_sign` is not enabled
- 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)
@@ -372,6 +434,12 @@ discipline `tdd` applies when behaviour is not test-specifiable.
- **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 `/boss` session with `pipeline.boss.spec_auto_sign` enabled. Each
juror tries to refute the spec along its lens; a unanimous `SOUND` is
what lets the orchestrator sign in the user's place. Any `BLOCK`
falls back to the human sign-off pause.
- **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; opt-in, not part of the standard