diff --git a/README.md b/README.md index 2b24420..ab09e67 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,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 | Standard 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; signs specs in the user's place through the auto-sign gate (see below) | User-invoked, never auto-dispatched | +| `boss` | User types `/boss` | autonomous-orchestrator session — dispatches the other skills until done-state or bounce-back; signs specs in the user's place on the `grounding-check` `PASS` (see below) | User-invoked, never auto-dispatched | **Entry is a selector cascade, not a single door.** New feature work is routed on a verification / enumeration axis, walked top to bottom, first @@ -99,7 +99,9 @@ This repo (the **plugin**) carries everything that is universal: - Status protocol: `DONE / DONE_WITH_CONCERNS / PARTIAL / BLOCKED / NEEDS_CONTEXT` - Working-tree-as-quarantine and only-orchestrator-commits -- main HEAD sacrosanct +- main HEAD sacrosanct below the session anchor (the one narrow + exception is the `/boss` rollback sandbox — own unpushed autonomous + commits above the run's start anchor) - No nested subagent dispatch (Claude Code platform constraint; Workflows orchestrate at the top level but do not lift it — the execution loops run as Workflow scripts so their phase agents are @@ -134,38 +136,29 @@ project's `CLAUDE.md`, which is standing reading on every dispatch. ### Spec auto-sign Under `/boss`, the orchestrator signs a spec in the user's place rather -than pausing at the user-review gate — so a `/boss` run carries on -across spec boundaries unattended. (Outside `/boss` the user signs every -spec directly.) The orchestrator never signs on its own confidence; -signing requires two stages to clear: +than pausing at the sign-off gate — so a `/boss` run carries on across +spec boundaries unattended. (Outside `/boss` the user signs every spec +directly.) The autonomous signature is the **`grounding-check` `PASS`**: +an independent fresh-context agent's verdict against currently-green +tests, not the orchestrator's confidence. On `PASS` 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 no-override +grounding `BLOCK` / `INFRA_ERROR` routes to the human sign-off pause. -- **Objective gates** — the precondition 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 `BLOCK` is never signed over. The five lenses split by what a `BLOCK` -means: an *editorial* one (`criterion`, `ambiguity`, `plan-readiness` — -the spec is under-articulated) the orchestrator repairs in a bounded -loop (edit, re-run the objective gates, re-dispatch all five lenses, up -to 2 rounds); a *design* one (`scope-fork`, `grounding` — the ground is -not settled), an `INFRA_ERROR`, any objective gate not green, or an -exhausted budget falls back to the human sign-off pause the spec would -have hit anyway. Re-dispatching all five lenses every round is the -backstop that stops an editorial repair from quietly settling a design -question. When a fork was settled in-context, `specify` gives the -`scope-fork` juror an auditable source for it (Step 1.5): a provenance- -bearing reconciliation comment when a seeding issue exists but lags the -discussion, or a freshly created seeding issue when the cycle had none — -either read via the project's issue show command, closing the blind spot -where the in-context entry path could otherwise never clear that lens. -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, +The judgement work happens **upstream**: under the bold stance, `specify` +Step 1.5 *decides* every load-bearing fork it can derive an answer for +(from the sources, the code, consistency, risk) and records the decision +on the run's reference issue, pulling an ad-hoc `spec-skeptic` lens as a +bias-breaker when it is unsure whether its leaning is judgement or bias; +only a *pure-preference* fork bounces to the human. The former obligatory +unanimous five-lens `spec-skeptic` panel is **retired** (baseline tag +`pre-autosign-rework`) — editorial roughness it would have caught is let +through deliberately, cheap to patch inline downstream. A wrong derived +call is recovered by the user's veto or, within the run, the rollback +sandbox (`boss/SKILL.md` § Direction freedom): the orchestrator may +hard-reset its *own unpushed* autonomous commits back toward the session +anchor on a dead end. See `specify/SKILL.md` Step 6, `specify/agents/spec-skeptic.md`, and `boss/SKILL.md` §"Spec auto-sign". ## Install diff --git a/boss/SKILL.md b/boss/SKILL.md index 2dd3e74..2aac8c4 100644 --- a/boss/SKILL.md +++ b/boss/SKILL.md @@ -65,7 +65,11 @@ language, RED-first for bugs) come from the project's `CLAUDE.md` layer above it, loaded in every session. Both bind regardless of mode; autonomy does not lift a user-level constraint (e.g. an external-service-consent rule that names `/boss` explicitly). This -skill does not restate them. +skill does not restate them — with one deliberate local refinement: +`main`-is-sacrosanct holds **below the session anchor**, and the +rollback sandbox (§ Direction freedom) is the one narrow `/boss` +exception, letting the orchestrator wind back its *own* unpushed +autonomous commits above that anchor. ## The Process @@ -168,9 +172,9 @@ route(task): fallback for prose-design work the sources already settle (an exhaustive issue body, a long in-context discussion). `specify` is bounded (no interview); dispatch it autonomously and it signs through - its own Step-6 auto-sign gate, escalating to a user-review pause (a - problem-state notify, not a pre-dispatch checkpoint) only when the - gate cannot clear. + its own Step-6 gate — the Step-5 `grounding-check` `PASS` — escalating + to a user-review pause (a problem-state notify, not a pre-dispatch + checkpoint) only when grounding blocks with no human to override it. **The straddle rule (a rule, not an example).** "Add an enum variant" straddles the compiler-driven and the tdd/spec arms. Decide by what the @@ -190,19 +194,21 @@ context budget: the four are bounded (no open Q&A; `compiler-driven` and `debug` self-settle on a run), whereas a fresh `brainstorm` is high-context discovery the orchestrator cannot compact on its own (see trigger 4). `specify` dispatched in `/boss` signs through its own Step-6 -auto-sign gate: 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. A spec that cannot clear the gate escalates to the user-review -pause (a final-sign-off notify, not a pre-dispatch checkpoint). The gate -is built so the orchestrator's own confidence is never what signs. 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; walk the cascade -honestly each time. The one principled tilt is two-sided and lives -*inside* the test: genuine doubt about whether the sources (or one -assertion) can pin the design *is itself* the design-fork signal, so it -resolves to `brainstorm` — not because `brainstorm` is preferred, but -because unresolved ambiguity is a fork by definition. The lighter arms +gate — the Step-5 `grounding-check` `PASS`, an independent agent's +verdict against currently-green tests, not the orchestrator's confidence; +the run then continues to `planner` without pausing. A no-override +grounding `BLOCK` escalates to the user-review pause (a final-sign-off +notify, not a pre-dispatch checkpoint). The judgement that used to gate +the sign now lives inside `specify` Step 1.5, which decides derivable +forks boldly — see §"Spec auto-sign" below. 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; walk the +cascade honestly each time. The one principled tilt is two-sided: a fork +`specify` can *derive* an answer for (from the sources, the code, +consistency, risk) is spec-driven work, decided inside `specify` (Step +1.5), **not** a `brainstorm` bounce; only a fork that needs genuine +discovery, or that hangs on a user preference no source settles, +resolves to `brainstorm`. The lighter arms also bounce reactively: a `specify` or `tdd` that later reports the design was not settled / not test-specifiable, or a `compiler-driven` run that hits a hole, escalates — `specify` / `tdd` to `brainstorm` (a @@ -253,19 +259,76 @@ Run the procedure named in "Done-state notifications" below. ## Direction freedom The orchestrator has authority to choose the next iteration, -refactor, or feature without asking. Wrong calls are contained, -not recovered: only the orchestrator commits, and only when the -working-tree state is consistent — so bad work doesn't reach -main in the first place. If a dispatched agent's output is -wrong, the remedy is `git checkout -- ` on the working -tree (orchestrator-side), never a rewind of main HEAD. main is -forward-only. +refactor, or feature without asking — and, under the bold stance, to +*decide* a load-bearing design fork it can derive an answer for rather +than bounce it (see `../specify/SKILL.md` Step 1.5). Wrong calls are +**contained or recovered**, not avoided by timidity: bad work is either +discarded before it reaches `main` (`git checkout -- ` on the +working tree), or — once it is autonomous, committed, unpushed work — wound +back inside the rollback sandbox below. Being wrong is allowed; the cost +of a wrong call is bounded, and a bounded cost is cheaper than the +context-switch of asking. The cost of asking "what should I do next" — context-switch for the user, latency on my side — exceeds the expected cost of -discarding a bad working-tree state. So when the queue is +discarding or rolling back a bad state. So when the queue is non-empty and the path is clear, just pick and proceed. +### The reference issue (mandatory) + +Every `/boss` run is anchored to a tracker issue — the one that seeded +the cycle, or one `specify` creates when the work was settled in pure +chat with no prior issue (`../specify/SKILL.md` Step 1.5). The run always +has exactly one such reference issue, and the orchestrator **comments its +fork decisions there as it goes**: each load-bearing fork it derives, the +chosen option, and the rationale (or, for a user decision minuted from +the discussion, the provenance). It is the run's decision log — three +things at once: + +- the **user's after-the-fact audit**: how the orchestrator decided what + it decided without them, in one auditable thread they can veto from; +- the orchestrator's **cross-run "issue memory"**: a later run reads the + thread to see what was already tried and why; +- the **only surviving trace of an abandoned attempt** — because a + rollback hard-drops the commits (below), the issue thread is what + remains of the dead-ended line. + +A run that reaches a fork decision without a reference issue to record it +on is a bug: create the seeding issue first (Step 1.5 mechanic), then +decide. + +### The rollback sandbox + +`main` stays sacrosanct **below the session anchor**. At the start of an +autonomous run the orchestrator notes the current `main` HEAD — the last +user-ratified state — as the **session anchor**. Everything it then +commits autonomously, this run, and has **not pushed**, is its own +sandbox above that anchor. + +Inside the sandbox, and only there, the forward-only rule is relaxed: +when the orchestrator runs itself into a dead end — `implement` stays +`BLOCKED` after its re-loops, `audit` or `fieldtest` exposes that an +earlier derived fork was wrong, a line of work is not salvageable +forward — it MAY `git reset --hard` back toward the anchor, to the point +before the wrong turn, and try again differently. The boundaries are +hard: + +- **Never below the anchor.** The anchor is the floor. User-ratified + history is never rewound; the sandbox is only the orchestrator's own + autonomous commits. +- **Never a pushed commit.** Pushing hands work to the outside; a pushed + commit leaves the sandbox and reverts to forward-only (`git revert`), + never `reset`. In practice the orchestrator does not push autonomously, + so the sandbox is local. +- **Hard-drop, no parking.** A discarded attempt is gone — no + `attempt-N` branch or tag is kept. The reference-issue thread is its + trace; the transcript holds the rest. (The user's standing preference: + what the orchestrator threw away, the user does not want to see.) +- **Rollback is an escalation response, not a reflex.** It is for a genuine + dead end, not for flinching at the first agent that returns + `DONE_WITH_CONCERNS`. Reach for it when forward correction is clearly + more expensive or less safe than winding back and re-deciding. + Bounce back to the user only when: - A queued option requires a real design judgement I have not @@ -389,40 +452,37 @@ actionable ask, not a wrap-up summary. ## Spec auto-sign Under `/boss`, the orchestrator signs a spec in the user's place -through `specify`'s Step-6 auto-sign gate, which is owned and defined -there. (Outside `/boss`, the user signs every spec directly; there is -no gate to run.) A spec that cannot clear the gate escalates to the -human sign-off pause. The boss-side contract is just this: +through `specify`'s Step-6 gate, which is owned and defined there. +(Outside `/boss`, the user signs every spec directly; there is no gate +to run.) A spec the gate cannot clear escalates to the human sign-off +pause. 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`. "The spec looks good to me" is - never a signature; that confidence is the exact signal the gate - refuses to trust. -- **A `BLOCK` is repaired or escalated, never signed over.** The gate - splits the five lenses by what a `BLOCK` means. An *editorial* `BLOCK` - (`criterion` / `ambiguity` / `plan-readiness` — the spec is - under-articulated) the orchestrator may repair in a bounded loop: - edit, re-run the objective gates, re-dispatch all five lenses, up to - 2 rounds. A *design* `BLOCK` (`scope-fork` / `grounding` — the ground - is not settled), an `INFRA_ERROR`, any objective gate not green, or an - exhausted 2-round budget routes the spec to the human sign-off pause - it would have hit anyway. The orchestrator never settles a design - question in the user's place; the full re-panel each round is what - stops an editorial repair from laundering one in. The gate owns this - loop (`../specify/SKILL.md` Step 6) — boss only enforces the notify. - One upstream detail matters here: a fork settled in-context may be - invisible to the `scope-fork` juror, which reads the seeding issue. - `specify` Step 1.5 gives it an auditable source either way — when a - seeding issue exists but still lists the fork open, it posts a - provenance-bearing reconciliation comment; when there is *no* seeding - issue (design settled in pure chat), it creates one that records the - resolution with provenance and becomes the cycle's seeding issue. - Both record a *user* decision; neither lets the orchestrator certify - its own — no real user statement is a Step-1.5 bounce, not an artefact - to manufacture. The orchestrator writes the record; the juror checks - the provenance. +- **The signature is the `grounding-check` `PASS`, not the + orchestrator's judgement.** Under `/boss` the autonomous signature is + the Step-5 `grounding-check` returning `PASS` — an independent + fresh-context agent's verdict against currently-green tests. "The spec + looks good to me" is never a signature; that confidence is the exact + signal the gate refuses to trust. The former obligatory five-lens + `spec-skeptic` panel is **retired** (baseline tag + `pre-autosign-rework`); the judgement it used to apply now lives + upstream, in `specify` Step 1.5's bold-decide stance. +- **A no-override grounding `BLOCK` is never signed over.** With no human + in the loop, a grounding `BLOCK` (or `INFRA_ERROR`) cannot be + overridden, so it routes the spec to the human sign-off pause it would + have hit anyway. That is the one objective denial of an autonomous + sign. +- **Forks are decided upstream, boldly, and recorded.** `specify` Step + 1.5 decides every load-bearing fork it can *derive* an answer for + (sources, code, existing-design consistency, risk) — pulling an ad-hoc + `spec-skeptic` lens as a bias-breaker when it is unsure whether its + leaning is judgement or bias — and records each decision in the run's + **reference issue** (see § Direction freedom). Only a *pure-preference* + fork, one only the user's taste can settle, bounces to the human. So a + spec reaching the sign gate carries no unresolved judgement; the only + thing the sign verifies is the objective grounding the check already + verifies. Editorial roughness the old panel would have caught is let + through deliberately — cheap to patch inline downstream, never worth an + obligatory five-juror panel on every spec. - **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 @@ -436,13 +496,15 @@ human sign-off pause. The boss-side contract is just this: reply vetoes. One example shape: "Signed off the spec for 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. +- **A veto is a forward correction — or, within the run, a rollback.** + If the user vetoes a spec already committed on `main`, undo it forward + — revert the spec commit, discard the downstream working-tree work with + `git checkout`, file the redirection. *Within* the autonomous run, the + rollback sandbox (§ Direction freedom) is the additional remedy: the + orchestrator may hard-reset its own unpushed `(boss-signed)` commit and + the work built on it back toward the session anchor when it judges the + fork was wrong — its own work only, never below the anchor, never a + pushed commit. ## Common Rationalisations @@ -461,8 +523,9 @@ human sign-off pause. The boss-side contract is just this: | "It's a bug but the fix is a one-line type edit — route it `compiler-driven`" | No. An observed bug is first in the cascade → `debug`, RED-first, regardless of how mechanical the fix looks. The bug-gate sits before the type-edit arm precisely so a regression cannot launder itself around RED-first. | | "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 the secondary skill, `brainstorm` is the real entry" | All entry paths are always available. The choice among them is the cascade, walked per item — not a habit of treating `brainstorm` as primary and the lighter arms as exceptions. The lighter arms exist to be reached; reaching past them by elimination is the failure the verification axis was added to prevent. | -| "This spec is clearly good — I'll sign it and skip the panel" | The panel IS how a spec gets signed under `/boss`; 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 never sign over a `BLOCK`. If it is an editorial lens, repair it and re-run the whole panel (≤ 2 rounds); if it is a design lens or the budget is spent, it routes to the human sign-off it would have had anyway. Signing because *you* think the juror is wrong is overruling the panel — confidence by the back door. | +| "This spec is clearly good — I'll sign it on my judgement" | Your judgement is not the signature; the Step-5 `grounding-check` `PASS` is. Run grounding and sign on the PASS. A no-override grounding `BLOCK` routes to the human — never signed over on confidence. (The old unanimous `spec-skeptic` panel is retired; do not re-introduce it as a gate.) | +| "There's an open fork — I'll bounce to `brainstorm` to be safe" | If you can *derive* an answer (sources, code, consistency, risk), decide it boldly and record it in the reference issue. Only a *pure-preference* fork bounces. Bouncing a derivable fork is exactly the timidity the bold stance retired; unsure if your leaning is bias, pull one ad-hoc `spec-skeptic` lens, then decide. | +| "I derived a fork but didn't bother logging it on the issue" | The reference-issue comment is mandatory. It is the user's only window into a call made without them — and, because a rollback hard-drops the commits, the only surviving trace of the attempt. No reference issue, no fork decision: create the seeding issue first. | | "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 @@ -477,8 +540,11 @@ human sign-off pause. The boss-side contract is just this: - About to route an observed bug to the `compiler-driven` arm because "the fix is mechanical" — a regression is `debug`, RED-first; the bug-gate is first in the cascade for exactly this reason. - About to route a behaviour-encoding change to `compiler-driven` because it "looks mechanical" — apply the straddle rule: if the change encodes new behaviour it is `tdd` / `spec-driven`, and doubt means it carries behaviour. - About to accept a `compiler-driven` edit on a clean build without confirming the suite is green *unchanged* — the conjunction is the done-signal; a green-but-wrong change builds clean. -- About to sign a spec under auto-sign on confidence — without all objective gates green and a unanimous `spec-skeptic` panel; signing over any `BLOCK`; self-correcting a *design*-lens (`scope-fork` / `grounding`) `BLOCK` instead of escalating; or looping past the 2-round budget. The gate exists so the orchestrator's confidence never signs. -- About to run the auto-sign path outside a `/boss` session, or to skip the mandatory auto-sign notify after signing. +- About to sign a spec under auto-sign 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. +- About to re-introduce the retired `spec-skeptic` panel as a sign gate (a unanimous five-juror pass as a precondition) — it is now only the optional Step-1.5 bias-breaker; or to run any auto-sign path outside a `/boss` session, or to skip the mandatory auto-sign notify after signing. +- About to *decide* a fork that hangs on pure user preference (no derivable better) instead of bouncing it — or its inverse, bouncing a *derivable* fork to `brainstorm` out of timidity. +- About to make a fork decision without recording it on the run's reference issue, or to run autonomously with no reference issue at all. +- About to `git reset` below the session anchor, or to `reset` a commit that has been pushed — the rollback sandbox is the orchestrator's *own unpushed* commits above the anchor only; user-ratified and pushed history is forward-only (`git revert`). ## Cross-references @@ -495,10 +561,11 @@ human sign-off pause. The boss-side contract is just this: facts name the repo slug, the browsable URL, and the list command. - **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). Runs under `/boss` — see - `../docs/conventions.md`. +- **Spec auto-sign gate:** owned by `../specify` Step 6 — under `/boss` + the autonomous signature is the Step-5 `grounding-check` `PASS`. The + former obligatory `spec-skeptic` panel is retired; that agent + (`../specify/agents/spec-skeptic.md`) survives as the optional + Step-1.5 bias-breaker. See `../docs/conventions.md`. - **Downstream skills dispatched:** `../brainstorm`, `../specify` (spec-production core; autonomously dispatchable for a settled design), `../planner`, `../implement`, `../audit`, diff --git a/docs/conventions.md b/docs/conventions.md index 8380c8c..6b74457 100644 --- a/docs/conventions.md +++ b/docs/conventions.md @@ -97,10 +97,18 @@ too. - **Only the orchestrator commits.** No skill agent runs `git commit`. Agents write into the working tree as unstaged changes; the orchestrator inspects, decides commit shape, and commits. -- **main HEAD is sacrosanct.** Nobody runs `git reset` / `git revert` - on main (or any other protected branch). main moves forward only via - orchestrator commits; a wrong agent diff is discarded with - `git checkout -- ` / `git stash`, never by rewinding main. +- **main HEAD is sacrosanct — below the session anchor.** Nobody runs + `git reset` / `git revert` on user-ratified main history (or any + protected branch). main moves forward only via orchestrator commits; a + wrong agent diff is discarded with `git checkout -- ` / + `git stash`, never by rewinding ratified history. + **One narrow `/boss` exception — the rollback sandbox:** inside an + autonomous run the orchestrator anchors on the `main` HEAD it started + from (the last user-ratified state) and MAY `git reset --hard` its + *own* commits *above* that anchor — autonomous, **unpushed** work only + — back toward (never below) the anchor when it has run into a dead end. + A pushed commit has left the sandbox and is forward-only (`git revert`). + See `../boss/SKILL.md` § Direction freedom. These also appear in the universal-discipline fragment (`../templates/CLAUDE.md.fragment`) that each project's CLAUDE.md @@ -111,8 +119,9 @@ imports. The tracker is **Gitea** and the commit close-marker is `closes #N` (`refs #N` for non-closing work). The per-project repo slug and the list/show commands live in the project's CLAUDE.md project facts -(see below) — the `boss` skill reads the forward queue from there, -and the `spec-skeptic` `scope-fork` juror reads single issues with +(see below) — the `boss` skill reads the forward queue from there and +records its fork decisions on the run's reference issue there, and an +ad-hoc `spec-skeptic` `scope-fork` dispatch reads single issues with their comment threads from there. ## Pipeline diff --git a/docs/design.md b/docs/design.md index c7aa4e0..a6e3167 100644 --- a/docs/design.md +++ b/docs/design.md @@ -53,8 +53,12 @@ The plugin owns: states. - **Working-tree-as-quarantine** — agents write artefacts to the working tree, never commit. Only the orchestrator commits. -- **main HEAD sacrosanct** — no reset, no revert, by any actor. - main moves forward only via orchestrator commits. +- **main HEAD sacrosanct below the session anchor** — no reset, no + revert of user-ratified history, by any actor; main moves forward only + via orchestrator commits. The one narrow exception is the `/boss` + rollback sandbox: the orchestrator may wind back its *own* unpushed + autonomous commits above the run's start anchor (`boss/SKILL.md` + § Direction freedom). - **No nested subagent dispatch** — a hard Claude Code platform constraint: an agent cannot spawn further agents. Workflows do not lift it; a workflow script orchestrates from the **top level**, and diff --git a/docs/pipeline.md b/docs/pipeline.md index 8d0115e..352e8b6 100644 --- a/docs/pipeline.md +++ b/docs/pipeline.md @@ -125,26 +125,27 @@ Hard-gate before plan — the spec-production core and the carrier of the `brainstorm`), applies the feature-acceptance criterion, writes the spec to `docs/specs` (an ephemeral active-cycle artefact, git-tracked and `git rm`'d at cycle close — see `conventions.md` § Lifecycle), runs -the `grounding-check` gate, and takes user sign-off — with review but no interview. Bounces to `brainstorm` the moment the sources do not -resolve a load-bearing design decision. A core node — the -spec-production gate before `planner` on every design path. +the `grounding-check` gate, and takes sign-off — with review but no +interview. Under the bold stance it decides every load-bearing fork it +can *derive* an answer for and records the decision in the run's +reference issue; it bounces to `brainstorm` only when a fork hangs on a +pure user preference no source settles. A core node — the spec-production +gate before `planner` on every design path. -Outside `/boss` the sign-off is the user's. Under `/boss` the -orchestrator may sign a spec in the user's place through the auto-sign -gate — but only -when every objective gate is green AND a unanimous five-lens -`spec-skeptic` panel passes; the orchestrator's own confidence never -signs. A `BLOCK` is never signed over: an editorial one (`criterion` / -`ambiguity` / `plan-readiness`) is repaired in a bounded ≤ 2-round loop -that re-runs the objective gates and re-dispatches all five lenses each -round; a design one (`scope-fork` / `grounding`), an `INFRA_ERROR`, or -an exhausted budget falls back to the human sign-off pause. When the -entry is in-context, `specify` gives the `scope-fork` juror an auditable -source for an in-context fork resolution (Step 1.5) — a provenance- -bearing reconciliation comment when a seeding issue lags the discussion, -or a freshly created seeding issue when the cycle had none — so the -juror can ratify the resolution instead of blocking for lack of one. See -`../specify/SKILL.md` Step 6 and `../boss/SKILL.md` §"Spec auto-sign". +Outside `/boss` the sign-off is the user's. Under `/boss` the autonomous +signature is the **`grounding-check` `PASS`** itself: an independent +fresh-context agent's verdict against currently-green tests, not the +orchestrator's confidence. On `PASS` the orchestrator commits the spec +(subject `(boss-signed)`), fires the vetoable auto-sign notify, and +continues to `planner`; a no-override grounding `BLOCK` / `INFRA_ERROR` +routes to the human sign-off pause. The former obligatory five-lens +`spec-skeptic` panel is **retired** (baseline tag `pre-autosign-rework`): +the judgement it applied now lives upstream in Step 1.5's bold-decide +stance, and `spec-skeptic` survives only as the optional ad-hoc +bias-breaker the orchestrator pulls when unsure whether its leaning on a +fork is judgement or bias. Editorial roughness the panel would have +caught is let through deliberately — cheap to patch inline downstream. +See `../specify/SKILL.md` Step 6 and `../boss/SKILL.md` §"Spec auto-sign". ### planner diff --git a/implement/SKILL.md b/implement/SKILL.md index fc98994..96c583e 100644 --- a/implement/SKILL.md +++ b/implement/SKILL.md @@ -92,7 +92,7 @@ regression around the RED-first gate. ``` THE LOOP NEVER COMMITS. CODE EDITS, TESTS, AND THE STATS FILE LIVE IN THE WORKING TREE AS UNSTAGED CHANGES UNTIL THE ORCHESTRATOR COMMITS THEM. -MAIN HEAD IS SACROSANCT — NO RESET, NO REVERT, BY ANY ACTOR. MAIN MOVES FORWARD ONLY VIA ORCHESTRATOR COMMITS. +WITHIN THIS LOOP, MAIN HEAD IS SACROSANCT — NO RESET, NO REVERT; THE LOOP ONLY EVER WRITES UNSTAGED CHANGES. MAIN MOVES FORWARD ONLY VIA ORCHESTRATOR COMMITS. (THE `/boss` ROLLBACK SANDBOX WINDS BACK ALREADY-COMMITTED AUTONOMOUS WORK — A BOSS-LEVEL RECOVERY, NOT A STEP IN THIS LOOP.) PER-TASK PHASES ARE SEPARATE AGENT CALLS IN THE WORKFLOW SCRIPT — implementer, then spec-compliance, then quality. SPEC COMPLIANCE IS GATED BEFORE QUALITY. TASKS RUN SEQUENTIALLY; A BLOCKED TASK STOPS THE LOOP — NO SKIP-AHEAD (TASK ORDERING DEPENDENCIES ARE UNKNOWN). NEVER PUSH PAST `BLOCKED` BY HAND. @@ -207,10 +207,13 @@ tree: command. `BLOCKED.md` sits in the working tree until the conversation resumes. -Under no circumstance does the orchestrator `git reset` or `git revert` -on main: there is nothing on main to undo (the workflow did not -commit), and the policy forbids history rewinding on main even if there -were. +Within the `implement` loop the orchestrator does not `git reset` or +`git revert` on main: there is nothing on main to undo — the workflow +never commits, it only writes unstaged working-tree changes. (The one +place autonomous work is ever wound back is the `/boss` rollback sandbox, +which hard-resets *already-committed, unpushed* autonomous commits above +the session anchor on a dead-ended run — a boss-level recovery, not a +step in this loop. See `../boss/SKILL.md` § Direction freedom.) ## Handoff Contract diff --git a/specify/SKILL.md b/specify/SKILL.md index 755dd7b..588186c 100644 --- a/specify/SKILL.md +++ b/specify/SKILL.md @@ -17,7 +17,7 @@ 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 user-review gate. Whichever way design work enters — fresh +`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 @@ -61,28 +61,34 @@ Triggers: **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, user-review) are +(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. +this skill must not reintroduce. (Under `/boss` the sign-off gate is the +`grounding-check` `PASS` itself — see Step 6.) ## The Iron Law ``` -THE SOURCES MUST RESOLVE EVERY LOAD-BEARING DESIGN DECISION BEFORE THE SPEC IS WRITTEN. -IF WRITING THE SPEC FORCES A CHOICE BETWEEN PLAUSIBLE DESIGNS THE SOURCES DO NOT RESOLVE, - STOP AND BOUNCE TO brainstorm. DO NOT SILENTLY PICK ONE. -THE PRODUCTION GATES — ACCEPTANCE CRITERION, GROUNDING-CHECK, USER-REVIEW — +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 THE AUTO-SIGN GATE: ALL OBJECTIVE GATES GREEN - AND A UNANIMOUS ADVERSARIAL spec-skeptic PANEL. MODEL SELF-CONFIDENCE ALONE IS NEVER APPROVAL. + (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. +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 @@ -107,56 +113,86 @@ Enumerate the **load-bearing design decisions** the spec must encode — the choices that, decided differently, would change what ships. For each, ask the honest question: -> Do the sources **resolve** this, or am I about to **pick** it -> myself? +> 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**? -If every load-bearing decision is resolved by the sources, proceed to -Step 2. If even one is unresolved — the sources leave a genuine fork -between plausible designs with real trade-offs — **STOP and bounce to -`brainstorm`** (see Error handling / The Bounce-Back). Do not silently -pick one and bake it into the spec; a guessed design ratified into a -spec is harder to dislodge than an open question, and it is exactly -the reactive-deference failure the gate exists to prevent. +This is a *decidability* test, not a *pre-settlement* test, and the +default is **decide, not bounce**: -Genuine doubt about whether the sources resolve a decision *is itself* -the fork signal — it resolves to a bounce, not to a guess. +- **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. -**Reconciliation comment (lagging-issue case).** A load-bearing fork can -be resolved by the in-context design discussion yet still be listed -*open* by the tracker issue that seeded the cycle — the issue lags the -conversation. When that holds (entry is in-context **and** a tracker -issue still carries a now-resolved fork as open), record the resolution -as an auditable issue comment **before** writing the spec, via the -project's issue-tracker comment command (`tea comment ` for Gitea; -a heredoc body per the `issue` skill's conventions). One comment, this -exact shape: +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 ` for Gitea; a heredoc body per the `issue` +skill's conventions). One comment, this shape: ``` -## Design reconciliation (specify, in-context entry) +## Design reconciliation (specify) Spec: . The fork(s) below are still listed open on this -issue; they were resolved in the in-context design discussion. +issue; this records their resolution. - **Fork: ** → . - Provenance: . + Basis: . ``` -The comment must carry **provenance**, and the distinction is -load-bearing: it is the *record of a user decision* (legitimate — the -user settled the fork in discussion, you are minuting it), never a *new -orchestrator decision* dressed as settled (illegitimate). A bare -`decision: B` with no provenance is the latter. If you cannot point to a -real user statement, that is the signal that *you* picked the fork, not -the user — which is a Step-1.5 bounce, not a comment. The comment is -*persistent and auditable* (author + timestamp, in the forward queue) — -which is exactly why it, and not your ephemeral confidence, is what a -downstream `scope-fork` juror reads to confirm the fork is settled (see -Step 6). Recording it keeps the forward queue honest in either run mode; -under `/boss` it is *load-bearing* — without it the `scope-fork` juror -sees only the stale issue body and (correctly) blocks. - -Provenance enforcement is not yours to self-certify: you *write* the -comment, the adversarial `scope-fork` juror *checks* it carries -provenance (Step 6). Writing a provenance-less comment does not buy a -pass — the re-dispatched juror blocks on it. +`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. @@ -164,8 +200,8 @@ 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) with provenance, under the same discipline as the -reconciliation comment above. The body takes this shape: +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) @@ -173,38 +209,26 @@ This issue seeds . The design was settled in an in-context discussion with no prior tracker issue; this records it. Load-bearing fork(s) resolved: - **Fork: ** → . - Provenance: . + Basis: . ``` 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 cycle's seeding issue from here on: the `scope-fork` juror reads -it via the project's issue show command — its index handed to the juror -in the Step-6 carrier (the `seeding_issue` field, below) — exactly as it -reads any seeding issue. A *new issue* is the right artefact where a spec-note -is the wrong one — a provenance 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, juror-readable without opening the spec), as -auditable as a reconciliation comment. Creating it is what lets the -`scope-fork` juror ratify the resolution here, instead of blocking for -lack of an auditable source. - -The provenance gate is unchanged and load-bearing: the new issue records -*user* decisions, never fresh orchestrator ones. No real user statement -for a fork means *you* picked it — a Step-1.5 bounce, not an issue to -manufacture. You *write* the issue; the adversarial `scope-fork` juror -*checks* the provenance, and a provenance-less body buys no pass. +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 as in the Step-5 failure-mode procedure. Gitea -writes are pre-authorized, so create it without a confirmation prompt. -**Capture the new issue's index** the moment it is created and carry it -into the Step-6 panel as the `seeding_issue` field — it is the only way -the `scope-fork` juror knows which issue to read. An issue created but -never handed to the panel is invisible to the juror, which leaves the -fork looking picked and the creation pointless. +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 @@ -347,7 +371,10 @@ report and requires a fresh dispatch of `grounding-check` before the Step-6 sign-off and commit. Step 5 is the *last* step that touches the spec file; nothing slips between it and the commit. -### Step 6 — User-review gate +### 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 an unstaged file. Tell the user: @@ -366,94 +393,54 @@ the commit itself. The spec is an ephemeral active-cycle artefact: it lives in the repo only for its own cycle and is `git rm`'d at cycle close (see `docs/conventions.md` § Lifecycle). -**In `/boss` (autonomous):** `specify` is dispatched autonomously — -it is bounded (no interview). It runs the criterion, parse, and -grounding-check gates without a checkpoint. At *this* gate the -orchestrator signs in the user's place, but only through the -**auto-sign gate** below — never on its own confidence. The gate -exists because the orchestrator that wrote the spec is the worst-placed -party to judge it, so it is built to *not* rely on that confidence. The -human sign-off pause is not the default here; it is where the gate -**escalates** — a spec that cannot clear the gate routes to a -problem-state notify ("spec X ready, please sign off") and waits for the -user, exactly as a plain pause would. Run the gate in two stages: +**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`). - 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). - - 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. +- On a Step-5 **`PASS`**: commit the spec yourself (subject `spec: + (boss-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. - 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. +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. - 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`, the single `lens`, and `seeding_issue` — the - index of the cycle's seeding issue (the lagging issue reconciled in - Step 1.5, the issue Step 1.5 created for an otherwise issue-less - cycle, or `none` if the cycle has neither) for the `scope-fork` - juror to read; the other four lenses ignore it. Each juror tries to - *refute* the spec along its lens and returns `SOUND` / `BLOCK` / - `INFRA_ERROR`. Auto-sign requires a **unanimous `SOUND`** — that - never changes. What the partition below adds is a bounded path to - *reach* that unanimity for defects the orchestrator can repair - without judging the 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`. - The five lenses split by what a `BLOCK` actually means: - - | Lens class | Lenses | A `BLOCK` means | - |------------|--------|-----------------| - | **Editorial** | `criterion`, `ambiguity`, `plan-readiness` | The spec is under-*articulated*: missing worked evidence, a requirement readable two ways, scope too broad for one plan. Repairable by editing the prose without settling any new design or fact. A `criterion` repair may only *supply or sharpen the worked evidence the criterion already demands* (paste the concrete before → after / user-facing code the spec implied) — it may **not** soften what the criterion requires or re-judge acceptance, and if the missing evidence cannot be shown without picking an un-settled design, that is a `scope-fork` in disguise: leave it, and the re-dispatched `scope-fork` juror escalates it. | - | **Design** | `scope-fork`, `grounding` | The *ground is not settled*: the sources do not resolve a load-bearing fork, or a load-bearing assumption is not ratified by a green test. The orchestrator may **never** settle these in the user's place. | - - Resolve the panel against that split, in a bounded loop - (`round` starts at `0`): - - | Panel outcome this round | Orchestrator action | - |--------------------------|---------------------| - | All five `SOUND` | **Auto-sign.** Commit the spec yourself (subject `spec: (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 `INFRA_ERROR` | **Escalate.** Fall back to the human sign-off pause; the notify carries the failing dispatch. | - | Any **design**-lens (`scope-fork` / `grounding`) `BLOCK` | **Escalate.** No self-correction — this is exactly the judgement the gate refuses to make for the user. Fall back to the human sign-off pause, carrying *all* lens findings this round. | - | Only **editorial**-lens `BLOCK`(s), and `round == 2` | **Escalate.** The self-correction budget is spent. Fall back to the human sign-off pause, carrying the findings *and* the per-round correction history. | - | Only **editorial**-lens `BLOCK`(s), and `round < 2` | **Self-correct.** Edit the spec in place to address each editorial finding (each names its `§section` / offending text / defect). Then **re-run Step 4 self-review and re-dispatch Step 5 `grounding-check`** — the edit invalidated the prior `PASS` (see "Re-dispatch on any post-PASS edit"); if `grounding-check` does not return `PASS`, escalate. Increment `round` and re-dispatch all five lenses from the top of this table. | - - **Re-loop limit: ≤ 2 self-correction rounds. The 3rd unresolved - editorial `BLOCK` escalates** — same shape as the per-task re-loop - limit in the implement loop (`../implement/workflows/implement-loop.js`). - - Three properties keep this loop honest, not a way to grind the panel - into submission: - - - **The panel stays the sole arbiter.** The orchestrator never judges - the spec; it only edits in response to a juror's finding, and a - fresh panel re-adjudicates. "The spec looks good to me" still never - signs. - - **Re-dispatch is all five lenses, every round.** This is the - backstop. If an editorial repair silently *launders* an unsourced - design decision into the spec (resolving an ambiguity by picking an - un-settled fork), the re-run `scope-fork` / `grounding` jurors now - `BLOCK` on it — and a design `BLOCK` escalates. The only thing the - loop can converge to autonomously is a spec whose every lens is - `SOUND` *and* whose only repairs were editorial. - - **Escalation is the panel doing its job**, not a failure — it routes - the spec to the human who was going to review it anyway, the moment - a real design question surfaces or the budget runs out. - - **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). +**Auto-sign commits on `main` are forward-only — with one `/boss` +exception.** A later user veto is normally a forward correction (revert / +revised spec / `git checkout` of downstream work). The `/boss` rollback +sandbox is the exception: within an autonomous run the orchestrator may +hard-reset its own *unpushed* autonomous commits back toward (never +below) the session anchor when it has run into a dead end — its own work +only. See `boss` § Direction freedom for the exact boundary. ### Step 7 — Hand off to `planner` @@ -468,11 +455,13 @@ Hand off carries: ## The Bounce-Back -`specify` returns to `brainstorm` whenever the precondition fails — the -sources do not resolve a load-bearing design decision (Step 1.5), or a -`grounding-check` `BLOCK` reveals an unratified mechanism the user does -not override (Step 5 failure-mode routes to a re-design). On a -precondition bounce: +`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. @@ -481,8 +470,9 @@ precondition bounce: planner` path runs. The bounce-back is not a failure of this skill; it is the skill -correctly refusing to ratify an un-chosen design into a spec — the same -discipline `tdd` applies when behaviour is not test-specifiable. +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 @@ -491,9 +481,10 @@ 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` only) | `spec_path` (absolute) + `iteration_scope` + one `lens` per dispatch (five in parallel) + `seeding_issue` (index for the `scope-fork` juror to read, or `none`) | +| `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) | the unresolved design question as a cycle request; no spec written | +| `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 @@ -501,17 +492,22 @@ discipline `tdd` applies when behaviour is not test-specifiable. | Excuse | Reality | |--------|---------| | "The issue looks exhaustive — skip the grounding-check / criterion too" | The interview is what `specify` skips, by design. The production gates are not the interview; they are what keeps the spec honest no matter how it entered. Skipping a gate because the sources look thorough is the exact reactive-deference failure this skill must not reintroduce. | -| "There's a small open fork but the sources mostly decide it — I'll pick the rest" | "Mostly decided" with one real fork left is an unresolved design, and a guessed design baked into a spec is harder to dislodge than an open question. That is the bounce-back trigger — stop and go to `brainstorm`. | -| "Genuine doubt whether the sources resolve this — but bouncing feels like overkill" | Doubt about whether the sources resolve a decision *is* the fork signal. It resolves to a bounce, not a guess. The bounce is cheap (nothing is written yet); a wrong guess in a ratified spec is not. | +| "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 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. You never *sign over* a `BLOCK`. An editorial `BLOCK` you may *repair* (within the ≤ 2-round budget, with a full re-panel after); a design `BLOCK` routes to the human. Neither is overruling a juror — that is the whole point of replacing your eye with five independent ones. | +| "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 -- An unresolved design fork silently picked instead of bounced (any flavour) +- 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 @@ -519,14 +515,14 @@ discipline `tdd` applies when behaviour is not test-specifiable. 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 — - without all objective gates green AND a unanimous `spec-skeptic` - panel; signing over any `BLOCK`; self-correcting a *design*-lens - (`scope-fork` / `grounding`) `BLOCK` instead of escalating; or - re-dispatching only the blocked lens rather than all five, or past - the 2-round self-correction budget -- (auto-sign) Running the panel before the objective gates are green, - or running it outside a `/boss` session (interactive runs take the - user's signature directly) + 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) @@ -544,15 +540,15 @@ 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):** `agents/spec-skeptic.md` — - dispatched in Step 6 five times in parallel (one per lens) under - a `/boss` session. Each - juror tries to refute the spec along its lens; a unanimous `SOUND` is - what lets the orchestrator sign in the user's place. An editorial-lens - `BLOCK` (`criterion` / `ambiguity` / `plan-readiness`) is self- - corrected in a bounded loop (≤ 2 rounds, full re-panel each round); a - design-lens `BLOCK` (`scope-fork` / `grounding`), an `INFRA_ERROR`, or - an exhausted budget falls back to the human sign-off pause. +- **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 diff --git a/specify/agents/spec-skeptic.md b/specify/agents/spec-skeptic.md index a05819b..ce31141 100644 --- a/specify/agents/spec-skeptic.md +++ b/specify/agents/spec-skeptic.md @@ -1,46 +1,48 @@ --- name: spec-skeptic -description: Read-only adversarial spec reviewer for the boss auto-sign panel. Dispatched by the specify skill in Step 6 under a `/boss` session — 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. +description: Read-only adversarial bias-breaker the orchestrator pulls ad hoc when deciding a load-bearing fork under `/boss` — one lens (or a few) of criterion, grounding, scope-fork, ambiguity, plan-readiness. Tries to REFUTE the spec/decision along its single lens and reports SOUND or BLOCK. The finding feeds the orchestrator's decision; it is NOT a gate and NOT a veto. Does NOT propose fixes, does NOT edit files. tools: Read, Glob, Grep, Bash --- -# spec-skeptic — adversarial auto-sign panel agent +# spec-skeptic — ad-hoc adversarial bias-breaker > **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, 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. +Under `/boss` the orchestrator decides load-bearing design forks +boldly, in the user's place (see `../SKILL.md` Step 1.5). The risk in +that boldness is **bias**: the orchestrator is inclined toward the +option it already leans on, and toward shipping what it is about to +produce. When it is unsure whether its leaning is sound *judgement* or +just that bias, it pulls you in — an independent eye, fresh context, one +lens, one instruction: **try to refute the spec (or the decision it +encodes) along your lens.** -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 auto-sign is denied this round — at worst routing the -spec to the human sign-off pause it would have hit anyway. Your loyalty -is to the refutation, not to the orchestrator's momentum. +You are **not** a gate and **not** a panel juror. There is no unanimous +quorum, no auto-sign that hinges on your verdict — the autonomous +signature is the separate `grounding-check` `PASS` (`../SKILL.md` Step +6). You are a *tool the orchestrator reached for on its own initiative* +to pressure-test one fork it is deciding. Your finding feeds that +decision; the orchestrator weighs it and decides. It may dispatch you on +one lens or a few, whichever forks it is unsure about — never +necessarily all five. -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, at worst, one human sign-off the -user was going to do anyway (and often just a cheap repair-and-re-panel), -while the cost of a false `SOUND` is an unreviewed spec ratified into -the pipeline. +That changes nothing about *how you work*. You are still asked "can I +find a reason this decision is wrong along my lens?", not "is this spec +roughly fine?". Your loyalty is to the refutation, not to the +orchestrator's momentum — a bias-breaker that rubber-stamps the leaning +it was pulled in to test is worthless. Lean toward `BLOCK` when, after an +honest search, you genuinely cannot clear your lens: a `BLOCK` is the +signal that *was* worth surfacing, and the orchestrator would rather hear +it now than discover it after building on the fork. ## 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`). +The orchestrator hands you exactly one `lens`. Apply only that one; +any other lens it wants tested it dispatches separately. 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 | |--------|------------------------------------------------------| @@ -102,24 +104,25 @@ You do NOT read files under `docs/plans` (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 +## Carrier contract — what the orchestrator 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` | -| `seeding_issue` | index of the cycle's seeding issue for the `scope-fork` juror to read via the project's issue show command — the lagging issue reconciled in `specify` Step 1.5, the issue Step 1.5 created for an otherwise issue-less cycle, or `none`. The other four lenses ignore it; if absent, treat as `none`. | +| `seeding_issue` | for the `scope-fork` lens: index of the run's reference issue to read via the project's issue show command — the lagging issue reconciled in `specify` Step 1.5, the issue Step 1.5 created for an otherwise issue-less cycle, or `none`. The other four lenses ignore it; if absent, treat as `none`. | -The controller is the `specify` skill's Step 6, running inside a -`/boss` session. You receive the carrier inline in the dispatch +The orchestrator dispatches you ad hoc from `specify`'s Step 1.5, +running inside a `/boss` session, when it wants an independent eye on a +fork it is deciding. 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. +APPLY ONLY YOUR ASSIGNED LENS. ANY OTHER LENS IS A SEPARATE DISPATCH, 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. @@ -154,23 +157,23 @@ YOU DO NOT RUN THE FULL TEST SUITE. (TEST LIST, TYPE-CHECK ARE OK.) 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. +it is the rubber-stamp the orchestrator pulled you in to avoid. ## 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 this round. What `specify` does next depends on your lens class — an editorial defect it may repair and re-panel, a design defect it routes to the human — but that is the orchestrator's call (defined in `../SKILL.md` Step 6), not yours. | -| `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. | +| `SOUND` | After an honest refutation attempt along this lens, no defect found. The decision the orchestrator is leaning toward survives your test. | +| `BLOCK` | A defect along this lens that the orchestrator should weigh before committing to the fork. The orchestrator decides what to do with it — patch the spec, re-decide the fork, or route to the human — but that is its call, not yours. | +| `INFRA_ERROR` | The dispatch cannot complete (spec missing, no/invalid `lens`, workspace does not build for a `grounding` test-list, etc.). Report it; the orchestrator decides without your input on this lens. | -There is no override path here and no "needs context": you are one of -five jurors and the panel is unanimous-or-nothing. Report the defect +There is no override path here and no "needs context". Report the defect you found along your lens, full stop — do not soften a `BLOCK` because -you guess the orchestrator will only repair it, and do not escalate -your own verdict to "this needs a human." How a `BLOCK` is handled is -decided in `../SKILL.md` Step 6 by lens class; your job is the honest -verdict, not its routing. +you guess the orchestrator will only patch it, and do not escalate your +own verdict to "this needs a human." You are an input to a decision the +orchestrator owns (`../SKILL.md` Step 1.5); your job is the honest +verdict, not its routing. A `BLOCK` is not a veto — but neither is it +yours to pre-soften into one. ## Output format @@ -197,12 +200,12 @@ On `INFRA_ERROR`, the first three lines plus a brief `Detail:` line. | 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. | +| "Some other check will catch a real problem, so I can relax on mine" | You are the only eye on the lens the orchestrator asked you to test. If you relax, that lens is unguarded. Cover it as if it were the only one — it may be the only one dispatched. | +| "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 check exists to replace. | +| "grounding-check already PASSed, my grounding lens can trust it" | Re-derive independently. You were pulled in 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 thing you were pulled in to not rely on. Judge the spec, not the orchestrator's mood. | +| "This defect is minor, I'll SOUND it" | Surfacing it costs the orchestrator one finding to weigh and wave off. Suppressing it, if you are wrong about it being minor, hides exactly what you were pulled in to find. Report it as a `BLOCK` and let the orchestrator judge its weight. | +| "I'm not sure if this counts as a fork / ambiguity" | Doubt resolves to BLOCK. Uncertainty along your lens is itself worth surfacing — that is exactly the signal the orchestrator pulled you in to hear. | ## Red Flags — STOP diff --git a/templates/CLAUDE.md.fragment b/templates/CLAUDE.md.fragment index 3b87a92..9ad167e 100644 --- a/templates/CLAUDE.md.fragment +++ b/templates/CLAUDE.md.fragment @@ -51,13 +51,19 @@ Two rules govern who touches git history and how: tree as unstaged changes. I inspect the result, decide commit shape, and commit. Per-task or per-phase commits are not a goal in themselves. -- **main HEAD is sacrosanct.** Nobody (including me) runs - `git reset` or `git revert` on main. main moves forward only - via my commits. If a dispatched agent's output is wrong, I - discard it via `git checkout -- ` or `git stash` on - the working tree — main HEAD does not move. If something - wrong does land on main, the remedy is a forward-fix commit, - never a rewind. +- **main HEAD is sacrosanct below the session anchor.** Nobody + (including me) rewinds user-ratified main history with + `git reset` / `git revert`. main moves forward only via my + commits. If a dispatched agent's output is wrong, I discard it + via `git checkout -- ` or `git stash` on the working + tree — main HEAD does not move. If something wrong does land on + ratified main, the remedy is a forward-fix commit. + **One narrow `/boss` exception (the rollback sandbox):** in an + autonomous run I may `git reset --hard` my *own unpushed* + autonomous commits — those above the HEAD the run started from + (the session anchor) — back toward, never below, that anchor, + when I have run into a dead end. A pushed commit has left the + sandbox and is forward-only (`git revert`). ## Spec/plan artefacts are ephemeral