Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

From feat to spec to wire

Most agent platforms fail at the same spot: an agent merges code, marks the task done, and nothing actually works. Supernova’s predecessor platform accumulated a catalog of 38 documented failure modes in exactly this territory — false-dones, stale review stamps, self-review, prod debris from smoke tests. The delivery flow described here is designed against that catalog, one structural fix per failure class, and the issue system that carries it is the reference system: the first system built end-to-end to prove the platform’s self-similar shape on something real.

The build-or-buy call here took one line: buy nothing. Matt (2026-06-04): “issues tracking is such stupidly easy thing to implement that it’s pointless to eat lock-in for something that’s like single type in database.” The interesting part was never the tracker — it’s the gates.

The flow

Delivery work moves top-down through three typed stages, with a hard code-vs-docs boundary at each (Matt, 2026-06-22: “spec can’t write code at all, neither can ‘feat’”):

flowchart LR
    D["discovery / idea"] -->|scoped into| F["feat — docs only"]
    F -->|decompose| S["spec — authors requirement IDs"]
    S -->|one wire per requirement| W1["wire — code only"]
    S --> W2["wire — code only"]
    W1 -->|annotations + tests| B["batch lands atomically"]
    W2 -->|annotations + tests| B

A feat states the goal and touches only docs. A spec decomposes it into numbered requirements — each with an Origin tracing to a human decision, never invented by the decomposing agent (see requirement percolation for how the R# DAG works). Each requirement then gets a wire: a code-only leaf task that builds against it, carrying source annotations and tests that the validator can join back to the requirement. A feat and all its wires land together as one atomic batch; a subset landing alone requires a cross-party approval, never a --force flag.

Bugs and security fixes run the same lifecycle bottom-up — investigate, reproduce, fix directly — and are the only delivery types allowed to touch code and docs in one task.

Ten statuses, every transition gated

The lifecycle has exactly ten statuses. claimed, assigned, blocked, and planning are deliberately not among them — ownership (claim and assignment), blocking, and planning notes are orthogonal overlay fields with their own events, so an issue never loses its lifecycle position by being claimed or blocked. Most trackers conflate these; here the separation is an invariant.

stateDiagram-v2
    [*] --> draft
    draft --> review: intake gate
    draft --> rejected: intake denial
    review --> ready: readiness stamp by non-filer
    ready --> in_progress: worker starts
    in_progress --> code_review: implementation done
    code_review --> integration: review stamps present
    integration --> soak: batch E2E green, diff coverage clears
    integration --> in_progress: boot back on red batch
    soak --> done: passive metric window met
    in_progress --> observation: feat only, child wires done
    observation --> done: usage audit and approver sign-off
    done --> [*]
    rejected --> [*]

Every transition is a deterministic, fail-closed gate [built in-repo] — unit-tested Rust in the Supernova workspace, not yet a production loop:

  • draft → review is the intake gate: dedup (a store query, not a human scan), acyclic dependencies, type validity, at least one filer-authored requirement and step. Failures land in terminal rejected as a recorded denial, never a silent drop.
  • review → ready requires a readiness stamp from a different capability-holder than the filer. Crucially, the closure criteria, steps, and evidence plan are filer-authored before ready — the worker who later claims the task may not invent the bar it will be judged against. Separation of plan-author and doer is the anti-gaming property everything downstream leans on.
  • Terminal states are immutable; the only re-entry is one explicit, audited reopen to draft.

Gate rejections are designed branches at severity warning, not errors — denials stay out of the error stream so the error stream stays meaningful.

Merge proves nothing about delivery

The D68 lifecycle redesign (2026-06-21/22, sixteen rulings) starts from one observation: for delivery types, merge proves nothing about delivery. The predecessor’s canonical failure was a feature merged, marked done, and never actually running. So done sits behind three post-merge observation states, each answering a different question with a different kind of evidence and a different verifier:

StageClaim provenVerified by
integrationthe batch works end to endbatch E2E on an isolated real stack, ~95% diff coverage over changed code
soakit is actually happening in the fieldpassive metric assertions over a time window, zero agent turns
observationit is genuinely usedindependent agent audit, at least twice, plus human approver sign-off — feat only

Smoke testing was removed from the lifecycle entirely (Matt, 2026-06-22): smoke actively poked production and was itself a failure class. “No stage actively mutates or calls the prod running system. That is the point.” The evidence-kind machinery behind these gates — typed evidence, coverage joins, decay — belongs to the requirements page; the durable workflow that drives a feat through these stages belongs to workflows.

Two details worth noting. First, boot-back: a red batch E2E reverts the implicated wires from integration to in_progress and clears their review stamps — the certified content must change, so the certification is void — then wakes the original coder with the red output rather than blind-retrying. Second, closure evidence is adversarially checked: producer references must be canonical event strings bound to the exact issue id, because the system assumes its own closing agent might launder plausible-looking evidence. The close-gate tests read like an attack catalog [built in-repo].

Wire, bug, and sec close at green soak; only a feat runs the full observation window. The full production composite — real metric windows, real independent usage audits, the sign-off flow — is [supernova design]: specced with declared evidence obligations, not yet field-satisfied.

The frontier: sprints are dead

Matt, 2026-06-18 (D5/D14): “Sprints are dead and silly. I don’t see point of forced work stoppages other than outages.”

There is no sprint anywhere in the model. Work is a dependency graph of issues, and the queue continuously surfaces the frontier — the unblocked, ready issues whose dependencies are satisfied — for each worker to pull from the moment they free up. The only legitimate work stoppage is an outage, which is the monitor’s problem, never an issue state.

Claiming a frontier issue records unique ownership and emits an event but does not move the status; starting work is a separate audited edge. A same-worker retry of a claim is an idempotent no-op; a second worker’s claim is a denial, never a double-grab — proven down to a row-locked Postgres transaction with a two-connections-one-winner concurrency test [built in-repo].

The frontier also pipelines ahead of done: a dependency edge auto-clears when the blocker has merged with a green E2E, before its soak finishes — and a later failed soak mechanically re-adds the edge. Dependents start early; the system compensates if the optimism was wrong.

Task = worktree = workspace

From the foundational vision (idea009, 2026-05-16): task = worktree = one object. Filing a code-bearing issue spawns a git worktree on its own branch; terminal done tears it down. There is no separate “make a worktree” step disjoint from the issue — the issue is the unit of work and its workspace, with invariants forbidding orphan worktrees and worktrees shared across issues. The tasks themselves live in the issue system’s database, not in any repo — the predecessor kept them as markdown files in a shared-checkout tracking repo [live in automatt], which produced an entire class of index-contamination bugs that a database dissolves by construction.

Audit is the bus: every mutation emits an event through a same-transaction outbox, and history is the bus’s retention, not a bespoke audit store (D46).

What this costs

  • Ceremony. Eight issue types, ten statuses, four overlays, four capability groups, and an approval flow to bypass anything. Filing requires authored criteria, steps, and an evidence plan, plus a separate readiness reviewer, before any work starts. For a solo-operator platform this is a lot of machinery; the bet is that agents, not humans, absorb the ceremony. Unproven either way.
  • Closure latency is intentional but real. Nothing closes faster than its soak window; a feat needs a 24-hour (default) observation window plus an independent audit plus a human. Urgency has exactly one escape hatch, and it is an approval flow.
  • The observation tier is the least-proven part. Window durations, metric-assertion schemas, and what counts as one “usage confirmation” were still open questions at ratification. The heart of the design — the lifecycle itself, task=worktree, demonstrable closure — remains at draft requirement status even with heavy test coverage, precisely because the live-substrate composites haven’t run.
  • Fast-moving canon. The design synthesis that produced D68 was superseded within days of being written (its content promoted into the ratified lifecycle doc); two issue types were added and removed in the same week. The decision ledger keeps this honest, but any snapshot of the model ages quickly.
  • The frontier is only as strong as its neighbors. Auto-unblock, boot-back, and soak verdicts lean on the vcs, test, workflow, and monitor systems; the issue system’s guarantees are joint guarantees, and some of those neighbors are earlier in their build than this page’s subject.