# The raid target pick — a verdict on `TradeManager+0x0c` - **Type:** control-flow (static decode of the writer + live measurement) - **Owner / date:** lane AR · 2026-09-08 → 2026-09-09 · guest **VM141** (`sots-re-win10-b`, 192.168.10.143) — held from the time the predictions were committed, **released** (§10) - **Status:** **verified** for the verdict, for `A`'s per-fleet cost and for the oracle pair; **one observation** of the pick itself, and the coverage limits are listed in §7 - **Decides:** lane AG's `gate-indexed-rng-audit.md` §3.3 final paragraph — *per-system containing-sector table* versus *sector-indexed vector of six* — which lane AD (`raid-gate-multiplicity.md` §4) measured and correctly reported it could not separate on sector `TradeID 832` - **Instrument:** lane Z's return-address ledger (`draw_sites`) + lane H's entry probes at **`probes=8`**, the byte-neutral set. **Not `probes=11`** (lane H bisected index 8 as not byte-neutral) --- ## 1. Predictions, committed before the build (rule 2) *Everything in §1 was written and committed before the shim was built, before the workload was played and before any counter was read. It is reproduced verbatim below when the results are added; nothing in it is edited after the fact, only annotated with verdicts.* ### 1.0 The static result this lane found first, stated as a falsifiable prediction Lane AG's §7 lists **"`ServerTradeManager+0x0c`'s writer was not found"** as the one load-bearing inference in its document. This lane found the writer on the host before touching the guest, and it decides the question on its own. It is written here **as a prediction**, because a live run can falsify it, and because rule 3 says static reading and behavioural comparison are different instruments and neither is trusted alone. **`FUN_00841700`** (`this` in `ecx` → `ebx`; 214 bytes, `0x00841700`–`0x008417d5`, decoded to the next function start per rule 17) does exactly three things: ``` ; 1. CLEAR the +0x0c vector 0084170b lea ecx,[ebx+0xc] ; &this->vec0c 0084170e call 0x459f70 ; vector::resize(0) -- arg pushed at 0x841709 ; 2. RESIZE it to the length of the vector at [this+4]+0x40 .. +0x44 00841713 mov ecx,[ebx+0x4] 00841716 mov eax,[ecx+0x44] 00841719 sub eax,[ecx+0x40] 0084171c mov edx,[ebx+0x10] ; vec0c._Mylast 0084171f mov edi,[ebx+0xc] ; vec0c._Myfirst 00841726 sar eax,0x2 ; N = count([this+4]+0x40..+0x44) 00841729 sar ecx,0x2 ; cur = count(vec0c) 0084172c mov DWORD PTR [ebp-0x4],0x0 ; fill value = NULL 00841733 cmp eax,ecx 00841735 jbe 0x841749 0084173f lea ecx,[ebx+0xc] ; grow: _Insert_n(_Mylast, N-cur, NULL) 00841742 call 0x50e6a0 00841754 lea ecx,[ebx+0xc] ; shrink: erase(_Myfirst+N, _Mylast) 00841757 call 0x4ddfc0 ; 3. FILL it by walking sectors x their member systems 0084175c ecx = this->+0x1c ; eax = (this->+0x20 - ecx)/4 ; the SECTOR vector 00841778 sect = sectors[i] 0084177f inner count = (sect->+0x7c - sect->+0x78)/4 ; the sector's MEMBER vector 00841798 m = sect->members[j] 008417a2 idx = m->+0x5c ; the member's OWN INDEX field 008417a5 edi = this->+0x0c 008417a8 mov DWORD PTR [edi + idx*4], ecx ; table[idx] = sect ``` Three things follow, and each is checkable by a reader who disagrees: 1. **The table's length is, by construction, the length of the container that `trfr` indexes.** `FUN_00841cd0` — the function that settles what `trfr` means, and the one AG cites for exactly that — resolves a route's source endpoint at `0x00841d36` as `mov eax,[edi+0x4]; mov ecx,[eax+0x40]; mov edx,[esi+0xc]; mov eax,[ecx+edx*4]`, i.e. **`([this+4]+0x40)[rt->trfr]`**. Step 2 above resizes the `+0x0c` vector to the length of *that same vector on that same object*. So `G_B1a` (`0 <= rt->trfr < count(this->+0x0c..+0x10)`) is satisfied by **every route with a valid `trfr`, by construction**, in the same way that AG showed `vslot15`'s G1 is satisfied by every `rt` in every save by construction. 2. **The slot index is a system's own index field, and the slot value is a `TradeSector*`.** Step 3 writes `table[m->+0x5c] = sect` where `sect` came out of the sector vector and `m` came out of that sector's member list. That is the definition of a **per-system containing-trade-sector table**. `FUN_00841c70` reads it back the same way (`arg->+0x5c` → bounds check against the same count → `table[idx]`, then `table[idx] + 0x78` — the member vector — is handed to `FUN_0059ec00`), which is the independent confirmation that `+0x5c` on the indexing object and `+0x78` on the table element are the two halves of one relation. 3. **The table is rebuilt on load.** `FUN_00841700` has five callers; one of them is **`FUN_00858a10`**, which is full of `ReadInt`/`ReadFloat` calls and invokes `FUN_00841700` at `0x00858f07` as its last real act. So a loaded save has a populated table, and this is not a galaxy-generation-only structure. > **P0 — the verdict, predicted.** `TradeManager+0x0c` is a `std::vector` of length > `numSystems`, indexed by system index. **AG's per-system reading is right; the sector-indexed-vector-of-six > reading is false**, and `0x0088b613` is therefore **reachable in principle**. `ad-turn27-two-raiders.sav` > has `systemIds` of length **28**, so the table has 28 slots and `trfr ∈ {14,16,18,20}` clears `G_B1a` > with room to spare. **How P0 could be wrong, and the symptom of each way** (rule 2 requires this): | way it could be wrong | symptom in the run | |---|---| | `[this+4]+0x40` is not the systems vector — some other container of a coincidentally similar length | `B` is entered on a success and still costs **0** words | | `m->+0x5c` is not a system index (e.g. the member list holds something else) | same symptom; `table[trfr]` would then be null or a wrong sector, and `G_B1b` rejects | | the members of sector 816 do not include the systems the routes are sourced at | `B` entered, 0 words; and the save's `tssys` list would contradict the route's `trfr` | | `FUN_00841700` is not called on this path after all (my caller read is wrong) | `B` entered, 0 words, table all-null | **In every one of those cases the observable is the same: `B` entered, 0 words.** That single number is the whole experiment, and it is why the run is worth taking even though the static read looks closed. ### 1.1 The state, read fresh from the save (rule: do not inherit a number) Read from `verify/results/saves/ad-turn27-two-raiders.sav` with `verify/save-reader/save_reader.py --dump`, before touching the guest. **`trdmgr` holds FIVE `rt` records at turn 27, not three.** Lane AD's §4 reports *"three route records, `trfr = 18, 14, 14`"*; the save has **five**, `trfr = 18, 16, 14, 20, 14`, `tro = 32` (the AI) on all five, `trfrs = trtos = 0` on all five. This is a correction to `raid-gate-multiplicity.md` §4 and to its board row (rule 11), recorded before the run rather than after. **System index ↔ system id is `index = id/16 − 3`**, pinned from `Sim.systemIds` `[48, 64, 80, …, 480]` (28 entries, stride 16, first = 48). Applying it to each sector's `tssys` list reproduces lane AG's index sets for all six sectors exactly, which is the check that the mapping is right: | sector `TradeID` | grid | `tsct` | `tscr` | member system **indices** | fleets present | |---|---|---|---|---|---| | 752 | 1 | 2 | 253 | 1, 10, 20, 24, 17 | `6864` | | 768 | 2 | 2 | 253 | 2, 7, **14**, 21, 22, 27 | `6880` | | 784 | 3 | 0 | 253 | 4, 8, 12, 25 | — | | 800 | 4 | 0 | 253 | 6, 11, 5 | — | | **816** | **5** | **2** | **253** | 9, 15, **16**, **18**, 19, 26 | `7072` **`Freighters`** (PID 32, 11 ships), `7088` `Escorts` | | 832 | 6 | 0 | 253 | 13, 23, 0, 3 | `3744` Alpha, `6544` Beta — AD's two raiders | So on the turn-27 route set: - **sector 816 sources TWO routes** (`trfr` 18 and 16) → candidate list `n = 2`, `bound = 1`; - sector 768 sources two (`trfr` 14 twice) → `n = 2`; - sector 752 sources one (`trfr` 20) → `n = 1`, `bound = 0`; - sectors 784, 800, 832 source **none**. 832 is still the one sector no route is sourced in. **Geometry, recomputed rather than inherited** (node positions from `trdmgr`, colony positions from `Sim.systems[].Sys.Pos`; player 0 = `PlyrIdx 0` = `PID 16`, `HomeSys 48`, `CnRad true`): | sector | from Epsilon Eridani (idx 0) | from Downbelow (idx 12) | sources a route? | |---|---|---|---| | 752 | 12.85 | 8.43 | yes (1) | | **768** | **11.53** | **10.14** | **yes (2)** | | 784 | 9.36 | 3.49 | no | | 800 | 9.37 | 11.77 | no | | **816** | **15.66** | **12.12** | **yes (2)** | | 832 | 4.99 | 4.56 | no | Reproduces lane AD's table to the last digit. Player-0 fleets at turn 27: `3744` *Alpha Fleet* and `6544` *Beta Fleet* on 832 (both `DesID 17`, one `CR Repair and Salvage` each, `Range` consumed to 4.0125), and `6672` *Gamma Fleet* at `LocID 48` (home, `Range 9.0`). ### 1.2 The workload Build **several separate single-ship `Extended Range` destroyer fleets** (stock hull, `Range 27.0`, cost 2,252, node speed 4.0 — no research required) and park them on **sector 816's node**, `Pos` bit-equal, for as many End Turns as the session allows. Sector **768** is a secondary target if the map allows it: it is *closer* (10.14 ly from Downbelow) and also sources two routes, so a fleet there is a second independent instance of the same test at no extra build cost. **Separate fleets, not one big fleet, and this is arithmetic not taste.** `A` is per fleet (lane AD) and its odds are `ODDS_DE + PER_SHIP·nShips` for a destroyer fleet. One 5-destroyer fleet rolls **once** at `0.05 + 0.05 = 0.10`; five 1-destroyer fleets roll **five times** at `0.06` each — expected successes 0.10/turn against 0.30/turn. Three times the signal for the same ships. ### 1.3 The numbered predictions | # | prediction | |---|---| | **P0** | *(above)* `+0x0c` is the per-system containing-sector table; AG's reading is right and the sector-indexed reading is dead | | **P1** | `TradeManager::Slot13RngCalleeA` is entered **once per parked permitted fleet per turn** and costs **1 word** each — lane AD's per-fleet result, re-confirmed on a different sector and a different hull | | **P2** | On a turn `A` succeeds for a fleet on **816**, `Slot13RngCalleeB` is entered **and reaches `0x0088b613`**, costing **≥ 1 word** — the number lane AC and lane AD both measured as **0** | | **P3** | `B`'s full cost on such a success is **2 words**: `NextInt` at `0x0088b613` (exactly 1 — `RNG_NextInt` has no zero-bound early-out, and with `bound = 1` the mask is 1 so **no rejection is possible either**) plus `NextFloat` at `0x00820c1b` inside `FUN_00820af0`, unless that function's species short-circuit fires (`owner->+0x5c == 1`, or either of the two `SpeciesDef` tests) | | **P4** | Therefore `OnAllCombatDone_Tail` costs **k + 2s** words on a turn, where k = parked permitted fleets and s = successes among them. With one raider that is **1 on a failing turn and 3 on a succeeding turn** — AG's committed number in §3.3, tested | | **P5** | `draw_sites` shows a strategic row at call `0x0088b613` (`NextInt`) with `calls == words == s`, and one at `0x00820c1b` (`NextFloat`) with `calls == s`, `words == s − (species short-circuits)`. Both are sites **no lane has ever fired**; `0x00820c1b` is one of the six lane AG added to the inventory | | **P6** | `0x00820e18` (`A`'s `NextFloat`) shows `calls == words == k`, reproducing AD's per-fleet pricing on a hull and a sector AD did not use | | **P7** | The `hooks=off` control **will not agree with itself** — I expect AD's failure to repeat, because it is the per-process client-AI seed and the AI is larger by turn 33 than at 27, not smaller. I predict the variation is again confined to `Player[32]`'s designs / build queues / fleet ids, and that `/Sim/RNG` and `/Sim/trdmgr` are **bit-identical across all runs**. If a `/Sim/trdmgr` leaf, a trade-sector leaf or a player-0 fleet leaf moves, my numbers are **not** off a reproducible sub-tree and I will say exactly that instead of reporting them | | **P8** | If `A` is entered `k` times but `B` is never entered across the run, that is **not** a negative — it is a run of failed Bernoulli trials, and I will report the exact binomial probability rather than the word "unremarkable" (rule 20) | ### 1.4 The falsifier, stated as the sentence I will have to write > **If a raider is parked on sector 816 with `Pos` bit-equal, `A` succeeds for it, `B` is entered, and > `B` still costs 0 words — then P0 is false, `TradeManager+0x0c` is not the per-system table, lane AG's > §3.3 decode is retired, and the campaign loses a finding it is currently leaning on.** That is a real result and it is the one I am most interested in, because it would mean a careful static read of the writer produced a confident wrong answer — which is rule 3's warning pointing the other way from its usual direction. ### 1.5 What this lane will not be able to settle, predicted in advance (rule 15) - **The freighter doubling.** Sector 816 holds the AI's `Freighters` fleet, so `param_2` is finally testable in principle — but separating `p = 0.06` from `p = 0.12` needs on the order of a hundred fleet-rolls. At the sample size a session affords, the success count is **consistent with both** and I will report it as consistency, not validation. - **The `design+0x12c > 1` short-circuit.** Still unpriced; the Dreadnought category was empty for lane AD and nothing in this workload changes that. - **`bestScale`.** `0x009f8d48 = 0.33f` applies when `ship+0x18 & 0x100000`. I will read the destroyer's flag from the save rather than assume it is clear. - **A rung-A calibration pair.** P7 predicts there is none to be had on this lineage. --- *Results, and the verdict, follow below. Nothing above this line is edited after the run.* --- ## 2. The verdict > ### `TradeManager+0x0c` is the **per-system containing-trade-sector table**. Lane AG's §3.3 reading is **correct**; the sector-indexed-vector-of-six reading is **dead**. > > Two independent instruments agree, and they are the two rule 3 names. > > **Static.** The writer AG's §7 lists as not found is `FUN_00841700`. It resizes the `+0x0c` vector > to the length of the *systems* vector — the same container `FUN_00841cd0` indexes with `rt->trfr` — > and fills it with `containingSector[system.Idx] = sector`. `G_B1a` cannot reject a valid `trfr`. > > **Behavioural.** On turn 42 of the instrumented run, with a raider parked on sector `TradeID 816` > and `Pos` bit-equal, `TradeManager::Slot13RngCalleeB` was entered once and the return-address ledger > priced it: **`NextInt` at call `0x0088b613`, calls = 1, words = 1.** `OnAllCombatDone_Tail` cost > **5** words on that turn against **4** on every other turn of the same run. Bracket residual **0**. > > **And the same run carries its own control.** On turns 38 and 40 `Slot13RngCalleeB` was entered > once each — by a cruiser parked on sector `TradeID 832` — and cost **0 words**, exactly as lane AC > and lane AD measured. **Same process, same build, same instrument, same function, same turn > structure; the only difference is which sector the raider stands on.** That is the cleanest > available demonstration that AC's and AD's proof-carrying zero is a fact about the *sector*, and > that the code path itself is live. `0x0088b613` had never fired in this campaign. It has now. --- ## 3. What was run Four fresh processes on VM141, all on the same guest with the same dist (`C:\SOTS\shimdist-ar`, `BUILD_ID ar-989c692-20260909T0313Z`, built in `/srv/re-lab/build/sots-engine-ar` after `ssh spicy 'rm -rf …'` of the whole tree, from a lane-private `git worktree` at `~/sots-engine-ar` with no local `build*` shipped — rules 21 and 24) and the same input save. | run | config | End Turns | purpose | |---|---|---|---| | play-forward | `shim.cfg.hoff` | 10 (turn 27 → 37) | build the workload | | **R1** | `shim.cfg.hp8` (`probes=8`) | 6 (turn 37 → 43) | the measurement | | **OA** | `shim.cfg.hoff` | 1 (turn 37 → 38) | control | | **OB** | `shim.cfg.hoff` | 1 (turn 37 → 38) | control, second fresh process | **Instrument armed and verified from `shim.log`, not assumed** (rule 1): all seven `drawsite:` detours `create=MH_OK enable=MH_OK`; `config: probes=8 -> 8 lane-H entry probes` and all eight `create=MH_OK enable=MH_OK`; **zero** `config: ignoring unknown key` lines. Probe indices 8–11 report **NOT INSTALLED**, never 0 — index 8 is `GenerateTradeRaidEncounters`, the detour lane H bisected as *not* byte-neutral, excluded by construction. `shim.cfg.hp8` was used **unmodified**. ### 3.1 The workload, and what it cost From `ad-turn27-two-raiders.sav`: five stock `Extended Range` destroyers queued at Epsilon Eridani (Build screen confirms `Range 27.0`, `Construction Cost 2,252`, `Speed (Node Speed) 0.2 (4.0)` — lane AD's costing is exact), completed over turns 28–31, then **split into four separate fleets** and each ordered to sector 5's node. They arrived on turn 35; the state was saved on turn 37 as `verify/results/saves/ar-turn37-816raiders.sav` (sha256 `b6f4e05ff226eabd1695003b36293553642553cea96ef417364393e2332a7094`). **Three UI facts the next lane should have, because each cost this lane time.** 1. **A new ship joins an existing fleet at the colony, and a fleet's `Range` is the minimum over its ships.** The five 27-ly destroyers landed in `Gamma Fleet` alongside AD's 9-ly `Repair and Salvage` cruiser and the fleet read `Range: 9.0 (9.0)` — sector 816 is 15.66 ly away and was not a legal destination until the cruiser was split out. **Split the cruiser off first, then read the range.** 2. **Splitting is a right-click context menu on a *ship row* in the map's fleet panel**, not the Manage Fleets screen (which offers only `Rename Fleet` and "Fleet Layout Not Available" here). The menu is `Add To New Fleet` / `Split Ships` / `Add Note`, and its first item sits **+15 px** below the click. The click helper has no right-click verb, but **`rdrag x y x y` — a right-drag of zero length — works as one**, and that is how every split in this run was made. 3. **A trade-sector node is a legal move target even when its cube is not drawn.** Lane AD reported that only sector 6's cube renders at any zoom, and that is still true. It does **not** mean the other nodes are unreachable: in Move mode the hover readout names them (`Sector 5 / Range: 15.7 / ETA: 4 Turns`) and a plain click commits. Two known screen points are enough to fit `screen = (A·wx + B·wz + C, D·wx + E·wz + F)` from the save's world coordinates and land the cursor on any node first try; this run fitted it from Epsilon Eridani and sector 800 and hit sector 816 at (825, 444) on the first probe. **Hovering near a sector also makes its cube appear**, which is the confirmation that the aim was right. ### 3.2 The gate, read from the save for the measured turns (rule 28) `ar-turn37-816raiders.sav`, player 0 = `PlyrIdx 0` = `PID 16`, `CnRad true`: | fleet | id | `LocID` | `Pos` vs sector `Pos` | rolls `A`? | |---|---|---|---|---| | `Alpha Fleet` (1 CR) | 3744 | **832** | `[0, 0, 8.0]` — **bit-identical** | yes | | `Beta Fleet` (1 CR) | 6544 | **832** | `[0, 0, 8.0]` — **bit-identical** | yes | | `Epsilon Fleet` (1 DE) | 49 | **816** | `[8.307682991027832, 0.05633879080414772, 0.4591276943683624]` — **bit-identical** | yes | | `Eta Fleet` (1 DE) | 81 | **816** | same three floats — **bit-identical** | yes | | `Zeta Fleet` (1 DE) | 65 | 816 | `[9.2771635055542, 0.03959554061293602, 1.8529905080795288]` — **not** the node | **no** (G4 fails) | | `Delta Fleet` (1 CR) | 33 | 48 | home | no | `Trade[816]`: `tsct 2`, `tscr 253`, `tsnumflt 5`, `tsflt 49, 65, 81, 8752, 8768` — my three plus the AI's. `tsct = 2` is the AI's bit, so `TradeSector_PlayerTradesHere` is false for player 0 and **no `FtFlg & 0x800` is required**, exactly as lane AD read it; every fleet above carries `FtFlg 4`. **Four qualifying fleets, and `Slot13RngCalleeA` was entered exactly four times on every turn** — which is both the confirmation of lane AD's per-fleet result on a new sector and a new hull, and the proof that the two 816 destroyers clear G0–G4. **`trfr` re-read on the state actually built, as instructed.** `trdmgr` at turn 37 holds **eight** `rt` records — not lane AG's four at turn 22 and not lane AD's three at turn 27 — with `trfr = 18, 16, 14, 20, 14, 20, 14, 25`, `tro = 32` and `trfrs = trtos = 0` on all eight. Mapping each through the sector membership lists: **sector 816 sources two of them (`trfr` 18 and 16)**, 768 sources three, 752 two, 784 one, and 832 still sources none. So the candidate list on 816 has `n = 2`, `bound = n − 1 = 1`, the mask is 1 and **no rejection is possible** — the site costs exactly one word, which is what it cost. **Correction to lane AD (rule 11).** `raid-gate-multiplicity.md` §4 reports *"three route records, `trfr = 18, 14, 14"* in `ad-turn27-two-raiders.sav`. That save holds **five**, `trfr = 18, 16, 14, 20, 14`. Read directly with `save_reader.py --dump` before this lane touched the guest. The consequence matters: **sector 816 already sourced two routes at turn 27**, not one. --- ## 4. The numbers ### 4.1 Per turn, all three instruments side by side `A` = `TradeManager::Slot13RngCalleeA` (probe 5) · `B` = `Slot13RngCalleeB` (probe 6) · "tail" = `OnAllCombatDone_Tail`'s word delta from the boundary ledger · `0x0088b613` = the raid target pick, from `draw_sites` return-address attribution. | turn | `A` entries | `0x00820e18` calls/words | `B` entries | **`0x0088b613`** | **tail words** | bracket residual | |---|---|---|---|---|---|---| | 38 | 4 | 4 / 4 | **1** | — | 4 | 0 | | 39 | 4 | 4 / 4 | 0 | — | 4 | 0 | | 40 | 4 | 4 / 4 | **1** | — | 4 | 0 | | 41 | 4 | 4 / 4 | 0 | — | 4 | 0 | | **42** | 4 | 4 / 4 | **1** | **calls = 1, words = 1** | **5** | 0 | | 43 | 3 | 3 / 3 | 0 | — | 3 | 0 | **Read the two rows that matter together.** Turns 38 and 40: `B` entered, tail 4 — `B` cost **0**. Turn 42: `B` entered, tail **5** — `B` cost **1**, and the ledger names the site. The difference is which sector the successful raider stood on, and nothing else moved: `A`'s row is `calls = words = 4` on all five of those turns and the bracket residual is 0 on every one. Turn 43's `A = 3` is not a defect: `Epsilon Fleet` had been displaced off the node by its own successful raid on turn 42 (§4.3), so only three fleets satisfied G4. ### 4.2 `B` costs **one** word on a success, not two — and why **No `0x00820c1b` row appears on turn 42.** `FUN_00820af0` was called (it always is, immediately after the pick) and returned without drawing. That is the species short-circuit, and this lane pinned which disjunct fires, from the image: ``` FUN_00820af0: if (routeOwner->Species == 1) frac = 1.0 ; AI here is Species 2 -- no if (StarFleet_GetCrewSpeciesForIntercept(fleet) == 1) frac = 1.0 ; raider is Species 0 -- no if (SpeciesDef_HasInterceptFlag(Get(that same species))) frac = 1.0 ; <-- THIS ONE else frac = NextFloat() ; 0x00820c1b, 1 word ``` `Get` `0x00545cc0` returns `0x00b10a00 + k*0x184`; `InitTable` `0x005453a0` fills element `k` at that same address and, at `0x0054562f`/`0x00545638`, sets `elem->+0x144 |= 1` when `k == 0` and `|= 2` when `k == 5` — **and for no other species**. (Both of those addresses were **already named** in `ghidra/addresses.json` as `SpeciesDef_Get` and `g_SpeciesDefTable`, from `handoff/tech-effects.md`. This lane derived them independently from the `FUN_00820af0` call chain and the generator's duplicate-name check is what surfaced the agreement — rule 14 working as designed. Only the `+0x144` flag word is new, and it is the fragment's one data entry.) `SpeciesDef_HasInterceptFlag` `0x0053baf0` is twelve bytes: `xor eax,eax; cmp [ecx+0x144],eax; setne al; ret`. So the flag is set for **Human (0) and Zuul (5)** and clear for the other five. > **A Human or Zuul raider intercepts at `frac = 1.0` and draws nothing; every other species draws a > `NextFloat` at `0x00820c1b`.** **This corrects two committed numbers, and the corrections point the same way** (rule 11): - lane AG §5.2, *"`B`'s cost on success is `1 (NextInt) + 1 (NextFloat)`"* — true for five of the seven species, false for the two whose flag is set, and the player in this lineage is one of them; - lane AG §3.3's committed prediction, *"**3 words** on a turn it succeeds (`A` 1 + `B`'s `NextInt` 1 + `FUN_00820af0`'s `NextFloat` 1)"* — the measured figure for one raider is **2**. My own P3/P4 carried the same error with a hedge on it; the hedge was the right half. The general model, then, and it is a model of the *state*, not a constant (rule 20): > **`OnAllCombatDone_Tail` costs `k + s + z` words**, where `k` is the number of permitted raiders > parked on a trade-sector node with `Pos` bit-equal, `s` is how many of their raid rolls succeeded > **on a sector that sources at least one raidable route**, and `z` is `s` again for a raider whose > species does not set `SpeciesDef+0x144`. Measured here at `k + s` with `k` = 4, 4, 4, 4, 4, 3 and > `s` = 0, 0, 0, 0, 1, 0. ### 4.3 A success moves the raider off the node — so a fleet raids at most once per parking `Slot13RngCalleeB` writes `fleet->Pos = out` at `0x0088b672`, *after* the pick. G4 then fails for that fleet on the following turn, because `Pos` is no longer bit-equal to the sector's. This is visible in the saves and it explains turn 43's `A = 3`: | fleet | `Pos` at turn 37 | `Pos` at turn 43 | |---|---|---| | `Eta Fleet` (81) | the node, bit-equal | the node, **still bit-equal** | | `Epsilon Fleet` (49) | the node, bit-equal | `[7.13520622253418, 5.090692520141602, -2.1875174045562744]` — **displaced**, `LocID` still 816 | | `Alpha`/`Beta` (832) | the node, bit-equal | the node, **still bit-equal** | The 832 raiders are **never** displaced, because on 832 `B` returns at `G_B4` *before* the `Pos` write. So the within-run control is durable by construction and the 816 arm exhausts itself — which is a real constraint on this workload and the reason the run has one firing of the pick and not six. ### 4.4 Two more of lane AG's unread gates opened, on turn 43 ``` turn 43 * STRAT NextInt call 0x008939ee FUN_008938a0+0x14e calls= 1 words= 1 * STRAT NextFloat call 0x00820c1b FUN_00820af0+0x12b calls= 1 words= 1 probe: ServerTradeManager::CreateRaidEncounter calls=3 ``` - **`0x008939ee` fired.** That is the site behind `CreateRaidEncounter`'s empty-candidate-list gate — lane H's measurement of it (*entered 2× on Zuul turn 24, 1× on turn 25, 0 words every time*) is the campaign's case study for rule 20, and `tail-rng-ledger.md` has carried it as a zero ever since. **The candidate list is not always empty**, and the first non-zero reading of that site is in this trace. - **`0x00820c1b` fired**, and **not** through `Slot13RngCalleeB` — `B` was entered 0 times on turn 43. It came through the other caller, `0x0082cf65` inside the `CreateRaidEncounter` subtree, i.e. lane AG's §5.1 chain `CreateRaidEncounter → 0x00892640 → 0x0082ce00 → FUN_00820af0`. Both of AG's §5.1 and §5.2 readings of that function's two call sites are therefore confirmed live, from opposite directions. ### 4.5 The odds arithmetic — consistency, not validation (rule 15) | arm | hull | odds per fleet-turn | rolls | expected | observed | |---|---|---|---|---|---| | sector 832 | 1 CR | `(double)0.2f + (double)0.01f` = 0.21000000275671482, no freighter | 12 | 2.52 | **2** | | sector 816 | 1 DE | `(double)0.05f + (double)0.01f` = 0.06, **doubled to 0.12** if the AI's `Freighters` fleet (id 7072, `LocID 816`) satisfies `param_2` | 11 | 0.66 / 1.32 | **1** | **The freighter doubling is still not decided and I said in advance it would not be.** One success in eleven rolls sits comfortably inside both hypotheses; separating 0.06 from 0.12 needs on the order of a hundred rolls, and a fleet retires itself from the 816 arm the moment it succeeds (§4.3), which is the structural reason this workload cannot cheaply accumulate them. The honest statement is that the observed rate is consistent with the read constants and validates neither. ### 4.6 The news event `B` posts, named `Slot13RngCalleeB`'s tail loop formats two strings held at `ds:0x00af0b5c` and `ds:0x00af0b64`. Resolving their `GlobalConst` registrations in `FUN_009bf960` (`0x009bfcf0`, `0x009bfd10`) names them **`EVENTSUM_SECTOR_RAIDERS_DETECTED`** and **`EVENTMSG_SECTOR_RAIDERS_DETECTED`**, and **each of those two globals is referenced from exactly one function in the whole image — `0x0088b440`, `B` itself.** So that event pair is a signature of the raid target pick having fired, visible in the news feed without any instrument at all. It is posted to every player whose bit is in `sector->tssec`, which is why the *raider* does not see it. --- ## 5. Verdicts on the committed predictions | # | prediction | verdict | |---|---|---| | **P0** | `+0x0c` is the per-system containing-sector table; AG's reading right, sector-indexed reading dead | **CONFIRMED**, by the writer statically and by `0x0088b613` firing live | | **P1** | `A` entered once per parked permitted fleet, 1 word each | **CONFIRMED** — 4/4 on five turns and 3/3 on the sixth, `0x00820e18` `calls == words` every turn | | **P2** | `B` reaches `0x0088b613` and costs ≥ 1 word on an 816 success | **CONFIRMED** — calls = 1, words = 1 | | **P3** | `B` costs 2 words (`NextInt` + `NextFloat`), *unless the species short-circuit fires* | **HALF WRONG, and the hedge was the right half.** It costs **1**. The short-circuit fires, and §4.2 names the disjunct: `SpeciesDef[Human]+0x144` bit 0, set by `InitTable` for species 0 and 5 only | | **P4** | tail = `k + 2s`; 1 word on a failing turn and 3 on a succeeding one for one raider | **CORRECTED to `k + s`** — 4, 4, 4, 4, **5**, 3 against `k` = 4, 4, 4, 4, 4, 3. Lane AG's committed "3 words on a success" is **2** for this species | | **P5** | a `draw_sites` row at `0x0088b613` with `calls == words == s`, and one at `0x00820c1b` | **CONFIRMED for `0x0088b613`** (calls = words = 1). **FALSIFIED for `0x00820c1b` via `B`** — no such row on turn 42; the site did fire on turn 43 but through `CreateRaidEncounter`, not through `B` | | **P6** | `0x00820e18` shows `calls == words == k`, reproducing AD's per-fleet pricing on a new hull and sector | **CONFIRMED** on all six turns | | **P7** | the `hooks=off` control will not agree with itself; the variation will be the AI's decisions; `/Sim/RNG` and `/Sim/trdmgr` bit-identical | §6 | | **P8** | if `A` fires but `B` never does, report the binomial probability rather than "unremarkable" | **not triggered** — `B` fired three times and the pick once | **The prediction that was wrong is the useful one.** P3/P4 were written from lane AG's §5.2 and they are wrong for exactly the reason rule 23 exists: the deciding value is a **flag word set by a constructor for two species out of seven**, and no amount of reading `FUN_00820af0` alone reveals it. The measurement found it because the word count came out one short. --- ## 6. The control — and it is an oracle pair (rules 19 and 26) **P7 predicted the `hooks=off` control would fail to agree with itself, as lane AD's did on `ad-turn27-two-raiders.sav`. P7 is FALSIFIED. The control agrees, byte for byte.** Two fresh processes, same guest, same build, same `shim.cfg.hoff`, the same input save and the same procedure — load, End Turn, resolve the one encounter query with `Auto Resolve Peacefully`, End Turn: ``` input ar-turn37-816raiders.sav b6f4e05ff226eabd1695003b36293553642553cea96ef417364393e2332a7094 OA (Autosave EndTurn).sav Frame 38 15b99255e1f03dab3e35ab8c1ac64f221cb5aa9321f113c7a6e3d1263c3f34ca (Autosave).sav Frame 39 7a8b3d5eb3a60ebac9f40646d3e4b15768a24a0af047a439ce090c7cf38e8b38 OB (Autosave EndTurn).sav Frame 38 15b99255e1f03dab3e35ab8c1ac64f221cb5aa9321f113c7a6e3d1263c3f34ca (Autosave).sav Frame 39 7a8b3d5eb3a60ebac9f40646d3e4b15768a24a0af047a439ce090c7cf38e8b38 ``` `state_checksum.py --floats bits --mask none` on the two post-turn saves prints **`IDENTICAL`**, root `237020deca931f5a180289592cece7ae`, `coverage: PROVED` (1,173,884 bytes rebuilt == inflated; 67,239 leaves), `0 error, 0 warn`. > **This is a rung-A oracle pair, from a lineage that did not have one.** Lane AD ran the same check > on `ad-turn27-two-raiders.sav` and got 94 differing leaves — all of them the AI empire's designs, > build queues and fleet ids — and correctly refused to call that state calibration data. Ten turns > later on the same lineage, the same check comes out byte-identical. **I do not have an explanation for the difference and I am not going to invent one.** What can be said precisely: AD's variation was confined to `Player[32]`'s decision sub-tree, and on this state that sub-tree does not vary across processes. Whether that is because the AI's choices are forced here, or because the per-process seed AD pinned enters somewhere this workload does not reach, is **not settled by anything I measured**. The load-bearing consequence for the campaign is narrower and solid: **AD's rule-26 result is a fact about that state, not about the lineage or the engine**, and a lane that treats "the AI varies per process" as a general property of this game will be wrong at least once. Two honest limits on this pair, stated rather than glossed: * **Two processes, not three.** Rule 26's bar is "reproduced in two fresh processes and agrees with itself", which this clears; lane AD's `turn1-state` episode needed three to expose the variation, and a third run here would be cheap for whoever wants it. * **One workload.** Both runs took the same two End Turns and resolved the same encounter query the same way. A pair is a statement about that procedure. ### 6.1 Rule 19 — the same two turns with the instrument installed Run **R2**: a fourth fresh process, `shim.cfg.hp8` (`probes=8` + the seven `draw_sites` detours + the boundary-ledger template hooks), same save, same two End Turns, same encounter resolution. ``` input ar-turn37-816raiders.sav b6f4e05ff226eabd1695003b36293553642553cea96ef417364393e2332a7094 OA hooks=off Frame 38 15b99255e1f03dab3e35ab8c1ac64f221cb5aa9321f113c7a6e3d1263c3f34ca Frame 39 7a8b3d5eb3a60ebac9f40646d3e4b15768a24a0af047a439ce090c7cf38e8b38 OB hooks=off Frame 38 15b99255e1f03dab3e35ab8c1ac64f221cb5aa9321f113c7a6e3d1263c3f34ca Frame 39 7a8b3d5eb3a60ebac9f40646d3e4b15768a24a0af047a439ce090c7cf38e8b38 R2 probes=8 Frame 38 15b99255e1f03dab3e35ab8c1ac64f221cb5aa9321f113c7a6e3d1263c3f34ca Frame 39 7a8b3d5eb3a60ebac9f40646d3e4b15768a24a0af047a439ce090c7cf38e8b38 ``` > **All three processes are byte-identical at both snapshot points, instrumented and not.** The > `probes=8` + `draw_sites` + boundary-ledger instrument is **behaviour-neutral on this state, at > whole-save byte granularity** — not "neutral on the sub-tree the measurement reads", which is the > weaker statement lane AD could make, but neutral outright. Rule 26's coincidence caveat does not apply here and it is worth saying why. AD warns that one instrumented run agreeing with one control is a `1/k` coincidence when the control has an outcome set of size `k`. **Here `k = 1`: the control was reproduced first and shown to be a single outcome, and only then did the instrumented run match it.** That is the order the rule requires. R2's own counters reproduce R1's turn 38 line for line — `A` `calls = words = 4`, `B` entered once at **0 words**, `OnAllCombatDone_Tail` **4**, bracket total 24, **residual 0**, all seven `drawsite:` and all eight `probe:` detours `create=MH_OK enable=MH_OK`, zero `ignoring unknown key`. So the measurement is reproducible across processes as well as neutral. **What this licenses, and what it does not.** It licenses treating `ar-turn37-816raiders.sav` + two End Turns as a **rung-A calibration pair** for the standalone, which is the first one this lineage has produced. It does **not** license the six-turn R1 sequence as one: R1 resolved encounter queries on turns its own play produced, and that path was exercised once here, not twice. --- ## 7. Coverage, and what was not done (rule 15) * **Six instrumented turns, one process, four qualifying fleets, two sectors, two hull classes, one species.** The pick fired **once**. One firing is enough to decide reachability — that was the question — and it is **not** enough to price the site as a constant. The word count 1 is corroborated by the static read of `RNG_NextInt` (mask smear, `bound = 1` ⇒ mask 1 ⇒ no rejection possible), which is why I am willing to state it; if the candidate list on 816 ever exceeds two, the rejection loop becomes live and the cost stops being 1 (rule 20 — do not fit a constant to one observation). * **The `k + s + z` model is fitted to `s ∈ {0, 1}` and `z = 0`.** `z` — the `FUN_00820af0` `NextFloat` charged to `B` — has **never been observed through `B`**, in this lane or any other, because the only species that has ever raided in this campaign is one of the two whose short-circuit flag is set. **A non-Human, non-Zuul raider is now the cheapest unexercised state in the trade half**, and it is one save away: the same workload played as Tarka, Liir, Hiver or Morrigi. * **The freighter doubling is still untested** (§4.5), and the structure of the workload is why: a successful raider leaves the node (§4.3), so the 816 arm cannot accumulate rolls without re-issuing move orders every time. * **`bestScale` was not read.** `0x009f8d48 = 0.33f` applies when `ship+0x18 & 0x100000`; that flag is not obviously on the wire and this lane did not chase it. `A` cost exactly one word per fleet on every turn regardless, which is independent of the scale. * **The `design+0x12c > 1` short-circuit is still unpriced**, as it was for lane AD — the Dreadnought category is empty in this game. * **The spy half is untouched.** * **No probe wanted `probes=11`.** Indices 8–11 are reported as NOT INSTALLED, never as zeros. * **One accidental loss, disclosed.** `Gamma Fleet` (2 destroyers) and later `Zeta Fleet` (1) were destroyed resolving encounters during the play-forward and the measured run. Both losses are inside the workload, not the measurement: the input save is on disk and every number in §4 is read off the trace of a run that loaded it. * **What no lane has yet done on this state: a Rung B capture.** `--turn-commands` replay runs no AI, and this state now has an *unconditional* rung-A pair, which makes it the obvious candidate for the standalone's first trade-raid comparison. --- ## 8. Corrections to earlier findings (rule 11) 1. **Lane AG `gate-indexed-rng-audit.md` §7** — *"`ServerTradeManager+0x0c`'s writer was not found. This is the one load-bearing inference in the document and it is flagged as one."* **Found: `FUN_00841700`** (§1.0). AG's §3.3 reading is upheld and the alternative it offered is dead. The flagging discipline is what made this a one-lane job, and it is worth saying so. 2. **Lane AG §3.3's committed prediction** — *"**3 words** on a turn `A` succeeds"* — is **2** for a Human or Zuul raider, because `FUN_00820af0`'s third short-circuit fires (`SpeciesDef[k]+0x144`, set by `InitTable` only for species 0 and 5). §4.2. 3. **Lane AG §5.2** — *"`B`'s cost on success is `1 (NextInt) + 1 (NextFloat)`, minus the species short-circuit"* — right about the code, and the subtraction applies to the only species that has ever raided in this campaign. `B` costs **1**. 4. **Lane AG's row-186 correction and `tail-rng-ledger.md` §11.1** — *"a success costs 0 or 1 further word"* was corrected by AG to "at least six draws". Both sentences are now measured on the same turn: `CreateRaidEncounter` entered 3× on turn 43 and drew **two** words in its subtree (`0x008939ee` and `0x00820c1b`, one each). The correct statement is that the cost is **unbounded above and state-dependent**, and the first non-zero observation is 2. 5. **Lane AD `raid-gate-multiplicity.md` §4** — *"three route records, `trfr = 18, 14, 14"* in `ad-turn27-two-raiders.sav`. It is **five**, `trfr = 18, 16, 14, 20, 14`. §3.2. 6. **Lane AD §5 and its board row** — *"there is no oracle pair for this state"*. True of `ad-turn27-two-raiders.sav`; **not** true of the same lineage ten turns later. §6. 7. **Lane H's `CreateRaidEncounter` zero** (`tail-rng-ledger.md`, rule 20's case study) — the candidate list is **not** always empty. First non-zero reading of `0x008939ee` is in `verify/traces/ar-r1-turn38-turn43.jsonl`. --- ## 9. Artefacts | what | where | |---|---| | this document | `findings/control-flow/raid-target-pick-verdict.md` | | **input state — 4 raiders on two sectors, turn 37** | `verify/results/saves/ar-turn37-816raiders.sav` (`b6f4e05f…`) | | `probes=8` trace, six instrumented End Turns (the pick fires on turn 42) | `verify/traces/ar-r1-turn38-turn43.jsonl` | | `probes=8` trace, the two control turns | `verify/traces/ar-r2-control-turn38-turn39.jsonl` | | site / ledger / probe reports for R1 | `verify/results/shim/ar/ar-r1-{sites,ledger,probes}.txt` | | shim logs (detour + probe install status) | `verify/results/shim/ar/ar-r{1,2}-shim.log` | | **oracle pair**, two fresh `hooks=off` processes | `verify/results/saves/ar-oracle-{A,B}-post.sav` (both `7a8b3d5e…`) | | pre-turn half of the pair | `verify/results/saves/ar-oracle-A-pre.sav` (`15b99255…`) | | the instrumented run's post-turn autosave, byte-identical to both | `verify/results/saves/ar-r2-probes8-post.sav` (`7a8b3d5e…`) | | R1's final state, turn 43 | `verify/results/saves/ar-r1-turn43-post.sav` | | new addresses (7 entries, no name collides) | `ghidra/addresses.d/ar.json` | | instrument | `sots-engine` `src/shim/shim.cfg.hp8`, **unchanged**; build `ar-989c692-20260909T0313Z` | | build tree | lane worktree `~/sots-engine-ar` (branch `wip/ar`) → CT111 `/srv/re-lab/build/sots-engine-ar`, `rm -rf`'d before the build; dist `/srv/re-lab/shim/dist-ar` | **New content for the coverage ratchet (rule 27):** `ar-turn37-816raiders.sav` carries a `TradeSector` with **`tsnumflt 5`** and five `tsflt` entries mixing both empires' fleets; a `trdmgr` with **eight** `rt` records where the corpus maximum was four; and — the first in the corpus — a `StarFleet` whose `LocID` is a `TradeSector` id **while its `Pos` is not the sector node's**, which is the serialised signature of a raider displaced to an interception point. Nothing here is a new *kind* of item, so the ratchet should hold. --- ## 10. VM141 as left Guest **restored**, hold **released**. Game stopped; `C:\SOTS\shim.cfg` is `shim.cfg.hoff`; `C:\SOTS\binkw32.dll` is this lane's build (`ar-989c692-20260909T0313Z`), with the original still at `binkw32_real.dll`. `C:\SOTS\SavedGames` is lane AD's set **plus `ar-turn37-816raiders.sav`**, so **Load-dialog row positions have moved again — screenshot the dialog.** With the three autosaves deleted the list is 12 rows from y = 260 at 29 px pitch, and `ar-turn37-816raiders` is **row 3 at (400, 318)**. Left in place, all additive: `C:\SOTS\shimdist-ar` (4 files) and `C:\SOTS\ui\ar-*.ps1` (`ar-go.ps1` takes `-Cfg`, `ar-ui.ps1` writes `cmd.txt` and runs the helper once, plus three one-shot copy helpers). **`click_helper.ps1` is unmodified** from lane AC's version. **Four things that cost this lane time, for the next holder.** * **Startup is faster than the board says if you drive it.** `fg` + `key {ESC}` three times spaced ~2.5 s, then ~90 s, put the main menu up in about **two minutes**, not four and a half. Loading a turn-37 save is a further **3–4 minutes** and that part is not compressible. Verify both from a screendump. * **`rdrag x y x y` is a right-click.** The click helper has no right-click verb and the fleet panel's `Add To New Fleet` / `Split Ships` menu is right-click-only. A zero-length right-drag opens it. * **A trade-sector node is a legal move target even when its cube is not drawn** (§3.1), and its screen position is computable from the save. Do not conclude a sector is unreachable because you cannot see it. * **The encounter query blocks the End Turn**, so a scripted turn loop must detect it. This lane detected it by sampling **one pixel**: the `Done` button at (233, 673) reads ≈ `(183, 18, 0)` when a query is up and ≈ `(8, 8, 8)` on the map. `Auto Resolve Peacefully` is the fourth icon at (667, 641) and `Done` at (233, 673). --- ## Proposed board rows New rows: ``` | VERDICT: `TradeManager+0x0c` IS the per-system containing-sector table - the writer is found and the raid target pick FIRES | control-flow | verified | high | 100% | 2026-09-09 | **Lane AR**, VM141, `findings/control-flow/raid-target-pick-verdict.md`. Decides lane AG's §3.3 final paragraph, the one load-bearing inference AG flagged as unproven, and lane AD correctly reported it could not separate on sector 832. **BOTH INSTRUMENTS AGREE (rule 3).** STATIC: the writer AG's §7 lists as NOT FOUND is **`FUN_00841700`** (214 B, 0x00841700-0x008417d5) - it clears the +0x0c vector, RESIZES it to `count(([this+4])+0x40..+0x44)` (the SYSTEMS vector, the very container `FUN_00841cd0` indexes with `rt->trfr` at 0x00841d36), then walks the SECTOR vector x each sector's MEMBER SYSTEM vector executing `mov [this->+0x0c + m->+0x5c * 4], sector` at 0x008417a8. `ServerSystem+0x5c` is the serialised **`Idx`** field (objects/layouts.md, grade verified), so this is literally `containingSector[system.Idx] = sector` and **G_B1a cannot reject a valid trfr, BY CONSTRUCTION**. It is called from the DESERIALISER `FUN_00858a10` at 0x00858f07, so a loaded save has the table populated. LIVE: with 4 raiders parked (2 CR on sector 832, 2 DE on sector **816**, all `Pos` bit-equal), `Slot13RngCalleeA` is entered **4x/turn, 4 words**, every turn - and on turn 42 `Slot13RngCalleeB` reached its target pick: **`NextInt` at call `0x0088b613`, calls=1 words=1**, the FIRST firing of that site in the campaign. `OnAllCombatDone_Tail` cost **5** words that turn against **4** on every other turn; bracket residual **0** on all six turns. **THE SAME RUN CARRIES ITS OWN CONTROL**: on turns 38 and 40 `B` was entered by a cruiser on sector 832 and cost **0 words** - same process, same build, same instrument, same function, only the sector differs. AC's and AD's proof-carrying zero is a fact about the SECTOR, not the code path. Instrument `probes=8` (NOT 11), shim `ar-989c692-20260909T0313Z`, cfg `shim.cfg.hp8` unmodified, lane worktree + own build dir `/srv/re-lab/build/sots-engine-ar` rm -rf'd first (rules 21, 24) | ``` ``` | `B` costs ONE word on a success, not two - and the deciding value is a SPECIES FLAG set by a constructor for exactly two species | control-flow | verified | high | 100% | 2026-09-09 | Lane AR. Lane AG's committed §3.3 prediction was **3 words on a succeeding turn** (`A` 1 + `B`'s NextInt 1 + `FUN_00820af0`'s NextFloat 1) and §5.2 says `B` costs 2 on success. **MEASURED: the tail cost 5 with k=4 raiders and one success, i.e. `B` cost 1, and there is NO `0x00820c1b` row on that turn.** Why: `FUN_00820af0`'s third short-circuit is `SpeciesDef_HasInterceptFlag 0x0053baf0` - twelve bytes, `cmp [ecx+0x144],0; setne al` - and `InitTable 0x005453a0` sets that flag word at 0x0054562f/0x00545638 for **species 0 (HUMAN) bit 0 and species 5 (ZUUL) bit 1 ONLY**. `Get 0x00545cc0` returns `0x00b10a00 + k*0x184`, the same table InitTable fills. So **a Human or Zuul raider intercepts at frac=1.0 and draws nothing; the other five species draw a NextFloat at 0x00820c1b**. The general tail model is **`k + s + z`** words: k = permitted raiders parked with `Pos` bit-equal, s = their successes ON A SECTOR THAT SOURCES A ROUTE, z = s again unless the raider's species sets the flag. Measured at k+s with k = 4,4,4,4,4,3 and s = 0,0,0,0,1,0. THE CHEAPEST UNEXERCISED STATE IN THE TRADE HALF IS NOW A NON-HUMAN, NON-ZUUL RAIDER - z has never been observed through `B` by anyone. Rule 23's lesson pointing a new way: the deciding value was not a float literal but a FLAG WORD SET BY A CONSTRUCTOR, invisible to any amount of reading `FUN_00820af0` alone | ``` ``` | ORACLE PAIR on the turn-37 raider state - and the probes=8 instrument is BYTE-NEUTRAL, whole-save | meta | verified | high | 100% | 2026-09-09 | Lane AR (rules 19, 26). Two fresh `hooks=off` processes loading `ar-turn37-816raiders.sav` and running the same two End Turns produced **BYTE-IDENTICAL** autosaves at both snapshot points: Frame 38 `15b99255e1f03dab…` and Frame 39 `7a8b3d5eb3a60eba…`; `state_checksum --floats bits --mask none` prints **IDENTICAL**, root `237020deca931f5a180289592cece7ae`, coverage PROVED (1,173,884 B rebuilt, 67,239 leaves), 0 error 0 warn. **THEN** a fourth process with `shim.cfg.hp8` installed produced the SAME TWO HASHES. So the instrument is behaviour-neutral **at whole-save byte granularity**, not merely on the sub-tree the measurement reads - the stronger form of what lane AD could show. Order matters and it was the right order: the control was reproduced FIRST and shown to be a single outcome, so rule 26's `1/k` coincidence caveat does not apply (k=1). **THIS CORRECTS THE SCOPE OF LANE AD'S ROW**: "no oracle pair for this state / the AI varies per process" is true of `ad-turn27-two-raiders.sav` and NOT true of the same lineage ten turns later, so it is a fact about that state, not about the engine. No explanation for the difference is offered and none should be inferred. `ar-turn37-816raiders.sav` + 2 End Turns is the first RUNG-A CALIBRATION PAIR from this lineage and the obvious candidate for the standalone's first trade-raid comparison | ``` ``` | `CreateRaidEncounter`'s candidate list is NOT always empty - 0x008939ee fires, and rule 20's case study gets its positive | control-flow | verified | high | 100% | 2026-09-09 | Lane AR, turn 43 of `verify/traces/ar-r1-turn38-turn43.jsonl`. `ServerTradeManager::CreateRaidEncounter` entered **3x** and its subtree drew **two** words: `NextInt 0x008939ee calls=1 words=1` - the site lane H measured at 0 on every turn and that `tail-rng-ledger.md` has carried as a zero ever since, the campaign's own case study for rule 20 - and `NextFloat 0x00820c1b calls=1 words=1` through the OTHER caller `0x0082cf65`, i.e. lane AG §5.1's chain `CreateRaidEncounter -> 0x00892640 -> 0x0082ce00 -> FUN_00820af0`. `Slot13RngCalleeB` was entered **0** times that turn, so neither word is `B`'s. **Two of AG's §5.1/§5.2 unread gates are now read from opposite directions.** The honest form of the cost claim is neither "0 or 1 further word" nor "at least six draws" but **unbounded above and state-dependent**; the first non-zero observation is 2 | ``` Edits to existing rows: - **Row 62** (guest holders) — `VM141 = FREE (lane AR released 2026-09-09; guest restored, `shim.cfg.hoff`, this lane's binkw32.dll, SavedGames = lane AD's set PLUS `ar-turn37-816raiders.sav`, so Load-dialog rows have MOVED AGAIN - with the autosaves deleted the list is 12 rows from y=260 at 29 px pitch and `ar-turn37-816raiders` is row 3 at (400,318)).` Lane AR left `C:\SOTS\shimdist-ar` + `C:\SOTS\ui\ar-*.ps1`; `click_helper.ps1` unmodified. **GOTCHA (corrects the startup figure): `fg` + `key {ESC}` x3 spaced ~2.5 s then ~90 s puts the main menu up in about TWO minutes, not 4.5** - the 4.5 figure is what you get by waiting the movies out. Loading a turn-37 save is a further 3-4 min and that part is not compressible. **GOTCHA: `rdrag x y x y` (a zero-length right-drag) IS A RIGHT-CLICK** - the fleet panel's `Add To New Fleet` / `Split Ships` menu is right-click-only and the helper has no right-click verb. **GOTCHA: a trade-sector node is a legal move target EVEN WHEN ITS CUBE IS NOT DRAWN** - in Move mode the hover readout names it (`Sector 5 / Range: 15.7 / ETA: 4 Turns`); fit `screen = (A*wx + B*wz + C, D*wx + E*wz + F)` from two known points in the save and you land on any node first try. **GOTCHA: the encounter query BLOCKS the End Turn** - detect it by sampling the `Done` button pixel at (233,673): ~(183,18,0) when a query is up, ~(8,8,8) on the map; `Auto Resolve Peacefully` is (667,641), `Done` (233,673).` - **Row 399 / the AC-AD raid rows** — append: `RESOLVED 2026-09-09 (lane AR): AD's "my data does NOT distinguish AG's per-system vs sector-indexed reading" is now decided BOTH WAYS - `FUN_00841700` is the writer and the pick fired live at 0x0088b613 with the raider on sector 816. AD's zero on 832 stands and is reproduced inside lane AR's own run as the within-run control.` - **Row 207** — append: `0x0088b613 IS NO LONGER UNFIRED (lane AR 2026-09-09): calls=1 words=1 on turn 42 of ar-r1-turn38-turn43.jsonl, with the raider on sector 816. 0x00820c1b also fired, but through CreateRaidEncounter's caller, never through B - the species short-circuit blocks B's second draw for Human and Zuul raiders.` - **Row 186** (`RNG LEDGER CLOSED`) — append: `Lane AR 2026-09-09: the tail's cost is `k + s + z` - one word per parked permitted raider, PLUS one per success on a route-sourcing sector, PLUS one more per success unless the raider's species sets SpeciesDef+0x144 (Human and Zuul only). Measured 4,4,4,4,5,3 over six turns with k = 4,4,4,4,4,3.` - **Lane AD's "Sector 816 is UNREACHABLE" row** — append: `REACHED 2026-09-09 (lane AR) exactly as costed: five stock Extended Range destroyers (Range 27.0, 2,252 each) built at Epsilon Eridani over turns 28-31, split into four fleets, ETA 4 turns, parked on sector 5's node turn 35. AD's geometry table and its build costing are exact. TWO THINGS AD's recipe did not say: a new ship JOINS an existing fleet and a fleet's Range is the MINIMUM over its ships, so the 9-ly cruiser has to be split off before the node is a legal target; and the sector node is clickable even though its cube is not drawn.`