Architecture
Three stores, one write path each. How Sirius, Ametrite, and Hayvenhurst fit together, what Sirius is allowed to write, and the five facts the design rests on.
Sirius sits between three stores and owns exactly one of them. The other two — Ametrite and Hayvenhurst — it touches only through their command-line interfaces. Every quantitative claim below points at a harness in benchmarks.
Three stores, one write path each
amt --json (all writes) HTTP :7777 + hayven CLI
│ │
.ametrite/ametrite.db ┌──────────────────┐ Hayvenhurst daemon + index
Ametrite owns writes │ sirius (Rust) │ Sirius reads read-only
▲ │ CLI · loop · │
read-only │ │ policy · bridge │
│ └─────────┬─────────┘
│ │ writes ONLY here
│ .sirius/sirius.db ← the ledger
│ ▲
┌────────┴────────────────────┴─────────┐
│ Sirius Console (Bun.serve, :1777) │
│ reads all three read-only; │
│ mutates by shelling `sirius --json` │
└────────────────────────────────────────┘
- Ametrite owns issues, claims, decisions, and the activity log. Sirius
writes it only through
amt … --json. - Hayvenhurst owns the code graph, entity claims, context packs, the
affected-tests gate, and fleet memory. Sirius uses the
hayvenCLI orhttp://localhost:7777. - The ledger (
.sirius/sirius.db) is Sirius’s only write target: run history, receipts, the worker roster, policy outcomes. It is an audit log, not a second brain — delete it and no work is lost, only the trail of how it happened. It is git-ignored and branch-invariant, because the ledger is a fact about work, not a code snapshot.
The design invariant: one write path per store, and Sirius owns only its own. Sirius never opens either parent’s SQLite for writing.
The ledger schema
Five tables — meta, workers, iterations, receipts, policy_events —
defined authoritatively in contracts. The bench harnesses
model these tables 1:1 so their measurements match what the real ledger reports,
and the console reads the same tables read-only, polling
PRAGMA data_version for live updates.
The five contract facts
Sirius is built on facts verified in both parent codebases. Any parent release
that breaks one is a Sirius-blocking regression — and sirius doctor checks them
live:
- Ametrite claims are hard locks.
BEGIN IMMEDIATE; zero double-claims under a 4-claimer race. Leases default to 900 s; re-claiming your own id is a heartbeat. - Hayvenhurst claims are hard locally. Overlap returns a synchronous
409at the daemon. Only oracle adjacency verdicts are soft (202, forceable). - Fleet memory is a plain supported write, not CRDT-synced — so reverse provenance needs no special surgery and stays machine-local.
- The gate exists and is measured. SAFE tier: 0 missed regressions across ~95 replayed bugs on 4 repos.
- Every Ametrite mutation has a
--jsonCLI form; every Hayvenhurst read/write has a CLI or:7777form. No MCP or proxy surface is depended on.
One iteration, exactly
The loop is claim → map → lock → brief → work → gate → receipt → release. Two rules carry the coordination guarantees:
- Claim order is law: issue first, entities second, release in reverse. A
409on an entity releases the issue back with a comment naming the blocker — never hold an issue while spinning on a code lock. - The gate is on the board: an issue cannot reach
in_reviewthrough Sirius with a failing SAFE tier.
What we measure, and where
| Metric | Target | Harness |
|---|---|---|
| Claim integrity | 0 double-assignments, 30-min / 4-worker soak | bench/soak.ts |
| Gate escape rate | < 2% undetected regressions | bench/gate-escape.ts |
| Provenance coverage | 100% of done issues carry a two-way receipt | bench/receipts.ts |
| Wasted-work ceiling | < 15% tokens on release-without-completion | bench/wasted-work.ts |
| Adaptive claiming | adaptive ≤ best static mode per completion | bench/claim-mode.ts |
| Loop overhead | < 1 s Sirius-added latency per iteration | timed in the live sirius run |
Today the harnesses report fixture-mode numbers — faithful simulations of the ledger and the parents’ hard-lock and gate semantics — so the targets are met in simulation and the harnesses are proven sound. Live numbers on real workspaces arrive with the binary; see benchmarks for each method.