Lane BQ (VM145) takes the seed-exposure predicate's first forward test. Part 1b: ar-oracle-A-pre.sav + one End Turn from a LOAD must reproduce 7a8b3d5e... (it has only ever been reached by continuation). Part 1: ar-oracle-A-post.sav in two fresh hooks=off processes must DIFFER, confined to Player[32]'s research leaves, because that save carries ResTNm == '' for the one player that can research. Also records the exposure facts (ResTNm / NumDes / NumOwn / completions) for every player on both inputs, and names a false-positive class in the predicate before the run: four NPC players carry ResTNm == '' on the very turn whose control agreed, and all four have NumOwn == 0.
13 KiB
The seed-exposure predicate's first forward test — probe 1 (parts 1b and 1)
- Type: control-flow / determinism (two
hooks=offmeasurements from saves already on disk; no build, no shim config change, no instrument) - Owner / date: lane BQ · 2026-09-09 · guest VM145 (
sots-re-win10-145, 192.168.10.145) - Spec:
findings/resolutions/2026-09-09-seed-exposure-is-a-predicate.md§6, probe 1 - Tests:
guides/method-rules.mdrule 26 corollary (c) — the predicate written from lane AR's falsified P7, so far supported only by three states read after the fact - Depends on:
findings/control-flow/raid-target-pick-verdict.md§6 (lane AR's pair)
1. Predictions, committed before either run (rule 2)
Everything in §1 and §2 was written and committed before the game was launched on VM145 and before any hash was read. It is not edited after the fact, only annotated with verdicts in §5.
1.1 What is actually at stake
The resolver ruled that the per-process AI client seed (row 326) is present in every process on every turn, and reaches the save only through a decision whose outcome set is larger than one given the state — and that whether such a decision is reached is a predicate on the pre-turn save. That ruling currently rests on three states read after their controls were run (lane AD's turn 28, lane AS's turn 16, lane AR's turns 38–39). It has never made a forward prediction.
This lane makes two, on states nobody has run, and both can fail.
1.2 Part 1b — the precondition
Procedure. ar-oracle-A-pre.sav (Frame 38, sha256 15b99255e1f03dab3e35ab8c1ac64f221cb5aa9321f113c7a6e3d1263c3f34ca),
one fresh process, hooks=off, one End Turn, no other input.
P1b — committed. The resulting
(Autosave).sav(Frame 39) hashes to7a8b3d5eb3a60ebac9f40646d3e4b15768a24a0af047a439ce090c7cf38e8b38.
Why it matters. Lane AR's 15b99255… → 7a8b3d5e… step has only ever been reached by
continuation — the second of two End Turns inside one process that started from
ar-turn37-816raiders.sav. A calibration pair for the standalone must be a load → turn
procedure. If P1b holds, the single-turn pair is certified in that form and is the first pair
anywhere that exercises the trade-raid roll (four raid rolls, one word each, no encounter). If it
fails, the pair remains valid only as the two-turn procedure from turn 37, and the resolution
names the first suspect: the resave canonicalisation (determinism-oracle.md, round-trip
section).
P1b-aux — committed, and it costs nothing. The same run also writes
(Autosave EndTurn).sav, which is the state as End Turn is pressed — i.e. a resave of the file that was loaded. I predict it hashes to15b99255…, the input's own hash. This is a direct test of the resave-canonicalisation suspect, taken in the same run whichever way P1b goes:
- P1b holds and P1b-aux holds ⇒ load→resave is byte-exact here and the pair is clean.
- P1b fails and P1b-aux fails ⇒ the divergence is present before the turn runs; it is the round trip, not the turn, and the resave canonicalisation is confirmed as the cause.
- P1b fails and P1b-aux holds ⇒ the round trip is exact and the turn diverged from its continuation form. That is the interesting failure and it is not one the resolution anticipated; it would mean a load boundary changes turn 39's outcome, and it is a resolver case, not a lane result.
- P1b holds and P1b-aux fails ⇒ the resave is not byte-exact but is behaviourally equivalent; the pair is certified and
determinism-oracle.md's round-trip section needs a note.
1.3 Part 1 — the exposure test
Procedure. ar-oracle-A-post.sav (Frame 39, sha256 7a8b3d5e…), two fresh processes,
hooks=off, one End Turn each, any encounter query resolved with Auto Resolve Peacefully in
both.
P1 — committed. The two
(Autosave).savfiles differ, and the difference is confined toPlayer[32]'sTechTree/*,ResTNm,otch,Events,turnstats/…/tchandSummary/Checksum, while/Sim/RNG,/Sim/trdmgr, everyPlayer[16]leaf and every player-0 fleet are identical.
The reasoning, and it is the predicate speaking: ar-oracle-A-post.sav carries ResTNm == '' for
Player[32] (§2). By the AS precedent (as-turn15 → 16, 22 leaves, entered with ResTNm == '') and
the row-326 precedent on turn1-state, that is a research-pick turn. So the predicate says, in
advance, that lane AR's pair must not be extended by a turn — and this run is what makes that a
measurement rather than an inference.
How P1 can be wrong, and the symptom of each way (rule 2):
| way it could be wrong | symptom |
|---|---|
a producer supplied the target, so the pick had an outcome set of size 1 (as for player 32 on turn1-state) |
the two files agree byte-for-byte; the predicate survives but needs a producer gate, and lane L4's airesearch=on dump names which producer returned non-null |
| something else on turn 40 is exposed as well as the pick | the files differ, but outside the named leaf set — e.g. in fleets, trdmgr, or Player[16] |
| the pick is exposed but its outcome-set is 1 for a different reason (only one affordable node) | files agree; same follow-up as the producer case, and otch/TechTree at turn 40 says which node was taken |
| VM145 is not byte-faithful to the lineage | P1b fails as well, and part 1b is the guard against reading part 1 off a guest that cannot reproduce anything |
A negative here is a result, not a null. If the two files agree, the honest statement is "no exposed decision was reached on turn 40 either, and the pick is therefore producer-supplied on this state" — never "the AI is deterministic here" (rule 26 (c)).
1.4 A false-positive class in the predicate, named before the run
Read off the two saves (§2), and stated here because it is a pre-run correction to the predicate as the resolution words it:
ResTNm == '' at turn start is true of four players on ar-oracle-A-pre.sav — the turn whose
control agreed byte-for-byte. Players 528 (Alien Menace), 544 (Peacekeeper Enforcer), 560
(Von Neumann) and 576 (Independent Colony) all carry ResTNm == '' on turn 38 and turn 39,
and player 16 (the human) does too. They have NumOwn == 0: no colonies, no research income, no
pick to make. So the raw predicate has a known false-positive class already sitting inside the very
state that falsified AR's P7.
The sharp form the next lane should use is therefore:
ResTNm == ''at turn start, for a non-eliminated AI player withNumOwn > 0, names a research-pick turn.
On ar-oracle-A-post.sav exactly one player satisfies that: Player[32], NumOwn 18. That is
the whole basis of P1, and it is why P1 names Player[32]'s leaves and no one else's.
(Note for honesty: players 496 and 512 — the two Spengler NPCs — hold non-empty ResTNm and also
have NumOwn == 0. They are not evidence either way; they are listed in §2 for completeness.)
1.5 What this lane will not settle (rule 15)
- Two processes, not three, for part 1 — rule 26's bar, matching AR's.
- One state. Neither part says anything about
ad-turn27, which is probe 2's job on VM146. - The producer gate is not run here unless part 1 comes out as agreement and time allows; if it does not, this document names it as the next step rather than guessing at it.
0x0069dbb0's 3–40-turn fuse cannot fire in a one-turn-from-load run, by construction — so neither part can say anything about it, in either direction.- No instrument.
hooks=offthroughout, so this lane measures behaviour and never attributes it to a draw site. The consumer identification is probe 3's job.
2. The exposure facts, read off the saves before the runs (rule 26 (c))
uv run python3 verify/save-reader/save_reader.py --json, three saves on the AD/AR lineage.
NumDes = the designs list length, NumOwn = the owners list length (both are the on-wire count
prefixes; verified against the --dump tree at NumOwn/NumDes). "ships +" is the per-owner
ShipID set delta from the previous save in the lineage.
2.1 ar-oracle-A-pre.sav — Frame 38, ModCount 2108, the input to part 1b
| PID | PlyrIdx | name | species | NPC | ResTNm |
NumDes |
NumOwn |
ships | fleets |
|---|---|---|---|---|---|---|---|---|---|
| 16 | 0 | re (human) |
0 | no | '' |
6 | 3 | 5 | 5 |
| 32 | 1 | The Eternal Empire | 2 | no | BIO_EnvTail |
47 | 18 | 243 | 59 |
| 496 | 2 | Spengler | 0 | yes | DRV_PlsFiss |
0 | 0 | 0 | 0 |
| 512 | 3 | Spengler | 2 | yes | XNC_TrnsMorr2 |
0 | 0 | 0 | 0 |
| 528 | 4 | Alien Menace | 4 | yes | '' |
19 | 0 | 0 | 0 |
| 544 | 5 | Peacekeeper Enforcer | 4 | yes | '' |
1 | 0 | 0 | 0 |
| 560 | 6 | Von Neumann | 4 | yes | '' |
6 | 0 | 0 | 0 |
| 576 | 7 | Independent Colony | 4 | yes | '' |
1 | 0 | 0 | 0 |
Predicate reading for turn 38→39: the only player that can research holds a target
(BIO_EnvTail), NumDes is constant at 47, NumOwn constant at 18. No exposed decision
predicted — which is exactly what AR measured (three processes agreed). Part 1b is therefore a
re-run of an agreeing turn from a load, and its only open question is the load boundary itself.
2.2 ar-oracle-A-post.sav — Frame 39, ModCount 2147, the input to part 1
| PID | PlyrIdx | name | species | NPC | ResTNm |
NumDes |
NumOwn |
ships | fleets |
|---|---|---|---|---|---|---|---|---|---|
| 16 | 0 | re (human) |
0 | no | '' |
6 | 3 | 5 | 5 |
| 32 | 1 | The Eternal Empire | 2 | no | '' ← pick signature |
47 | 18 | 245 | 59 |
| 496 | 2 | Spengler | 0 | yes | DRV_PlsFiss |
0 | 0 | 0 | 0 |
| 512 | 3 | Spengler | 2 | yes | XNC_TrnsMorr2 |
0 | 0 | 0 | 0 |
| 528 | 4 | Alien Menace | 4 | yes | '' |
19 | 0 | 0 | 0 |
| 544 | 5 | Peacekeeper Enforcer | 4 | yes | '' |
1 | 0 | 0 | 0 |
| 560 | 6 | Von Neumann | 4 | yes | '' |
6 | 0 | 0 | 0 |
| 576 | 7 | Independent Colony | 4 | yes | '' |
1 | 0 | 0 | 0 |
Predicate reading for turn 39→40: EXPOSED. Player[32] enters with ResTNm == '' and NumOwn 18.
otch moved 46 → 47 across turn 39 (BIO_EnvTail completed), which is the same shape AS recorded.
2.3 Ship completions on the lineage, for the fleet-assignment half of the predicate
| transition | ModCount |
PID 16 ships | PID 32 ships | reading |
|---|---|---|---|---|
| turn 37 → 38 | 2057 → 2108 | −7408 (Zeta Fleet's destroyer, lost in the encounter) |
+8784, +8800 | 2 completions, into existing fleets — not a batch |
| turn 38 → 39 | 2108 → 2147 | none | +8816, +8832 | 2 completions, into existing fleets — not a batch |
Two ships a turn into existing Freighters fleets is the quiet fleet consumer, not the
thirteen-into-five-new-fleets batch that AD's turn 28 carried. designIds is constant at 95 and
fleetIds at 64 across both transitions, corroborating "no design turn, no fleet creation".
So: on the input to part 1b the predicate says NOT exposed; on the input to part 1 it says EXPOSED, via the research pick, for exactly one player.
3. Procedure and configuration
hooks=off throughout, no build (rule 24 is satisfied trivially — nothing is compiled).
| item | value |
|---|---|
| guest | VM145 sots-re-win10-145, 192.168.10.145 |
| shim build | C:\SOTS\shimdist-l4\binkw32.dll, BUILD_ID l4r-20260908T2208Z |
| config | C:\SOTS\shimdist-l4\shim.cfg.l4off, unmodified — hooks=off, installs nothing |
| why this build | lane L4 proved on this guest, with this exact DLL and this exact config that VM145 reproduces the campaign's published autosave oracle byte-identically (ai-order-capture.md §3: bb4fd9ac89f41e3b / 978041acd168b56e). It is the only hooks=off pair on VM145 with a published byte-fidelity result behind it |
SavedGames |
reset to exactly one file — the run's input save — before every launch, so the Load dialog has one row and its position is re-derived from a screenshot anyway |
| main menu | verified from a qm monitor screendump (tools/vmshot.py --one 145), never by sleeping |
| encounter query | detected by sampling the Done pixel at (233, 673): ≈(183,18,0) query up, ≈(8,8,8) map. Auto Resolve Peacefully (667,641), Done (233,673) |
VM145 as found, recorded so it can be put back (§8):
binkw32.dll 15,527,327 B sha256 903527f4a698eea9fbe25f3a6236657c7d8348f994eef394696f187e5e554b97
(= shimdist-recap, BUILD_ID recap-7584bad-20260908T0615Z)
shim.cfg sha256 0ae410cc72fe155837d711c78543e14b1f5743310cd023298eb1e5bbd5457e71 (hooks=trace, lane R recapture)
SavedGames 9 files, saved to C:\SOTS\ui\preBQ\
game not running
4. Results
(added after the runs; nothing above this line is edited)
5. Verdicts on the committed predictions
(added after the runs)
Proposed board rows
(added after the runs)