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

Supernova in one page

Supernova is a personal automation platform: a fleet of AI agents that watch your inputs, propose actions, and execute the approved ones — every action riding a single event bus, gated by a risk-tiered safety engine, and traceable back to a documented human decision. What makes it worth reading about is less any single feature than the coherence: nineteen systems (the set is open-ended) sharing one five-part shape, one traceability spine from requirement to code line to test evidence, and a decision ledger where rulings terminate in the human’s exact words — or are explicitly labeled when they don’t.

Who builds it

Supernova was seeded by automatt, a live, self-modifying agent platform that pushes twenty-plus tasks overnight and self-organizes around incidents [live in automatt] — and it has since taken over its own construction: “Supernova is bootstrapping itself” (Matt, 2026-07-05). The agents building it work through its own machinery — issues claimed from its own tracker, worktrees cut by its own vcs system, closure gated by its own validator — so improving the platform and building the platform are the same activity. The original plan had automatt building everything and shipping a finished product; that ruling is now superseded on the record, which is itself how this project works. Why this exists tells the full story — including why the artifact it ships is still meant to hold still.

Ten ideas that carry the project

Each idea carries a build-state tag — the four tags are defined under build status at the bottom of this page.

IdeaWhat it isBuild state
Decisions as case-lawRulings terminate at a human-verbatim anchor or carry an explicit PARTIAL/NONE grade; supersession is formal, cited, never deleted[live in automatt]
Requirement percolationRequirements form a DAG percolating to one root; @R# spans annotate code; coverage is computed, not asserted[live in automatt]
Docs as enforced contractPer-file specs, Requirements/Invariants/Interfaces per system, a validator that fails the build on drift[live in automatt]
The 5-part shapeEvery system is code + client lib + CLI namespace + wiki docs + config section; adding a system is a scaffold, not a redesign[built in-repo] (scaffold + validator); the frontend renderer is [supernova design]
The bus as audit logKafka transport, mandatory envelope, two-write outbox, the durable trail — history is a retention settingenvelope/outbox/reactor [built in-repo]; Kafka-as-transport [supernova design]; a bespoke predecessor is [live in automatt]
Park-on-failureA failed workflow parks alive at zero compute while the system heals, then resumes from the failed step — retries were removedprimitive [engineered, not deployed]; full delivery parking [supernova design]
Fork/zygote agentsWarm parent sessions fork children onto a shared prompt cache — ~99.7% cache reads in the field[live in automatt]; the 24h cache patch is [engineered, not deployed]
Layered safetyFive risk tiers, capability groups instead of agent names, one external-send chokepoint; a denial is a hard wall[live in automatt]
Evidence-gated deliveryfeat → spec → wire; sprints are dead, the task-graph frontier surfaces ready work; closure requires typed evidence, and done is rented, not owned[live in automatt], sharpened in design (D68, 2026-06-21/22)
Rust, wholesaleThe 2026-06-21 language ruling and what a typed workspace buys a machine-verified project[built in-repo]

The shape of the thing

flowchart TD
  wiki["wiki: requirements + specs"] -->|"declares obligations"| issue["issue: tracked work"]
  issue -->|"drives"| workflow["workflow: Temporal"]
  workflow -->|"runs"| agent["agent: runtimes"]
  agent -->|"acts via"| bus["bus: Kafka + trail"]
  bus -->|"events + metrics"| monitor["monitor: Sentinel"]
  monitor -->|"evidence closes or decays R#s"| wiki
  bus -->|"external sends only through"| link["link: sole egress"]
  approval["approval: risk gates"] -->|"gates"| link

That loop — obligations declared in the wiki, driven by tasks, proven by evidence, reverted when evidence decays — is the platform’s core mechanism. The supporting cast (test harness, review stamps, ops, ingest, config, and friends) exists to keep it honest.

Build status

Supernova is a design and in-build project, not a running product. It is a Rust workspace with real code, real tests (including opt-in end-to-end runs against a checked-in Kafka/Temporal/Prometheus stack), and a full design corpus — and zero of its nineteen systems are production-live in a standing deployment. The project’s own readiness dashboard can be green on local checks while still reporting production_ready: false; this site keeps the same discipline. Every claim on this site carries its tag: [live in automatt] (a rough version runs in the builder today), [supernova design] (specced, not running), [built in-repo] (code and tests exist in the Supernova workspace; nothing is deployed), [engineered, not deployed] (built and verified, not in production). When in doubt, this site under-claims.

Where to go next

Why build a second system

Supernova exists because its builder already works — and can’t be shared. automatt is Matt’s live, personal, self-modifying automation platform: it specs, builds, reviews, and ships software overnight with a workforce of agents. Those same properties make it useless as a product. Supernova is the clean-slate successor: the capabilities automatt has already proven, rebuilt as a coherent, shareable system — seeded by automatt, and now far enough along that it bootstraps itself.

You can’t fork a self-improving system

The origin is a sharing constraint, not a scaling one (idea009, the project’s founding design note, 2026-05-16). Matt wants to collaborate with other people, and automatt can’t do that: it is personal, unstable, and self-modifying. You can’t hand someone access to a system that rewrites itself around one person’s life, and you “can’t fork a self-improving system” — a fork of a thing whose value is its accumulated self-modifications diverges instantly and forever. Shoehorning external projects into automatt’s internals was the third bad option, after sharing access and forking.

There is a second, quieter motivation: coherence. Self-building projects accrete one-off pieces that don’t form a whole. automatt made two unifying moves — a single command surface and a wiki — and in the wiki’s own words they helped only “kind of.” Supernova’s answer is the five-part self-similar shape, where every system has the same anatomy and every piece of code has an obvious home.

Friction-on-friction

The obvious alternative — refactor automatt in place until it’s shareable — fails twice.

First, mechanically: “refactoring a live system from within itself is friction-on-friction, every agent doing the restructuring runs on the system being restructured (‘you break the thing you’re standing on’).”

Second, economically: restructuring a codebase you intend to migrate off is paying the same price for a worse outcome. The work is throwaway by construction.

So the bootstrap doc reframes the question. Not “reorganize automatt or build Supernova?” but “is automatt a good-enough builder as-is?” The evidence says yes — it pushes twenty-plus tasks overnight and self-organizes around incidents [live in automatt]. automatt therefore gets targeted stabilization only (recurring footguns like shared-checkout contamination and a hook blocking its own fix), never an architectural reorg.

The builder model

The relationship between the two systems was originally settled by a single ruling. Matt, 2026-06-10, verbatim:

“supernova is not intended to bootstrap itself, automatt will build it entirely and ship a mostly finished product. Automatt is the bootstrap and supernova will live as a subproject and get spun off.”

That ruling superseded two earlier designs, both still visible struck-through in the wiki with the ruling attached — supersession is formal in this project, and decisions are case-law. Gone at the time: the “self-hosting kernel” model, where a first slice of systems would run on Supernova and build the rest of it; and the migration clause where automatt moves onto Supernova mid-build.

Then practice overtook the ruling, and the same ledger discipline applies. As the issue, vcs, review, and wiki systems came up in the workspace, development moved onto them, and the standing word is now the reverse of the June plan: “Supernova is bootstrapping itself” (Matt, 2026-07-05). The agents building it claim work from its own issue tracker, operate in task-keyed worktrees its vcs system cuts, pass its review pipeline, and close work through its own validation gates. The self-hosting-kernel idea, struck down in June, is roughly what happened anyway — and the overruled ruling stays on the record, marked superseded, exactly the way the ledger says it should.

flowchart LR
    am["automatt: live, self-modifying, the seed"]
    sn["Supernova: bootstrapping itself"]
    ship["shipped mostly finished"]
    spin["spun off as its own project"]
    later["automatt migrates onto a Supernova instance"]
    am -- "seeded: specs, scaffolding, first systems" --> sn
    sn -- "its own issues, worktrees, reviews, gates" --> sn
    sn --> ship
    ship --> spin
    spin -. "post-spin-off decision, not a milestone" .-> later

Builder throughput IS the Supernova schedule (finding F15, 2026-06-10) survives the supersession with its meaning shifted: the builder is now increasingly Supernova itself, so the delivery date is a direct function of the platform’s own constraint chain — dispatch, review throughput, decomposition. Improving the platform is not competition with building it; it is the critical path. The schedule has no dates, only a bottleneck.

Owned infrastructure

One principle constrains every build-or-buy choice downstream. Matt, 2026-06-04, verbatim:

“everything has to run locally as part of project itself unless it absolutely can’t (models)”

with “local” later sharpened to something more precise than geography:

“‘local’ to me is more.. ‘I control software stack completely and functionally own machine and can configure it however I want and I won’t get billed per-run’ which GitHub runners do NOT fulfill nor does any hosted solution”

Local means ownership, control, and no metered billing. A Proxmox VM across the room qualifies; GitHub Actions, Confluent Cloud, Temporal Cloud, and every hosted CI do not. The consequences are concrete: self-hosted Kafka, Temporal, Prometheus, Grafana, and Postgres, all [supernova design] as an assembled stack (secrets use a lightweight encrypted-local store, not a Vault server), with model APIs as “the single metered remote dependency” — the one thing that absolutely can’t run on owned hardware. The footprint was checked before committing: single-broker Kafka runs in ~1–2 GB and Temporal in ~500 MB on a 64 GB box; the heavy cost is model calls, which are remote anyway.

The RSI story

A platform built by agents, for running agents, invites the recursive-self-improvement reading. For once the reading is roughly right — with the build-state care this site owes it.

The loop’s first home was automatt [live in automatt]: monitoring feeds alerts back into its own bus; a listener agent acts on them; recurring incidents mechanically propose new permanent checks. That loop is what made automatt an effective seed — and also exactly what makes automatt unshippable.

The loop’s second home is Supernova’s own construction. Every improvement its agents land — to the issue gates, the review pipeline, the traceability validator, the agent substrate itself — immediately sharpens the process that builds the next improvement [built in-repo]: the recursion runs on the workspace implementations and the sun CLI, not on a deployed Kafka/Temporal stack. automatt’s construction-site-and-crane problem — “you break the thing you’re standing on” — is mitigated rather than repeated here, because the thing being modified is not yet load-bearing under anyone’s life: breaking the scaffolding costs a rebuild, not an outage.

What stays deliberately out of the artifact is unattended self-modification of the shipped product. The platform bootstraps itself; what it ships is meant to hold still. Self-improvement of a running instance stays optional, on the far side of the spin-off, as a choice its operator can make rather than a property they inherit.

The second-system trap

Supernova is, unavoidably, a second system built with everything learned from the first — the classic setup for over-design, and the wiki names the risk itself (“beat the second-system trap”). Three mitigations are structural rather than aspirational. The build is incremental and system-by-system, each landing with end-to-end tests, not a big-bang rewrite. The substrate is bought, not built — Kafka, Temporal, Postgres, Prometheus — replacing bespoke components that had already failed on the record (the Python event bus was retired on same-night failure evidence — the bus page keeps the record). And the migration doctrine transfers problem classes, not features: each of automatt’s documented failure modes must be mapped to a named prevention mechanism or explicitly marked non-portable, with fresh state as the default. Scope is bounded by what already broke, not by what might be nice.

Whether that’s enough is a fair question — see the long view for what still has to prove out.

What this costs

  • The two-systems window is real. automatt stays live through the build — it seeded Supernova and still backstops it — and self-bootstrapping adds its own tax: every process bug is now also a build bug. The bootstrap doc calls the dual-system cost mitigated, not eliminated.
  • Nothing is production-live. Supernova today is a large design corpus plus a Rust workspace with test evidence. The project’s own readiness surface can report every local check green while production_ready:false — in-repo proof is deliberately distinct from live-substrate proof.
  • The design corpus is enormous relative to running code. That ratio is the second-system trap’s natural habitat; the mitigations above are named, but the risk is inherent and the docs admit it.
  • Owned infrastructure makes one person the ops team. Kafka, Temporal, Prometheus, Grafana, and Postgres on personal hardware, with no managed fallback on principle. The decisions record itself notes Kafka is heavy for one user; Matt chose it anyway.
  • The loop is never fully self-contained. Model APIs remain the single metered remote dependency. An “owned” platform whose intelligence is rented is a tension the design acknowledges rather than resolves.

The self-similar shape

Why this exists ends on the coherence problem: self-building platforms accrete one-off pieces, and automatt’s unifying moves only half-worked. Supernova’s answer is structural: every system in the platform has the identical five-part shape, keyed by one canonical name, so every piece of code has an obvious home and an auditable contract. The shape is the contract a new system must satisfy, not a convention it may follow. [built in-repo] — the shape is enforced by a scaffolding validator in the Rust workspace; no Supernova instance is production-deployed.

Five parts, one name

Pick a system name — issue, monitor, vcs — and the name keys everything:

PartWhere it livesWhat it is
Code foldersystems/<name>/the system’s logic and long-running services
Client librarysun_lib/<name>the stateless typed front door
CLI namespacesun <name> ...thin wrappers over the client library
Wiki docsthe system’s wiki foldermandatory index plus requirements, invariants, interfaces
Config section<name>:one top-level key in the single config.yaml, singular canonical name

The governing rule is blunt: “All sun commands fall under a system.” There is no miscellaneous drawer.

A new system inherits the platform for free: bus topics under the event.<system>.<entity>.<verb> convention on the shared Kafka bus, CLI dispatch and namespace registration, a config section with schema validation and hot reload, the docs contract whose requirements/invariants/interfaces (RII) sections make the shape auditable — an undocumented interface is a flaggable gap, enforced by the wiki validator — and, by design, rendering in the shared frontend.

sun_lib: a lens, never a store

Two invariants carry most of the shape’s weight, both from Matt’s 2026-06-04 ruling: sun_lib holds only client/frontend libraries, and it never owns authoritative state. Nova — automatt’s lead agent — produced the formulation that stuck as the platform-wide invariant: “sun_lib is a lens, not a store” — swap, rebuild, or wipe it and nothing authoritative is lost. A client library calls into the system that owns the data; ephemeral convenience (a connection handle, a brief in-call cache) is permitted, persistent state is forbidden. This is the flagship rule on the platform-wide critical list that review checks every patch against.

The frontend falls out of this invariant rather than being designed separately. It is not a system: it is a renderer inside core (2026-06-20, final), “the visual sibling of the CLI.” CLI and UI are two stateless consumers of the same sun_lib — text layer and rendering layer — and each view is owned by and derives its spec from its host system. [supernova design] — the renderer itself is unbuilt; the CLI framework, dispatch, and shape validation are implemented in the workspace.

core itself is the one deliberately different system: horizontal rather than vertical, owning framework concerns (CLI entrypoint, scaffolding, the sun_lib aggregation, the config-schema registry) and never a domain’s rules. It earned system status by accumulating real occupants — Nova: “‘util’ is junk-drawer name; ‘core’ is the same stuff with self-respect.”

The map around the bus

Nineteen systems (the set is open-ended), everything riding one Kafka bus:

flowchart LR
    delivery["delivery loop: issue, workflow, agent, wiki, vcs, project"]
    boundary["external boundary: link, ingest, chat"]
    control["control and proof: monitor, ops, test, review"]
    substrate["substrate and safety: core, config, auth, permission, approval"]
    bus["bus: Kafka substrate + bespoke reactor"]
    delivery -- "emit events" --> bus
    bus -- "reactor dispatches" --> delivery
    boundary -- "inbound events" --> bus
    bus -- "gated outbound" --> boundary
    bus -- "metrics and alerts" --> control
    control -- "actions back onto the bus" --> bus
    substrate -- "config and identity events" --> bus

