# Pipeline ``` [new cycle] [bug observed] | | v v brainstorm -> plan -> implement debug -> implement (mini) (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 ``` ## 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 → 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. 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. ## Phase descriptions ### brainstorm Hard-gate before plan. Gathers requirements, explores 2-3 approaches with trade-offs, presents a sectioned design with user approval, writes the spec to the configured `spec_dir`. ### planner Hard-gate before implement. Produces a placeholder-free, bite-sized implementation plan in the configured `plan_dir` that the implement skill can execute task-by-task. Dispatches the plan-recon agent for read-only file-structure mapping. ### implement Dispatches the implement-orchestrator agent, which runs the entire per-task loop (implementer phase → spec-compliance check → quality check) as sequential role-switches inside its own context. Writes code, tests, and stats files directly in the working tree as unstaged changes. On `PARTIAL` or `BLOCKED`, also writes `BLOCKED.md` at the repo root. ### 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. ### 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. ### 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, 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: - `brainstorm` is never skipped at cycle start. - `planner` is never skipped at iteration start, except for the bug-driven `debug → implement (mini)` side path. - `implement` is the iteration body; not skippable. - `audit` is mandatory at cycle close. - `debug` is mandatory RED-first for any observable bug. - `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 The phase set, gating, and conditional dispatch are configured in the project profile under `pipeline:`. A project that does not want `fieldtest` simply omits the key. A project that wants a different gate set (e.g. `planner` without a `brainstorm` gate, for trivial bug-fix iterations) configures it there. See `profile-schema.md` for the syntax.