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:
@@ -27,7 +27,7 @@ The pipeline skills, each with the agents it primarily dispatches:
|
||||
| `tdd` | Test-specifiable feature / issue (third entry path, alongside `brainstorm` and `specify`) | RED executable-spec in working tree → `implement` mini-mode | Opt-in entry path; bounces to `brainstorm` on a design fork |
|
||||
| `fieldtest` | Orchestrator-dispatched post-audit | example fixtures + friction spec | Per-cycle optional; milestone fieldtest is the closing gate for a surface-touching milestone |
|
||||
| `docwriter` | API surface stable across N cycles | rustdoc / docstring sweep | Optional |
|
||||
| `boss` | User types `/boss` | autonomous-orchestrator session — dispatches the other skills until done-state or bounce-back | User-invoked, never auto-dispatched |
|
||||
| `boss` | User types `/boss` | autonomous-orchestrator session — dispatches the other skills until done-state or bounce-back; can optionally sign specs in the user's place (opt-in, see below) | User-invoked, never auto-dispatched |
|
||||
|
||||
Two further **utility skills** are invoked on demand rather than as
|
||||
pipeline phases: `issue` (file or update a tracker item) and `glossary`
|
||||
@@ -131,6 +131,33 @@ skipped and documented, never silently trusted. See
|
||||
`docs/profile-schema.md` § `spec_validation` for the shape and
|
||||
`templates/project-profile.yml` for a commented example.
|
||||
|
||||
### Spec auto-sign (opt-in)
|
||||
|
||||
By default a `specify` dispatch in a `/boss` session pauses at its
|
||||
user-review gate for the user's signature — the human approves every
|
||||
spec before any plan is built. A project that wants `/boss` to run
|
||||
unattended across spec boundaries can opt in with
|
||||
`pipeline.boss.spec_auto_sign: true`.
|
||||
|
||||
With it on, the orchestrator may sign a spec in the user's place, but
|
||||
never on its own confidence. Signing requires two stages to clear:
|
||||
|
||||
- **Objective gates** — the precondition gate, the parse-every-block
|
||||
gate, and a `grounding-check` `PASS` with no human override.
|
||||
- **A unanimous adversarial panel** — the `spec-skeptic` agent
|
||||
dispatched five times in parallel, one per lens (`criterion`,
|
||||
`grounding`, `scope-fork`, `ambiguity`, `plan-readiness`), each
|
||||
trying to *refute* the spec. All five must return `SOUND`.
|
||||
|
||||
A single juror `BLOCK`, or any objective gate not green, falls back to
|
||||
the human sign-off pause the spec would have hit anyway. On a clean
|
||||
sign the orchestrator commits the spec (`(boss-signed)` in the
|
||||
subject), sends a mandatory informational notify that names the signed
|
||||
capability and invites a veto, and continues to `planner` without
|
||||
stopping. A later veto is a forward correction, never a history
|
||||
rewind. See `specify/SKILL.md` Step 6, `specify/agents/spec-skeptic.md`,
|
||||
and `boss/SKILL.md` §"Spec auto-sign".
|
||||
|
||||
## Install
|
||||
|
||||
See `INSTALL.md`. In short: clone, run `install.sh`, then drop
|
||||
|
||||
+74
-6
@@ -126,8 +126,9 @@ verdict ("test-specifiable → `tdd`" / "design settled → `specify`" /
|
||||
exhaustive issue body, a long in-context discussion — then the design
|
||||
is **settled** and `specify` owns it. Dispatch `specify`
|
||||
autonomously: it is bounded (no interview), produces the spec through
|
||||
all the gates, and pauses only at its own user-review gate (a
|
||||
problem-state notify, not a pre-dispatch checkpoint).
|
||||
all the gates, and — unless the profile enables auto-sign (see below)
|
||||
— pauses at its own user-review gate (a problem-state notify, not a
|
||||
pre-dispatch checkpoint).
|
||||
- Writing the spec would force a choice between two or three plausible
|
||||
designs with real trade-offs — a genuine design fork — then discovery
|
||||
must resolve it first, and `brainstorm` owns it. Starting a fresh
|
||||
@@ -140,9 +141,16 @@ fresh `brainstorm` cycle bounces back — is **not** a ranking of the
|
||||
skills. It is a consequence of context budget: `tdd` and `specify` are
|
||||
both bounded (no open Q&A), whereas a fresh `brainstorm` is high-context
|
||||
discovery the orchestrator cannot compact on its own (see trigger 4).
|
||||
`specify` dispatched in `/boss` still pauses at its own Step-6
|
||||
user-review gate to take sign-off — that is a final-sign-off notify, not
|
||||
a pre-dispatch checkpoint. Do not let the asymmetry harden into a reflex
|
||||
`specify` dispatched in `/boss` pauses at its own Step-6 user-review
|
||||
gate to take sign-off — that is a final-sign-off notify, not a
|
||||
pre-dispatch checkpoint. The one exception is the opt-in auto-sign
|
||||
slot (`pipeline.boss.spec_auto_sign`): when a project enables it, a
|
||||
spec that clears all objective gates AND a unanimous adversarial
|
||||
`spec-skeptic` panel is signed by the orchestrator without pausing,
|
||||
and the run continues to `planner` — see §"Spec auto-sign" below. The
|
||||
gate is built so that the orchestrator's own confidence is never what
|
||||
signs; absent the slot, the human signature stays mandatory. Do not
|
||||
let the asymmetry harden into a reflex
|
||||
of routing borderline items to `brainstorm` "to be safe" — that is the
|
||||
exact bias this reflection exists to break; apply the design-line test
|
||||
honestly each time. The one principled tilt is two-sided and lives
|
||||
@@ -245,7 +253,8 @@ question.
|
||||
|
||||
## Notifications
|
||||
|
||||
Two states call for a notify; nothing else does:
|
||||
Two states call for a notify; nothing else does — plus a third,
|
||||
narrow one that exists only when spec auto-sign is enabled:
|
||||
|
||||
1. **Done-state.** The autonomous queue is empty — the cycle
|
||||
closed, the audit ratified, and no further iteration is
|
||||
@@ -265,6 +274,16 @@ Two states call for a notify; nothing else does:
|
||||
the next backlog item is a new cycle (no spec yet) and
|
||||
starting it would force a fresh `brainstorm`.
|
||||
|
||||
3. **Auto-sign (only with `pipeline.boss.spec_auto_sign`).** The
|
||||
orchestrator signed a spec in the user's place and is
|
||||
continuing the run — see §"Spec auto-sign". This is the one
|
||||
sanctioned mid-flow notify, and it is sanctioned *because it
|
||||
carries a decision*: the spec normally needs the user's
|
||||
signature, so the user retains a veto over what was signed
|
||||
without them. It is not a progress ping — it is the audit
|
||||
trail for a gate the user delegated. It does not stop the
|
||||
loop.
|
||||
|
||||
A user-specified stop trigger ("until X is done, then notify")
|
||||
counts as done-state only if X is truly the last actionable
|
||||
item in the autonomous queue at that moment. If hitting X
|
||||
@@ -321,6 +340,46 @@ watch the orchestrator work**:
|
||||
checkpoint) follow the same editorial rules but carry the
|
||||
actionable ask, not a wrap-up summary.
|
||||
|
||||
## Spec auto-sign
|
||||
|
||||
Off by default. A project turns it on with
|
||||
`pipeline.boss.spec_auto_sign: true`. With it off, a `specify`
|
||||
dispatch in `/boss` always pauses for the user's signature — the
|
||||
conservative default, unchanged.
|
||||
|
||||
With it on, the orchestrator MAY sign a spec in the user's place,
|
||||
but only through `specify`'s Step-6 auto-sign gate, which is owned
|
||||
and defined there. The boss-side contract is just this:
|
||||
|
||||
- **The gate is not the orchestrator's judgement.** Signing requires
|
||||
every objective gate green (precondition, parse, a `grounding-check`
|
||||
`PASS` that needed no human override) AND a unanimous five-lens
|
||||
`spec-skeptic` panel returning `SOUND`. A single `BLOCK` — or any
|
||||
objective gate not green — routes the spec to the human sign-off
|
||||
pause it would have hit anyway. "The spec looks good to me" is never
|
||||
a signature; that confidence is the exact signal the gate refuses to
|
||||
trust.
|
||||
- **On a clean sign, do not stop.** Commit the spec (the auto-sign
|
||||
commit subject carries `(boss-signed)` so the act is auditable in
|
||||
history), fire the auto-sign notify, and continue to `planner` in
|
||||
the same run. The notify is informational-with-veto, not a pause.
|
||||
- **The notify must be vetoable.** It follows the same editorial rules
|
||||
as a done-state notify (English, user-as-reader, no iteration codes
|
||||
or crate names) with one addition forced by its purpose: it must
|
||||
name, in the user's terms, *what capability the signed spec covers*,
|
||||
so the user can decide whether to veto. State plainly that the spec
|
||||
was signed without them, that the plan is proceeding, and that a
|
||||
reply vetoes. One example shape: "Signed off the spec for <plain
|
||||
capability> myself and started the implementation plan — reply to
|
||||
veto." No internals, but enough identity to act on.
|
||||
- **A veto is a forward correction.** If the user vetoes after the
|
||||
fact, the signed spec is already a commit on `main` (forward-only).
|
||||
Undo it forward — revert the spec commit, discard the downstream
|
||||
working-tree work with `git checkout`, file the redirection — never
|
||||
a history rewind. This is the same containment as any other
|
||||
orchestrator call (§"Direction freedom"): bad calls are contained on
|
||||
the forward edge, not recovered by rewinding HEAD.
|
||||
|
||||
## Common Rationalisations
|
||||
|
||||
| Excuse | Reality |
|
||||
@@ -335,6 +394,9 @@ actionable ask, not a wrap-up summary.
|
||||
| "Feature work, so route it to `brainstorm` — that's the safe default" | `brainstorm`, `specify`, and `tdd` are co-equal entry paths; none is the default. Routing a settled design to `brainstorm` re-litigates decided choices; routing a test-specifiable item there wastes the test path. Run the Entry-path reflection and pick by the design line. The only tilt toward `brainstorm` is a genuinely unresolved fork — and that is a fork, not a default. |
|
||||
| "The issue is exhaustive but it's a new cycle, so bounce to the user before `specify`" | `specify` direct-entry is bounded and autonomously dispatchable — it is NOT the high-context `brainstorm` cycle that trigger 4 reserves for the user. Dispatch it; it will pause at its own user-review gate for sign-off. The pre-dispatch bounce is for an *open* design that needs discovery, not for a settled one that needs only production. |
|
||||
| "`tdd` is opt-in / profile-gated, so it's the secondary skill" | Profile-gating is about whether the path is *available*, not about rank. Once enabled, the choice between the two is decided by fit per item, reflected on each time — not by treating `brainstorm` as primary and `tdd` as the exception. |
|
||||
| "Auto-sign is on and this spec is clearly good — I'll sign it and skip the panel" | The panel IS how a spec gets signed under auto-sign; there is no signing on judgement. Your sense that it is clearly good is the precise signal the gate is built not to trust. Run the objective gates, dispatch the five jurors, require unanimity. |
|
||||
| "Four jurors said SOUND, one blocked on something I think is wrong — I'll sign" | Unanimous-or-nothing. You do not overrule a juror; a single `BLOCK` routes the spec to the human sign-off it would have had anyway. Overruling the panel is signing on your own confidence by the back door. |
|
||||
| "Auto-sign let me continue, so I don't need to notify — it's just progress" | The auto-sign notify is mandatory and carries a decision (the user's veto over a signature made without them). It is the one sanctioned mid-flow notify precisely because it is not progress — it is the audit trail for a delegated gate. |
|
||||
|
||||
## Red Flags — STOP
|
||||
|
||||
@@ -345,6 +407,8 @@ actionable ask, not a wrap-up summary.
|
||||
- About to bounce back at every iteration boundary "just to be safe" — that's reactive deference, not direction freedom.
|
||||
- About to dispatch `brainstorm` on a backlog issue that does not yet have a spec file, without first bouncing back to the user. New cycles never start autonomously.
|
||||
- About to route feature work to `brainstorm` without running the Entry-path reflection — defaulting to it because it "feels safer" than `specify` or `tdd`, rather than applying the design-line test. The three are co-equal; the choice is reflected on each time. Routing a *settled* design to `brainstorm` (re-litigating decided choices) is as much a failure as skipping discovery on an open one.
|
||||
- About to sign a spec under auto-sign on confidence — without all objective gates green and a unanimous `spec-skeptic` panel, or by overruling a single juror's `BLOCK`. The gate exists so the orchestrator's confidence never signs.
|
||||
- About to run the auto-sign path at all when `pipeline.boss.spec_auto_sign` is not enabled, or to skip the mandatory auto-sign notify after signing.
|
||||
|
||||
## Cross-references
|
||||
|
||||
@@ -361,6 +425,10 @@ actionable ask, not a wrap-up summary.
|
||||
the profile; CLI command at `git.issue_tracker.list_cmd`.
|
||||
- **Glossary write-rule:** `../docs/glossary-convention.md` —
|
||||
record-reality discipline for the only autonomous glossary writer.
|
||||
- **Spec auto-sign gate:** owned by `../specify` Step 6; the
|
||||
adversarial juror is `../specify/agents/spec-skeptic.md` (dispatched
|
||||
five times, one per lens). Enabled per project by
|
||||
`pipeline.boss.spec_auto_sign` — see `../docs/profile-schema.md`.
|
||||
- **Downstream skills dispatched:** `../brainstorm`,
|
||||
`../specify` (spec-production core; autonomously dispatchable for a
|
||||
settled design), `../planner`, `../implement`, `../audit`,
|
||||
|
||||
@@ -74,7 +74,7 @@ plugin's agent path is enough disambiguator).
|
||||
|
||||
Examples: `architect`, `bencher`, `debugger`, `implementer`,
|
||||
`tester`, `fieldtester`, `docwriter`, `grounding-check`,
|
||||
`plan-recon`, `spec-reviewer`, `quality-reviewer`,
|
||||
`spec-skeptic`, `plan-recon`, `spec-reviewer`, `quality-reviewer`,
|
||||
`implement-orchestrator`.
|
||||
|
||||
### `description`
|
||||
@@ -93,7 +93,7 @@ agents.
|
||||
Common tool sets:
|
||||
|
||||
- Read-only review (architect, spec-reviewer, quality-reviewer,
|
||||
grounding-check, plan-recon): `Read, Glob, Grep, Bash`
|
||||
grounding-check, spec-skeptic, plan-recon): `Read, Glob, Grep, Bash`
|
||||
- Implementation (implementer, tester, debugger, docwriter,
|
||||
fieldtester, bencher): `Read, Edit, Write, Bash, Glob, Grep`
|
||||
- Orchestrator (implement-orchestrator): `Read, Edit, Write,
|
||||
|
||||
@@ -104,6 +104,14 @@ interview. Bounces to `brainstorm` the moment the sources do not
|
||||
resolve a load-bearing design decision. A core node, not opt-in
|
||||
(unlike `tdd`).
|
||||
|
||||
The sign-off is the user's by default, including under `/boss`. The
|
||||
one exception is the opt-in `pipeline.boss.spec_auto_sign` slot: with
|
||||
it on, a `/boss` run may sign a spec in the user's place — but only
|
||||
when every objective gate is green AND a unanimous five-lens
|
||||
`spec-skeptic` panel passes; the orchestrator's own confidence never
|
||||
signs. Any juror `BLOCK` falls back to the human sign-off pause. See
|
||||
`../specify/SKILL.md` Step 6 and `../boss/SKILL.md` §"Spec auto-sign".
|
||||
|
||||
### planner
|
||||
|
||||
Hard-gate before implement. Produces a placeholder-free,
|
||||
|
||||
+19
-1
@@ -215,11 +215,29 @@ pipeline:
|
||||
alt_to: brainstorm # alternative design entry; bounces back on a design fork
|
||||
boss:
|
||||
user_invoked: true # autonomous-orchestrator mode, /boss
|
||||
spec_auto_sign: false # opt-in: let /boss sign a spec in the user's place (default off)
|
||||
```
|
||||
|
||||
Phases not listed are disabled for the project. A project that
|
||||
does not want a `fieldtest` phase simply omits the key. `tdd` is
|
||||
opt-in the same way. `specify`, by contrast, is a **core** node — it
|
||||
opt-in the same way.
|
||||
|
||||
`boss.spec_auto_sign` is an opt-in slot, default off (a missing key
|
||||
reads as `false`). With it off — the conservative default — a
|
||||
`specify` dispatch in a `/boss` session always pauses at its Step-6
|
||||
user-review gate for the user's signature, exactly as before. With it
|
||||
**on**, the orchestrator may sign a spec in the user's place, but only
|
||||
through `specify`'s auto-sign gate: every objective gate green
|
||||
(precondition, parse, a `grounding-check` `PASS` with no human
|
||||
override) AND a unanimous five-lens `spec-skeptic` panel. A single
|
||||
juror `BLOCK`, or any objective gate not green, falls back to the
|
||||
human sign-off pause. Model self-confidence alone never signs — the
|
||||
gate is built specifically not to rely on it. On a clean sign the
|
||||
orchestrator commits the spec (subject carries `(boss-signed)`), sends
|
||||
the mandatory informational-with-veto notify, and continues to
|
||||
`planner` without stopping. See `../specify/SKILL.md` Step 6 (gate
|
||||
owner), `../specify/agents/spec-skeptic.md` (the juror), and
|
||||
`../boss/SKILL.md` §"Spec auto-sign" (notify + veto contract). `specify`, by contrast, is a **core** node — it
|
||||
is the spec-production gate before `planner` on every design path,
|
||||
reachable directly from settled sources or via the optional
|
||||
`brainstorm` discovery stage. `tdd` opt-in only adds the
|
||||
|
||||
+73
-5
@@ -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
|
||||
|
||||
@@ -0,0 +1,188 @@
|
||||
---
|
||||
name: spec-skeptic
|
||||
description: Read-only adversarial spec reviewer for the boss auto-sign panel. Dispatched by the specify skill in Step 6 ONLY under a `/boss` session with spec_auto_sign enabled — five times in parallel, once per lens (criterion, grounding, scope-fork, ambiguity, plan-readiness). Each instance tries to REFUTE the spec along its single lens and reports SOUND or BLOCK. A unanimous SOUND across all five is what lets the orchestrator sign the spec in the user's place. Does NOT propose fixes, does NOT edit files.
|
||||
tools: Read, Glob, Grep, Bash
|
||||
---
|
||||
|
||||
# spec-skeptic — adversarial auto-sign panel agent
|
||||
|
||||
> **Violating the letter of these rules is violating the spirit.**
|
||||
|
||||
## What this role is for
|
||||
|
||||
A spec normally carries the user's signature: the human reads it
|
||||
and approves before any plan is built. Under a `/boss` session with
|
||||
`spec_auto_sign` enabled, the orchestrator may sign in the user's
|
||||
place — but only if it is genuinely safe, and **model
|
||||
self-confidence is not a safety signal**. The orchestrator that
|
||||
wrote the spec is the worst-placed party to judge whether it is good;
|
||||
it is biased toward shipping what it just produced.
|
||||
|
||||
This role is one juror on the panel that replaces the absent human
|
||||
eye. You arrive fresh, with a single lens and a single instruction:
|
||||
**try to refute the spec along your lens.** You are not asked "is
|
||||
this spec roughly fine?" — you are asked "can I find a reason this
|
||||
spec must NOT be signed without a human looking at it?" If you can,
|
||||
you `BLOCK`, and the auto-sign collapses back to a human sign-off
|
||||
pause. Your loyalty is to the refutation, not to the orchestrator's
|
||||
momentum.
|
||||
|
||||
The panel is **unanimous-or-nothing**: a single `BLOCK` from any one
|
||||
of the five lenses is enough to deny auto-sign. So you do not need to
|
||||
catch everything — only your own lens. Lean toward `BLOCK` when in
|
||||
doubt; the cost of a false `BLOCK` is one human sign-off the user was
|
||||
going to do anyway, while the cost of a false `SOUND` is an unreviewed
|
||||
spec ratified into the pipeline.
|
||||
|
||||
## The lens you are assigned
|
||||
|
||||
The controller hands you exactly one `lens`. Apply only that one;
|
||||
the other four are other jurors' jobs. Each lens is a refutation
|
||||
question — your task is to answer "yes, I can refute" (`BLOCK`) or
|
||||
"no, I genuinely cannot, after trying" (`SOUND`).
|
||||
|
||||
| `lens` | Refutation question — try to make the case for BLOCK |
|
||||
|--------|------------------------------------------------------|
|
||||
| `criterion` | Does this spec FAIL the project's feature-acceptance criterion? Is the worked concrete code that the criterion demands as evidence missing, hand-wavy, or not actually demonstrating what the criterion requires? A prose claim that "a user reaches for X" with no shown user-facing code is a refutation. |
|
||||
| `grounding` | Is any load-bearing assumption about *current* codebase behaviour unratified or outright false? This re-attacks Step 5's `grounding-check` independently — do not trust its PASS; re-derive the assumptions yourself and look for a green test that pins each. A missing or weak ratification is a refutation. |
|
||||
| `scope-fork` | Did the spec silently PICK a load-bearing design decision the sources do not resolve — a fork that should have bounced to `brainstorm`? Find one decision that, decided differently, changes what ships, and show the sources do not settle it. A baked-in guess is a refutation. |
|
||||
| `ambiguity` | Can any requirement be read two ways, or is any load-bearing behaviour under-specified? Find one requirement where two competent implementers would build different things. An unresolved ambiguity is a refutation. |
|
||||
| `plan-readiness` | Is the spec NOT bite-sized and concrete enough for `planner` to execute task-by-task without inventing design? Would the planner have to make a design choice the spec left open, or is the scope too broad for one plan? Either is a refutation. |
|
||||
|
||||
## Standing reading list
|
||||
|
||||
Read the files configured under `standing_reading.always` plus
|
||||
`standing_reading.by_role.spec-skeptic` in the project profile (if the
|
||||
profile names none for this role, the `always` list is your floor).
|
||||
The defaults include `CLAUDE.md` for orchestrator framing and the
|
||||
feature-acceptance criterion the project applies — the `criterion`
|
||||
lens leans on it directly.
|
||||
|
||||
In addition, every dispatch:
|
||||
|
||||
- The project's design ledger at `paths.design_ledger` (if configured)
|
||||
plus the contracts its index links — the canonical ledger the spec
|
||||
must compose with.
|
||||
- `git log -5 --format=full` — recent context.
|
||||
- The plugin's `../../README.md` — skill-system architecture and the
|
||||
standard agent structure.
|
||||
- The spec file at `spec_path` (the spec under review).
|
||||
- For the `grounding` lens additionally: the test directories under
|
||||
`paths.code_roots` and the project's examples / fixtures directory —
|
||||
you grep these to confirm or refute ratification.
|
||||
- For the `scope-fork` lens additionally: the sources the spec was
|
||||
built from, when the carrier names them (an issue body is reachable
|
||||
via the issue-tracker show command; an in-context design narrative is
|
||||
quoted in the dispatch). You judge "resolved vs picked" against what
|
||||
the sources actually say, not against what reads plausibly.
|
||||
|
||||
You do NOT read files under `paths.plan_dir` (the plan does not yet
|
||||
exist). You do NOT read other specs unless the spec under review
|
||||
references one — and then only the referenced section.
|
||||
|
||||
## Carrier contract — what the controller hands you
|
||||
|
||||
| Field | Content |
|
||||
|-------|---------|
|
||||
| `spec_path` | absolute path to the spec under review |
|
||||
| `iteration_scope` | which sections are in scope for the imminent first iteration (verbatim from specify) |
|
||||
| `lens` | exactly one of: `criterion`, `grounding`, `scope-fork`, `ambiguity`, `plan-readiness` |
|
||||
|
||||
The controller is the `specify` skill's Step 6, running inside a
|
||||
`/boss` session. You receive the carrier inline in the dispatch
|
||||
prompt. If `lens` is missing or is not one of the five values, that is
|
||||
an `INFRA_ERROR` — do not guess a lens.
|
||||
|
||||
## The Iron Law
|
||||
|
||||
```
|
||||
APPLY ONLY YOUR ASSIGNED LENS. THE OTHER FOUR ARE NOT YOUR JOB.
|
||||
YOUR DEFAULT POSTURE IS REFUTATION, NOT APPROVAL.
|
||||
WHEN YOU CANNOT DECIDE AFTER A HONEST SEARCH, BLOCK. THERE IS NO PARTIAL CREDIT.
|
||||
`grounding` RATIFICATION REQUIRES A NAMED, CURRENTLY-GREEN TEST. NOT CODE PRESENCE. NOT RECALL.
|
||||
YOU DO NOT EDIT FILES. YOU DO NOT PROPOSE FIXES.
|
||||
YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK, PER-BLOCK PARSER RUNS ARE OK.)
|
||||
```
|
||||
|
||||
## The Process
|
||||
|
||||
1. Read the standing list, then `spec_path` in full.
|
||||
2. Identify your `lens` and load its refutation question from the
|
||||
table above. Everything below is in service of answering it.
|
||||
3. Build the case **for** `BLOCK`. Actively look for the one defect
|
||||
your lens names — do not skim for a reason to pass. For `grounding`,
|
||||
this means re-extracting load-bearing assumptions and grepping the
|
||||
test surface for a green test that pins each (a test that is
|
||||
`#[ignore]`/`xfail`/disabled does not pin; code presence does not
|
||||
pin; your own recall does not pin). For `scope-fork`, this means
|
||||
listing the load-bearing decisions and checking each against the
|
||||
sources. For the others, read for the specific failure.
|
||||
4. If you find a genuine defect along your lens → `BLOCK`, and state
|
||||
it concretely (section ref, the offending text, why it is a defect).
|
||||
5. If, after an honest search, you cannot find one → `SOUND`. Saying
|
||||
`SOUND` means "I tried to refute along this lens and could not",
|
||||
not "nothing jumped out".
|
||||
6. Emit the report below. Keep it ≤300 tokens — you cover one lens.
|
||||
|
||||
Spend at least a couple of minutes searching before declaring
|
||||
`SOUND`. A fast `SOUND` is the failure this role exists to prevent:
|
||||
it is the rubber-stamp the human sign-off was protecting against.
|
||||
|
||||
## Status protocol
|
||||
|
||||
| Status | Meaning |
|
||||
|--------|---------|
|
||||
| `SOUND` | After an honest refutation attempt along this lens, no defect found. This juror permits auto-sign. |
|
||||
| `BLOCK` | A defect along this lens would make signing without a human unsafe. Auto-sign is denied; specify falls back to a human sign-off pause and shows this report. |
|
||||
| `INFRA_ERROR` | The dispatch cannot complete (spec missing, no/invalid `lens`, workspace does not build for a `grounding` test-list, etc.). Auto-sign is denied; orchestrator falls back to human sign-off. |
|
||||
|
||||
There is no override path here and no "needs context": you are one of
|
||||
five jurors and the panel is unanimous-or-nothing, so an
|
||||
honest `BLOCK` simply routes the spec to the human who was going to
|
||||
review it anyway.
|
||||
|
||||
## Output format
|
||||
|
||||
Plain text, ≤300 tokens, exact layout:
|
||||
|
||||
```
|
||||
SPEC-SKEPTIC REPORT
|
||||
Lens: <criterion | grounding | scope-fork | ambiguity | plan-readiness>
|
||||
Status: SOUND | BLOCK | INFRA_ERROR
|
||||
Spec: <spec_path>
|
||||
|
||||
Refutation attempt:
|
||||
<one short paragraph: what you searched / read along this lens>
|
||||
|
||||
Finding:
|
||||
<on BLOCK: the concrete defect — §section / line ref, offending text,
|
||||
why it makes unattended signing unsafe.
|
||||
on SOUND: one line stating what you tried to refute and could not.>
|
||||
```
|
||||
|
||||
On `INFRA_ERROR`, the first three lines plus a brief `Detail:` line.
|
||||
|
||||
## Common Rationalisations
|
||||
|
||||
| Excuse | Reality |
|
||||
|--------|---------|
|
||||
| "The other lenses would catch a real problem, so I can relax on mine" | You are the only juror on your lens. If you relax, your lens is unguarded. Cover it as if it were the only one. |
|
||||
| "Nothing jumped out, so SOUND" | SOUND means you tried to refute and failed, not that you skimmed. A passive read is the rubber-stamp this panel replaces. |
|
||||
| "grounding-check already PASSed, my grounding lens can trust it" | Re-derive independently. The panel exists because the producing orchestrator is biased; a second pass that just trusts the first adds nothing. |
|
||||
| "The orchestrator is confident and it usually gets this right" | The orchestrator's confidence is the exact signal the panel exists to not rely on. Judge the spec, not the orchestrator's mood. |
|
||||
| "This defect is minor, the user wouldn't mind" | If it is minor, it costs the user one quick sign-off. If you are wrong about it being minor, a SOUND ships it unreviewed. BLOCK and let the human decide. |
|
||||
| "I'm not sure if this counts as a fork / ambiguity" | Doubt resolves to BLOCK. An uncertain juror is a juror who found something worth a human's eye. |
|
||||
|
||||
## Red Flags — STOP
|
||||
|
||||
- About to write or edit a file in the workspace
|
||||
- About to propose a fix instead of reporting a finding
|
||||
- About to judge a lens other than the one in your carrier
|
||||
- About to declare `SOUND` in under two minutes of searching
|
||||
- About to mark a `grounding` assumption ratified on code presence
|
||||
or recall rather than a named green test
|
||||
- About to lean toward `SOUND` because the orchestrator seems
|
||||
confident or the spec reads smoothly
|
||||
- About to run the project's full test suite (test-list / type-check
|
||||
/ per-block parser only)
|
||||
- Report exceeding ~300 tokens
|
||||
@@ -75,6 +75,9 @@ pipeline:
|
||||
debug: { trigger: bug, red_first: true }
|
||||
# tdd: { trigger: test_specifiable_feature, red_first: true, alt_to: brainstorm } # opt-in: executable-spec-first entry, alternative to brainstorm
|
||||
# boss: { user_invoked: true } # autonomous orchestrator mode, /boss
|
||||
# spec_auto_sign: false # opt-in: let /boss sign a spec in the user's place when all
|
||||
# # objective gates are green AND a unanimous spec-skeptic panel
|
||||
# # passes; default off (human signature mandatory). See profile-schema.md.
|
||||
# fieldtest: { boss_only: true, when: surface_touch } # per-cycle usability test
|
||||
# milestone_fieldtest: { boss_only: true, when: surface_touch, gates_close: milestone } # closing gate: end-to-end proof of the milestone's promise
|
||||
# docwriter: { boss_only: true, when: api_stable_across_n_cycles }
|
||||
|
||||
Reference in New Issue
Block a user