Wiki · Evidence & Verdicts
Phase 2 — the red run, recorded before any implementation
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.
Eighty-seven dated pages: receipts, pre-registrations, handoffs, validation records and review verdicts. A receipt is written at the moment a piece of work was checked. It names what was claimed, the commit and the seed, what was actually run, and the outcome in one of a small set of controlled words. Then it names what the work did not achieve. That last part is what makes it a receipt rather than an announcement. A pre-registration is the same discipline run in advance: the conditions that would count as a pass and the conditions that would falsify the claim are written down before the run, so neither can be adjusted once the numbers arrive.
That is why so many small dated stubs are an audit trail rather than noise. No one of them is meant to be a good read. The value is in the sequence and in the dates, because you can watch a prediction be registered, then the run happen, then the verdict land — sometimes against the prediction. Pages here record a falsified result, a rejected fix, a retracted overclaim, and a green receipt that turned out not to be reproducible from the commit that carried it. A record that carried only successes would be worth a good deal less than this one.
A gentle way in is to read a pre-registration first, so the shape becomes familiar, then a result page, then one of the corrections. This section sits off the main navigation on purpose: it is the record you check the rest of the site against, not the place to begin.
What it is not: documentation, and not a summary. Nothing here has been tidied in hindsight. Every entry reads as of its date, a later entry may overturn an earlier one, and the presence of a page is not a claim that its result stood.
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.
Date: 2026-07-25 · Repo: UNI.Minecraft @ bf50500 (gen2-runtime)
Plan: docs/control-plane/phases/PHASE-2.md in UNI-FLAGELLUM (§2, seven tests named before written)
Raw output: phase2_red_2026-07-25.txt
$ mix test test/sp/control_plane
59 tests, 56 failures
lib/sp/control_plane/ does not exist at this commit. Every failure is
UndefinedFunctionError against a module that has not been written — the tests
fail for the stated reason, not for an accidental one.
Red-then-green is proven per test file, not asserted
| file | failure mode pre-registered | observed in red |
|---|---|---|
ledger_append_only_test.exs |
editing entry n leaves verify/1 passing |
SP.ControlPlane.Ledger.new/0 is undefined |
ledger_chain_tamper_test.exs |
a truncated chain verifies | SP.ControlPlane.Ledger.new/0 is undefined |
gate_row_schema_test.exs |
a row with verdict: "MOSTLY_PASS" is accepted |
SP.ControlPlane.GateRow.validate/1 is undefined |
gate_row_supersedes_test.exs |
a revision mutates the row it supersedes | SP.ControlPlane.GateRow.supersede/2 is undefined |
command_is_only_writer_test.exs |
a write succeeds outside Command |
SP.ControlPlane.Ledger.append/3 is undefined |
read_never_actuates_test.exs |
a read function mutates or spawns | SP.ControlPlane.Ledger.new/0 is undefined |
drift_like_for_like_test.exs |
a prose-vs-file-listing comparison is constructible | SP.ControlPlane.Drift.observation/3 is undefined |
Three tests passed in the red state. Two of them passed VACUOUSLY.
This is stated rather than presented as compliance (H-AIF-G3).
| test | why it passed | vacuous? |
|---|---|---|
gate_row_schema_test.exs — "the schema this module hand-implements is on disk…" |
reads production/schemas/gate_row.schema.json directly; asserts the enums and additionalProperties: false that GateRow must reproduce |
No. It is a genuine precondition on the schema, and it would fail if the schema changed under the validator. |
command_is_only_writer_test.exs — "F10 — no module in lib/ other than command.ex calls the ledger writer" |
Path.wildcard("lib/**/*.ex") finds no offender because no Control Plane module exists yet |
Yes. It becomes load-bearing only once command.ex exists. |
read_never_actuates_test.exs — "this whole phase writes no row to the canonical ledger" |
scans lib/sp/control_plane/**/*.ex, which is an empty glob |
Yes. Same reason. |
Both vacuous guards are static source scans over a directory that does not yet exist. A source scan cannot fail before its subject is written. They are kept because they are the only mechanical statement of F10's real fence — Elixir cannot restrict callers at runtime — and they acquire force at the green commit, where the directory they scan is non-empty. The green receipt records their non-vacuous run.
One adverse result, recorded here and asserted in the suite
A hash chain does not detect truncation from the tail. A prefix of a valid
chain is itself a valid chain: every prev_hash still resolves and seq is
still contiguous from 1. verify/1 will return :ok over it.
Deletion from the middle is detected, because the successor's prev_hash no
longer resolves. Deletion from the end is not, and no amount of internal
hashing fixes that — detection requires an anchor held outside the chain
(the expected head hash and the expected length).
ledger_chain_tamper_test.exs asserts both: that verify/1 cannot see the
missing tail, and that verify/2 with an anchor can. The limitation is a
property of the mechanism, not a defect in this implementation, and it is
written into the test so it cannot be quietly forgotten.
Constraints held at this commit
mix.exsunchanged —deps: [], no hex dependency.evidence/gates.ndjsonnot written. Fixtures live intest/fixtures/control_plane/.test/sp/brain/mc_test.exsuntouched (user-owned).- No P-level moved. No verdict authored. No gate row appended.
sha256 8569968a523fd279 — of the original file, so what was ingested stays checkable.
Plain — written for this website, not the source document
This is the record of a test run made deliberately before the code existed, so that the tests could be shown failing for the right reason. Nearly all of them fail because the modules they call have not been written. Three passed anyway, and the page says outright that two of those passed for no good reason: they scan a directory that does not yet exist, and a scan over nothing cannot fail. It also records one adverse finding about the mechanism itself, which no amount of care inside the design can fix.
Plain · written 2026-08-01 by claude-opus-5 · not yet checked by a person · about the document whose sha256 is 8569968a523fd279
Clear — written for this website, not the source document
A red run. The tests were written first, run against a commit where the code they call does not exist, and the output was recorded before anything was implemented. The page opens with the command and the totals, then makes the point that matters: every failure is an undefined module, so the tests fail for the stated reason rather than for an accidental one.
A table pairs each test file with the failure mode it was written to catch and the failure actually observed in the red state. That pairing is what turns red-then-green from an assertion into something a reader can check file by file.
The most unusual section admits weakness. Three tests passed in the red state, and two of them passed vacuously, because they scan a directory of source files that does not exist yet. The page marks them as such in a table with a column that says plainly whether each was vacuous. It argues for keeping them anyway, since they are the only mechanical statement of a limit the language cannot enforce at runtime. They acquire force only at the green commit, where the later receipt, the file recording the run, shows it was not vacuous. The third pass is defended as a genuine precondition on a schema file that would fail if that schema changed.
Then the adverse result, stated as a property rather than as a bug. A hash chain does not detect deletion from the end, because a prefix of a valid chain is itself a valid chain: every link still resolves and the sequence is still unbroken from the start. Deletion from the middle is caught, deletion from the tail is not, and no amount of internal hashing fixes it. Detection would need an anchor held outside the chain, carrying the expected head and the expected length. The test asserts both halves, so the limitation cannot be quietly forgotten.
A short closing list records what did not move: no dependency added, no entry written to the list that counts, a user-owned file untouched, no verdict authored and no gate row appended.
Clear · written 2026-08-01 by claude-opus-5 · not yet checked by a person · about the document whose sha256 is 8569968a523fd279