UNI Universal Natural Intelligence

Wiki · Architecture & Decisions

Phase 2 — The ledger and the command path

Architecture & Decisions · docs/control-plane/phases/PHASE-2.md @ b909801f3db4 (hierarchical-aif/motor-stack) — opens the published snapshot 8b4b5935bcba

How to read this page

Three ways to read this page. Precise is the document itself, exactly as it is written in the repository. Plain and Clear were written for this website to help you meet that document — they are about it. They are not it, and they are not evidence.

This is the design record of the part of the estate whose job is to stop the rest of it claiming more than it has measured. It runs to architecture notes, numbered decision records, phase plans, and the results written after each phase ran.

It is for anyone curious how a decision was actually reached — what was considered, what was refused, and what the refusal cost. The decision records are the most durable part: each names one choice, the alternatives, and the consequence accepted in exchange. The failure-modes page is worth the detour, because it states each refusal as something you could go and test rather than as a promise.

Read the architecture page first. It opens by declaring itself part design and part built, which sets the tone for the whole section. Then the first decision record, then whichever phase interests you — read as a pair, the plan and the results page written afterwards, including the phases where a premise turned out to be wrong and the receipt says so.

What it is not: a description of running software, and not a complete record. Three documents from this area were withheld from publication, because they describe private infrastructure or the operator declined them; they are listed as withheld rather than quietly dropped, so you can see that they exist.

Your browser cannot switch reading levels, so the document itself is shown.

Precise — the source document

This is the document. Rendered from the repository at the commit above, with nothing rewritten for the web. A gate re-renders it on every deploy and fails the build if a single byte differs.

Status: EXECUTED 2026-07-25 → PHASE-2-RESULTS.md · Written from: PHASE-1-RESULTS.md, not from Phase 1's assumptions Bound: first code of the Control Plane. SP.ControlPlane.{Ledger,GateRow,Command} in the root zero-dep app of UNI.Minecraft. No verdict authored. No row appended to the real ledger. No P-level moved. Authorises: ADR-0006, ADR-0007


0. What Phase 1 changed about this phase

Phase 1 found that four of five drift signals compare different kinds of thing and can never converge. That is not a documentation problem, and it reshapes Phase 2 in three ways:

  1. The Control Plane's own drift detection must compare like with like — receipt-to-receipt, hash-to-hash — never prose to a file listing. Phase 1 is the worked example of how a comparison can be honest, mechanical, and still uninformative.
  2. A new work item exists: nothing detects chip-versus-canonical ledger drift. DONE 2026-07-25, out of phase order. drift.replica_ledger.* now compares the canonical ledger digest against each replica's, agent-captured via viewer/gaia/replica_ledger_probe.cjs. Three replicas, all DIFFERS, none holding evidence canonical lacks. See item 2.7.
  3. equal=false is not evidence of staleness. Any Control Plane surface that renders drift must show both sides, never a bare boolean.

1. Pre-registration — written before execution

# item expected outcome falsifier
2.1 SP.ControlPlane.Ledger — append-only, hash-chained append/2 links prev_hash; verify/1 walks the chain; tampering any past entry fails verification an entry can be edited or deleted with verify/1 still passing
2.2 SP.ControlPlane.GateRow — build + validate a row is validated against production/schemas/gate_row.schema.json in hand-written Elixir with stdlib JSON, no hex dep; supersedes chains a revision without mutating the superseded row a row missing a required key, or with a verdict outside the enum, is accepted
2.3 SP.ControlPlane.Command — the only writer every canonical mutation records actor, role, utc, unix_ns, prior, transition, authorization, evidence, resulting, hash any write path exists that does not pass through Command
2.4 Inherit the Door's law a read function performs no write and spawns nothing a read has a side effect
2.5 Zero-dep proven mix test runs offline with deps: [] unchanged; SP.Prop used for property tests a hex dependency is added to the root app
2.6 Like-for-like driftSP.ControlPlane.Drift compares only values of the same type (hash↔hash, verdict↔verdict) and refuses a cross-type comparison at construction a comparison is constructed between a prose string and a command output
2.7 Chip-vs-canonical ledger drift CLOSED AHEAD OF THE PHASE, 2026-07-25. Its falsifier — "a seat is built before the decision is recorded"fired: the operator ruled "build the seat" and I built it the same hour. The ruling IS the decision being recorded, so the item is satisfied, but not in the order this plan pre-registered. Recorded rather than back-dated. (fired; see left)

