resolution: V2 vindicated, my Rung B claim corrected, AC's probes=11 caveat; rule 28 on gated negatives

This commit is contained in:
alex 2026-09-08 21:43:00 -04:00
parent 479a0d28ae
commit 9eaec9ba2c
3 changed files with 335 additions and 1 deletions

View file

@ -396,8 +396,11 @@ Status flow: `backlog → in-progress → mapped → verified` (or `blocked`).
| SD self-reported a rule-21 shaped error | meta | verified | high | 100% | 2026-09-09 | Twice it ran `verify/design-rules/stock_designs.py` inside the **shared** sots-re clone to identify a save's players; **the script writes stock_designs.json as a side effect** and it restored the file with `git checkout -- <path>`. Clean afterwards, but that is exactly rule 21's shape - **and it would not have known if another lane had work in flight there.** Worth generalising: a read-only-looking script can have write side effects, so run analysis tools against a copy, not the shared tree |
| REVERSAL: THE TAIL DOES DRAW - W3's risk is REALISED | verify | verified | high | 100% | 2026-09-09 | **Lane AC overturns the "retired by evidence" conclusion I reported.** OnAllCombatDone_Tail consumed **1 RNG word per turn** in the state AC built, against **0 in its own control** (same guest, same build, same probe config, one End Turn on L3's turn-15 save, run immediately after). `TradeManager::Slot13RngCalleeA` - **entered 0 times in every measurement any lane had ever taken** - was entered **1x/turn on both instrumented turns**; CalleeB on the turn the roll succeeded; CreateRaidEncounter once. All probes installed=true, watchpoint canary PASS every turn. **THE RNG LEDGER AND THE STANDALONE'S GENERATOR MODEL NEED EXTENDING BY ONE DRAW SITE** |
| and the gate is a TECH, not container contents | verify | verified | high | 100% | 2026-09-09 | **Neither freighters nor a deployed spy is in the predicate** - AC disassembled the gate chain BEFORE building the state. `ServerTradeManagerImpl::vslot13` does not iterate routes or sectors; it iterates the **FLEET** vector and requires a fleet whose LocID resolves to a node of kind **2 (TradeSector)**, positioned **bit-equal** to the sector, whose owner's bit is set in the sector's **`tscr`** mask. `tscr` was **252 in every corpus save = exactly the six NPC slots**, and AC's own prediction P6 said that excluded real players and the callees would stay 0. **WRONG, AND INSTRUCTIVELY**: the mask is not fixed. Researching **`CCC_ComRaid` (Commerce Raiding, RP 12,000, one turn off CCC_FTLEcon)** takes tscr **252 -> 253** on every sector and sets the ServerPlayer flag serialised as **`CnRad`**. **The game says so in as many words**: before the tech, `Alpha Fleet cannot raid trade sector.`; after it the same click is accepted. **That dialog is the cheapest test of the whole chain** |
| CORRECTION: L3's own save falsified the freighter hypothesis | verify | verified | high | 100% | 2026-09-09 | L3 3.5 says "every trade sector has `tsnumflt = 0`". **Wrong about its own save**: `human-turn15-spyprogram.sav` sector TradeID 816 has **`tsnumflt 1`, `tsflt 2736` - the AI's Freighters fleet, on an active route, across all seven of L3's instrumented turns, with the callees at 0.** So "freighters in service" was falsified BEFORE lane AC started. Also **`tsflt` is not a freighter list** - at turn 20 sector 6 reads tsflt 3744, which is AC's WARSHIP fleet. And lane V2's "trade slot 13 is draw-free" was a statement about the states that occurred (rule 23), not about the code |
| CORRECTION: L3's own save falsified the freighter hypothesis | verify | verified | high | 100% | 2026-09-09 | L3 3.5 says "every trade sector has `tsnumflt = 0`". **Wrong about its own save**: `human-turn15-spyprogram.sav` sector TradeID 816 has **`tsnumflt 1`, `tsflt 2736` - the AI's Freighters fleet, on an active route, across all seven of L3's instrumented turns, with the callees at 0.** So "freighters in service" was falsified BEFORE lane AC started. Also **`tsflt` is not a freighter list** - at turn 20 sector 6 reads tsflt 3744, which is AC's WARSHIP fleet. **[CORRECTED 2026-09-09 by the resolver: LANE V2 IS VINDICATED AND WAS MISQUOTED.** `indirect-edges.md` 3.1 lists trade slot 13 as **DRAWING at 0x00820e18 - the exact site that fired.** "Closure 185, draw-free" is V2's row for **slot 9**, the route rebuilder lane L3 trapped. Lane AC carried the number to the wrong slot and I published it. V2's static reading was right all along.] |
| spies2 NOT settled, and the deploy state is unreachable in that game | verify | backlog | — | 0% | 2026-09-09 | AC could not deploy a spy and **declined to infer around it**. `ARes2` on ServerSystem **is the asteroid-belt field** (non-zero values 1703-2531 sit inside SYSTEM_MIN/MAX_ASTEROID_RESOURCES 1500-3000); in L3's save only **5 of 28 systems have a belt and NONE is AI-owned** - the textbook deploy target does not exist in that game. **AND L3's "the next condition is spyon" UNDERSTATES IT BY THREE TURNS AND A DETECTION ROLL**: the chain needs `deat != 0`, then `sdet` set by a detection roll on an EARLIER turn, then `turn - sdet >= 3`. **That detection roll is itself an RNG draw, inline in vslot13, not inside P** - so a probe on P reading 0 does not mean the spy half is draw-free |
| AC's coverage caveat, stated | verify | backlog | — | 0% | 2026-09-09 | Two turns, one fleet, one sector, one ship. **`Slot13RngCalleeA` has a short-circuit (`design+0x12c > 1` returns true without rolling) that AC's hull did not exercise**, so a different raider could cost **0 words while still firing B**. The one-word-per-turn figure is this raider's, not the site's |
| ratchet warning: AC's saves carry new content | verify | backlog | — | 0% | 2026-09-09 | `ac-turn20-raider.sav` and `ac-turn22-raider.sav` (both --strict clean) carry **`CnRad`, `tscr = 253`, three `rt` route records, and a StarFleet whose `LocID` is a TradeSector id - the first fleet in the corpus located anywhere but a star.** Expect the coverage ratchet to break (rule 27); that is the content to type |
| LAB: jmove reads but does not commit; static-link the shim | meta | verified | high | 100% | 2026-09-09 | **`jmove` (jiggle) is required to READ the star-map hover readout but SILENTLY FAILS TO COMMIT a move** - use plain `click` to confirm, and verify the order from `Flt.LocID` in the autosave, never from the fleet panel. And on the WSL dev box the mingw toolchain links **posix-threads**, so the shim DLL imports libwinpthread-1.dll and **the game dies at load with 0xC0000135 and NO LOG AT ALL**; `-DCMAKE_SHARED_LINKER_FLAGS=-static` fixes it. AC did not change the toolchain file - flagged for the integrator |
| MY ERROR: Rung B IS affected - replay runs the tail | meta | verified | high | 100% | 2026-09-09 | I told lane RB that command-stream replay was unaffected by a tail draw "because replay runs no AI". **Wrong.** The resolver: this is a **sim draw on S+0x16c keyed on save state**, and `--turn-commands` replay **runs the tail** (`command_replay.h:83`). **Rung B needs the same generator model as Rung A.** The canonical pair happens to be untouched by the predicate (tscr = 252, no fleet at a sector), so nothing measured is invalidated - but the reasoning I gave RB was wrong and would have bitten on any raid-turn replay |
| AC's numbers are at probes=11, which is NOT byte-neutral | verify | verified | high | 100% | 2026-09-09 | The resolver's exoneration is partial and precise. **The tail's +1 stands** - control 0 / active 1 under identical guest, build and config, with the callee going 0 -> 1 entries on the same turns. **But every AC number is at `probes=11`, which lane H bisected as NOT byte-neutral**, and AC's own predictions doc promised a `probes=8` primary reading **it never took**. Consequences: the turn totals 20/18 are **not calibration data**, and **no AC autosave is an oracle pair**. `ac-turn22-raider.sav` remains a valid INPUT state. A reminder that rule 19's control must be at the configuration you are quoting |
| lane Z's ledger: the method is sound, the AUDIT is not | meta | verified | high | 100% | 2026-09-09 | The resolver's structural ruling. A bracket state-difference **cannot miss a draw that happens** - the instrument is sound. But **the audit is indexed by FIRING**: a site enters the table when a state reaches it, so **it can only grow by luck** (hives, now the raid roll - two qualifications in two days). **What makes the next audit complete: GATE-INDEXED** - one row per statically reachable site (lane I's 22+28, V2's 8, L1's hive, node-line decay, the SVSO overrides), each carrying **either a measured firing or a decoded predicate on save fields plus the corpus count satisfying it**. Today's unfilled rows are named: 0x0088b613, 0x0082cdb8, 0x0088dc43, the spy-13 family, and the SVSO generator which is still unknown |

View file

@ -0,0 +1,304 @@
# Resolution — the tail draws behind a tech gate; the ledger was firing-indexed, the audit must be gate-indexed
- **Type:** resolution (course-setting; no measurement taken here)
- **Trigger:** lane AC's `findings/control-flow/trade-raid-rng-gate.md` — `OnAllCombatDone_Tail`
costs 1 word/turn with a permitted raider parked on a trade-sector node, 0 in its own control
- **Date / author:** 2026-09-09 · re-resolver
- **Touches:** board rows 186 / 207 / 373 / 399 / 62; `tail-rng-ledger.md` headline (third
qualification); `indirect-edges.md` §3.1 (vindicated, and misquoted by AC §6); `backlog.md`
§3 item 3, §4 item 3, §5; `sots-engine` `phase_catalog.cpp` T23 and `TurnResult::rngUnaccounted`;
`method-rules.md` (new rule 28)
---
## 0. Decision
1. **The surprise is real and the instrument is exonerated for the word it found.** Same guest,
build, config; control reads 0, active reads 1; the callee that holds the decoded `NextFloat`
went 0 → 1 entry on the same turns; the success-only callee `B` fired on one turn of two,
which is what a roll does. **One qualification that AC's own prediction doc promised and the
run did not deliver:** every active-state number was taken at `probes=11`, which lane H
bisected as *not* byte-neutral (it suppresses a `ProcessTurn` research draw). The tail delta
survives that (it is entry-attributed and the perturbation is elsewhere in the turn); the
turn totals 20 / 18 do **not** become calibration numbers and **no AC autosave is an oracle
pair**. `ac-turn22-raider.sav` is a valid *input* state regardless.
2. **Lane Z's ledger is sound as an instrument and was never a completeness proof.** It reads
generator state across a bracket, so it cannot miss a draw *that happens*; its site table lists
sites *that fired*. Twice now (hives, raid roll) a site outside the table cost 0 on every turn
Z measured and non-zero on a state nobody had built. The structural gap is not in the ledger
but in the **audit** built on it: indexed by firing, it can only grow by luck. The next audit is
complete when it is **gate-indexed** (§3).
3. **Lane V2's static reading is vindicated, not overturned — and AC §6 misquotes it.** V2 §3.1
lists trade slot 13 (`0x0088ef80`, closure 84) as **drawing** `NextFloat, NextInt`, with the
`NextFloat` at **`0x00820e18` inside `0x00820ca0`** — the exact site AC fired. "Closure 185,
draw-free" is V2's row for **slot 9** (`0x00868060`, the route rebuilder L3 trapped), and
nothing contradicts it. Board row 399's last clause and AC §6's V2 paragraph are wrong and
must be corrected in place (rule 11). The static inventory was ahead of every measurement
here; what was missing was the step from *gate* to *save predicate*.
4. **The coordinator's "risk retired" row is overturned; L3's measurement survives.** L3's zeros
were true of its state. Its *inference* — "the next condition is freighters / `spyon`" — was
a guess at the nearest container, falsified by its own save (AI freighter on an active route
for seven turns) and by the predicate (freighters are not in it). Four lanes converged on a
false negative about reachability because none of them decoded the gate to a predicate on the
save and counted the corpus against it. **Rule 28, drafted in §6.**
5. **Rung B is affected exactly as Rung A is — the coordinator's reading is wrong.** The draw is
a *sim* draw on `S+0x16c`, keyed on state (`Flt.LocID` → `TradeSector`, `Pos` bit-equal,
`tscr` bit), not on the AI. `--turn-commands` replay runs no AI but **does run the tail**
(`command_replay.h:83`). Any pair whose input carries a permitted parked raider needs the
site modelled for both rungs. The canonical pair is untouched (`tscr = 252`, no fleet at a
sector node). No rung moves; §3 of the backlog gains an item.
6. **One probe, VM141, ~5 turns from `ac-turn22-raider.sav`:** a second raider of a different
hull on the same sector, measured with lane Z's **return-address** ledger (`draw_sites`) at
`probes=8` or `hooks=off`, two fresh processes. It separates per-fleet from per-sector cost,
prices the `design+0x12c > 1` short-circuit, catches `B`'s inner `NextInt`, and hands the
standalone its first raid-turn **oracle pair**. §4.
7. **The spy half is a lane, not a probe, and it needs a new game** (no AI-owned belt exists in
L3's map). Brief in §7; its instrument is `draw_sites`, not entry probes on `P`, for exactly
the reason AC gave.
---
## 1. The surprise, precisely
On VM141 under shim build `ac-7e726b9`, config `shim.cfg.l3probe`: one End Turn on lane L3's
`human-turn15-spyprogram.sav` gives `OnAllCombatDone_Tail` **355 → 355** and
`TradeManager::Slot13RngCalleeA` **0 entries**; two End Turns on AC's turn-21/22 lineage give
**468 → 469** and **487 → 488**, `A` **1 entry each**, `B` **1 then 0**. The difference between
the two states, read from the saves: `CnRad` true on player 0, `tscr` 253 not 252 on all six
sectors, and one `StarFleet` whose `LocID` is a `TradeSector` id with `Pos` bit-equal to the
sector's — the first such fleet in the corpus. AC's committed P6 predicted **no** firing on the
`tscr`-is-fixed reading; it was falsified, which is the strong form of rule 2.
## 2. The instrument
**Exonerated for the delta.** Three independent signals agree: the boundary ledger's +1, the
entry probe's 0 → 1 on the callee V2 had statically placed the `NextFloat` in, and `B`'s
success-only firing pattern. The control is the same instrument on the same guest minutes apart.
The `hooks=off` control on `ref-turn2` matched the three-process published oracle (rule 26's bar,
met by agreement with an already self-consistent control).
**Qualified on byte-neutrality — and AC knew.** `docs/AC-predictions.md` §2: *"I will take the
primary reading at `probes=8` … and cross-check at `probes=11`."* The report is `probes=11`
only. Lane H showed that configuration suppresses `RollResearchEvent`'s draw earlier in the turn.
Consequences: (a) the tail's +1 stands — it is attributed by entry and decode, and the known
perturbation is a `ProcessTurn` site; (b) the turn totals and `left` positions in AC's traces are
**not** calibration data; (c) AC's `(Autosave).sav` files were produced by a perturbed process and
are **not oracle pairs** — the raid-turn oracle pair still has to be made (§4 makes it). None of
this touches the *state* in `ac-turn22-raider.sav`, which is an input like any other.
## 3. Standing claims
| claim | where | verdict | scope / correction |
|---|---|---|---|
| "18–22 words/turn, every word attributed, zero residual" | lane Z, board 186 | **survives as measurement; qualified a second time** | True of every turn measured. "Every word attributed" is per-turn; it was read as "the site set is complete", which the instrument never claimed. Now two sites outside the set: hives (`BeginProcessTurn`, L1) and the raid roll (tail T23 call 7, AC). The ledger's *method* — state difference across a bracket — is exactly right and would show any future site as residual the moment its state is reached |
| L1's qualification of Z (creation-turn hive draws) | `hive-creation-rng.md`, board 336 | **survives** | Same shape as this one; both are rule-6 sites that no corpus state reached |
| V2: trade slot 13 draws `NextFloat`/`NextInt` at `0x00820e18`/`0x0088b613`; spy 13 draws at `0x00887c8a` (inline) + three in `P`; trade 15 and spy 14 one `Chance` each; "hook them with a live workload" | `indirect-edges.md` §3.1, board 207 | **survives — vindicated** | The site AC fired is V2's `0x00820e18`. Its *negative* rows (slots 7/8/9/11/12/14, spy 15) remain lower bounds by V2's own §6 (inlined draws). Board 207's "our corpus has neither" was the wrong diagnosis of *why* — the containers were never the gate |
| AC §6 / board 399: "V2 recorded trade slot 13 as closure 185, draw-free" | AC, board 399 | **overturned (misattribution)** | 185 / draw-free is slot **9**, the route rebuilder; L3 §3.3 quoted it correctly for slot 9 and AC carried the number to the wrong slot. Correct both in place |
| H §3: four outer callees entered every turn, gated inside; P2b-alt falsified — "the per-fleet test chain is the gate and rejects every fleet on a 23-fleet save" | `tail-probes.md` §3.1 | **survives exactly** | H stopped one step short of decoding the chain. It also established `probes=8` as the neutral configuration, which AC then did not use |
| W3: "if either container ever fills, the ledger and generator model need extending; the trigger is now detectable" | `w3-containers-status-handlers.md` §1 | **survives as a risk; trigger overturned** | Filling the containers changed nothing; the extension was needed for a state the container watch cannot see. The detectable trigger is `Flt.LocID` resolving to a `TradeSector` id |
| L3 §3.5 measured zeros with 21 routes + 1 spy | `trade-and-spy-workload.md` | **survives** | True of that state, and the state had an AI freighter on an active route the whole time |
| L3 §3.5 "the next condition is `tsnumflt > 0` / `spyon != 0`"; coordinator's "risk retired by evidence" | L3, board 373 | **overturned** | Freighters are not in the predicate; `spyon` understates the spy chain by `deat != 0`, a detection roll on an earlier turn (itself a draw), and `turn − sdet ≥ 3` |
| L3: "`spies2` is not the spy list" | L3 §6 | **still open** — unchanged | Deploy not reached; AC's P4 (fills only for a deployed spy) is the live reading; rule-6 flag stays |
| AC: gate = fleet at `TradeSector` node, `Pos` bit-equal, `tscr` bit, `tsct` ⇒ `FtFlg & 0x800`; `CCC_ComRaid` sets `CnRad` and bit 0 of every `tscr` | AC §2.1, §3 | **survives** (verified, one state) | Coverage: 1 fleet × 1 sector × 1 ship × 2 turns. The per-fleet loop is read, not measured (§4) |
| AC: cost = 1 word/turn | AC §1.2 | **qualified** | That raider's cost. `A` short-circuits without drawing when any ship's `design+0x12c > 1`; `B` ran once at 0 words with a `NextInt` inside it gated on something unread. Cost per turn is `Σ_fleets [passes G0–G4] × (short-circuit ? 0 : 1) + B's cost on success` — the first term is inference, the rest unmeasured |
| AC §2.2: the spy detection roll is inline in `vslot13`, invisible to an entry probe on `P` | AC | **survives — and V2 already listed the site** (`0x00887c8a`) | The fix is instrument choice: lane Z's `draw_sites` keys on return address and sees every entry-point call wherever it sits; only an *inlined* MT (rule 16) escapes it, and `0x008e6dd0` is `Chance`, an entry point |
| Backlog §4 item 3: "four can draw and none has fired (no trade routes / spy program in the corpus)" | `backlog.md` | **overturned** | One has fired; the corpus reason was wrong. Restated in §8 |
| Backlog §2: Rung B "unaffected … replay runs no AI" (coordinator's reading in the brief) | brief | **overturned** | Sim draw; the tail runs under replay. Rung B needs the same generator model as Rung A |
| Standalone calibration pairs `z2-*`, `z-t6-*` | lane Y | **survive** | Both turns have `tscr = 252` and no fleet at a sector; the site costs 0 there by the predicate, not by luck |
### 3.1 The ledger question, answered
*Is the method sound and the scope narrower, or is there a structural reason it kept missing
sites?* Both, and they are different objects. The **instrument** (bracket state difference +
return-address attribution) is sound and complete *for the turn it measures* — an unlisted site
that fires shows up as residual, which is how L1's run announced the hive draws. The **audit**
(`tail-rng-ledger.md` §11 read as "the generator model's site list") is structurally incomplete
because it is **indexed by firing**: a site enters it when a state reaches it, and no instrument
on a state can enumerate the states it is not in. It kept "missing" sites because the corpus kept
not reaching them, and nothing in the audit could say so.
**What makes the next audit complete rather than larger:** index it by **gate**, not by firing.
One row per statically-known draw site reachable from `BeginProcessTurn` ∪ `ProcessTurn` ∪
`OnAllCombatDone_Tail` over direct + tail-jump + pinned-virtual edges (lane I's 22 + 28 inlined,
V2's 8, L1's hive site, node-line decay, and V2 §4.3's SVSO overrides — the last with *which
generator* still unknown). Each row must carry **one of two things**: a measured firing (save,
turn, words), or a decoded gate written as a **predicate on save fields** plus the number of corpus
saves satisfying it. A row with neither is the audit's own to-do list; a row with predicate and
count 0 is rule 6 with a recipe attached (`tscr` bit ⇒ research `CCC_ComRaid`). Completeness is
then a property you can check by reading the table, and the table can be *wrong* — a predicate
claim is falsifiable by one manufactured save — which the firing-indexed list never was.
Today's unfilled rows, from V2's eight: `0x0088b613` (`B`'s `NextInt`; `B` ran, cost 0, gate
unread), `0x0082cdb8` (trade 15 `Chance`; loop is the route vector, L3 had 21 routes, cost 0,
gate unread), `0x0088dc43` (spy 14 `Chance`; loop is the spy vector, L3 had 1, cost 0, gate
unread), and the spy-13 family (`0x00887c8a` inline + `P`'s three) whose gate AC decoded and
whose corpus count is 0. Plus the SVSO slot-4/11/25 overrides with generator unknown.
## 4. The one probe — a second raider, a different hull, the return-address ledger, an oracle pair
**Load `ac-turn22-raider.sav` on VM141. Build one warship of a hull whose `design+0x12c > 1`
(AC's short-circuit field — a DN if that is hull class; whichever satisfies the read), keep it as
its own fleet, order it to sector 6 with a plain `click`, verify `Flt.LocID = 832` from the
autosave, then End Turn twice with lane Z's `draw_sites` detours armed and entry probes at
`probes=8`, in two fresh processes each, `hooks=off` once for the oracle bytes.**
Live hypotheses it separates, with the number each predicts on the tail:
- **H-fleet** (the decoded loop): cost = one draw per fleet passing G0–G4 that is not
short-circuited. Two raiders, one short-circuited ⇒ `A` entered **2×**, **1 word**, `B` entered
≥ 1× (the short-circuited fleet succeeds without rolling, so `B` fires for it every turn).
- **H-fleet, no short-circuit** (if the hull read is wrong): `A` 2×, **2 words**, `B` 0–2×.
- **H-sector** (one roll per sector, AC's reading wrong about the loop): `A` **1×**, **1 word**
regardless of fleet count.
Every outcome is informative and all three are cheap to tell apart. What rides along for free:
`draw_sites` prices `0x00820e18` and `0x0088b613` by return address (settling `B`'s cost on
success, which entry counting cannot), and the `hooks=off` run in two processes — agreeing, rule
26 — gives the standalone a **raid-turn calibration pair** it does not have, because AC's
autosaves were made under a perturbing configuration. Predictions to commit before the build:
`A` 2×/turn; 1 word if the short-circuit is real, 2 if not; `B` ≥ 1×/turn; `B` costs 0 on every
success; the un-instrumented pair reproduces in two processes.
Do **not** spend this probe on the spy half. Nothing in that game can reach a deployed spy.
## 5. The generator model, extended precisely
For `sots_turn`, in `phase_catalog.cpp` **T23** (currently `"eight vtable calls, wholly
unidentified"` — they are all identified, V2 §3): call 7 of 8, `ServerTradeManagerImpl::vslot13`
(`0x0088ef80`, dispatched at `0x007d97f7`), after the slot-9 route rebuild (call 5) and before
slot 15 (call 8). Iterate `StrategyServer` fleets in vector order; for each fleet `F`:
```
sector = F.LocID resolved; require node.kind == 2 (TradeSector) -- G2
require !(runtime flag pair +0xb8/+0xbc & 0x80000) -- G3a (not on the wire; assume clear)
owner = F.owner; require owner
require (sector.tscr >> owner.index) & 1 -- G3b (tscr is on the wire)
if ((sector.tsct >> owner.index) & 1) || owner.+0x5c == 4: -- G3c
require F.FtFlg & 0x800
require F.Pos == sector.Pos, all three floats bit-equal -- G4
if any ship in F has design+0x12c > 1: success, 0 words -- A short-circuit (read, unmeasured)
else: 1 × NextFloat via rng+4 (1 word, no rejection loop), success iff < odds
if success: B (0 words on 1 observation; contains NextInt 0x0088b613 behind an unread gate)
```
Odds: AC read `0.20` / `0.05` base, `+0.01·nShips`, ×2 with a freighter in the sector, scaled by a
per-ship float — **static, unvalidated** (two turns, one success); the standalone should carry the
**count** now and the decision as `rngUnaccounted`-style "not a prediction" until the odds are
checked, exactly as `trade_raid.cpp` already does for hits. Add the row to `TurnResult::
rngUnaccounted` today as `"T23c7 raid roll: N fleets pass the gate"` computed from the save, so
that on the canonical pair it prints 0 by predicate and on `ac-turn22-raider.sav` it prints 1 —
that line is the standalone's own rule-28 check.
**Interval:** unchanged at the ends (`BeginProcessTurn` → post-turn autosave). **Rung B:** same
model; additionally the *move order to a sector node* is a list-8 fleet move whose destination
is a non-star node, which `game/nav` cannot currently route — a new destination kind, noted for
RB, not urgent (no captured stream contains one).
**Ratchet (rule 27):** `CnRad` on `ServerPlayer`, `tscr = 253`, three `rt` records, `tsflt`
holding a warship id, and `Flt.LocID` = a `TradeSector` id are the content to type. `tscr` is
already a named wire field (L3); the schema needs `CnRad` and the reader needs to accept a
non-star `LocID`.
## 6. Draft rule 28 for `method-rules.md`
> ## 28. A zero on a gated path is not a negative until the gate is a predicate on the save
>
> Four lanes measured the trade-raid callee at zero entries and each was right about its state.
> Lane H read that the loop is over fleets and that "the per-fleet test chain rejects every
> fleet"; lane L3 built both containers, measured zero again, and named the next condition by
> looking at the nearest container (freighters, a deployed spy); the coordinator published the
> risk as retired by evidence. Lane AC decoded the chain to four tests, three of them on fields
> the save carries, found `tscr = 252` in every corpus save, went looking for what writes it, and
> found a tech. Nobody had been wrong about a measurement. Everybody had been wrong about
> **reachability**, because the negative was never stated as *which predicate failed*.
>
> So, for any site that a static inventory says can draw and a measurement says did not:
> **(a)** decode the gate to a predicate over save-visible fields, and say which conjunct failed
> on the state measured; **(b)** count the corpus saves that satisfy the whole predicate — if
> the count is 0 the result is rule 6 with a recipe, not a negative; **(c)** name the next
> workload from the failed conjunct, never from the nearest container or vector. A field that
> holds the same value in every corpus save (`tscr = 252`, like rule 8's `ReqCL == (Species != 4)`)
> is a corpus coincidence until its writer is found — find the writer before calling it a
> constant. And when a lane's instrument counts *entries* to a function, a draw sitting in the
> caller is invisible to it: pair entry probes with the return-address ledger before reporting
> a subtree draw-free.
>
> Damage: three lanes on the wrong variable, a "retired" row on the board for a day, and a
> generator model that would have shipped without the site. Caught by a committed prediction
> (P6) being falsified — rule 2 again.
Below rule 27, append as 28.
## 7. Course — guests and briefs
Five guests free. Spend two; keep VM140 as the oracle guest untouched.
**Lane AD — VM141 (AC's guest: its dist, saves and click verbs are there).** The §4 probe.
One-paragraph brief: *Start from `ac-turn22-raider.sav`. Add a second raider fleet of a hull
that satisfies `design+0x12c > 1` (say which field that is and which hull you chose); park it on
sector 6; confirm `Flt.LocID 832` from the autosave, not the panel. Measure two End Turns with
`draw_sites` armed and `probes=8` — not 11 — in two fresh processes; then `hooks=off` twice from
the same save for the oracle pair, and cite the agreement. Commit before the build: `A` entries,
words, `B` entries per turn under H-fleet, H-fleet-no-short-circuit, and H-sector. Report per-site
words by return address for `0x00820e18` and `0x0088b613`. The pair you produce is the
standalone's raid-turn calibration; hash it into `determinism-hashes.txt`.*
**Lane AS — VM144 (L3's guest: the research/design/Build Spy click paths and the tender
recipe live there).** The spy half, as a lane. Brief: *L3's map has no AI-owned belt; do not
reuse it. Start a new custom game at L3's settings, End Turn once, and read `ARes2 > 0` against
AI ownership in the autosave before investing a turn — regenerate until an AI colony with a belt
exists. Then L3's §5 recipe to a docked spy, move to the belt colony, `Special → Deploy Spy`.
Instrument: lane Z's `draw_sites` return-address ledger, not entry probes on `P` — the detection
roll at `0x00887c8a` (`Chance`, gated on `0x00743f80(system) & 1`) is inline in `vslot13`. Commit
before the build: `deat != 0` on the deploy turn; a tail draw on the first turn the system-side
bit is set (`sdet` stamped, `EVENT_SPY_DETECTED`); `P` entered on turn `sdet + 3` if the system
stays foreign-owned; `spies2` non-empty in exactly the deploy system (AC's P4). Report every
conjunct of the chain that was and was not satisfied per turn. This is ~20 turns; it is a lane.*
**Lane AG — host, no VM.** The gate-indexed audit (§3.1): one table, every reachable draw site,
firing-or-predicate, corpus count. Decode the three unread gates (`0x0088b613` in `B`,
`0x0082cdb8` in trade 15, `0x0088dc43` in spy 14 — closures 54–84, small) to save predicates and
count the corpus. Do not measure; hand each count-0 row a recipe for whoever holds a guest next.
State which generator the SVSO overrides use where it can be read, and mark the rest unknown.
**Engine (RB or the standalone owner).** §5: the T23 slot, the `rngUnaccounted` predicate row,
`CnRad` in the schema, non-star `LocID`. No `game/nav` work yet.
**Docs to correct in place (rule 11):** AC §6's V2 paragraph (slot 9, not 13); board 399's last
clause; `tail-rng-ledger.md` headline gains a second qualification block pointing here (the
first is L1's); `indirect-edges.md` §3.1 gains a one-line "fired: `0x00820e18`, lane AC" note;
L3 §3.5's "next condition" paragraph gets a pointer to AC §2 rather than a rewrite.
## 8. Roadmap — no rung moves; three lines change
`backlog.md` §3, add after item 3:
> | 3b | **the trade-raid roll in the tail** — T23 call 7; one `NextFloat` per fleet passing a
> four-test gate on `Flt.LocID`/`Pos`/`tscr`, 0 under a hull short-circuit; `B` on success
> (cost 0 on one observation) | `app` | lane AC decoded, lane AD measuring the loop | the
> `/Sim/RNG` leaf on any raid-turn pair; currently costs the canonical pair nothing by predicate |
§4 item 3, replace with: *trade + spy managers — all 11 virtual targets named; four can draw;
**one has fired** (trade 13, behind `CCC_ComRaid` + a parked raider — lane AC). The gate was
never the containers. Spy 13 decoded, unreached; trade 15 / spy 14 / `B`'s inner draw: gates
unread (lane AG).*
§5, replace "trade routes + spy program — the four tail draw sites" with: *a deployed-and-detected
spy at a foreign belt colony (lane AS); a second raider hull on a sector node (lane AD).*
---
## Proposed `campaign/board.md` rows
New row:
```
| RESOLUTION: the tail draws behind a tech — ledger firing-indexed, audit to be gate-indexed; V2 vindicated; Rung B affected | meta | verified | high | 100% | 2026-09-09 | Resolver on lane AC (`findings/resolutions/2026-09-09-tail-draws.md`). INSTRUMENT: exonerated for the +1 (same guest/build/config, control 0, callee 0->1, B success-only) — but every AC number is `probes=11`, the configuration lane H bisected as NOT byte-neutral, and AC's own predictions promised a `probes=8` primary reading it never took: the tail word stands, the turn totals are not calibration data, and NO AC AUTOSAVE IS AN ORACLE PAIR. LANE Z: instrument sound (state difference cannot miss a draw that happens); the AUDIT is structurally incomplete because it is indexed by FIRING — twice now (hives, raid roll) a site cost 0 on every measured state and fired on one nobody had built. Next audit must be GATE-INDEXED: every reachable site carries a measured firing OR a decoded predicate on save fields + the corpus count satisfying it (lane AG). V2 VINDICATED, NOT OVERTURNED: `indirect-edges.md` §3.1 lists trade slot 13 as DRAWING at 0x00820e18 — the exact site AC fired; "closure 185, draw-free" is SLOT 9, misquoted by AC §6 and row 399 — correct both. RUNG B IS AFFECTED: the draw is a SIM draw on S+0x16c keyed on Flt.LocID/Pos/tscr; replay runs the tail (command_replay.h:83). Canonical pair untouched (tscr=252, no fleet at a sector). Model: T23 call 7, per fleet passing G2/G3/G4, 1 NextFloat unless design+0x12c>1 (0 words), B on success (0 on one observation; NextInt 0x0088b613 gate unread). ONE PROBE, VM141 (lane AD): second raider of a short-circuit hull on sector 6 from ac-turn22-raider.sav, draw_sites + probes=8, two fresh processes, hooks=off pair for the oracle — separates per-fleet (A 2x) from per-sector (A 1x), prices the short-circuit, costs B by return address. Spy half = lane AS on VM144, NEW game (regenerate until an AI colony has a belt), draw_sites not entry probes (the detection roll 0x00887c8a is inline in vslot13). RULE 28 DRAFTED: a zero on a gated path is not a negative until the gate is a predicate on the save and the corpus is counted against it; name the next workload from the failed conjunct, never the nearest container; a corpus-constant field is a coincidence until its writer is found. No rung moves; backlog §3 gains 3b, §4 item 3 and §5 restated |
```
Edits to existing rows:
- **Row 186** (`RNG LEDGER CLOSED - zero residual`) — prefix: `QUALIFIED TWICE (L1 2026-09-08, AC 2026-09-09; resolver): "every word attributed" is per-turn and TRUE; the site table is firing-indexed and NOT a completeness claim — hives (BeginProcessTurn) and the trade-raid roll (tail T23c7) both cost 0 on every turn here and fire on states this corpus never held. Calibration pairs z2/z-t6 still valid (both cost 0 there by predicate).`
- **Row 207** — append: `FIRED 2026-09-09: 0x00820e18 (trade 13), lane AC, behind CCC_ComRaid + a fleet parked on a sector node. The "our corpus has neither" diagnosis was wrong — containers were never the gate. Seven of the eight sites still unfired; gates for 0x0088b613 / 0x0082cdb8 / 0x0088dc43 UNREAD (lane AG).`
- **Row 399** — replace the final clause (`And lane V2's "trade slot 13 is draw-free" … not about the code`) with: `CORRECTION TO THIS ROW AND TO AC §6: V2 never said trade slot 13 was draw-free — §3.1 lists it as DRAWING NextFloat/NextInt at 0x00820e18/0x0088b613, the exact site that fired. "Closure 185, draw-free" is V2's row for SLOT 9 (the route rebuilder L3 trapped), which stands.`
- **Row 62** (guest holders) — `VM141 = lane AD (raid-loop probe + oracle pair, from ac-turn22-raider.sav); VM144 = lane AS (deployed-spy lane, new game); VM140 reserved as oracle guest; VM145/VM146 free.`

View file

@ -388,3 +388,30 @@ Two integrator lessons from the same episode:
- **Scope that control by an explicit list, not by a name filter.** My first control excluded
`*traderoutes*` and still failed, which briefly looked like the merge *was* at fault — the lane had
added more saves under other names while I worked. Pin the control to the exact set you mean.
## 28. A zero on a gated path is not a negative until you have the predicate
Four lanes measured one call site at zero. Each reported it correctly. One lane read it statically and
placed the draw. The campaign nevertheless recorded "the tail does not draw" — and it does.
The site is gated on a fleet standing at a trade-sector node whose owner's bit is set in a mask that
reads **252 in every save we own**. Nobody had the predicate, so everybody hunted the nearest visible
container: trade routes, then freighters, then a deployed spy. The actual switch is a **tech**
(Commerce Raiding, one turn's research) that flips the mask to 253. One lane's stated "next
condition" was falsified by its *own* save, which had a freighter on an active route the whole time
with the site still at zero.
So, four practices:
1. **A zero is a negative only once the gate is a predicate on save fields and the corpus has been
counted against it.** Until then it is "not reached in the states measured" — which is a different
sentence and should be written as one.
2. **Name the next workload from the failed conjunct, not from the nearest container.** Decode the
gate first, then build the state it names. Lane AC disassembled the chain *before* building
anything and found the predicate had nothing to do with what three lanes were chasing.
3. **A field constant across the whole corpus is a coincidence until its writer is found.** `tscr` at
252 everywhere looked like a fact about the game; it was a fact about our saves. Compare rule 8's
eighteen fields that split a roster identically because nothing exercised them.
4. **Pair entry probes with the return-address ledger before calling a subtree draw-free.** An entry
probe on an inner function reading zero says nothing about an *inline* draw in its caller — which
is exactly where the spy half's detection roll lives.