The groupings are descriptive, not architectural — every system talks to every other system the same way, over bus events and stateless library calls. The one sanctioned exception to “everything rides the bus” is ops’ bus-independent Kafka broker health probe, since the broker cannot report its own death over itself (see the supporting cast).

Adding a system

Adding a system is a defined path, not a redesign. sun system new scaffolds the five parts; the shape validator checks them; the new system inherits topics, dispatch, config, docs contract, and rendering as above. There is no fixed system count — the 2026-06-20 ruling struck the earlier “20 confirmed systems” framing, and the canonical systems doc now reads: “19 systems as of 2026-06-24. The count is descriptive, not a cap.”

The set shrinks by the same discipline it grows: audit folded into monitor, reactor into bus, memory into agent, scheduler into workflow, deploy into ops, and refactor was removed as a system outright, surviving only as the wiki move/rename verbs. Each fold is a recorded ruling in the decision ledger.

Cold start: a hint, not a gate

There is a recommended bring-up order (Matt’s ruling, 2026-06-19): config → permission → auth → bus → approval → workflow → e2e test → the rest, with Sentinel — the monitor’s alert-consuming agent (see the supporting cast) — last. The testing rig stands up immediately after the first safety primitive, so every system built afterward lands with a working way to validate it end-to-end — instead of bolting testing on at the end.

But per D67, encoded as standard S24 (2026-06-20), that order is a hint that minimizes retry churn, not a correctness gate. Every system must start and restart in any order — a system whose dependencies aren’t up yet retries until they are — and any single system must be restartable while the rest of the platform stays stable. The one hard edge: static config must exist before the bus can read it. Order-independence is what makes isolated restart and rolling single-system updates possible; the ordering is a cheap optimization on top.

Build or buy

The default is bespoke carry-over from automatt. Specific calls, from the canonical systems doc — every “buy” is self-hosted on owned hardware, per the owned-infrastructure principle:

ConcernDecisionWhy
Bus transportBuy: self-hosted Kafkathe bespoke Python bus was “consistently painful + slow”
Bus reactorBuildthe event-to-action dispatch arm on top of the bought substrate
Workflow engineBuy: self-hosted Temporaldurability, retries, observability; scheduling = Temporal Schedules
MonitoringRebuild: OTel + Prometheus + Grafanathe stack existed in automatt but was “barely used”; the rebuild wires it end-to-end
StorageBuy: self-hosted Postgrescross-cutting infrastructure, not a system
SecretsBuy candidate: an encrypted-local store (sops/age-style)auth’s storage substrate; Vault and AWS SM were explicitly ruled out as too heavy / off-owned-infra; the identity model above it is bespoke
Issue trackingBuild“a single type in a database”; buying eats lock-in for nothing
WikiBuild, carry-over“I like the way wiki works, no plan to change it”
IngestBuildnothing off the shelf does trust-tiered, injection-contained, two-gate triage
Test harnessBuild: Rust sun-testowned-hardware constraint disqualifies metered CI — no GitHub Actions, no SaaS
Everything elseBuild / carry-overbespoke domain logic; carry-over means no decision was needed, not a pending gate

The pattern: buy the substrate (transport, durability, storage, dashboards, secrets), build every system whose rules are the product.

What this costs

The shape is a uniformity tax. Every system — including trivial ones — pays for five parts: a docs contract with RII sections, a config schema, a CLI namespace, a client library. The bet is that the tax is cheaper than the drift it prevents, but the tax is real and paid up front.

core is a standing junk-drawer risk: a horizontal system that hosts every other system’s CLI and libraries accretes by default. Two invariants guard it (stays thin on domain logic; sun_lib stays a lens), and automatt provides the cautionary precedent of a CLI that grew fat because it became where logic lived. The guard is a review rule, not a law of physics.

The open-ended count cuts both ways: adding a system is cheap by design, which invites sprawl. The fold record shows the pruning pressure works so far — but “so far” is a design corpus plus a workspace, not a platform under years of load.

And the gap: the frontend renderer is design-only, and no part of the shape has been exercised by a standing production deployment. What exists today is the contract, the scaffolding, the validator, and in-repo test evidence — the shape’s real test, a stranger adding a system without asking anyone, hasn’t happened yet.

The wiki as a system

Documentation drifts because nothing stops it from drifting: the code changes, the prose doesn’t, and six months later nobody can say why a behavior exists. Supernova’s answer is to make the docs a machine-validated artifact — a requirement graph the build is not allowed to diverge from, checked by a blocking gate on every commit. The founding directive is Matt’s, verbatim: “point of system is that every bug, inconsistency, missing feature or quirky behavior is traceable back to concrete root cause all way to creation of feature.”

This design carries over nearly verbatim from automatt, the predecessor platform, where it runs in production [live in automatt]. Matt’s carry-over ruling (2026-06-04): “I have yet to see anyone else build anything even close to as comprehensive as wiki system we use.” The Rust reimplementation is further along than most of Supernova — it is the working gate on the Supernova repo itself today — but it is in-repo proof, not a deployed service [built in-repo].

Three layers, one mapping

LayerLocationContract
System docswiki/systems/<name>/index.md front door + a requirements doc with mandatory ## Requirements, ## Invariants, ## Interfaces sections — the RII contract
Architecture docswiki/architecture/Cross-cutting: the decisions ledger, enforced standards, failure classes, the readiness dashboard
Per-file specswiki/specs/<source-path>.spec.mdOne spec per source file, carrying that file’s numbered requirements

RII is the build contract for a system: what it must do, what must never be false, and what it exposes. Matt mandated the triple on 2026-06-04 (“for each system I want requirements + invariants + interfaces”), and on 2026-06-20 it graduated from convention to a validator-enforced rule. Every system folder must also have an index.md that references each sibling file — likewise a validated requirement, not a habit.