Standing expectation: every item lands as pure, offline, deterministic Elixir with no hex dependency and no Phoenix in the loop. The real evidence/gates.ndjson is not written in this phase — all tests use fixtures in test/fixtures/.

2. Red tests, named before they are written

Per LAB_PROTOCOL.md §II and the flagellum's documentation-first TDD, each test is named and its failure mode stated before implementation:

test must fail before the code exists, for this reason
test/sp/control_plane/ledger_append_only_test.exs editing entry n leaves verify/1 passing
test/sp/control_plane/ledger_chain_tamper_test.exs a truncated chain verifies
test/sp/control_plane/gate_row_schema_test.exs a row with verdict: "MOSTLY_PASS" is accepted
test/sp/control_plane/gate_row_supersedes_test.exs a revision mutates the row it supersedes
test/sp/control_plane/command_is_only_writer_test.exs a write succeeds outside Command
test/sp/control_plane/read_never_actuates_test.exs a read function mutates or spawns
test/sp/control_plane/drift_like_for_like_test.exs a prose-vs-file-listing comparison is constructible

Each is committed red with its failure output recorded, then made green. Red-then-green is proven, not asserted — where it is not achieved, that is stated rather than presented as compliance (H-AIF-G3's standing rule).

3. Verification

cd ~/Documents/UNI.Minecraft
mix format --check-formatted
mix compile --warnings-as-errors --force
mix test                                   # offline; deps: [] unchanged
mix test test/sp/control_plane             # the new suite
git diff mix.exs                           # MUST be empty — no dependency added
node viewer/verify_gaia.cjs                # 12 gates PASS; 8 drift signals surfaced (5 original + 3 replica-ledger)

Acceptance: all seven red tests recorded red, then green. mix.exs unchanged. evidence/gates.ndjson byte-identical (this phase writes no row). mc_test.exs untouched. verify_gaia.cjs still passes gaia-drift-surfaced.

Rollback: the module is additive under lib/sp/control_plane/; delete the directory and its tests. Nothing existing is modified except the addition of a moduledoc disambiguation line to SP.Producer (ADR-0006).

Stop conditions: STOP_TEST_REGRESSION if any existing test breaks · STOP_PROTOCOL_CHANGE_REQUIRED if a hex dep looks necessary · STOP_DESTRUCTIVE_ACTION_REQUIRED before any write to the real ledger.

4. Explicitly not in this phase

Authoring a verdict. Appending to the real evidence/gates.ndjson. The lab view. Rooms and airlocks. A new Gaia seat. Any Phoenix code. Any change to ui/.

5. Exit condition — the phase ends by starting the next

Phase 2 is complete only when PHASE-3.md exists, is committed, and is pre-registered in this same form — written from Phase 2's observed results, not from this plan's expectations. Passing all seven tests is not completion.

PHASE-3.md must carry:

  1. Every Phase 2 disposition, including each falsifier that fired.
  2. The recorded decision on chip-vs-canonical drift (item 2.7) and what it implies.
  3. The Phase 3 build items — Registry, Verdict, and the structural refusals from ARCHITECTURE.md §7.1 — each with a red test named before it is written.
  4. Its own §5 requiring PHASE-4.md.

A phase that closes without its successor has stopped, and stopping is legitimate only under a declared STOP condition.

sha256 f15f72022c058fb2 — of the original file, so what was ingested stays checkable.

Plain — written for this website, not the source document

Written for this website — not the document. This is a plain-language retelling, written to help you meet the document. It is not the source, and it is not evidence. It has not yet been checked by a person. (or choose Precise in the reading-level control above)

The second phase, planned before the work and from what the first phase actually observed rather than from what it had assumed. Its results are recorded elsewhere.

The phase builds the first real code of the body that runs the science. A ledger that is only ever added to, each entry locked to the one before. A validated gate row. And a single command path that is the only thing allowed to write. It is bounded — no verdict authored, no row appended to the real ledger, no confidence level moved.

A short opening section says what the first phase changed here. Because most of the disagreement signals compared different kinds of thing and could never converge, this phase's own comparison must compare like with like, and any surface showing a disagreement must show both sides rather than a bare true-or-false.

The tests are named before they are written, each with the reason it must fail first. The page states that red-then-green is to be proven rather than asserted, and that where it is not achieved this must be said rather than presented as compliance.

Plain · written 2026-08-01 by claude-opus-5 · not yet checked by a person · about the document whose sha256 is f15f72022c058fb2

Clear — written for this website, not the source document

Written for this website — not the document. This is a clearer retelling, written to help you meet the document. It is not the source, and it is not evidence. It has not yet been checked by a person. (or choose Precise in the reading-level control above)

Planned and pre-registered before it ran, the second phase was committed in advance and written from the previous phase's observed results, not its assumptions. It names its bound at the top: the first code of the body that runs the science, in the dependency-free root application. No verdict authored, no row appended to the real ledger (a list only added to), no confidence level moved.

It opens by saying what the earlier phase changed here. Most of the disagreement signals under watch compared different kinds of thing and could never converge; that is not a documentation problem, and it reshapes the plan in three ways. This body's own drift detection must compare like with like — one record of a run against another — and never prose against a file listing. A work item about copies of the ledger differing from the one that counts is struck through and marked done ahead of the phase, with a note explaining how. And an unequal reading is not evidence of staleness, so any surface rendering a disagreement must show both sides.

The table then gives each build item its expected outcome and the result that would show it wrong. The ledger must link each entry to the one before and fail verification when a past entry is tampered with; what would show that wrong is an entry being edited or deleted while verification still passes. The gate row must be validated by hand against an existing schema, using only the standard library, and a revision must chain without mutating what it supersedes. The command path must record who acted, under what authority, when, what the state was before and after, how it was authorised and on what evidence — and what would show that wrong is any write path that avoids it. A read must actuate nothing. The absence of dependencies must be shown, not asserted. And a comparison between two different kinds of thing must be refused at construction.

One row is unusual: an item that had been listed as a decision was instead built the same hour the operator ruled on it — exactly the outcome that item had named as showing it wrong. The page records this rather than back-dating it.

A second table names each test before it is written, with the reason it must fail first. The reasons: an editable entry, a truncated chain that still verifies, a row with an invalid verdict accepted. A revision that mutates what it supersedes, a write outside the one permitted path, a read with a side effect, and a cross-kind comparison being constructible. Each is to be committed failing, with its failure output recorded, then made to pass. The page states that this is to be proven rather than asserted, and that where it is not achieved, that must be said rather than presented as compliance.

Verification lists what must hold afterwards: every named test recorded failing and then passing, the build file unchanged, the real ledger byte-identical because this phase writes no row, and the user-owned test file untouched. Rollback is deleting the added directory, since the work is additive apart from one clarifying line of documentation.

Sections then list what is out of scope — authoring a verdict, writing to the real ledger, the lab view, rooms and airlocks, anything touching the web application — and give the exit condition. The phase is complete only when the next plan exists, committed and pre-registered in the same form, written from what this phase observed. Passing the tests is not completion.

Clear · written 2026-08-01 by claude-opus-5 · not yet checked by a person · about the document whose sha256 is f15f72022c058fb2