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:
| Part | Where it lives | What it is |
|---|---|---|
| Code folder | systems/<name>/ | the system’s logic and long-running services |
| Client library | sun_lib/<name> | the stateless typed front door |
| CLI namespace | sun <name> ... | thin wrappers over the client library |
| Wiki docs | the system’s wiki folder | mandatory 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:
| Concern | Decision | Why |
|---|---|---|
| Bus transport | Buy: self-hosted Kafka | the bespoke Python bus was “consistently painful + slow” |
| Bus reactor | Build | the event-to-action dispatch arm on top of the bought substrate |
| Workflow engine | Buy: self-hosted Temporal | durability, retries, observability; scheduling = Temporal Schedules |
| Monitoring | Rebuild: OTel + Prometheus + Grafana | the stack existed in automatt but was “barely used”; the rebuild wires it end-to-end |
| Storage | Buy: self-hosted Postgres | cross-cutting infrastructure, not a system |
| Secrets | Buy 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 tracking | Build | “a single type in a database”; buying eats lock-in for nothing |
| Wiki | Build, carry-over | “I like the way wiki works, no plan to change it” |
| Ingest | Build | nothing off the shelf does trust-tiered, injection-contained, two-gate triage |
| Test harness | Build: Rust sun-test | owned-hardware constraint disqualifies metered CI — no GitHub Actions, no SaaS |
| Everything else | Build / carry-over | bespoke 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.