UNI Universal Natural Intelligence

Wiki · Architecture & Decisions

Phase 3 — Registration, verdict authorship, and the anchor

Architecture & Decisions · docs/control-plane/phases/PHASE-3.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-3-RESULTS.md · item 3.6 landed PARTIAL, 3.7 a standing known-fail · Written from: PHASE-2-RESULTS.md, not from Phase 2's expectations Bound: SP.ControlPlane.{Registry, Verdict, Anchor} in the root zero-dep app of UNI.Minecraft. A verdict may be authored in this phase. No row is written to the real evidence/gates.ndjson, and no P-level moves. Authorises: ADR-0006


0. What Phase 2 changed about this phase

Three things, and the first is not a build item — it is a question that must be answered before the code that would answer it wrongly gets written.

  1. The canonical ledger violates its own schema twelve times (PHASE-2-RESULTS.md §4.1). Phase 3 builds the thing that authors rows. It must not author its thirteenth instance, and it must not silently normalise the twelve. The remedy is an operator decision and it blocks item 3.1.
  2. The hash chain has no anchor, so tail truncation is undetected in practice (§4.2). Ledger.verify/2 already accepts one; nothing holds one. Phase 3 makes the anchor a real artifact.
  3. A pre-registered verification command fails and it is not ours (§4.3). mix format --check-formatted fails on lib/sp/brain/language.ex, committed with CRLF. Inherited here as item 3.7.

1. The operator decision that gates item 3.1

Twelve canonical rows carry "pre_registration_path": null, which the schema forbids. What is the remedy?

ANSWERED 2026-07-25 — the operator chose option A. Item 3.1 is DONE.

Executed the same day. Two corrections were made before acting, and are recorded rather than smoothed away:

  1. Eleven rows, not twelve. Twelve violations across eleven distinct gate namesbroadcast-test-stages-honest accounts for two of them. My recommendation said twelve; it was wrong.
  2. "The ledger conforms" can only mean the effective state. Append-only means the twelve originals stay at rows 112-123 and stay non-conformant forever. Conformance is a claim about the last row per gate name — what render_gates.cjs, UNI TRACK and Gaia's gates seat all resolve to. The stronger claim is not available and is not made.

And the first attempt was wrong, and was rolled back. The ledger has mixed line endings — 58 CRLF, 137 bare LF, ending on a bare LF. The appender asked whether CRLF occurs anywhere and so chose the minority terminator, then added a spurious separator, leaving an undeclared blank line in canonical evidence. Caught by git diff --numstat showing 12 added lines for 11 rows; rolled back to the exact pre-write digest before anything was committed. Two permanent fixes: the terminator now comes from the last line, and a five-condition post-write self-check restores the original and exits non-zero if the write cannot prove what it did.

sha256 34084835...bab1514 -> 964ea25c...1d8a4c44 · 195 -> 206 rows · 11 added, 0 removed
render_gates: 109 gates -> 92 PASS · 4 PARTIAL · 1 FAIL · 12 PENDING (tally unchanged)

Receipt: docs/receipts/control-plane/phase3_item31_schema_correction_2026-07-25.md in UNI.Minecraft. Red at b649683, green at 0abc2ba.

A gap this exposed and did not close: the mutation was not recorded in a Control Plane ledger entry. SP.ControlPlane.Ledger has structure but no persistence — Phase 2 built the shape, not a store. So the audit trail for the Control Plane's first write to canonical evidence is a git commit and a receipt: the very mechanism this body exists to replace. That becomes a PHASE-4.md build item, alongside a home for the anchor item 3.6 needs.

The original three options are kept below as the decision record.

option what it means cost
A — append twelve corrective rows each superseding row carries "" instead of null, keeping every original row intact and the correction visible in the append-only record twelve new rows; the ledger grows; the history shows the correction, which is the point
B — amend the schema to admit null "type": ["string", "null"], and null becomes an honest "no pre-registration exists" one line; but it retroactively legitimises rows written before anyone decided that, and "" already means the same thing in 114 other rows
C — leave the disagreement standing, pinned what Phase 2 did: the twelve are named, a thirteenth fails the suite, a silent repair fails the suite no work; but the ledger stays non-conformant to its own schema indefinitely

This is not mine to pick. Option A is the one that matches the append-only discipline and the existing convention ("", not null, in 114 rows), and it is what I would propose — but it writes twelve rows to the canonical ledger, which is exactly the kind of act that requires a human decision rather than an agent's judgement.