The spec layer is where the contract touches code. The path mapping is mechanical: prepend wiki/specs/, append .spec.md. The wiki system’s own invariant WIKI-I1 states it flatly: “Deterministic spec path mapping is sacred.” No exceptions, no overrides — this is what makes traceability work without search. The inverse holds too: a spec without a source file, or an annotated source file without a spec, is a validation error. Inside each spec, numbered requirements (R#s) form a DAG with typed evidence obligations and line-level source annotations; that machinery — percolation, @R# spans, evidence kinds, coverage joins — is the subject of the requirements page.

Frontmatter is typed

Every wiki page must carry title, category, updated, and author. The status: field is a closed enum — draft | living | ratified | superseded | historical | findings — collapsed in June 2026 from roughly fifteen ad-hoc values that had sprawled across the corpus. Historical and superseded docs additionally carry current_truth: false, so a reader or a validator can tell a settled truth from a captured artifact without parsing prose. Spec files add two more fields: source: (the repo-relative path they mirror) and covers: (references up to the design-level requirements they implement). None of this is convention; every field is checked.

The validator is the gate

sun wiki validate is a pre-commit gate with deliberately binary semantics — per the wiki requirements doc, “a failed validation gate crashes the commit; it never degrades to ‘warn and allow.’” The same checks run in a second mode, --audit, which surfaces findings as data for the monitor system (described on the supporting-cast page) instead of blocking.

flowchart LR
    C["commit attempt"] -->|"pre-commit hook"| V["sun wiki validate"]
    V -->|"gate mode"| K["links, frontmatter, mapping, RII shape, DAG, annotations, evidence"]
    K -->|"all pass"| OK["commit lands"]
    K -->|"any failure"| X["commit crashes"]
    V -.->|"--audit mode"| M["findings stream to monitor"]

What it enforces on the Supernova repo today, verified against the readiness dashboard (2026-06-30):

CheckState
Frontmatter contracts, closed status enum, review-doc fieldsenforced today
Broken links, #R# fragments resolving to real requirementsenforced today
1:1 spec-to-source mapping, both directionsenforced today
RII section presence, per-folder index.md completenessenforced today
Requirement DAG: cycles rejected, orphans flagged, reciprocal edgesenforced today
@R# annotation coverage of code-bearing Rust lineschecked today; uncovered-line findings are warning-tier (delta-scoped during the D75 backlog burn-down) — orphan/missing @R# annotations block
Evidence declared on every live R#; named test symbols must existenforced today
Per-evidence-test line execution via LCOV, fail-closed on empty recordsenforced when per-test LCOV shards are supplied (strict validator flags); delta-scoped during the annotation-backlog burn-down (D75)
Legacy Test: fields rejected in active docsenforced today
Standards catalog S1–S24 mechanical checkspartially wired; rest are tracked follow-ons [supernova design]
Provenance “% grounded” read-lens over the spec-trace slicelands with the monitor pass [supernova design]
Spec viewer, DAG graph, coverage dashboard UIdeclared interfaces [supernova design]

The staging of the standards row is stated in the standards doc itself: until each mechanical check lands, that standard is “enforced by review … [which] is honor-system and exactly why the mechanical checks are the priority.”

Why this beats prose docs

The thesis, from the standards doc: “Uniform shape is what makes the docs a build contract rather than a sketch.” With prose docs, drift is a discovery someone makes; here, drift is a computed error with a location. Rename a file without its spec — error. Change a requirement’s text — its done status reverts to draft, because done-ness must not outlive its description. Delete a requirement something still references — blocked until the last inbound reference is gone. Cite a test as evidence that doesn’t actually execute the annotated lines — fails closed (the per-test coverage rule, from Matt’s 2026-06-25 parity directive).

Each rule earned its place through a concrete corpus failure. Six incompatible invariant-ID styles made review citations unresolvable, so IDs got a scheme. A superseded design survived as authoritative prose on the same page that marked its replacement done, so supersession now propagates mechanically. A plausible-but-wrong config path survived multiple semantic audits, which produced the grounding rule in the standards catalog: “Reviewers, human or AI, get fooled by plausibility; grounding does not” (standard S22, anchored in Matt’s D35 ruling). The standards themselves became a validated wiki artifact by ruling D22 (2026-06-18) — with the explicit rider that “it will need enforcement mechanisms too.”

One boundary worth noting: the wiki deliberately does not own all provenance. D59 (2026-06-20) ruled provenance a cross-cutting concept realized in four slices — auth answers who, the bus’s trail answers what happened, the wiki answers why does this requirement exist, vcs answers what changed in code — with a unified grading surface planned as a monitor read-lens. An earlier framing that put case-law inside the wiki was superseded, and its requirement retired as a tombstone in the graph.

Self-hosting

The wiki system is itself a Supernova system, with its own RII doc (R0–R34, twenty invariants), its own per-file specs, and its own annotations — validated by the very gate it implements. The Rust crate is about 8,000 lines across 16 modules (the validator alone is 2,564 lines) with 18 test modules and no TODO(req:) stubs in source. The corpus it gates is 250 spec files (a count measured on the Rust page) carrying roughly a thousand requirements, and all of it passes the gate. The gate is also how the delivery flow knows when work is actually done: requirements close on evidence the validator can check, not on a human ticking a box.

That self-hosting is real, and it is also the ceiling of the claim: the readiness verdict for the wiki row is “partial.” Bus events flow through a file-backed outbox with tests; real broker delivery exists only in opt-in end-to-end runs [built in-repo]. Several capabilities marked done in the requirements doc are done on unit evidence — proven in-repo, never production-exercised.

What this costs

  • Authoring overhead is enormous. Every source file needs a spec, every code-bearing line an annotation, every requirement five fields plus a typed proof obligation. This is tractable because agents write most of it; for a human-only team it would be brutal. The design quietly assumes agent labor at scale.
  • Status words can still overstate. The readiness dashboard exists precisely because R# statuses alone conflate in-repo proof with live capability — a requirement can be done on a single unit test. The dashboard is the correction, but it is a second thing to keep honest.
  • The enforcement layer is partially aspirational. Standards are normative with specced checks, yet many checks are tracked follow-ons; until wired they fall back to exactly the honor-system review the doc warns about.
  • The gate is load-bearing infrastructure. Every commit passes through it; a validator bug or an over-strict check halts all work. Crash-never-degrade is deliberate, but it concentrates risk in one binary.
  • Design churn left scar tissue. Test: became Evidence:; a standalone refactor verb was folded into move/rename; the case-law framing was superseded by D59. The machinery handles supersession cleanly, but each superseded framing had already propagated before it was corrected.
  • Open questions remain: percolation performance on large DAGs is untested at scale, the store substrate (filesystem vs database) is unresolved, and validator error reporting is a flat error list.

Requirement percolation and coverage

Most requirement trackers answer “what did we say we’d build?” Supernova’s requirement graph answers a harder question: “what is actually proven to work, right now?” Every requirement is a node in one rooted DAG, every code line is annotated back to a requirement, every requirement declares typed proof, and “done” is a computed state that can be revoked. The mechanism runs in the predecessor platform today [live in automatt]; the Rust rewrite is the trace gate on Supernova’s own repository — self-hosting proof, not a deployed service.

One graph, one root

Each source file’s spec (see docs as an enforced contract for the deterministic spec mapping) contains numbered requirements — R0, R1, R2… Each R# carries five fixed fields: Status, Origin (the immutable “why does this exist?” pointer), Evidence (the typed “what would prove it?” declaration), and reciprocal Depends on / Subtasks edges. The edges form a DAG: cycles are rejected, and every R# must have a path to its spec’s R0. File specs chain upward via covers: references to system-level design requirements, which chain to a systems-registry root. The result is one connected graph from an individual code line to “the platform works”:

flowchart TD
    L["code line"] -- "// @R3 span" --> R3["file spec R3"]
    R3 -- "Depends on / Subtasks" --> R0f["file spec R0"]
    R0f -- "covers:" --> RS["system requirement R#"]
    RS -- "Depends on / Subtasks" --> R0s["system root R0"]
    R0s -- "registry" --> ROOT["registry root"]
    T["named unit test"] -- "evidence" --> R3
    E2E["integration E2E"] -- "evidence" --> RS

Percolation is the operation that keeps this graph well-formed and rolls proof up it. sun wiki percolate repairs reciprocal edges, rejects cycles, verifies root paths, and is idempotent — it edits DAG edges in place, never requirement text. Evidence percolates the same way: a parent is satisfied partly by its children’s evidence and never re-proves the leaf; its own obligation is only the increment. The kind of claim escalates with altitude — correct at the file-spec leaf, integrated at the system, landed at the feature, used/valued at the exercised user journey — so total proof cost stays bounded.

Annotation spans in source

Rust code carries requirement annotations as comments: // @R3, multiple IDs (// @R1 @R3), or ranges (// @R1-R3). An annotation on its own line opens an active span covering the following block, and stays active while brace depth remains open; a same-line annotation covers just that line; a blank line outside a block clears the span. Blanks, comments, attributes, and use/mod lines are exempt.

The coverage rule is two-sided:

  • every code-bearing line must sit under an active span for a live file-local R# — no unowned code;
  • every live R# must cover at least one source line — no phantom requirements.

The no-phantom-requirements direction is a blocking validation error; the no-unowned-code direction is currently surfaced as a non-blocking warning, delta-scoped to changed lines while an admitted ~798-line annotation backlog burns down (D75). The gate runs error-clean today; the measured numbers live on the Rust page.

Typed evidence

The per-requirement Test: field was replaced by Evidence: in a 2026-06-23 ruling. Matt, verbatim: “test is now basically evidence and every requirement has to provide some form of it but it’s not necessarily a unit test, it might be e2e integration or some monitoring requirement or something else entirely.” Evidence is the forward dual of Origin — Origin points backward at why the requirement exists; Evidence points forward at why we believe it holds, and whether that is still true.

KindClassWhat satisfies it
spec, unit, integration_e2e, review_stampcode/runnamed test or review, green at the landing commit
coveragecode/runpercentage against a declared threshold
field_metriccode/runa named production metric holding an assertion over a window [supernova design]
usage_audit, cuj_exercisecode/runobserved real usage of the capability [supernova design]
human_approval, external_correspondence, document_artifact, agent_confirmationattestationa signed claim at the attester’s trust tier; valid until revoked or expired
derivedstructuralAND-rollup over subtask evidence — for aggregator and root R#s
plannedstructuraldeclared intent for proof that does not exist yet; keeps the R# out of done
retiredstructuraltombstone for intentionally dead requirements

Two rules do the anti-gaming work. First, the obligation is filer-authored at filing — the assignee cannot lower the bar, and the kind is fixed (only a numeric threshold may be sharpened, and only before evidence is evaluated against it). Second, there is no none: every live R# must declare evidence, even aspirationally. The 2026-06-24 ruling puts it plainly — Matt: “Requirements are very much ‘I want this to be true’ not ‘this is true’.” Declaration and satisfaction are separate checks — a missing declaration is always an error; red or pending evidence merely blocks done.

“It exists” is not “it works”

Status is derived, not asserted. You cannot mark an R# done; it becomes done when its accrued evidence matches its declared obligation — the validator rejects any status: done requirement whose evidence isn’t present, green, and fresh, the exact forward dual of the Origin check. Closure-by-checkbox is structurally impossible, a rule bought with scar tissue: the predecessor platform once closed a bug with all requirement checkboxes unchecked, and batch-moved fourteen work items to done with no validation.

And closure is non-monotonic — the substrate doc’s phrasing is “done is rented, not owned — you do not finish a requirement, you keep it satisfied”:

stateDiagram-v2
    draft --> ready : evidence declared
    ready --> done : obligation satisfied, computed
    done --> ready : evidence decays
    done --> draft : requirement text edited
    ready --> retired : intentional tombstone

Decay is per-kind, so it is proportionate: isolated test evidence falls only on a breaking code change; field evidence falls on live-signal regression; attestations mostly don’t decay (a created OAuth app stays created). When a leaf goes red, the response is trigger-and-recheck, not propagate-the-verdict: the parent’s own covering proof is re-run, targeted through the annotation and percolation maps — “blast radius is computed by re-proof, not assumed.” What happens to in-flight work when a requirement decays — wires reverting, features gaining an at-risk overlay — is the delivery lifecycle’s slice of the design; the delivery page covers the analogous test-triggered boot-back. The decay and recovery reactors that drive this loop are [engineered, not deployed]; today’s enforcement is the validator gate, not a standing ledger.

The coverage join

The strictest check joins three artifacts: the R#’s declared evidence test, the R#’s annotated source lines, and a per-test LCOV shard. The rule — named the “Automatt parity rule” after the predecessor’s behavior (Matt, 2026-06-25) — is that a line counts as covered only when the requirement’s own declared test executes the requirement’s own annotated lines. A passing test symbol plus a whole-suite coverage hit is not enough; unrelated test coverage is explicitly rejected (there is a test named for exactly that case). An evidence target whose LCOV record has no execution counters fails closed as malformed evidence rather than passing as “not instrumented.” This join is implemented and tested in the workspace [built in-repo], invoked via strict per-test LCOV flags on the validator; it runs delta-scoped while an admitted ~798-line annotation backlog burns down (D75, 2026-07-03).

D75 also added a counterfactual flag for correctness tests: when set, the declared test must be green at the landing commit and red at the pre-fix merge-base — the gate runs both, proving the test actually detects the bug it claims to.

Staleness

Even a cleanly validating repo can rot, so a scoring design (2026-06-26) treats truth decay as a first-class signal across three lanes: InternalDrift (one of a code/spec/design pair moved and its partner didn’t), ExternalDrift (a claim depends on an outside fact — an SDK, a price, an advisory), and ImprovementReaudit (“‘not known stale’ is not the same as ‘still the best design’”). A weighted score prioritizes requirement and interface movement over raw line churn, and Git time is authoritative over frontmatter — a timestamp-only edit cannot launder a stale spec. The trace-unit producer and the scorer are implemented with unit and E2E tests; the full rollout — review-gate blocking, external verification receipts — is further along the design than the deployment [engineered, not deployed].

What this costs

  • The annotation tax is real. Every code-bearing line needs an active span; every R# needs five fields and typed evidence — the same agent-labor bet the wiki page names. And even here, the ~798-line backlog means the absolute coverage invariant is itself aspirational today.
  • The model is only as honest as its weakest evidence producer. D82 (2026-07-03) is blunt about this: the E2E harness was assessed at roughly 12% real, with always-green stubs — and under a percolating model, a fake producer poisons everything above it. A planned reconciliation of ~390 requirements is deliberately frozen until real E2E and the D75 validator both land — the freeze is Matt’s own ruling, quoted on the long view.
  • The most striking part is the least deployed part. The durable, decaying evidence ledger, field metrics, and the revert/at-risk reactors are the substrate’s architecture, not its running state. Most wiki-system R#s read done on unit evidence — in-repo proof of the mechanism, not production deployment.
  • Hand-tuned knobs. The staleness weights and age bands are asserted, not calibrated from data.
  • Superseded designs along the way: a none evidence kind (abolished 2026-06-24), the evidence ledger initially drafted into the wiki system (overruled — monitor owns it), and type-keyed gate profiles (superseded by D75 obligation inheritance). The decision ledger carries the tombstones.

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.

Decisions as case-law

Every design system eventually contradicts itself: a ruling made in May quietly survives in one document while a June ruling overturns it in another, and both look equally authoritative. Supernova’s answer is to treat decisions like case-law rather than like a folder of ADRs — one living ledger where every ruling carries the human’s verbatim words, every reversal formally cites what it overrules, and nothing is ever silently deleted. The ledger is the backward half of the traceability chain that requirement percolation carries forward: code → annotation → spec → Origin → decision → Matt’s actual sentence.

The ledger [live in automatt]

The decision ledger is a single living document in the project wiki — roughly 2,900 lines and ~150 dated entries by heading count (the ledger’s own index, written in June, still says ~110) — organized as dated ruling batches from the 2026-06-04 baseline forward. Conflict resolution between batches is explicit: read newer-over-older, with a marked CURRENT-TRUTH section that supersedes conflicting entries in earlier batches. An entry carries a title, Matt’s verbatim quote where one exists, the decision and its rationale, a pointer to the spec R# where the ruling is applied, and a Supersedes: line when it overturns a prior call. Quotes are cited like court records, down to transcript ID and minute (f70f827b @ 04:03); one contested fold ruling — delete-folded-dirs-no-tombstone, reversed ten minutes later — was adjudicated from the gap between two utterances.

The recording convention is strict (Matt, 2026-06-22: “I would prefer if you could backport the decisions to the decisions log and make clear in the project that’s how it goes”): every decision is recorded in the ledger in the same session it is made. Folding a ruling into a spec annotation is necessary but not sufficient — the spec is where a decision is applied; the ledger is where it is recorded. A ruling that lives only in an R# annotation, a synthesis doc, or a commit message is not yet recorded. Backfill is a sanctioned move: rulings discovered folded-but-never-recorded get backported as a grouped batch.

Supersession: strike through, never delete

The supersession convention (2026-06-10) was born from a concrete failure, not from tidiness. A 2026-05-16 ruling about task storage survived in an issue-system requirement despite a 2026-06-04 database ruling that superseded it — and adversarial review missed it, because both claims carried valid Matt provenance from different dates. Temporal drift, not doc-vs-doc inconsistency. Two true quotes, no way to adjudicate without formal supersession. Hence two rules:

  1. Every entry that changes a prior call carries an explicit Supersedes: line naming what it replaces, with ID and date.
  2. Superseded claims get a struck-through SUPERSEDED marker citing the superseding ruling — history preserved, authority removed.

The ledger’s own justification: “Provenance is exactly what makes stale claims look authoritative; mechanical validation only catches what is declared.”

stateDiagram-v2
    [*] --> OPEN : escalated, not yet canon
    [*] --> Canon : Matt rules, recorded same session
    OPEN --> Canon : Matt ratifies
    Canon --> SUPERSEDED : newer entry cites ID and date
    Canon --> CONTESTED : conflicting utterances, docketed
    CONTESTED --> Canon : re-ratified by Matt
    SUPERSEDED --> [*] : kept in place, struck through

Authority grades

Not every ruling is equally grounded, and the ledger says so out loud. A 2026-06-22 provenance dig — a full pass of the ledger against raw session transcripts — produced a strength taxonomy that now appears inline on entries:

LabelMeaning
STRONGA direct verbatim Matt utterance decides it
PARTIALMatt set the property or gave the steer; the specific architecture answering it is agent-crystallized — “quote the steer; mark the agent-added specifics”
NONENo Matt utterance backs it as stated — “NOT canon, labeled as such”

There is deliberately no limbo: “a ruling is either canon … or it is OPEN (escalated to Matt, not yet canon).” A verbatim quote is mandatory — not merely preferred — when a ruling supersedes a prior Matt ruling, adds or kills a system, touches the permission/approval/security/traceability apparatus, or narrows a founding property. For mechanical applications of existing rulings, “the precedent IS the provenance.” Even embarrassments are labeled rather than disguised: a load-bearing outbox rule sat in the ledger for weeks marked “Provenance: NONE — no Matt quote backs this as stated” until a later ruling ratified its substance.

The formalized version of this — standard S21, “provenance as case-law” — grades every record authoritative (chain terminates at a Matt-verbatim anchor), derived (cites a graded-authoritative parent via synthesis), or ungrounded-or-drifted (no anchor, or contradicted by newer authority), with a corpus-level provenance-coverage metric. Today those grades are assigned by humans and agents reading transcripts [live in automatt]; the mechanical grading engine, chain resolver, and coverage audit are [supernova design].

Eight rulings, spanning the range

DecisionDateWhy it’s here
Bus transport → Kafka2026-06-04The entry preserves the evidence of failure that forced it — a socket vanishing under a live service, a 479 MB bus.db file, 1.6 GB memory peaks — alongside Matt’s verdict: “kafka is like industry standard that does everything we could ever want.” See the bus.
Sentinel IS the agent2026-06-10Clean formal supersession of a founding document: “Supersedes: idea009 ‘Sentinel = subsystem, not an agent’ (2026-05-16).”
D7 — mechanical vs subjective audits2026-06-18“Enumerate audits; keep MECHANICAL vs SUBJECTIVE as separate concepts.” Ripples everywhere: every check in the standards enforcement table is marked mechanical or subjective per D7.
Sprints are dead2026-06-18“Sprints are dead and silly. I don’t see point of forced work stoppages other than outages.” Agents work the task-graph frontier continuously — see delivery.
D67 — order-independent startup2026-06-19“Strict bringup order as a CORRECTNESS REQUIREMENT is the antipattern”; order survives only as an optimization hint. Realized as a cross-cutting standard rather than a system.
D68 — issue-lifecycle redesign2026-06-21/22Sixteen backfilled entries, the first sanctioned backfill batch. Sample: smoke tests removed because “smoke testing touches the actual prod running system and has caused many many issues in automatt.”
Agent naming, superseded same day2026-06-23A fully-quoted entry recorded in the morning; “I have changed my mind on the unambiguous agent ID” hours later. The old entry stands with a SUPERSEDED banner. Discipline at hourly granularity.
D80 — no JSON-file state2026-07-03“yes, no json state lock it in.” The file-fallback path was deleted outright, not left default-off — an opt-in fallback that silently diverges from production is the banned “fallbacks hide bugs” pattern.

Honorable mention: choosing Next.js over Rust for the cockpit UI (D70) on the grounds that “building a website in rust just seems weird and I suspect random agents will be really bad at it” — training-distribution density treated as an engineering constraint.

Why case-law beats ADRs-in-a-folder

An ADR folder records decisions; it does not notice when the corpus contradicts them. The ledger’s machinery is aimed at exactly that gap. The temporal-drift incident above is one instance; the standards doc cites another, where a system index page marked a ratified ruling DONE while still narrating the superseded model on the same page — “a spec author reading the superseded model implements decided-against architecture.” Formal supersession plus a per-round sweep of foundational quotes is what catches two individually-true claims that disagree.

The ledger also indicts itself, which is the property that makes it trustworthy. A 2026-07-01 entry records that ~773 of 1,328 done requirements were found inflated, naming the exact mass-promotion commits that did it. D82 (2026-07-03) records, about the project’s own E2E harness, “~12%, disjoint stubs … a fake/always-green harness lets everything FAKE-CLOSE.” Case-law even outranks fresh literal words when the words conflict with standing precedent: one entry overrides Matt’s own “kill -9 a session thread” instruction by invoking the standing anti-watchdog rule — and flags the override for confirmation rather than hiding it.

Enforcement is layered. Canon, the decision-ledger judge, is a persistent agent definition [live in automatt]: on ambiguity it searches the ledger and verbatim archives for controlling precedent, rules and records when the case is mechanically analogous, and escalates to Matt when it is load-bearing or precedent-free. “Canon never invents Matt provenance; a NONE entry stays NONE until Matt speaks.” A first mechanical slice — a decision_ledger_conflict check that parses the ledger’s headings and blocks when two entries take opposite build/no-build positions on the same topic without a declared supersession — is real, tested code that runs today inside the wiki validator as a development gate [built in-repo]. Canon’s precedent search, escalation workflow, and autonomous adjudication remain [supernova design].

What this costs

  • It is a 2,900-line hand-maintained monolith. Conflict resolution is “read newer-over-older” — a human protocol, not a data structure — and resolving a D# means grepping the ledger and two archive logs. There is no mechanical D# registry.
  • Mechanical enforcement is thin against the standard’s ambition. The live check catches only opposite-polarity headings on a normalized topic; conflicts phrased differently slip through. Authority grading, coverage metrics, and supersession-propagation scans are design-stage. Today’s real guarantee is editorial discipline plus one validator slice.
  • Quote-mining is expensive and fragile. The provenance dig required full transcript excavation from session logs stored outside the repo, with genuine retention risk for future re-audits.
  • The human is the bottleneck, by design. Mandatory-provenance items queue on Matt; a ten-item docket of NONE/PARTIAL rulings sat OPEN or CONTESTED for weeks. Case-law that cannot be ratified stalls.
  • PARTIAL is a fuzzy grade. “Matt set the property; the architecture is agent-crystallized” covers everything from a schema detail to an entire taxonomy, with very different amounts of agent invention behind the same label.
  • The ledger records; it does not prevent. The 773-requirement inflation happened under this regime and was caught by a deliberate deep-dive, not by the standing apparatus. The fixes it prescribed are themselves partly aspirational.
  • Churn is preserved, faithfully. Same-day supersession means the ledger keeps its thrash on display; readers must trust the banners to navigate it. That is the price of never deleting anything.

The bus: nervous system and audit log

Supernova has one rule about communication: everything is an event on the bus. Kafka is not a source that feeds other systems — it is the substrate every system communicates through. Monitoring, workflows, agents, chat: all of it rides the same broker, and the durable record it leaves behind doubles as the platform’s audit log.

Why buy Kafka: the 479 MB bus.db

The predecessor platform, automatt, ran a bespoke Python event bus [live in automatt] — and it was the single most reliable source of unreliability. Documented failure modes: the Unix socket vanishing under a live service, the orchestrator crash-looping on the missing socket, oversized frames tripping LimitOverrunError, and a bus.db that bloated to 479 MB, with 1.6 GB memory peaks, forcing restarts every couple of hours. Matt’s ruling (2026-06-04):

“the EVENT BUS has consistently been pain and python will always be slow and kafka is like industry standard that does everything we could ever want and its performant and its right there.”

Moving to Kafka isn’t “off-the-shelf is easier”; it’s “the bespoke one keeps breaking and the proven one won’t.” This is the build-or-buy pattern at its cleanest: buy the broker, build only the conventions on top — plus the one genuinely bespoke layer.

Two layers, clearly delimited

  1. The substrate (bought). Kafka provides durable pub/sub, topics, partitions, consumer groups, retention. The integration is deliberately thin: the bus crate must not reimplement storage, partitioning, or replication, and invariants ban domain logic in this layer.
  2. The dispatch arm (built). The reactor layer — “do X when Y condition is met” — was once a standalone system and was folded into the bus (2026-06-20), because the dispatch arm is the consumer layer for the substrate. It exists because there is no native Kafka→Temporal trigger; someone has to own that seam.

The envelope

The bus owns the platform envelope: the mandatory field set every published event carries, enforced at publish time — a malformed envelope is rejected, never silently transported.

FieldJob
message_idUnique per event. The canonical dedup key; downstream idempotency keys derive deterministically from it — a Temporal workflow ID is a deterministic function of the message_id.
correlation_idCausal-chain trace ID. Tracing only; must never be used for dedup.
severitydebug < info < warning < error < critical. A property of any event, never a topic — there is no error topic anywhere; the monitor filters on severity >= error.
principal_idWhich auth principal originated the chain. Required per-topic (D62, 2026-06-19); ownerless topics — TTL expiries, timers, probe results — omit it, never fake it.
timestamp, event_name, payloadCreation time, the four-segment name, and the variable data consumers filter on.

Delivery is at-least-once, never exactly-once; duplicates are expected and correct, and dedup rides message_id alone. The two IDs stay separate because merging them fails both ways: distinct actions in one chain would collide, and a retried event with a new correlation ID would double-fire (D21, 2026-06-18 — a round-two review caught the workflow system deriving IDs from correlation_id and reconciled it). The no-double-email guarantee rests on this rule. Baking correlation and initiator into the envelope from day one makes observability structural, not retroactive — automatt had the same fields, inconsistently populated, which is how you get recurring validation errors instead of traces.

Topic grammar and the registry

Every topic is event.<system>.<entity>.<verb> — first segment the owning system, verb in the past tense (“what happened”). No dynamic topic names, no wildcards; Matt (2026-06-04): “we don’t do dynamic topic names… I’d rather filter on params.” Variable data goes in the payload. The taxonomy stays fixed and enumerable, so it can live in a single canonical registry — roughly 90 topics across eighteen of the nineteen systems (core, the framework substrate, publishes none), each tagged owned or ownerless, mechanically diffed against every system’s declared topics by the wiki validator [engineered, not deployed]. A subscribed topic must have a registered producer; subscribers themselves are optional (Matt, 2026-06-23) — advisory wiring documentation, not a completeness gate. Naming disputes land in a reconciliation ledger with states registered | ruled | proposed | superseded that system docs must not silently re-litigate.

The two-write outbox

The bus-topics doc, rule 6 (ratified 2026-06-10): a state mutation and its event emission are two writes that “MUST NOT be able to diverge silently.” The outbox pattern is how: the event is recorded transactionally with the mutation — same store, same transaction — then relayed to the broker. If the broker is down, events queue locally and replay on reconnect in per-key order; a mutation whose event can never be recorded fails closed. publish() returns the generated message_id precisely so the producer can record it before relay. This is the mechanism that makes “every behavior traceable to root cause” hold exactly when things fail.

D81 (2026-07-03) narrowed the scope: the outbox is required only for load-bearing state-transition events from the five or six DB-backed systems. The discriminating test — “if this event is silently lost, does the system end up permanently wrong in a way that won’t self-correct?” Yes: outbox. No — config updates, wiki edits, log lines: publish directly, because losing one is a missed notification, not corruption.

flowchart LR
  P["producing system"] -->|"mutation + event, one txn"| O["outbox"]
  O -->|"relay, replay on reconnect"| K["Kafka topics"]
  K -->|"consume"| R["reactor dispatch arm"]
  R -->|"typed actions"| C["workflows, agents, chat, link"]
  C -->|"actions emit events"| K
  K -.->|"retention = durable history"| T["the trail"]
  M["monitor read-lens"] -.-> T

Note the cycle: subscribers’ actions are themselves events, emitted back onto the bus for others to react to — actions feed back into the trail rather than vanishing into logs.

The trail

The bus owns the trail: the durable event record plus its correlation_id causal chains. There is no separate audit store — “history of X” is a per-topic retention setting, not a new system. Matt (D46): “we kinda treat bus as audit and anything that cares should subscribe via metrics or reactor.” This one ruling dissolved a planned ops-audit store, the issue system’s audit list, project audit, and the monitor findings store into retention config. The monitor is a read-lens over the trail, not its owner; the trail also transports the attestation events that requirements evidence indexes. Even structured logging is just bus events on a registered log topic — instead of opaque text logs nobody can subscribe to.

The reactor dispatch arm

A reactor binding is a name, trigger topics, a declarative side-effect-free when predicate, and a typed action from a closed catalog — start_workflow, signal_workflow, chat_action, link_action, field_update, lib_call. No arbitrary callables; schema-invalid bindings are rejected at registration. Bindings are runtime registry state, loaded and unloaded dynamically, not static config.

The load-bearing case is the Kafka→Temporal bridge: the default primitive is signalWithStart, with the workflow ID derived from the trigger’s message_id — so a redelivered event converges on the one workflow instead of racing a double-start. Each binding keys idempotently on the message and binding name and fires once; bindings never suppress each other. Failure handling follows the platform failure classes: transient failures fail closed and let the uncommitted offset redeliver (the config schema deliberately has no retry knobs — blind retry is banned), deterministic failures auto-file a bug with an event-context snapshot, and denials are a designed branch kept out of the error stream.

Two details worth naming. First, the dispatch arm is never a side door to the outside world: there is exactly one external-action path, and it is the link system’s permission-and-approval-gated path. Second, the same find→attach→listen wakeup mechanism serves two consumers: it wakes sleeping agents and un-parks Temporal stage gates — one mechanism, two consumers.

The bus is also its own hardest case: broker-down means the loudness channel is down. The design enumerates its own exception — a bus-independent probe in ops (the one sanctioned violation of “everything rides the bus”) watches the broker and, on recovery, emits event.bus.broker.connected onto the freshly recovered bus, where a default reactor resumes parked workflows. The one recovery signal that cannot ride the bus to begin with is delivered by the only component allowed not to.

Where this stands

Build state, since “event bus” invites overclaiming:

  • The Rust bus crate is real [built in-repo]: thirteen modules (~2,900 lines) with one-to-one test files covering the envelope, topic parser, outbox, reactor engine, and registry validation. All bus requirements are marked done on unit and integration evidence.
  • The reactor pump demonstrably fires against a live project event spool — hundreds of observed dispatches driving pod spawns and ingest gates on the dev box.
  • But the day-to-day transport today is a JSONL file spool, not Kafka. A compose Kafka broker is provisioned and answers, and a conditional live test exercises outbox queue-and-replay through it, but dual-write verification was still planned as of 2026-07-02. D80 (2026-07-03) is blunt about the interim file layer: the current file-outboxes are “the live two-write DIVERGENCE” — the very failure mode the pattern exists to prevent — and are scheduled for deletion as authoritative state moves to Postgres, Kafka, and Temporal.
  • Retention tiers as operated config, the monitor’s OTel lens, and topic-browser surfaces are [supernova design] only. CloudEvents and W3C Trace Context were evaluated and deliberately deferred (2026-06-19) with a written non-breaking upgrade path — restraint over resume value.

What this costs

Kafka is heavy: a JVM broker under KRaft for a single-tenant platform on one box, serving ~90 topics — the wiki itself names NATS and Redpanda as lighter alternatives; Matt’s call was Kafka. At-least-once delivery pushes idempotency onto every consumer: each one must derive its idempotency key deterministically from message_id or double-fire, and ordering is per-partition-key only, which is easy to forget. The registry is mechanical to validate but manual to maintain, and it has lagged reality — a 2026-06-22 audit found an entire system section and four already-subscribed topics missing. Bus-as-audit couples audit depth to retention config: with a seven-day default, durable history is a knob, not an archival guarantee. D81’s outbox narrowing was an honest scope walk-back, but it means “cannot diverge silently” now protects only the DB-backed core, not everything. And per-requirement “done” here means design-plus-unit-proven, not production-soaked: a platform-wide assessment (D82, 2026-07-03) rated the end-to-end harness at roughly 12% real, and a sampled live envelope carried timestamp: 0 — the contract field existed; the honesty of its population did not. The design’s own case-law is the first to say so, which is rather the point.

Durable workflows and park-on-failure

Multi-stage agent work — decompose a feature, implement its wires, review, integrate, promote — takes hours to days and must survive process crashes, machine reboots, and broker outages without losing its place. Supernova puts that work on Temporal for durable execution, then inverts the default most workflow systems ship for the same moment: what happens when a step fails. It doesn’t retry. It parks.

Temporal, bought not built

The substrate ruling came early and flat. Matt (2026-06-04): “workflows are be temporal [sic]. straight up.” — and, in the same ruling, the philosophy the substrate serves: this project is “agents do what they want within very loosely structured workflows, with correctness enforced through disabling anything too sharp.” Workflows define step existence, ordering, and durability boundaries; correctness comes from the permission layer and gates, never from step-level validation of an agent’s choices.

The deployment posture [supernova design]: self-hosted Temporal on owned hardware with Postgres persistence — explicitly not Temporal Cloud — with workers and definitions written in Rust (the Temporal Rust authoring SDK, Public Preview as of May 2026). Scheduling is a verb under workflow, not a system: Temporal Schedules absorb all cron and interval work.

There is no native Kafka→Temporal trigger, so the bus reactor dispatch arm is the seam: reactors consume events and call signalWithStart with a deterministic workflow ID derived from the triggering event’s message_id — never its correlation id; the bus page owns that dedup rule (D21). All non-determinism lives in activities, every activity declares an explicit timeout (a missing timeout is a definition-validation error), and side-effecting activities are idempotent under deterministic tokens.

Park, don’t retry

The signature semantics, from a design note dated 2026-05-16: a failed workflow parks — alive, zero compute, awaiting a resume signal — while the system heals around it. An agent fixes the root cause, signals resume, and the run retries from the failed step, not from the beginning.

This forced a reckoning with the platform’s older “fail loud, no fallbacks” principle, resolved in the failure-classes doc (ratified 2026-06-10):

“Never proceed wrong, never die quiet, never kill the platform to make a point.”

Parking is failing loud, for contexts that have state worth keeping. Two axes decide everything. Context durability decides the loud-failure mode: durable Temporal steps park; ephemeral contexts — CLI invocations, handlers, reactors — crash with a nonzero exit. There is no third mode; “log a warning and continue” does not exist. Failure class decides the resume path:

ClassExampleAt failureResume
deterministicbug, contract violation, misconfigpark + auto-file a bug carrying the context snapshotexplicit signal only, after a fix lands — never automatic
transient operationalbroker down, rate limitpark + monitor alertautomatable: a reactor consumes the health-recovered event and signals every workflow parked on that dependency
denialpermission refused, approval deniednot a failure — info/warning, a designed branchthe designed branch, or park on the approval-resolved signal

Denials stay out of the error stream so the error stream stays meaningful. And blind retry is forbidden outright: Temporal’s max_attempts is conceptually always 1, and the retry-policy knobs are removed from config rather than defaulted — an operator setting max_attempts > 1 would silently re-enable the forbidden behavior. Retrying a deterministic bug with identical inputs can never succeed; it only burns compute and manufactures noise.

stateDiagram-v2
    [*] --> Running
    Running --> Completed: all steps green
    Running --> Parked: step fails, parked event emitted
    Parked --> Parked: system heals around it, zero compute
    Parked --> Running: resume signal, retry from failed step
    Completed --> [*]

Every park emits a lifecycle event carrying the workflow id, failed step, error, and failure class over the bus envelope, so parking is loud by construction. One refinement worth quoting — Matt, 2026-06-10: “I’m also not as militantly attached to ‘crash and fall over’ if the error visibility through the monitoring system is actually good.” So crashing is the bootstrap implementation of loudness, not the principle [supernova design]: a component class earns the right to stay standing only while synthetic canary errors demonstrably produce alerts within SLA; a failed canary reverts the class to crash-loud. The right to stay standing is continuously re-earned.

Composition: a shallow tree of durable runs

A feat entering ready starts exactly one named delivery workflow [supernova design] — the issue statuses and gates themselves belong to the delivery lifecycle. The tree is deliberately shallow: a delivery parent, one child wire workflow per wire, and a thin promotion sub-workflow that decides dev→main (“workflow DECIDES promote; vcs ACTUATES the ff-only merge”). Nesting caps at two levels. A unit gets its own child workflow only if it needs all three of: an independent park boundary, an addressable durable lifecycle, and independent failure isolation — one criterion means it’s an activity. Wanting a third durable level is the smell that a phase or an external-system call is being modeled as a workflow when it should be an activity or a parked-await. Review, E2E testing, and decomposition are accordingly not workflows: they are reactor-driven parked-awaits on other systems’ bus events.

The stage gates themselves collapse into one primitive: every gate is a single uniform parked-await over the evidence ledger — advance iff the issue type’s required evidence kinds are present, green, and fresh; otherwise park. A new evidence tier is a config row plus a producer, zero new workflow wiring.

The ephemeral executor seam

A wire workflow does not host its coder’s agent loop. It forks the coder from a warm repo base under a deterministic idempotency token (an activity retry never forks a duplicate), then observes rather than drives: the agent system’s turn-manager runs the turns, and the workflow watches the wire’s issue-state outcome. The ownership line, verbatim from the seam contract: “agent owns fork identity + teardown, workflow owns the binding + lifecycle triggers.” There is no crate dependency from the workflow system to the agent system; the trigger crosses the boundary as an in-process goal loop or a subprocess spawn.

The detail that makes park cheap: park reaps the coder. “Alive at zero compute” describes the durable Temporal run, not a held-open agent process. A parked wire workflow tears down its disposable fork; resume re-forks a fresh coder warm from the parent base with the failure context — never cold-boots, never resurrects the dead ephemeral. Durability lives in Temporal state, not in processes kept breathing.

Goal loops

The platform already is a control loop: requirements are the setpoint, tasks the actuator, evidence the sensor. A goal loop (sun agent goal pursue) scopes that loop to one agent and one target:

flowchart LR
    ACT["ACT: agent works the target"] --> EMIT["EMIT: real producers emit evidence"]
    EMIT --> CHECK{"obligation satisfied?"}
    CHECK -- yes --> DONE["goal closed"]
    CHECK -- no --> PARK["PARK on the bus signal that could change the answer"]
    PARK -- wake --> ACT

Two prohibitions carry the design. The agent does not self-attest its own success — evidence comes from the same independent producers as everywhere else, against an obligation declared up front by someone other than the doer. And the loop never busy-checks the ledger — react, not poll; it parks on the signal that would change the answer. Loops are bounded (iteration cap, wall-clock and token ceilings) and fail loud by parking-and-signaling, “the same primitive as success-parking, just with a different signal target.” A standing goal is a keep-satisfied loop, because closure is non-monotonic — done is rented, not owned.

Ratified 2026-06-24; the v1 loop runtime is implemented and unit-tested in the workspace [built in-repo] — closes-on-obligation, parks-not-polls, bounded-and-fail-loud are exercised in tests — while async parked-session wake and standing-goal hysteresis remain specced follow-ons [supernova design]. Deliberately, the top-down delivery stage gate and the agent-initiated goal loop are the same primitive at two altitudes.

Where this stands

The machinery that runs Matt’s operations today is the predecessor platform’s bespoke engine — reactors, a ship workflow, a batch orchestrator, APScheduler [live in automatt]. Supernova’s workflow system is the designed replacement. Its core is real Rust with real evidence: the parked-resume primitive is proven live against a self-hosted Temporal server on the dev box — a run queried while parked, sent a typed resume signal, completing — along with probe-scale schedule, cancel, and delivery-shaped runs with recorded run IDs [engineered, not deployed]. The canonical delivery workflow, live promotion gate, and critical-user-journey (CUJ) E2E on a real stack are explicitly held at draft [supernova design].

The project grades itself in public: D82 (2026-07-03) assessed the E2E workflow harness at roughly 12% real — stub probes returning fakes, an always-green CUJ workflow, a hardcoded promotion path. Making E2E real is now the prerequisite gate for closing anything more, and the first stub retirements landed the next day. That ledger of self-assessment lives in decisions as case-law.

What this costs

  • Design far ahead of deployment. The most compelling machinery — the full delivery tree, the live promotion gate — is ratified prose and draft requirements, not a production system. Live evidence is probe-scale, and the E2E grade above is the project’s own number.
  • Park needs a healthy healer. Deterministic parks resume only via explicit signal after a fix. If the bug-filing → fix → signal pipeline stalls, parked runs accumulate silently at zero compute; the model leans on monitoring and the canary discipline, which are among the less-proven parts.
  • Closure rests on scope wording. Some requirements are marked done on carefully scoped slices while D82 simultaneously lists stubs in adjacent code paths; a skeptical reader should notice how much weight the scoping language carries.
  • Temporal Rust SDK risk. The authoring SDK is Public Preview; the sanctioned fallback is a Python/TS workflow service behind a Kafka/HTTP boundary — a real architectural wart if it’s ever needed.
  • Superseded along the way: per-project Temporal namespaces (rejected for one shared namespace with a project-id partition key), a dedicated rollback topic, the “ship workflow” naming, and correlation-id-as-dedup — each abandoned with the reasoning on record.

Agents and token economics

Every agent fleet eventually meets the same bill: dozens of LLM sessions, each re-reading the same repo, the same docs, the same instructions, at full price. Supernova’s agent substrate is built around one observation — most of what a fleet sends to a model is a prefix it has sent before, and providers serve a cached prefix at a small fraction of the cost. So the substrate treats spawning an agent as something that should be nearly free in tokens, and treats the token bill as a design input rather than an operating surprise.

The candor about why is on record: Matt has said plainly (2026-06-04) that much of the predecessor platform’s design was driven by keeping model costs sane rather than by any grand infrastructure theory. The agent system is the disciplined version of that instinct.

Where agents run

The load-bearing ruling from the substrate design dive (2026-06-21/22, recorded in decisions as case-law): own the agent loop rather than wrap a vendor CLI, because “the cache-economics primitives (prefork/warm-fork + prompt-cache lifecycle) must live INSIDE the loop — you cannot own cache/fork economics inside a vendor harness.” The rebuild is surgical, not from scratch: from the Apache-2.0 codex codebase it grabs three proven tools (the fuzzy-match patch applier, file search, shell command), reimplements the loop, tool dispatch, and a focused OAuth transport (~1–3K lines), and skips the 205K-line TUI, the ~140K-line app server, and the ~37K-line sandbox stack. Measured, then declined.

The hard constraint underneath: flat-rate subscription plans instead of metered API pricing. Per-token pricing blows the economics of a fleet pushing twenty-plus tasks overnight, and since Anthropic restricts its subscription to Claude Code, the owned runtime targets the OpenAI lane; Claude rides along via Claude Code or metered calls as the exception.

Three runtime backends sit behind one runner contract:

BackendWhat it isState
codex-subprocesscodex app-server as transport only, sandboxed, speaking JSON-RPC on MAX-plan authadapter built and tested in the Rust tree [built in-repo]; the pattern it ports runs in the builder platform [live in automatt]
channel-bridgea persistent Claude Code session is the runtime, bridged over a channel[supernova design]
native-ownedthe owned loop with in-loop cache/fork control[supernova design] — the transport seam currently maps to a fail-closed stub until the owned OAuth transport lands

Any runner plugs in at a statically declared capability tier — baseline is “a chat target”; session, turn, fork, warm-fork, and mid-turn-interrupt are higher tiers — and an unsupported capability downgrades to baseline with a loud warning. The invariant: “Tiers differ in control/economics, never in isolation or the message set.” Model routing follows a clever↔diligent spectrum: autonomous, repeatable, convergent work goes to the diligent fleet (Codex: rigorous, order-following, token-generous); judgment-heavy, novel, divergent work goes to the clever specialist (Claude), with guardrail strength scaled to the model’s initiative profile. Confinement itself belongs to the permission stack.

The zygote: warm-parent forks

The centerpiece primitive, the zygote — deliberately named after Unix prefork servers: a warm parent session holds a large corpus fully prompt-cached — the preforked process image — and every spawn forks it, so each child inherits the cached prefix the way a forked process shares pages. Fork is the default spawn for all fan-out: review-per-file, workflow stages, oracle-per-question, repo-warm coders. Cold boot is the permitted exception, and it requires typed paperwork — a permit with a stated reason and requester, rejected outright if a suitable warm parent already exists. Architecture violations become type errors; operator overrides become auditable evidence.

The core invariant (AGENT-I20, verbatim from the agent requirements doc):

“A fork never mutates its warm parent. The warm parent is the pristine ‘library’; forks are disposable ‘readers’. Cache maintenance is append-then-refork (R26), never in-place mutation of a shared warm base.”

The oracle pattern is the purest expression: a corpus sits warm in a parent; each question forks the base, answers through the disposable child, and the fork is discarded — so the parent never grows past its cached prefix and never compacts. The fork id is a hash of the normalized question, so replaying a question is idempotent: a cache key for the cache primitive. When the corpus changes, delta-sync appends the diff to the warm session and reforks the session that ate the diff as the new warm base — never reloading, because a prefix change invalidates the whole cache — with a periodic hard reload to reset the accumulated diff tail.

flowchart TD
    CB["cold boot: typed permit required"] -->|"pays full price once"| WP["warm parent v1: corpus fully prompt-cached"]
    WP -->|"fork: ~99.7% cache read"| R1["review child: file A"]
    WP -->|"fork: ~99.7% cache read"| R2["review child: file B"]
    WP -->|"fork per question"| O1["oracle child: disposable"]
    O1 -->|"answer, then discard"| D["fork disposed: parent never compacts"]
    WP -->|"append diff, then refork"| WP2["warm parent v2: cached prefix preserved"]

The field numbers: ~99.7% cache read, a fraction of a cent per query — measured in the live builder platform, where warm-session forking works today [live in automatt]. Fresh-agent spawn cost drops to nearly nothing, which is what makes review swarms, per-stage workflow fan-out, and repo-warm coding agents affordable at fleet scale.

Two notes the wiki insists on. First, in the Supernova tree the fork machinery is built and unit-proven — the fork engine, the fail-closed cold-boot contract, delta-sync, durable-run-bound forks — but the cache-economics requirement itself is deliberately still draft: its closure evidence is a planned production field metric, and a dedicated fail-closed classifier exists solely to reject local, mock, synthetic, or test-prefixed proof so the requirement cannot close on fake numbers (see evidence kinds). The project’s own hype-number is quarantined behind a parser. Second, the gates earned their keep: a 2026-07-02 audit found the implementation inverted — running 100% cold boots with the fork engine unused. Matt: “that’s a huge huge issue, I am surprised there is even a clear cold boot mechanism because there isn’t supposed to be, except literally for warming up sessions for forking.” Corrective work landed (thread resume, a warm-fork branch seam); the live branch round-trip measurement is a named follow-up, and the wiki records plainly that true provider-side thread fork — as opposed to proven thread resume — may not be exposed at all, with a weaker fallback of maximally stable shared prefixes plus provider prefix caching.

The 24-hour cache patch

A private patch extending a 24-hour prompt-cache window has been built and verified but is not deployed[engineered, not deployed]. The related prompt-cache configuration path crashes on the current SDK, so production uses auto-cache instead. It is easy to imagine this paragraph quietly claiming a deployed 24-hour cache; it doesn’t, because the difference between “verified code exists” and “runs in production” is exactly the distinction the whole project is organized around.

Token thrift as a discipline

The fork primitive is the headline, but the same economics run through everything as smaller habits:

  • Mechanical checks before agents (D7). Deterministic checks run once and agents judge over their artifacts, instead of N agents independently re-reading the whole repo. The monitor rebuild exists partly to make adversarial review cheaper, not just stricter.
  • Cheap-model triage ladders. Investigation escalates checks-first (free), then a small model for triage, then a frontier model only for genuinely complex cases — the monitor system’s layered-triage invariant, applied wherever classification precedes judgment.
  • React, don’t poll. Goal loops park — alive, zero compute — on reactor wakeups and never busy-check; an idle remote agent costs zero tokens because its mailbox accumulates centrally and the LLM wakes only on gated wake-mode messages, then batch-drains. The parking machinery itself belongs to workflows.
  • Resume over respawn (2026-07-01/02). Rework returns to the same session, which is probably still warm in the provider cache — but the ruling is not only about money: the thread history carries why the code was structured as it was, preventing guesswork-rework. Even cache-cold, resume; never fresh-spawn on cache expiry.
  • Lookup before fork. Cheap structured search and the agent memory graph are tried before any research spawn; only big-context questions earn an oracle fork.

What this costs

  • The economics rest on semi-supported ground. Subscription-OAuth lanes can drift or change terms — the design’s own words: “you find out in CI, not prod at 2am” — and one vendor’s restriction already forced the choice of primary lane. A pricing or ToS change upstream reprices the whole architecture.
  • The proof comes from the predecessor platform, not from Supernova. No cached-fraction measurement exists in the Supernova tree, and the requirement gates refuse to pretend otherwise.
  • The primitive proved easy to bypass. The fork-only architecture shipped inverted once already. The gates caught it, which is the system working — but it shows the default-spawn discipline needs enforcement, not just intent.
  • The provider may not cooperate. If true thread forking isn’t exposed, the fallback (each child re-sends a shared cached prefix) is real but strictly weaker than one warm session branching into N children.
  • The heavy lift is still ahead. The owned OAuth transport, streaming, compaction, and retry machinery do not exist yet; the native seam fails closed by design, but a fail-closed stub is still a stub.
  • Complexity budget. Warm-pool GC, corpus-generation tracking, hard-reload thresholds, per-provider cache semantics, and a fail-closed evidence-URI grammar are substantial machinery whose payoff depends on fleet scale and on providers keeping prefix caching cheap.
  • The 24h patch is a private fork of vendor behavior that must track upstream indefinitely — and the adjacent config path already crashes on the current SDK.

Permissions, approval, and the egress chokepoint

Supernova’s adversary model is not a remote attacker. It is the platform’s own agents, fed hostile text: a prompt can talk an in-process allowlist into anything, so the permission system’s root requirement demands authority that is “auditable, additive, OS-enforced, and impossible for a prompt to talk its way around.” The result is four small systems that each answer exactly one question about an action — and one door through which every external effect must pass, so that safety is a property of the path itself rather than of anyone’s good behavior.

Four layers, one question each

LayerQuestionOwns
authWho is acting?The single Principal contract (D4), transport-identity bindings, an encrypted-local secret store
permissionIs this actor allowed to?Capability registry, group membership, OS-level enforcement
approvalShould this specific action happen?Risk tiers, trust policies, human decisions, grant tokens
linkHow does it reach the outside?The only external-send path, with the gates built into it

Each layer refuses to own its neighbor’s thing: permission owns the model and the check() primitive but not the gating act — the system that owns an operation calls the check at its own call site (D54, ratified 2026-06-20). Auth owns credentials; link resolves them at action time and never stores any.

flowchart TD
    A["agent process"] -->|"asserts identity via whoami"| AU["auth: resolve Principal"]
    AU -->|"principal_id"| P["permission: capability group check"]
    P -->|"cap missing"| D1["denied — a designed outcome, not an error"]
    P -->|"cap held"| AP["approval: risk tier and trust policy"]
    AP -->|"denied or expired"| D2["hard wall — no auto-retry"]
    AP -->|"approved: one-shot grant token"| L["link: the only door out"]
    L -->|"scope digest re-verified at the boundary"| X["external world"]
    RG["resource gate: bwrap sandbox — fs binds, net namespace, seccomp"] -.->|"confines the process itself"| A

Permission: the kernel as the capability gate

The model [live in automatt] is three levels, carried over deliberately unchanged (Matt, 2026-06-04: “current plan for permissions is to keep it as-is”): atomic capability groups where one Linux group grants exactly one capability (cap-commit, cap-approve, cap-network, …), roles as config-file bundles that compile down to group memberships, and a real OS user per agent. The enforcement claim is the whole point: an agent without cap-commit cannot commit because the kernel says no — “not bypassable via prompting, environment manipulation, or in-process checks,” per the permission requirements doc. The flagship invariant: never check agent name for capability. Code checks group membership only.

Capabilities are additive-only — granted, never expressed as restrictions. Everything starts at zero; ephemeral agents get no groups at all, structurally rather than by policy. A grant validator (D40) makes one rule non-configurable in code: an ephemeral identity can never be placed in a privileged group, and granting a privileged capability requires already holding it.

Two honesty mechanisms are worth noting. First, every capability declares its enforcement class — os-enforced or hook-enforced — because a CLI flag like --no-verify is not a Linux permission; the weaker guarantee is labeled rather than hidden. Second, a denial is not a failure: the outcome taxonomy is allow / deny (a designed branch, kept out of the error stream) / cannot-determine, and the last of these fails closed — deny, then crash loudly.

Beneath the action gate sits an orthogonal resource gate (D39, 2026-06-19): each agent process is meant to run in a bwrap sandbox with default-deny filesystem binds, a denied network namespace unless cap-network is held, and a seccomp filter. The two gates compose; per the permission invariants, “confinement only restricts reach, it never GRANTS authority.” The sandbox primitives are [engineered, not deployed] — verified against live bwrap, including a confined agent pod that ran the Rust toolchain (cargo, rustc) and git in-sandbox while a write outside its worktree failed with EROFS (2026-07-02) — but fleet-wide confinement of every spawn surface is still [supernova design], and host-level sun permission sync deliberately fails closed until a host OS backend is wired.

Approval: five tiers and a hard wall

Approval is the decision half of the gate — permission answers whether the actor may act at all, approval whether this specific action should happen — [live in automatt]: the predecessor’s core rule is that every action touching personal data or external services passes through it. Risk levels are a closed, ordered enum, each with a time-to-live after which a pending request expires as denied:

TierTTLTypical disposition
read300soften auto-approved by policy
low600spolicy-dependent
medium1800spolicy-dependent
high3600susually a human
critical7200sa human

Trust policies are declarative config mapping action type, risk level, and agent to a disposition; most-specific wins, and on a precedence tie the system fails closed to human review. Pending requests generate periodic nudges bounded by the TTL, not by rate limits — an opinionated stance that the human should be pestered until they rule or the request dies.

The distinctive rule is what happens after a no. Per a 2026-06-20 ruling, “every approval request originates from an agent running into a wall and explicitly requesting to bypass it,” and a denial is a hard wall: there are no auto-dispatched retries. The agent adapts, tries a different approach, escalates through chat, or abandons. This came from approval fatigue in practice — Matt: “sometimes we want agents to just run into walls … we don’t want to pester me and nova every time.” The agent, not the platform, decides when a wall is worth an explicit ask.

Two structural details keep approvals from being a rubber stamp:

  • Approval is a token, not a boolean. An approved request yields an immutable grant token — a digest of the action type, normalized parameters, and approval id — re-verified at the egress boundary. Approving one email cannot authorize a different email; scope creep is structurally rejected.
  • Walled-command elevation (D3, a port of automatt’s am sudo [live in automatt]): a low-privilege agent that hits a wall runs sun approval request cmd <command> --reason <why>, and on approval receives a one-shot token scoped to exactly that command, consumed on use, with a 60-second lifetime. Elevation cannot bypass tests or hooks — it allows only the specific command submitted.

Agent-to-agent approval exists but is mechanically gated: the resolver must hold cap-approve (checked through permission, never by name), and a requester can never approve its own request. Even a Discord approval button resolves only after link verifies the provider’s Ed25519 signature, auth maps the external user id to a principal, and that principal proves cap-approve — “a raw bus event can never resolve a request.”

Link owns all external send (D1). It is a specialization of the bus reactor pattern with the gates built in — Matt: “links are special kind of reactor with built-in approvals.” That framing does the security work: because an external-boundary action is defined as a link action, and every link action carries the permission check plus the approval scope-verify before executing, there is no second path that could diverge into a bypass. The invariant is blunt: “No ungated outbound side effect, ever.” Blocked actions emit a .blocked event; nothing is silently dropped.

The same chokepoint stamps inbound traffic: every incoming item gets a trust tier from the transport-verified sender identity resolved via auth — not from the channel it arrived on. A message from an unknown sender on a trusted channel still lands as external_unknown and routes to triage rather than the realtime bus. Delivery at the boundary is idempotent, so a redelivered event cannot send two emails.

Build state: the gated send path is [engineered, not deployed] — live sends to Discord, ntfy, and Home Assistant require a cap-link actor, a non-self approval, and an auth credential reference, with a durable outbox before the provider call. The rest of the adapter inventory the design requires (Gmail, Calendar, Cloudflare, Proxmox, and others) is [supernova design], and no real-provider OAuth consent has been evidenced yet. The chokepoint is real; few doors are connected to it so far.

One deliberate hole in the layering is worth admitting rather than hiding: config writes are not gated by a runtime permission call. Matt: “config does NOT need permission, permission is technically enforced by operating system not by live system” — a whole-file OS write group guards the config file (D62), which breaks the circular dependency where permission’s own configuration would need permission to edit. Per-section gating was designed, found mechanically impossible to enforce, and retired; the decisions ledger keeps the tombstone.

Where this stands

The approval engine, one-shot elevation, and OS users/groups enforcement run today in automatt [live in automatt] — those behaviors are what Supernova treats as proven requirements. The Rust rewrite has all four systems implemented with test evidence [built in-repo]: durable approval lifecycle with the signed Discord resolve path, permission checks with container-level user/group projection and revocation, encrypted-local secret stores, and the gated live-send path. What is not yet true: per-agent OS users on every spawn surface and fleet-wide sandbox confinement are both draft requirements with planned evidence, and host-level permission actuation fails closed by design until a backend exists. Notably, the project’s own evidence system polices this gap — classifiers reject dry-run receipts, fixture proof, and placeholder ids as production-closing evidence, so local proof cannot masquerade as live proof.

What this costs

  • It is heavy for one person’s data. Four systems, hooks, containers, a sandbox layer, and an outbox contract — justified by the prompt-injection adversary model, but much of it is not yet wired end to end, and the complexity bill arrives before the protection does.
  • Hook-enforced caps are honor-system-adjacent. The docs admit that a missing hook means no enforcement; cap-approve and the CLI-flag caps are only as strong as the hook layer, unlike the kernel-backed groups. The enforcement-class labels make this auditable; they do not make it go away.
  • The flagship claim outruns the deployment. “An agent literally cannot commit” is proven inside container tests, not on a running fleet. Both per-agent-users-everywhere and confinement-everywhere are draft.
  • The agent-to-agent gate is coarse. One cap-approve group answers “is this a high-privilege agent.” A finer token-based scheme was proposed during the automatt-era security review, judged a stretch, and deferred rather than rejected — the promotion path is an acknowledged open item.
  • Expiry-as-denied can silently stall work if nobody is watching the inbox; the mitigation is a warning-severity event and monitor aging, which is thinner than one would like.
  • At-least-once delivery pushes idempotency work everywhere — dedup keys, one-shot token consumption, provider-receipt reconciliation — substantial machinery whose only job is making sure a redelivered event doesn’t send two emails.
  • Superseded scars remain: per-section config gating retired as unenforceable, human multi-tenancy dropped outright (2026-06-20; one human, project namespaces as the only tenancy axis), and resource quotas punted to ops cgroup governance — the sandbox gates reach, not CPU or memory.

Multi-project as the only multi-tenancy

Most platforms grow tenancy along the user axis. Supernova runs on one machine, for one person, and dropped human multi-tenancy deliberately (2026-06-20): “isn’t really designed to be shared on a single machine … safe to assume all humans have sudo” (Matt). The tenancy that survived is the one a builder platform actually needs — isolation between the projects it builds, so that several codebases can be worked concurrently without their coordination state bleeding together.

Who the tenants are

Human multi-tenancy is dropped, not deferred: no human-tenant principal model, no per-human routing identity, no privilege separation to model between people who all have sudo anyway. If you want to share, there are exactly two modes, and never a third:

ModeWhat is sharedIsolation boundary
Share the instanceCollaborators are assigned into its namespacesThe project boundary
Share the productIndependent instances coordinate through the repo and PRsGit itself

“Live builder DBs never cross instances. Databases do not merge; the design ensures they never need to.” One nuance: the system is single-human but chat is not — chat carries user identity for multiple humans. Participation is not tenancy.

Instances, namespaces, subjects

The model was ratified in a live session (2026-06-10) [supernova design]. A running instance hosts one namespace per project it is building. A namespace is the builder’s working memory about a subject, never an organ of the subject — “product-truth ships with the deliverable; builder-truth lives in the instance’s database.” Agents belong to the instance and are assigned to namespaces; asking “where does an agent live” is a type error, the way asking where a PM “lives” is — they work for the company and get assigned to a project. There are exactly two coordinator levels: a root coordinator allocating across projects, per-project coordinators allocating within. Matt’s test for whether any coordination layer earns its seat: “Allocation value is largely ‘un-bottleneck the critical path of top level agents.’”

flowchart TD
  RC["root coordinator"] -->|"allocates across projects"| CA["coordinator, project A"]
  RC -->|"allocates across projects"| CB["coordinator, project B"]
  AG["instance agents"] -->|"assigned, never resident"| NA["namespace A"]
  AG -->|"assigned, never resident"| NB["namespace B"]
  CA -->|"allocates within"| NA
  CB -->|"allocates within"| NB
  NA -->|"subject"| SA["repo A: code, specs, product wiki"]
  NB -->|"subject"| SB["repo B"]
  NA -.->|"builder-truth"| DB[("instance builder DB")]
  NB -.->|"builder-truth"| DB

The platform’s own next version is an ordinary subject: instance vN hosts a namespace whose subject is vN+1’s codebase. “Never develop on the instance you are running.” Promotion reconciles by replacement, never merge.

Three truth tiers

Every artifact gets sorted into one of three tiers, chosen per artifact rather than per repo:

TierContentsCommitted?
Project repoCode, specs and the R# DAG, product wiki, team practice docsAlways
.supernova/Thin agent definitions, team templates, project tool config, project.yamlYes, if the team shares Supernova
Builder DBTask rows, runs, session mappings, heartbeats, team state, reconcile stateNever

The middle tier generalizes the .github/ / .vscode/ convention: present means rich integration, absent means the repo is just a repo. project.yaml doubles as the cwd project-context marker — context resolution runs a fixed precedence (session’s bound namespace → explicit flag → cwd marker) and then fails loudly: no silent global default that lets a command mutate the wrong project’s state.

The tier boundaries encode a specific scar. The v1 builder kept coordination in a second repo, and Matt’s verdict was blunt: “this split has been a nightmare and caused endless torment” (2026-06-10). The post-mortem found two distinct causes, neither of them separation itself: the wrong medium (tasks as markdown in a shared git checkout is a database implemented as a filesystem race) and the wrong boundary (specs are product-truth, coupled line-by-line to source via @R# annotations, yet were exiled with the coordination). Fixes: builder-truth moves to a real database; specs return to the project repo. The standing rule: “never implement coordination as a second repo, and never exile the product’s own documentation along with it.” A pleasant consequence is that the “builder wiki” nearly vanishes — just a root portfolio view — so there is no second wiki and no wiki-reconciliation problem.

What may cross a boundary

The task system is unified — one schema, lifecycle, gate, and dispatch codebase — but the task space is partitioned per namespace. Cross-namespace machine-consumable edges are banned and rejected at write time, in both the project layer and the issue layer. The rationale is spin-off-ability: the moment a task in one project can block a task in another, neither namespace is independently dispatchable or extractable.

The only sanctioned crossing is the pointer-task: an obligation assigned to an agent whose subject lives elsewhere, carrying gating_edge: false, never consumed by gates or dispatchers. Matt’s canonical example: “‘hey nova get XYZ landed in duva’ … it’s mostly there to remind nova when they call ‘am next’ what they need to be doing” (nova is an instance agent, duva a sibling project’s namespace, and am the predecessor platform’s CLI). Close conditions cite observable outcomes in the target namespace, with evidence. And this yields the portfolio for free: “the root namespace’s pointer-task list IS the portfolio graph” — no separate project-graph machinery. Chat got the sibling rule (2026-06-23): explicit @-suffix addressing like onyx@duva is the sanctioned crossing; implicit cross-namespace resolution stays banned.

Structured reconciliation

Product-truth changes outside the builder’s actions — pulls, other builders, human edits, promotion — while builder-state references it: tasks keyed to R#s, coverage numbers, in-flight worktrees. Matt: “we really need reconciliation to be structured and that process to be clear and documented.” So it is a defined pipeline, not a vibe: four triggers (post-merge/post-pull VCS events carrying old and new heads, post-promotion, a scheduled drift sweep that makes missed events self-healing, and on-demand), a purely mechanical scope computation (git diff plus the R# parser — “no model judgment in scope computation”), and an eight-class taxonomy mapping each change class to a builder-state action. An R# whose text changed unchecks and flags dependent tasks needs-reconcile; a removed R# flags its orphan annotations; a moved spec re-points mechanically; conflict markers halt reconciliation for that file.

stateDiagram-v2
  [*] --> clean
  clean --> pending: vcs event or drift sweep detects delta
  pending --> reconciling: reconcile runs
  reconciling --> clean: all change classes applied
  reconciling --> conflicted: merge conflict markers found
  conflicted --> reconciling: human resolves and reruns

The invariants are the interesting part. Reconciliation is deterministic and idempotent (same diff in, same builder-state delta out; re-run is a no-op). It “never mutates product-truth” — it reads truth and adjusts builder-state only. It is never destructive to builder-state either: tasks get flagged, never auto-closed, auto-reassigned, or silently edited. It is loud by construction — a silent reconcile is a defect. And a conflicted namespace blocks auto-dispatch of new work while in-flight work continues; the refusal is a denial in workflow failure-class terms — a designed branch, not an error — while the conflict halt itself is a deterministic failure: the same diff can never auto-resolve, so it parks for a human. A former reactor that auto-filed issues from reconcile findings was deleted and covered with refusal regressions: automation surfaces findings; judgment principals — humans or agents holding judgment authority, never the automation itself — decide.

The CUJ registry

The project system’s second half exists because of a documented failure mode: on 2026-06-09 an audit found every top-level branch of the plan was infrastructure — “income had no node.” The CUJ registry is where “what is all of it for” lives: critical user journeys with an executable scenario reference each (D12: CUJs are “validated by running workflows through the e2e testing system”). The test system is the sole producer of exercise telemetry; the manual CLI verb for exercising a CUJ was removed by design, so self-incremented counts are impossible by construction. Definition-of-done is a measured pass — every registered CUJ must show a real, passed, batched run — “the platform’s done-ness is computed against measured runs, not declared.”

Where this stands

The model is ratified design [supernova design]; the live v1 builder still runs single-project on the old two-repo layout this design exists to retire. The project Rust system is real code with most requirements closed on named unit and integration evidence — reconcile proven against real git diffs, dispatch gating and the cross-namespace ban enforced at write time — and the builder dogfoods the registry on its own repo as row #1 [built in-repo]. Two requirements are openly ready, not done: namespace teardown and the transactional outbox, pending the final single-store database (current stores are local-JSON scaffolding, named as such). Per-project containers — a primary container for shared services, one container per project swarm enforcing that project’s permissions (ruled 2026-06-21, superseding one-container-per-instance) — are ruled, not built. See decisions as case-law for how those supersessions are recorded.

What this costs

  • Multi-project runs at n=1. One registered project. Namespaces, the edge ban, pointer-tasks, and reconciliation are designed and unit-proven but have never hosted two real concurrent projects. The load-bearing claim is untested at its actual load.
  • The isolation is software-only today. Until per-project containers exist, the namespace boundary is enforced by write-time rejections, not the container boundary the design leans on.
  • The two unclosed requirements are the hard ones. Teardown and the outbox are exactly the transactional parts — sibling receipts bound to one transaction, registry mutation and audit event committing together — still sitting on local JSON proofs.
  • Reconciliation’s conservatism is a queue. Never-destructive means needs-reconcile flags accumulate for judgment principals to triage, and a conflicted namespace stops new dispatch until someone acts. Monitor SLA alerts mitigate; the human-in-the-loop bottleneck is by design.
  • Dropping human multi-tenancy is a real bet. “All humans have sudo” forecloses shared-machine collaboration; sharing is instance-level trust or git-level independence, nothing in between.
  • It is a lot of machinery for one user. Three truth tiers, a reconcile state machine, an outbox, checkpointed teardown. The justification rests entirely on v1’s documented torment — which is at least a documented reason, not a hypothetical one.

Why Rust

Supernova’s predecessor is a Python platform whose failure modes — event-bus socket drops, database bloat, memory spikes, restart churn — are the project’s origin story. The rewrite’s answer was not “Python, but more carefully”; it was to move every guarantee that used to live in convention into something a machine checks: a compiler, a crate graph, a validator. Rust is the language where that move is cheapest.

The ruling

The implementation language was ruled on 2026-06-21:

“it’s okay to have exceptions if there’s a sane boundary but strongly prefer rust” — Matt

A sane boundary means a process boundary — an isolated Python or TypeScript service behind Kafka or HTTP — never in-process mixing. A follow-up directive the same day (“it’s rust now… if you see python change it to rust”) rewrote the Python framings across the specs, while preserving the dated rationale in the decision ledger — including Matt’s blunt “python will always be slow.”

The exception clause has never been exercised. Both candidates that were expected to need it stayed Rust: the agent runtime went custom-built over raw HTTP model APIs with tools lifted from Codex (which is itself Rust — see agents), and workflows went to the official Temporal Rust SDK rather than a Python/TS sidecar. The clause remains a flagged fallback, not a used door.

The viability analysis that backed the ruling put it plainly: the design is ~75–80% language-neutral by substance — every bought substrate (Kafka, Temporal, Postgres, OTel/Prometheus, Vault, git, OS users/groups) is polyglot with mature Rust clients, and the contracts say what, not how. No hard blocker remained.

One binary

All of Supernova compiles into a single static binary: sun. 19 systems (the set is open-ended), 22 crates, one process. The CLI is a thin wrapper over per-system client libraries; inter-system calls are direct in-process library calls, never routed through the CLI. Any system can also be hosted as an HTTP service from the same binary (sun <system> serve). Next to the heavyweight bought substrates — Kafka brokers, a Temporal cluster, Postgres — the platform itself is one small artifact to build, ship, and reason about.

Modularity is enforced structurally by the crate dependency graph, not by convention:

flowchart TD
  bin["sun binary - composition root"] -->|links| lib["sun-lib - client library aggregator"]
  lib -->|links| sys["19 system crates: issue, workflow, agent, bus, core, config, ..."]
  sys -->|depend on| contract["sun-contract - typed contracts, zero implementation"]
  sys -.- note["few typed cross-system exceptions: agent, link, monitor, ops depend on sun-permission; workflow on sun-review and sun-test; ops on sun-config"]

(The graph is deliberately flat: every system crate depends on sun-contract, not on other systems, apart from a handful of typed cross-system crate edges. The sun-lib crate implements the sun_lib client-library layer described on the shape page.)

The type system carries the contract discipline

At the bottom of that graph sits sun-contract, ratified 2026-06-22: a dependency-free crate holding the typed inter-system interfaces — the “headers” of Supernova, pure definitions, zero implementation. Trait surfaces like PermissionGate, ApprovalEngine, VcsRepo, and BusPublish live there; each system’s interface documentation references these types rather than re-describing them, so per the interfaces design, spec and contract “cannot drift — they are one artifact, not two that need reconciling.”

The crate exists because Rust forbids cyclic crate dependencies — and that prohibition did real design work. The first Rust spec pass surfaced a circular dependency between the core and config systems that the Python-shaped design had never exposed. The fix (a contract trait plus composition-root injection) became the platform’s interfaces layer. The type system performed an architecture review.

This matters because agents write most of the code. cargo check enforces implementation-matches-contract for free: per the interfaces layer design, an agent doing a wire task “literally cannot drift from the interface.” Editing a contract type breaks every dependent at compile time — the typed form of the existing rule that modifying a requirement unchecks it, with the compiler enumerating exactly which wire tasks must be revisited.

The trace-annotation gate

The distinctive discipline: every code-bearing Rust line must sit under an active // @R# annotation span tying it to a file-local requirement in a per-file spec, which in turn covers design requirements. The span semantics, evidence kinds, and coverage joins are owned by the requirements page; the enforcement machinery by the wiki page. What Rust contributes is a codebase where this is actually livable — annotations scope to brace-delimited blocks, and the validator (sun wiki validate) checks coverage mechanically on every run.

The density is the striking number: roughly 37,600 lines of the workspace carry @R annotations — about 12% of all lines are traceability. The gate runs green today in the repository: zero errors, with the remaining findings all non-blocking audit-tier warnings.

The workspace, measured

All figures measured directly against the workspace on 2026-07-04. This is an engineered, in-repo-proven codebase, not a deployed one [built in-repo] — the CLI itself reports production_ready: false on workflow starts, and non-probe production starts fail closed.

MeasureValue
Cargo workspace members22 crates
Systems19, mostly one-system-one-crate
Rust source582 files, 317,657 lines
Test functions2,711 across 331 test files
Per-file specs250 under the wiki spec tree
External dependencies~362 crates in the lockfile
Annotation-bearing lines~37,600 (~12% of all lines)

The ~362-crate dependency closure is deliberately small for a 19-system platform: heavy things (Kafka, Temporal, Grafana, Docker) are owned services, not linked dependencies. The Kafka client is rskafka — pure Rust, no librdkafka C dependency (see the bus); workflows use the official Temporal Rust SDK at 0.4 (see workflows). Even binary size is engineered in the open: the debug-info story lives as a checked-in comment in the workspace manifest (541MB full DWARF, 83MB stripped), escape hatch included; the line-tables-only dev binary it settles on comes in at 224MB today.

What this costs

  • Build times and fat dev binaries. One workspace, one binary means cargo test --workspace wall-clock and 224MB dev binaries are the daily tax, mitigated but not eliminated by the debug-info profile.
  • A 156K-line CLI crate. The single-binary, thin-wrapper pattern concentrated roughly half the workspace in the sun binary crate (much of it integration tests and serve hosts). It is a compile-time and review hot spot.
  • Agent-written Rust has friction. The annotation rule applies to every edit; in practice files over-annotate even validator-exempt lines. The audit still counts 1,210 uncovered source lines (non-blocking, tracked), plus 340 doc-level and 49 mock-backed done-evidence warnings — honesty debt in numbers.
  • Prerelease Temporal authoring SDK. The Rust core engine is the battle-tested one all Temporal SDKs wrap, but the authoring API is Public Preview (May 2026): churn, thinner docs, some glue. An earlier analysis mislabeled this as engine immaturity; the correction is on record in the wiki.
  • No official Anthropic Rust SDK. The model transport is hand-rolled over raw HTTP, with the OAuth path a small reimplementation using Codex’s login crate as its spec — and a documented subprocess fallback if that proves too hairy.
  • A smaller talent pool. If Supernova is ever a shareable product, Rust narrows who can contribute — a real cost accepted knowingly, hedged only by the never-yet-used sane-boundary clause.
  • One superseded design on record: an agent once added a sun-kernel crate without asking; it was deleted (2026-06-22, Matt: “you should ask for permission before adding whole systems like that”). The crate DAG is now guarded socially as well as structurally.

The supporting cast

Supernova’s headline machinery — the delivery loop, the bus, the agents — only survives because ten quieter systems notice failures, restart services, guard the repo, and keep hostile email from becoming shell commands. Each gets a paragraph here, led by its most opinionated design choice — with one build-state note up front: every system below is at least [built in-repo] (real Rust with code and tests in the workspace), and at best [engineered, not deployed] where an opt-in end-to-end proof runs against a checked-in Docker Compose stack. None is a standing service.

monitor — the loop must close

The predecessor platform had Prometheus and Grafana already [live in automatt] — “barely used,” because nothing consumed the alerts. The rebuild refuses that fate: systems emit to Kafka, an OTel collector feeds Prometheus and Grafana, and alerts flow back onto the bus, where a listener agent named Sentinel consumes and acts — “it’s whole circle of life” (Matt). Sentinel is an agent, not a subsystem (Matt’s ruling, 2026-06-10) — it investigates and escalates but cannot file issues, which is reserved for a judgment principal. Sentinel can’t report its own death over the bus it watches, so an out-of-band watchdog and a synthetic-canary loop are first-class requirements. Audits split (D7, 2026-06-18) into fast mechanical checks that write artifacts and a small agent-led pass that reads them and applies judgment — deliberately not automatt’s expensive swarm of eight ephemeral agents each re-reading the repo. The full stack runs today only as an opt-in test: post an OTLP metric through the collector, watch a real metric-backed Grafana alert land on the monitor bus [engineered, not deployed].

test — heavy E2E on hardware you own

Test earned system status by weight — “if it’s heavy enough to worry about RAM, it’s heavy enough to be its own system” — and by the owned-infrastructure definition of “local” that excludes every hosted, metered CI product: no GitHub runners, no per-run billing. A run stands up a full real stack (Kafka, Temporal, Postgres, mocked externals) once per batch, not per case, because concurrent spin-ups stress a 64GB box; isolation is absolute between batches. The sharpest choice is a deletion — smoke testing, removed from the lifecycle entirely (delivery tells that story); field truth now comes only from monitor’s passive Prometheus assertions. A ~95% coverage gate applies to the batch’s changed code, and a failed run carries the implicated wires so the issue system boots them back to in-progress [built in-repo]; remote offload to the owned Proxmox server is explicitly future work [supernova design].

review — stamps that die when the code changes

Review is “the enforcement MECHANISM, not the rule-store”: each system’s own invariants list is what gets checked against a touching patch, so declaring an invariant is registering it. Merging takes two stamps — primary and architecture/safety, either order — keyed to the reviewed content hash: a post-stamp change silently drops the stamp, so nothing merges stale (a fix for a real automatt bug). A third review type gates feature closure: an independent agent — neither implementer nor closer — confirms real usage at least twice, “separation-of-duties applied to closure, the same way the double-stamp applies it to merge.” Stamps live as fields on the issue record, written in the same transaction — no separate review store — and bypass exists only as a recorded approval-flow elevation, never a silent override [built in-repo].

ops — the motor neurons

Ops is where “restart” lives (Matt, 2026-06-04: “where else does ‘restart’ go? restart, update, status”): start, stop, and upgrade the owned fleet — Kafka, Temporal, Postgres, Prometheus, Grafana, the agent runtime — all Docker Compose and systemd on owned machines, explicitly not cloud IaC. The boundary with monitor is anatomical: “monitor = sensory (afferent)… ops = motor (efferent)” — monitor detects, a bus reactor fires, ops restarts. Ops also holds the sole sanctioned exception to everything-rides-the-bus: a bus-independent Kafka broker health probe, because you cannot ask a dead bus whether the bus is dead. Resource governance is deliberately soft (D6): no hard caps, pressure answered by “reclamation of rebuildable state, not enforced ceilings.” Container bring-up is real today — a primary container plus per-project swarms, source mounted read-only — and a checked-in inventory reports all nineteen systems production-ready only when every service has been started by hand; the default fails closed [engineered, not deployed].

ingest — hostile by default

Ingest’s premise: external input is “hostile by default until a transport-verified sender says otherwise.” Trust tiers derive from the authenticated sender, never the source channel, and taint propagates — a policy can never auto-approve unknown-external input above minimal risk. The most opinionated stage is the capability-stripped reader: classification runs under a permission profile denying network, tools, and external sends, so prompt injection is contained because the reader can do nothing even if the content tells it to. What escapes is a typed, versioned Recommendation record — “the SCHEMA is the security boundary” — then two human gates: intent (“act on this at all?”) and quality (“execute THIS exact produced thing?”). “A denial at either gate is not a failure — it is a designed branch”: gate-two denials park a Temporal workflow that resumes when a revised artifact arrives. The operator path, with a live authenticated Discord-webhook-to-issue proof, works today [engineered, not deployed].

chat — internal only, on purpose

Chat owns channels, DMs, threads, and identity-bound delivery, and does nothing external — all outward transport belongs to the link system. Discord is a link adapter, not a chat backend: inbound messages are re-emitted and restructured into internal chat semantics rather than mirrored 1:1, because third-party message shapes don’t map onto chat’s channel/thread/identity model. Interruption is structural, not textual: an urgency ladder (D55) runs from idle-read to between-turn steering to permission-gated interrupt to compact-then-context-switch, with defaults low and the old !!! bang-markers removed as a cross-system syntax (2026-06-22) — surviving only as a Discord-inbound convention parsed onto the ladder. One invariant exists purely because of an automatt incident — a self-message can never reach interrupt level — and channel-post authority is capability-group membership, “never a hardcoded agent name” [built in-repo].

vcs — git with numbered laws

Vcs “carries the platform’s most dangerous failure modes” — orphan worktrees, half-rebases, a crash in the window between rebase and merge — so its entire reason to exist is a set of numbered, citable invariants review can block on: never cherry-pick, ff-only merges to shared branches, never reset --hard on dev/main, never stash, atomic worktree create/teardown, and a two-step ship (rebase then ff-merge) that is “crash-window-atomic and re-runnable.” The distinctive gate (D58): merge-to-main carries an approval decision on top of the capability check — “the cap-group decides who may drive the merge; the approval decision decides whether this specific merge proceeds” — while ordinary worktree commits stay ungated. A live agent can drive the full ship today: approved record, real rebase, real fast-forward, provenance events replayed to the owned broker [engineered, not deployed].

config — one file, guarded by the OS

Matt’s founding spec (2026-06-04): “GIANT YAML FILE! cli to manage it… each system gets its own top level.” One config.yaml replaces the predecessor’s scatter of env files and per-tool configs, with per-project overlays cascading over global defaults (D51/D62). The unusual choice is who guards writes: an OS-level file permission on the whole file, never a runtime permission call — “config never calls permission, which dissolves the config-permission bootstrap deadlock” (D62). CLI and library are dumb writers that never emit; a single inotify watcher is the sole event emitter (D31), diffing against last-known-good and publishing section-update events that trigger hot reloads. There is no outbox and no audit table: “the file is the durable record” — hand-editing is allowed-but-discouraged, and the watcher keeps last-known-good and screams. Watcher service, schema validation, and rollback run today; the OS/container write gate still awaits proof from a real running container [engineered, not deployed].

auth — one identity object, no vault

Auth is who you are; permission is what you may do — a boundary defended by mirror invariants (“auth MUST NOT make authz decisions; permission MUST NOT own credential material”). Auth is the sole owner of the canonical Principal contract (D4): every other system stores only a principal_id reference, closing the seam where agent, chat, and approval each half-owned an identity. Its contrarian call is the secrets substrate: not HashiCorp Vault (“too heavy for a single owned box”), not AWS Secrets Manager (off-owned-infra) — a sops/age-style encrypted-local file store instead. An AES-GCM store with no-plaintext-at-rest evidence exists today [engineered, not deployed]; the credential-lifecycle contract for external integrations (D49) is [supernova design].

core — the substrate with self-respect

Core is a different kind of system: horizontal, owning framework concerns and never a vertical domain’s rules. It exists because scattered utilities kept accumulating occupants — in Nova’s words, “‘util’ is junk-drawer name; ‘core’ is the same stuff with self-respect” — and it is pointedly not named sun, because “a system named after the CLI that hosts every system’s CLI is circular.” It owns CLI dispatch, system scaffolding with 5-part-shape validation, the stateless client library every surface shares, and the config schema registry (D63). A validator binds contract to implementation: core must implement exactly each system’s declared interface — no orphan commands, no undocumented commands. The frontend is ruled a renderer, not a system (2026-06-20): “CLI = text layer; UI = rendering layer; both stateless, neither owns state,” each view owned by its host system. Framework, dispatch, and scaffolding validation are [built in-repo]; the web renderer is [supernova design] — no shipped UI.

What this costs

Ten systems means ten boundary disputes — monitor-vs-ops (“monitor aggregates, ops probes”), chat-vs-link, auth-vs-permission — each split buying clean invariants at the price of seams that reactors must bridge and reviewers must know. Some of the sharpest choices are admissions of past failure: smoke testing wasn’t refined, it was deleted (D68) after causing real bugs; the audit swarm was replaced, not optimized; Grafana Alloy and bang-markers were superseded; a refactor system was removed outright. And the gap is uniform: the readiness dashboard itself says “the remaining gap is not missing proof machinery; it is production/live-substrate readiness,” and flags that status words “can still conflate” specced, implemented, in-repo-proven, and live — the exact masquerade this page’s tags exist to prevent. Nothing here runs as a standing service: the evidence is real; the deployment is not yet.

The landscape, honestly

Every claim on this site is cheaper to evaluate against what already exists. This page compares Supernova to its four nearest neighborhoods — autonomous coding agents, agent orchestration and durable execution, requirements traceability, and self-hosted automation with its caching economics — and for each one states what the incumbents do better. Most individual Supernova ideas exist somewhere in this landscape; the argument of this page is narrower than “nobody does this,” and it ends by saying exactly what remains.

Autonomous dev agents

Devin, OpenHands, SWE-agent, Factory’s Droids, Google Jules, and GitHub’s Copilot coding agent all take an issue, write code, run tests, and open a PR. Running tests and linters before claiming done is universal; LLM critic agents reviewing LLM output are common (Jules ships two critics, Factory a dedicated Reviewer Droid, Devin reviews its own PRs). Copilot’s coding agent has the strongest mainstream closure discipline: it respects branch protection, and the person who assigned the issue cannot approve the resulting PR.

What they broadly lack is a deterministic closure gate above CI. Closure means “checks green plus a human merged it” — the checks are generic (tests, lint, security scans), not traceability to requirements. The nearest existing primitive — Claude Code and Codex hooks, deterministic gates that can block an agent from claiming done until tests pass — is per-user configuration, not a platform invariant. The research literature on reward hacking (agents commenting out failing tests, hardcoding outputs, claiming unimplemented changes) is the strongest external argument that this gap matters. Supernova’s answer is described on the requirements page: a requirement cannot close while it has planned-only evidence, open TODOs pointing at it, or uncovered changed lines — and the validator enforcing that already gates Supernova’s own development, its one daily-exercised component. The surrounding issue and delivery machinery is [built in-repo].

The reverse is stark. Devin and Factory are production systems with enterprise customers; OpenHands is MIT-licensed with over 75k stars, hundreds of contributors, and a public benchmark suite (53–77% on SWE-bench Verified, depending on model and evaluation setup). Supernova has no external users, no benchmark results, and no UI beyond a CLI. The spec-driven wave — AWS Kiro, GitHub Spec Kit — is the closest commercial cousin of Supernova’s requirements-first story, and it ships today; its traceability is generated and human-reviewed rather than validator-enforced — which is the entire difference, and the only one.

Orchestration and durable execution

Temporal defines the durable-execution category, and Supernova does not compete with it — it composes it. Restate, Inngest, Hatchet, and DBOS are credible self-hostable alternatives; DBOS in particular has the best “no new infrastructure, no metered billing” story in the category. On the framework side, LangGraph is the most production-deployed agent orchestrator, and Microsoft’s Agent Framework 1.0 (April 2026) is the closest big-vendor analog for durable multi-agent workflows with human-in-the-loop.

Two observations from this neighborhood. First, the industry default is retry-first: Temporal retries by policy, Restate auto-retries transient errors, Inngest and Hatchet retry into dead-letter queues. Temporal’s Activity Pause (public preview) adds operator intervention as an escape hatch. Supernova inverts the default: park-on-failure — a failed durable step stays alive at zero compute, awaiting an explicit resume, with the failure filed as work (ratified 2026-06-10) — is the platform posture, not an ops tool [engineered, not deployed]. Second, the pieces combine pairwise everywhere but not three ways:

flowchart TD
    K["Kafka event bus"] ---|"Confluent: agents on Kafka"| A["Agent runtime"]
    A ---|"Temporal + OpenAI Agents SDK, GA 2026"| T["Temporal durable workflows"]
    T ---|"enterprise integration pattern"| K

Each edge of that triangle is shipped and evangelized by someone. A single opinionated product shipping all three vertices — Kafka bus, Temporal workflows, and a multi-agent runtime — as one self-hosted platform did not surface in any search; enterprises assemble it bespoke. The closest single-vendor bundle is Inngest — events plus durable steps plus an agent framework (AgentKit) — but its event system is proprietary rather than Kafka, and it is TypeScript-centric and cloud-first. Supernova’s version is [built in-repo], and it inherits the cost: Temporal is heavy (four server services — frontend, history, matching, worker — plus persistence plus an application worker fleet), its Rust SDK is only in public preview, and Supernova runs this with a team of approximately one.

Requirements traceability

The requirement→test→coverage join is not novel; it is mandatory, standard practice in avionics and automotive. DO-178C requires structural coverage achieved by requirements-based tests, and toolchains from Parasoft, LDRA, and VectorCAST automate the join against DOORS, Jama, or Polarion. In open source, StrictDoc validates source markers in CI, OpenFastTrace fails builds on broken trace chains, and sphinx-needs runs in automotive projects with over a thousand engineers. The single closest comparable is tracey: a Rust-built spec-coverage tool with CI-gating queries, an MCP server, and bundled Claude Code skills that teach agents its annotation syntax — concrete, shipped proof that “LLM agents maintaining trace annotations” exists outside Supernova.

What no single found system spans is the integration: one validator covering the requirement DAG, per-file specs, line-level annotation coverage of changed code, typed evidence kinds, coverage-report joins, and a decisions ledger whose entries carry verbatim operator provenance and formal supersession — with agents forbidden to close requirements without satisfied evidence as a platform rule rather than a reporting convention. ADR practice has had supersession and immutability since 2011; what ADR tooling lacks is the verbatim-provenance discipline and any machine linkage into a validator. The combination appears to be new. The ingredients are not, and a determined engineer could compose tracey, StrictDoc, and ADR tools into a decent approximation.

The reverse: the incumbents are proven at scales Supernova has never seen, and the certified toolchains carry qualification evidence regulators accept. Supernova’s stricter per-line rule is unproven outside one project, and strictness alone is not a moat.

Self-hosted automation and caching economics

Huginn promised “agents that monitor and act on your behalf” in 2013, a decade before LLMs; Supernova shares that ethos exactly and its mechanism not at all. n8n is the mature center of the self-hosted automation category, with first-class AI agent nodes and a local-inference kit; Windmill is the closest architectural cousin — Rust engine, self-hosted, durable jobs, first-class approval steps. None of them has a traceability layer, a decisions ledger, or a tiered approval policy engine; Windmill’s approval steps are per-step workflow constructs, where Supernova’s approval engine evaluates a closed, ordered risk enum (read < low < medium < high < critical) against trust policies, failing closed to human review [built in-repo].

On caching: the mechanism behind Supernova’s zygote fork is documented vendor behavior, not an invention. Anthropic prices cache reads at 0.10x input and refreshes the TTL free on every read — the load-bearing fact for keeping a warm parent alive. Claude Code ships fork subagents (currently opt-in) that reuse the parent’s cached prefix; SGLang’s RadixAttention has a native fork() primitive; Anthropic themselves document deliberate pre-warming. What did not surface anywhere is a persistent, platform-managed, fleet-wide warm parent from which heterogeneous agents fork on demand, integrated with the approval and traceability machinery — an integration novelty, no more, and [built in-repo] with a cold-boot fallback for when the cache assumption fails. The irony is noted in Supernova’s own research: the cleanest version of the pattern on truly owned hardware is a local vLLM or SGLang stack with no TTL and no metered pricing at all.

Synthesis

CapabilityField stateSupernova’s position
Tests/lint before claiming doneUniversalNot a differentiator
LLM critics reviewing agent outputCommon (Jules, Factory, Devin)Not a differentiator; deterministic checks added on top
Durable agent executionTemporal, Restate, DBOS, MS Agent FrameworkComposed, not competed with
Agents on KafkaEvangelized pattern (Confluent)Shared; differs in pairing with Temporal, on owned hardware
Requirement→test→coverage joinStandard in DO-178C practice; tracey/StrictDoc in OSSDiffers in integration breadth + agent-closure enforcement
Decisions ledger, verbatim provenance + supersessionNo product match found; ADRs are the manual cousinGenuinely uncommon
Park-on-failure as defaultRetry-first everywhere; pause as ops escape hatchInverted default [engineered, not deployed]
Cache-fork agent spawningShipped (opt-in) in Claude Code; native in SGLangProductized as a fleet primitive, not a new mechanism
Maturity, community, UI, hosted convenienceEvery comparator has someSupernova has none

The sober version: almost every piece exists somewhere. The uncommon thing is the specific combination — a machine-checked requirements-to-code-to-evidence spine, decision case-law with verbatim provenance, an owned-hardware event and workflow substrate, and cache-fork agent economics — held together in one self-consistent personal platform, with the traceability spine already governing the platform’s own construction. That combination is unproven at scale, and this page is the record of what it is being measured against.

What this costs

The comparison cuts both ways. The composability threat is real: tracey plus StrictDoc plus Temporal plus Claude Code hooks approximates a large fraction of Supernova’s story using maintained tools with communities behind them, and that fraction grows every quarter — spec-driven development went from niche to AWS-and-GitHub mainstream in about a year. The zygote economics rent a provider’s cache behavior: exact-prefix brittleness means a changed tool definition cold-starts the fleet, and TTL regressions have been observed in the wild. The three-layer substrate is enterprise kit operated at personal scale, which is either the point or the problem depending on the week. And every system named above has users finding its bugs; Supernova has one, finding them serially.

The long view

Supernova has an unusual endgame: a platform bootstrapping itself in order to ship as something stable — self-improving scaffolding around an artifact meant to hold still once it ships.

This page covers where the project is deliberately headed, the control-loop framing that shapes every mechanism on this site, and — because build-state honesty is the house rule — the specific things that have not been proven yet and could still sink it.

Ship mostly finished, then spin off

The destination was fixed by the 2026-06-10 builder ruling, quoted in full on why this exists; the route has since been superseded — development moved onto Supernova’s own systems, and “Supernova is bootstrapping itself” (Matt, 2026-07-05) is the standing word. Builder throughput is still the schedule (finding F15); the builder is increasingly the platform itself. Two clauses of the original plan survive untouched:

  • Share the product, not the instance. The origin constraint — you can’t fork a self-improving system — means what gets shared is the git-shippable artifact. A collaborator clones Supernova; nobody gets a login to Matt’s automatt. Multi-tenancy of humans was explicitly dropped (2026-06-20); projects are the only tenants.
  • am-on-supernova is a maybe, not a milestone. Whether automatt eventually migrates onto a Supernova instance is, per the bootstrap doc, “evaluated against the shipped product, not a build milestone the schedule depends on.” If the migration never happens, the plan still counts as complete.

The recursive-self-improvement story — the loop is real and now runs through Supernova’s own systems, while the shipped artifact stays deliberately stable — is told on why this exists. What matters for this page is the consequence: the artifact ships clean, and everything below is about keeping a non-self-modifying artifact provably correct.

The platform as a control loop

The deepest framing in the design corpus, and the one this site keeps circling back to, is that the whole platform is a feedback controller. Matt’s keystone phrasing (2026-06-23): “tasks are the imperative part that enforce the declarative part.”

flowchart LR
    R["Requirements DAG: the setpoint"] -->|"unsatisfied gap spawns"| T["Tasks: the actuator"]
    T -->|"completed work produces"| E["Evidence: the sensor"]
    E -->|"satisfies requirements"| R
    E -.->|"decays, reopening them"| R
  • Requirements are the setpoint — declarative statements of what must be true, each naming the proof that closes it. The wiki owns them.
  • Tasks are the actuator — feat/wire/bug issues that drive declarative state toward satisfied, flowing through the delivery lifecycle. The issue system owns them.
  • Evidence is the sensor — typed, observed proof. The monitor system owns the ledger, and self-attestation is prohibited: evidence comes only from real producers such as test runs, review stamps, and field metrics.

The loop’s defining property is that closure is non-monotonic [supernova design]: “done is rented, not owned — you do not finish a requirement, you keep it satisfied.” A done requirement reverts when its evidence decays, and decay is per-evidence-kind (the requirements page owns the mechanics). The set of currently-down requirements is the live defect surface — there is no separate “what’s broken” list. System health becomes a gauge of how proven the DAG is right now, not a checkmark earned once.

The same loop recurs at smaller scale as agent goal loops — one agent, one target, ACT → EMIT → CHECK → PARK → WAKE, parked at zero compute on the exact bus signal that would change the answer. The v1 goal-loop runtime is [built in-repo]: implemented and tested in the Supernova workspace, nothing deployed.

The full platform loop is a different build state. Decay detection, live evidence feeds, the assembled sensor path — that is [supernova design], not something running end to end anywhere today.

What must still prove out

Nothing on this site should be read as a running production system. The readiness dashboard is explicit that the in-repo proof surface can be green while production_ready:false. These are the open questions, stated as falsifiable bets:

Open questionWhere it stands today
Production deploymentZero of the nineteen systems (the set is open-ended) run in a standing deployment. Substrate-backed tests exist, but they are test-triggered against a local Compose stack, not a live installation.
The E2E gatesD82 (2026-07-03) assessed the platform-wide E2E harness at “~12%, disjoint stubs” — always-green fakes, hardcoded results — and gated all mass requirement closure on the harness becoming real first.
Kafka ops burden for one operatorThe decisions ledger itself notes “Kafka is heavy ops-wise (JVM/KRaft); NATS/Redpanda are lighter Kafka-ish options if ops weight matters.” Matt chose Kafka anyway. Owned infrastructure means one person operates Kafka, Temporal, Postgres, Prometheus, and Grafana with no managed fallback.
Agent-written-Rust velocityThe Rust workspace is real and large, with thousands of tests — but whether agents sustain that pace through integration and hardening, on a Temporal Rust SDK still in public preview, is unproven.
Traceability under speed pressureEvery changed Rust line must sit under an active @R# annotation and a per-file spec, enforced by validator. The discipline holds now; whether it survives a deadline is exactly the kind of claim that needs field evidence, not assertion.

The E2E row deserves the verbatim, because it is the project applying its own standard to itself. Matt, in the D82 ruling: “all the waves that follow sort of rely on e2e testing being real, coherent, and enforced, otherwise we’re gonna just need to do this all over again when everything gets fake-closed.” A platform whose central claim is proof-backed closure correctly identified that a fake test harness would re-fictionalize everything, and stopped closing requirements until the harness is real.

What this costs

  • Non-monotonic closure is expensive machinery. Decay detection, per-kind volatility, hysteresis to avoid flapping — the requirements page covers the mechanics, but a fair reviewer would call this a lot of moving parts in exchange for “done means still-true.”
  • Superseded designs are kept on the books — the self-hosting kernel, human multi-tenancy, smoke tests as closure proof, a fixed system count. The decisions ledger preserves each reversal struck-through with the ruling attached — both a discipline and a record of how often the design has changed its mind.

The builder-model costs — the two-systems window, the corpus-to-code ratio, the metered-model dependency — are enumerated on why this exists.

Strip the framing away and what remains is checkable: a requirements DAG where closure is evidence-backed and reversible, a validator that fails the build when code and spec drift, a decisions ledger where every ruling terminates at a dated human quote, and a builder that already pushes twenty-plus tasks overnight [live in automatt] while the clean rebuild accumulates in a Rust workspace behind it.

The bet is that “done is rented, not owned” is what software maintenance actually looks like when you stop pretending otherwise, and that the first system built around that premise from day one will feel obvious in hindsight. The proving ground is scheduled: a real E2E harness, a standing deployment, and a spin-off. Until those land, the project’s own rule applies — under-claim, and let the evidence close it.