Files
claude fe5ca8f8c0 feat(pipeline): consolidate cycle recon, add fieldtest probe tier, enforce assumption economy
Implements the three efficiency findings from the #310 pipeline
measurement (refs #35): ~691k subagent tokens / ~3.5 h for a
deliberately small cycle, with recon duplication as the single
biggest obligatory per-cycle cost.

1. Cycle recon (pipeline.md § Cycle recon; specify, planner,
   brainstorm, boss, plan-recon): recon fan-out is budgeted per
   cycle, not per phase. One full plan-recon dispatch — normally
   specify Step 1, in a new pre-spec sources/recon_scope carrier
   form — serves both the spec's concrete code shapes and the
   plan's file-map. planner Step 2 becomes reuse-first (freshness /
   quotability / coverage conditions) with narrowly-bounded delta
   dispatches (new Delta dispatch contract in plan-recon.md);
   broad Explore-type grounding sweeps are banned in every mode.
   Field evidence: 151k (Explore) + 99k (plan-recon) with ~40 %
   overlap in one bounded cycle.

2. Fieldtest probe tier (fieldtest, fieldtester, pipeline.md,
   agent-template.md § model rule 2): a cycle whose user-visible
   delta is a single narrow axis dispatches the per-cycle
   fieldtest at tier: probe — 1-2 examples on exactly that axis,
   ~200-word report, explicit model:sonnet dispatch override (no
   dispatch-level effort override exists; frontmatter effort
   applies). Probe is a tier, not a skip; the milestone fieldtest
   always runs full tier on the frontmatter model, keeping the
   milestone-close gate's >=2-example floor unconditional.