Item 3.1 does not start until this is answered. Answered and executed; see above.

2. Pre-registration — written before execution

# item expected outcome falsifier
3.1 Remedy the twelve non-conformant rows DONE 2026-07-25, option A the ledger's effective state validates neither pre-registered falsifier fired — no row was edited in place (11 added, 0 removed) and the validator was not widened. A different defect did fire: the appender used the wrong line terminator and left an undeclared blank line. Rolled back to the pre-write digest, fixed, re-run behind a post-write self-check.
3.2 SP.ControlPlane.Registry — register a gate before its run a registration entry carries pass_condition, falsifies_condition, pre_registration_path, and lands in the ledger before any run entry that references it a verdict is authored for a gate with no preceding registration entry
3.3 SP.ControlPlane.Verdict — author PASS|PARTIAL|FAIL|WITHHELD|PENDING, and nothing else a verdict is a controlled word plus a receipt reference, never a number a numeric or percent score is accepted as a verdict
3.4 Structural refusals from ARCHITECTURE.md §7.1 a verdict with no pre-registered gate, a percent score, or a bare PARTIAL that does not name its holding sub-claim is refused, and the refusal names what is missing any of the three lands
3.5 Two-party authorship — the co-signer may not be the proposer a mutation whose authorization.granted_by equals its actor is refused an actor approves their own change
3.6 SP.ControlPlane.Anchor — hold the ledger's expected head and length outside the chain Ledger.verify/2 is fed from a real anchor artifact, and tail truncation is detected in practice rather than only in a test a chain is verified without an anchor and reported as sound
3.7 Inherited: mix format --check-formatted either lib/sp/brain/language.ex is normalised to LF in its own commit, separate from any evidence commit, or the failure is recorded as a standing known-fail with its reason the reformat is buried inside a Phase 3 evidence commit

Standing expectation: pure, offline, deterministic Elixir. No hex dependency. No Phoenix. No change to ui/. The real evidence/gates.ndjson is written only under item 3.1 and only on the operator's explicit answer to §1 — every other item uses fixtures in test/fixtures/control_plane/.

3. Red tests, named before they are written

test must fail before the code exists, for this reason
test/sp/control_plane/registry_precedes_run_test.exs a verdict is authored for a gate that was never registered
test/sp/control_plane/registry_prospectivity_test.exs a registration entry can be appended after the run entry it claims to precede
test/sp/control_plane/verdict_vocabulary_test.exs verdict: 0.93, "93%" or "MOSTLY_PASS" is accepted
test/sp/control_plane/verdict_partial_names_subclaim_test.exs a bare PARTIAL with no holding sub-claim is accepted
test/sp/control_plane/verdict_requires_receipt_test.exs a verdict lands with no receipt reference
test/sp/control_plane/cosigner_is_not_proposer_test.exs actor == authorization.granted_by is accepted
test/sp/control_plane/anchor_detects_truncation_test.exs a truncated chain verifies against a real anchor artifact
test/sp/control_plane/ledger_schema_conformance_test.exs DONE the canonical ledger contains a row the schema rejects and nothing fails — observed red at b649683 (6 tests, 4 failures), green after

Each is committed red with its failure output recorded, then made green. Where red-then-green is not achieved — including a guard that passes vacuously because its subject does not yet exist — that is stated, and the guard is mutation-tested at green before it is counted. Phase 2 did this and it is now the standing procedure, not a one-off.

4. Verification

cd ~/Documents/UNI.Minecraft
mix format --check-formatted                # see item 3.7 — known pre-existing FAIL on lib/sp/brain/language.ex
mix compile --warnings-as-errors --force
mix test                                    # offline; deps: [] unchanged
mix test test/sp/control_plane
git diff mix.exs                            # MUST be empty
sha256sum evidence/gates.ndjson             # unchanged unless item 3.1 was authorised
node viewer/gaia/verify_gaia.cjs            # 12 checks PASS; 8 drift signals
node viewer/gaia/gaia_lint.cjs              # 0 violations

Acceptance: all eight red tests recorded red, then green, with every vacuous guard mutation-tested. mix.exs unchanged. mc_test.exs untouched. verify_gaia still passes gaia-drift-surfaced. evidence/gates.ndjson byte-identical unless §1 was answered A, in which case its diff is exactly twelve appended rows and nothing else.