3. Assumption economy (specify Step 3 + self-review item 6):
   grounding-check cost scales with the spec's assumption count,
   so specs state current-behaviour claims only where the change
   relies on them (the gate's own falsity test), demote
   context-only mentions to ledger citations, and keep iteration
   scope tight — fewer restatements, never fewer reliances. The
   gate itself is unchanged.

Design reviewed pre-implementation (opus plan review); diff
adversarially verified by a 3-lens review workflow (consistency,
operability, cross-reference), confirmed findings folded in.

refs #35
2026-07-25 13:52:04 +02:00

22 KiB

Pipeline

        ENTRY PATHS — the selector cascade, walked top to bottom (see boss/SKILL.md)
  bug observed ........... debug ........................ implement (mini)   # RED-first; FIRST in the cascade
  design fork ............ brainstorm -> specify -> plan -> implement
  type/signature edit .... compiler-driven  -> commit (clean build + suite green unchanged)
                                           -> bounce: specify | tdd (a hole) | debug (suite red)
  test-specifiable ....... tdd -> implement (mini)        # RED executable-spec -> GREEN
  settled prose design ... specify -> plan -> implement

       (specify / tdd bounce to brainstorm on a design fork)
       (per iteration loop)
                  |
       [cycle close — a loop step, not a milestone close]
                  |
                  v
                audit  --(drift)--> plan + implement (tidy iteration)
                       --(ratify)-> --update-baseline + ratify paragraph in audit commit body
                       --(drift-clean)-+
                                 |
                       [orchestrator: cycle complete? if surface-touch:]
                                 v
                            fieldtest --(bug)------> debug -> implement (mini)
                                      --(friction)-> brainstorm OR plan (tidy)
                                      --(spec_gap)-> ratify OR tighten ledger
                                      --(clean)----+
                                                   |
                                       [orchestrator: surface stable across N cycles?]
                                                   v
                                              docwriter
                                                   |
                                                   v
                                             next cycle

The methodology taxonomy

Development paths differ on two irreducible axes — the first artefact written, and the correctness oracle. (Error-recovery is not a third axis: whole-attempt discard is the plugin's universal containment, not a per-path signature.) The top-level cut — ratified prose intent before code (spec-driven) vs. machine / test / run oracles — is the hard boundary; the paths cannot be centralised in one skill, only share the implement executor as a primitive and the cycle-close audit tail.

Path First artefact Oracle Bounce-out when
spec-driven ratified prose spec human intent, judged at the document (the deliberate heavy sink)
tdd / debug a RED test the assertion goes green not test-specifiable → brainstorm
compiler-driven a type / signature edit clean build + suite green unchanged a hole needs a decision → specify (or tdd if it is test-specifiable new behaviour); suite red → debug
try-and-error throwaway code an observed run attempt budget exhausted

try-and-error is deferred — listed for completeness, not yet a live path. It is an exploration front-end terminating in a tdd-style handoff, and its attempt tail is structurally unbounded (it can cost more wall-clock than the spec-driven baseline it is meant to beat, and its attempt-budget is a magic number the selector cannot derive). Out of scope until it is given a bounded form.

Cycle vs. milestone

These are two distinct axes, and conflating them is a bug.

  • A cycle is one round in the pipeline graph above (brainstorm → specify → planner → implement → audit → [fieldtest]). A cycle close is an internal loop step.
  • A milestone is a tracker container (Gitea milestone, GitHub milestone, Linear project — whatever the project's tracker calls a long-running work scope). A milestone spans potentially many cycles and closes only when the work it promised is complete and functional (see the gate below).

audit runs at cycle close and proves drift-clean — the code matches the design ledger. It is blind to whether the work is functional from a downstream consumer's point of view; that is what fieldtest measures. So no audit result closes a milestone, and neither does a /boss done-state.

Milestone-close gate

A milestone may be closed in the tracker only when both legs hold:

  1. Complete — every cycle filed under the milestone is audit drift-clean (or its drift explicitly ratified), and the milestone container has no open iterations / issues left.
  2. Functional — the milestone fieldtest has run its curated end-to-end scenarios against the milestone's promise and its status roll-up is clean: every scenario demonstrably delivers what the milestone promised; no open bug findings; friction / spec_gap findings resolved or ratified into the design ledger. A clean roll-up is honoured only with positive evidence the test actually ran — at least 2 examples in the working tree (examples_added). A milestone fieldtest always runs full tier (the probe tier is per-cycle only — ../fieldtest/SKILL.md § Two tiers: probe and full), so this floor is unconditional. A clean with fewer, over a milestone that touched user-visible surface, is itself a spec_gap, not a clean close (the agent owes the same floor — fieldtest/agents/fieldtester.md "What you DO NOT ship"; the gate verifies it rather than trusting the roll-up). The empty report is valid only when no example was applicable.

The milestone fieldtest is the milestone-wide variant of the fieldtest skill: the same fieldtester agent, a carrier scoped to the milestone's promise rather than one cycle's surface. Its scenarios are chosen top-down from what the milestone as a whole promised, not assembled as the union of per-cycle axes.

A milestone whose entire scope is internal (no user-visible surface) is exempt from the functional leg — the milestone fieldtest is not applicable and the complete leg suffices.

This gate defines when a milestone is closeable. The actual close stays a deliberate human / orchestrator act — the tracker's own milestone-close action (on Gitea, tea milestone close); no skill performs it automatically.

Harvest sweep

A recognised batch shape for draining settled single-issue backlog. When small, settled items accumulate on the tracker (bundled fieldtest findings, absorbed leftovers, mechanical one-offs), one full pipeline cycle per item is structurally uneconomical; a harvest sweep drains them in one batch:

  • the settled issue bodies stand in for spec and plan — each item is already ratified and bite-sized, so specify and planner are skipped by design (the exception is registered in § Skip rules);
  • the implementer works in sequential batches of 2-3 items — direct implementer dispatches (the implement-loop carrier needs a plan the sweep deliberately lacks), with no per-task review pair; the whole-diff review below replaces it;
  • the sweep closes with one independent diff review over the whole sweep — an ad-hoc fresh-context reviewer over the sweep's full diff, independent of the orchestrator and the implementers (the per-task reviewer carriers do not fit a whole-sweep diff) — then the mandatory audit close, and one compact fieldtest under its normal skip rules (a zero-surface sweep skips it).

The whole-diff review is not removable. Unlike a planned cycle, where the task is the unit of review (planner's decomposition discipline), the sweep amortises review over the batch — and in the consumer-project sweep this shape was ratified from (recorded on issue #36), that one review caught the only substantive error, which originated from orchestrator

  • fieldtest consensus, not from the implementers.

A sweep is orchestrator-decided at queue selection — a judgement call like the fieldtest / docwriter dispatches, not an arm of the selector cascade; the trigger is observed accumulation of settled single-issue items.

Cycle recon

Recon fan-out is budgeted per cycle, not per phase. The field evidence behind the budget (issue #35, one bounded cycle): a broad Explore-type sweep grounding specify (151k tokens) plus the plan-recon dispatch grounding planner (99k tokens) overlapped ~40 % — two full recon passes over the same territory, the single biggest obligatory per-cycle cost. This section is the single source of the budget, reuse, and delta rules; the skills point here and add only their own dispatch mechanics.

  • At most ONE full recon dispatch while a valid cycle recon exists — the cycle recon. It is a plan-recon dispatch (../planner/agents/plan-recon.md) in the pre-spec carrier form, normally fired at specify Step 1 when the work enters code territory the orchestrator has not recently read; an ad-hoc dispatch brainstorm fired earlier in the same cycle is the cycle recon instead (subject to the coverage condition below). One report serves every downstream consumer: the spec's concrete code shapes and the plan's file-map. Normally that is one full dispatch per cycle; a further full dispatch is legitimate only via the fallback below.

  • Broad exploration sweeps are not recon. No Explore-type fan-out for spec, plan, or pre-dispatch grounding — grounding fan-out goes through the one cycle-recon dispatch. This binds the orchestrator in every mode, /boss included.

  • Reuse over re-dispatch. A downstream phase reuses the cycle-recon report while ALL of these hold:

    • Freshness — no commit since the dispatch has touched the paths the report maps (git log <since-recon> -- <mapped paths> is empty; commits elsewhere — fixtures, tracker side-effects — do not invalidate it). In a multi-iteration cycle, iteration 1's commits to mapped paths invalidate the report for iteration 2's planning.
    • Quotability — the orchestrator can still quote the report's Modify entries verbatim. A summarized memory of the report is not the report. (The designed reuse window is the standard same-session specifyplanner handoff; across a session break the fallback below applies.)
    • Coverage (brainstorm-fired recons only) — the ratified design's territory appears in the report's file-map or existence-table rows, not merely as a one-line out-of-scope acknowledgement. Missing territory is a delta below; a design that pivoted wholly outside the mapped territory voids the dispatch as cycle recon, and specify fires the cycle recon afresh.
  • Delta dispatches do not count against the budget. A delta is a narrow re-dispatch whose focus_hint names the gap; its bounded contract is Delta dispatch in ../planner/agents/plan-recon.md. Triggers:

    • the spec names a path or symbol that appears in neither the cycle recon's file-map nor its existence table;
    • MANDATORY: the iteration scope is a signature / variant / removal or content-pin-perturbing scope and the cycle recon carries no compile-driven site set for it — planner MUST delta-dispatch before planning that scope. (specify avoids this delta by naming the anticipated change shape in recon_scope, arming the compile-driven enumeration inside the cycle recon itself.)

    Two deltas in one planner run is the smell that the iteration scope is too broad — re-read the spec.

  • A full re-dispatch is the bounded fallback, not a failure: no cycle recon exists (a direct tidy dispatch that skipped specify; a session break), or a reuse condition failed. The cost regression is capped at the pre-consolidation status quo — one full dispatch.

Phase descriptions

brainstorm

Optional discovery front-end. Enumerates the cycle's load-bearing design forks, then — instead of a serial interview — populates them with a parallel swarm of grounded, genuinely-opposed synthetic-user stances and triages the result: a fork the swarm settles on a cited shared ground was derivable and is decided (the user vetoes); a fork it splits on, or agrees on with no citable ground, is a direction fork the user settles. The orchestrator authors the 2-3 approaches from the populated space (never the swarm) and hands the ratified design to specify (it writes no spec itself). A fire-check skips the swarm when there are too few forks or the project is below a grounding floor (greenfield, no ledger to cite against), falling back to a direct interview. Skipped entirely when the design is already settled in the sources — that work enters through specify directly. Under /boss the swarm runs autonomously: convergent forks are decided and recorded on the reference issue, only a divergent direction fork (or a sub-floor greenfield design) bounces to the user.

specify

Hard-gate before plan — the spec-production core and the carrier of the "no plan without an approved spec" invariant. Takes a settled design (directly from sources, or a ratified design handed over by brainstorm), applies the feature-acceptance criterion, writes the spec to docs/specs (an ephemeral active-cycle working file — git-ignored, never committed, shell-rm'd at cycle close — see conventions.md § Lifecycle), runs 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. Its code grounding comes from the single cycle-recon dispatch (§ Cycle recon), never a broad exploration sweep. 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 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 keeps the signed spec as a git-ignored working file (never committed), records the autonomous sign on the run's reference issue, 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

Hard-gate before implement. Produces a placeholder-free, bite-sized implementation plan in docs/plans (an ephemeral, git-ignored working file, shell-rm'd alongside the spec at cycle close — see conventions.md § Lifecycle) that the implement skill can execute task-by-task. Its file-map normally comes from reusing the cycle-recon report (§ Cycle recon); it dispatches plan-recon only for that section's delta triggers, or in full when no valid cycle recon exists.

implement

Runs the implement-loop Workflow (implement/workflows/implement-loop.js), a deterministic script that executes the per-task loop — implementer → spec-compliance → quality, each a separate agent() call — and aggregates the verdicts in code. A Workflow orchestrates from the top level, so the per-task phases are real, independently-invokable agent calls; this retired the former implement-orchestrator agent's inline-role-switch workaround (the four phase agents survive as the agent-types the script dispatches). Writes code and tests directly in the working tree as unstaged changes; never commits. The end-report carries the finished stats.json and — on PARTIAL/BLOCKEDBLOCKED.md contents, which the orchestrator writes (issue #29 retired the finalize dispatch that only templated the script's own aggregate).

compiler-driven

The lighter executor for a behaviour-preserving type/signature edit at a definition site — the cascade arm between debug and tdd. Runs the compiler-driven-edit Workflow (implement/workflows/compiler-driven-edit.js): make the edit, propagate it mechanically across the sites the build enumerates, then let a real build + suite run settle the verdict — observe-then-bounce. Clean build AND suite green unchanged → the edit is committed by the orchestrator; a hole that forces a design decision → bounce to specify (or tdd if it turns out to be test-specifiable new behaviour, per the straddle rule); the suite not green-unchanged (a regression — the edit was not behaviour-preserving) → bounce to debug, RED-first. A truly trivial edit may run inline without the workflow, under the same done-signal. Never skips the review-and-commit discipline; the orchestrator inspects and commits.

audit

Runs at cycle close. Dispatches the architect agent (read-only drift review against the design ledger) and the bencher agent (regression diagnostics). Reports drift and regress. Once it is drift-clean, the orchestrator discards every working-tree spec and plan with a plain shell rm (nothing to git rm — they were never committed); the cycle-close commit contains only code and ledger changes (see conventions.md § Lifecycle).

debug

Runs whenever a bug is observed. RED-first: produces a failing test in the working tree before any fix is attempted. Hands off the GREEN side to the implement skill in mini mode.

tdd

A standard alternative entry, alongside brainstorm → specify → planner, for work whose desired behaviour is test-specifiable — expressible as one failing test. RED-first: the tdd-author agent turns a description or issue into a single minimal, autonomous RED executable-spec ("how it should work"), then hands the GREEN side to implement in mini mode, exactly as a bug fix. When the behaviour is not test-specifiable (a genuine design fork surfaces), or two decomposition rounds fail, it bounces back to brainstorm. When one iteration cannot reach GREEN, the headline test is carved into a ladder of BLOCKER sub-tests, each its own RED→GREEN mini-cycle. Distinct from the per-task TDD the implementer already practices inside implement.

fieldtest

Optional. Orchestrator-dispatched after the audit closes clean on a cycle that touched user-visible surface. Picks 2-4 real- world tasks within the cycle's scope (probe tier, for a single-axis surface delta: 1-2 tasks on that axis — see ../fieldtest/SKILL.md § Two tiers: probe and full), implements them using only the design ledger and public examples (never the language's own implementation), runs the results, and writes a friction- and-bug spec.

docwriter

Optional. Orchestrator-dispatched after API surface has stabilised across multiple cycles. Brings docstrings up to a level where a newcomer can navigate the public API without reading the design ledger first.

Status protocol

Agents return one of these terminal states:

State Meaning
DONE Task complete; no concerns.
DONE_WITH_CONCERNS Task complete; flagged issues the orchestrator should weigh before committing.
PARTIAL Task partially complete; the rest is blocked or out-of-scope. Writes BLOCKED.md.
BLOCKED Task cannot proceed; explanation in report. Writes BLOCKED.md.
NEEDS_CONTEXT Task cannot proceed without additional information from the orchestrator.

Reviewer agents have role-specific states:

Role States
spec-reviewer compliant / non_compliant / unclear / infra_blocked
quality-reviewer approved / changes_requested / infra_blocked

Skip rules

Skipping is codified per skill, not ad hoc. Each SKILL.md documents what the skill skips and under what conditions:

  • specify is never skipped at cycle start — it is the spec-production gate before planner. brainstorm is the optional discovery stage before it: skipped when the design is already settled in the sources (the work enters through specify directly), run when a load-bearing decision is still open. The one batch exception is the harvest sweep (§ Harvest sweep): its settled issue bodies are the ratified spec source, so no new spec is written.
  • planner is never skipped at iteration start, except for the side paths that carry no prose plan: the bug-driven debug → implement (mini) path, the compiler-driven path (whose "plan" is the type-checker's enumeration of edit sites), and the harvest sweep (whose items are already bite-sized — § Harvest sweep).
  • implement is the iteration body; not skippable.
  • audit is mandatory at cycle close.
  • debug is mandatory RED-first for any observable bug — first in the selector cascade, so a mechanical-looking fix cannot bypass it.
  • tdd is a standard alternative entry to brainstorm for test-specifiable work; it bounces back to brainstorm on a design fork. Always available — not opt-in.
  • compiler-driven is the cascade arm for a behaviour-preserving type/signature edit: it skips specify and planner, and its done-signal (clean build + suite green unchanged) is the gate. It bounces on a hole to specify (a design choice) or tdd (discovered test-specifiable new behaviour), and to debug on a regression. Always available — not opt-in.
  • fieldtest and docwriter are optional and orchestrator- dispatched.

If a skill's body says it must run and the orchestrator wants to skip it, the orchestrator records the reason in the relevant commit body — never as undocumented practice.

Pipeline configuration

There is none. The phase set, the gates, and the conditional dispatch shown above are fixed — the same for every project. All phases (brainstorm, specify, planner, implement, audit, debug, tdd, fieldtest, docwriter) are always available; which ones run on a given iteration is the orchestrator's judgement per the skip rules above, not a per-project setting. There is no behavioural toggle either: spec auto-sign is always on under /boss. See conventions.md.

If a project declares a glossary in its CLAUDE.md project facts, that file is standing reading for every role — the canonical-nomenclature source every skill and agent consults (see glossary-convention.md).