Rollback: additive under lib/sp/control_plane/. Item 3.1, if taken, is append-only and therefore not rolled back by deletion — it is corrected by a further superseding row, which is the discipline working.

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 — item 3.1 begins in this state and does not leave it without a human answer.

5. Explicitly not in this phase

Run execution. The pairing guard. Rooms, airlocks and keys. A new Gaia seat. The lab view. Any Phoenix code. Any change to ui/. Moving a P-level.

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

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

PHASE-4.md must carry:

  1. Every Phase 3 disposition, including each falsifier that fired.
  2. The operator's answer to §1 and what was actually done about the twelve rows.
  3. Whether the anchor (3.6) made tail truncation detectable in practice, or only in a test.
  4. Ledger persistence. Carried from item 3.1: the Control Plane's first write to canonical evidence was not recorded in its own ledger, because the ledger has no store. Until it does, the Control Plane's audit trail is git — the mechanism it exists to replace.
  5. The gate ledger's mixed line endings (58 CRLF / 137 LF) as a standing hazard for every future appender, with the rule that took a rollback to learn: take the terminator from the last line, and prove the write afterwards.
  6. The Phase 4 build items — Run, Pair, and the run-status refusals F12–F18 from FAILURE-MODES.md — each with a red test named before it is written.
  7. Its own §6 requiring PHASE-5.md.

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

sha256 0fbb2c735317d1b3 — 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)

For the third phase, the plan was written from what the second phase observed rather than from what it expected. Its results are recorded separately, and the status line already tells you that one item landed only partly and one is a standing known failure.

The phase builds the parts that register a gate before it is run, and author a verdict in words rather than numbers. It also holds the expected head of the ledger — the list of results only ever added to — outside the chain, so that losing the end of it can be noticed.

The most interesting section is not a build item. It is a question the plan refuses to answer itself: twelve rows in the ledger that counts break the schema, and what to do about them is the operator's decision, not an agent's. Three options are laid out with their costs. The page later records the answer, and — unusually — records that the first attempt at carrying it out was wrong and was rolled back before anything was committed, along with the two fixes that came out of it.

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

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)

Written from the previous phase's observed results and committed in writing before execution, this third-phase plan already carries the outcome of two items in its status line: one landed partial, and one became a standing known failure.

An opening section says what the previous phase changed here. The first item is not a build task but a question that must be answered before code answers it wrongly. Twelve rows in the ledger that counts (a record only ever added to) break the schema the ledger is judged by. This phase builds the thing that authors rows, so it must neither add another instance nor quietly normalise the existing ones. The second is that the chain of linked entries has no anchor, so losing the end of it goes unnoticed in practice. The third is an inherited formatting failure on a file this work does not own.

The decision section is the most striking part. It states the question and lays out three options with their costs: append corrective rows, widen the schema, or leave the disagreement standing and pinned. It then says plainly that this is not the author's to pick, while naming which option he would propose and why. The answer is recorded afterwards, with two corrections made before acting. The count was eleven distinct names rather than twelve. And the claim that the ledger conforms can only mean its effective state, because a record only added to keeps the original rows non-conformant forever. The stronger claim is unavailable and is not made.

Then comes something a plan rarely contains: an account of getting it wrong. The first attempt chose the wrong line terminator, because the ledger has mixed line endings and the appender asked whether one kind occurred anywhere instead of looking at the last line. It left a stray blank line in the evidence that counts, was caught when added lines did not match the number of rows, and was rolled back before anything was committed. Two permanent fixes came out of it, including a post-write self-check that restores the original and stops if the write cannot prove what it did.

The page also records a gap it exposed and did not close: the write was not recorded in the body's own ledger, which has structure but no store yet. So the audit trail for its first write to the evidence that counts is a commit and a receipt, the file recording what was run — the very mechanism this body exists to replace.

The table then gives each remaining item its expected outcome and what would show it wrong. Registration must precede any run that references it. A verdict must be a controlled word plus a receipt reference, never a number. The structural refusals must refuse and name what is missing. A co-signer may not be the proposer. And the anchor must make truncation detectable in practice, not only in a test.

A second table names each test before it is written, with the reason it must fail first. A standing procedure is stated: where failing-then-passing is not achieved — including a guard that passes vacuously because its subject does not exist yet — that is said, and the guard is mutation-tested before it counts.

Verification, rollback and stop conditions follow, including that the one authorised write to real evidence begins in a stop state and does not leave it without a human answer. The exit condition requires the next plan to exist, carrying every disposition, every failure sign that fired, and several named hazards inherited from this one.

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