26 KiB
Resolution — the seed is in every process; it reaches the save only through an exposed decision, and exposure is a predicate on the pre-turn save
- Type: resolution (course-setting; one new measurement taken here, from saves already on disk)
- Trigger: lane AR's P7 falsified —
raid-target-pick-verdict.md§6 (twohooks=offprocesses byte-identical onar-turn37-816raiders.sav) against lane AD's §5 (94 leaves apart on the same lineage ten turns earlier) and lane AS's §5.1 (22 leaves apart on a fresh map) - Date / author: 2026-09-09 · re-resolver
- Touches: board rows 326 / 415 (AD's oracle row) / 424 (AR's oracle row);
backlog.md§2 Rung A;determinism-oracle.md;determinism-hashes.txt;method-rules.mdrule 26 (corollary, not a rule)
0. Decision
- Reading 2 wins, restated: on AR's two turns the AI reached no decision whose outcome set is
larger than one given the state. Not "no live decisions" — Player[32] changed ~100 leaves a
turn, formed a fleet, built ships, finished a tech. Not "lucky" either: the pre-turn saves say why
each turn went the way it did. On AD's turn 28 the AI entered with a batch of thirteen ships
completing, created a design and colonised a system; on AS's turn 16 it entered with
ResTNm == ''and had to pick a tech; on AR's turns 38 and 39 it entered with a target held, completed it, created no design, and put two freighters a turn into existing freighter fleets. §3 has the numbers, read off the saves. - The organising fact: the seed is present in every process on every turn; it reaches the save
only through a consumer whose outcome depends on the draw, and whether such a consumer is reached
is a predicate on the pre-turn save — rule 28's shape applied to determinism. One predicate is
already decodable:
ResTNm == ''at turn start names a research-pick turn. The build/fleet consumer that fed AD's variation is unidentified (it is not the composer — AD's two "Bravestar Mk 3" designs are byte-identical apart fromDesID). §4. - Reading 3 (a non-seed per-process cause) is not excluded on AD's state and is cheap to
exclude. Row 360 proved pinned seeds collapse three processes to one on
turn1-state, an early-game turn. AD's turn 28 is the richest AI turn we own and has never been pinned. One config-only run settles it. §6, probe 2. - AR's pair: yes, with a named precondition. It certifies exactly
ar-turn37-816raiders.sav→ (End Turn, Auto Resolve Peacefully, End Turn) →15b99255…/7a8b3d5e…, and nothing else. The half the standalone should use is the second turn,ar-oracle-A-pre.sav(Frame 38) →7a8b3d5e…: one End Turn, no encounter, four raid rolls at one word each — the first pair anywhere that exercises the trade-raid roll. Precondition: one load→End Turn run of that file must reproduce7a8b3d5e…(it has only been reached by continuation, never by load). And turn 40 is predicted to vary —ar-oracle-A-post.savcarriesResTNm == ''for Player[32] — so the pair must not be extended by a turn. §5. - No rule 29. Rules 23 and 26 produced the right behaviour without prompting — AR wrote "a pair is a statement about that procedure" before anyone asked. Nothing wrong was published; rules are written from damage. Rule 26 gets a corollary carrying the predictive tool (§7).
- Three probes, ranked, two guests, none longer than a session — §6. The one to run first is
the pinned-seed run on
ad-turn27, because it tests C-exact on a rich state and the whole Rung C restatement leans on it.
1. The surprise, stated precisely
Two hooks=off processes loading ar-turn37-816raiders.sav and taking the same two End Turns
produced byte-identical autosaves at both snapshot points; a third, instrumented process matched
them. Ten turns earlier on the same lineage, two hooks=off processes from ad-turn27-two-raiders.sav
differed in 94 leaves; on a different map, lane AS's differed in 22. AR predicted (P7) that its control
would fail like AD's. It did not.
The evidence is as strong as reported. All three lanes used their own fresh build directories
(rule 24), unmodified shim.cfg.hoff, sha256 on the files and state_checksum --floats bits --mask none with coverage proved. AR reproduced the control before running the instrument, so the 1/k
coincidence caveat does not apply. This is a real surprise, not a stale binary.
2. The instrument and the comparison — reading 4 exonerated
The three comparisons are equivalent in every way that matters: same tool, same policy, same
snapshot semantics ((Autosave EndTurn) = state when End Turn is pressed, (Autosave) = post-turn),
same hooks=off config. The only structural difference is that AR's procedure contains an encounter
query between the two End Turns, resolved identically (Auto Resolve Peacefully) in all three
processes. That is part of the procedure the pair certifies (§5), not a non-equivalence. Reading 4 is
out.
3. What the saves say — the measurement this resolution adds
All five saves are in verify/results/saves/. Three turn transitions, diffed with state_checksum --no-audit, Player[32] = "The Eternal Empire" on the AD/AR lineage, "Revenge Fleet" on AS's map:
| transition | ModCount | Player[32] leaves | research | NumDes |
ships completed → where | fleets ± | colonies | control |
|---|---|---|---|---|---|---|---|---|
| AD 27→28 | 1428→1496 (A) / 1500 (B) | 117 | BIO_TerBac held → completed, ResTNm → '' |
46→47 (Bravestar Mk 3) |
13 (ShipIDs +13 −1) → five new fleets |
−3 +7 | NumOwn 15→16 |
varies, 94 leaves |
| AR 37→38 | 2057→2108 | 107 | BIO_EnvTail held, TResDone 15495→31283 |
47 | 2 → existing Freighters 6880 / 8704 |
−3 +1 (Omikron VIII; human's Zeta lost in the encounter) | — | agrees |
| AR 38→39 | 2108→2147 | 93 | BIO_EnvTail completed, ResTNm → '', tech 5 unlocked |
47 | 2 → existing Freighters 6880 / 8704 |
none | — | agrees |
| AS 15→16 | — | 22 differ | ResTNm == '' at turn start → pick (64 in A, 62 in B) |
15 | — | — | — | varies, 22 leaves |
Three further facts from the same files:
- AD's varying design is not the composer varying.
Des["Bravestar Mk 3"]inad-oracle-A-postand-B-postare byte-identical apart fromDesID(2002 vs 2018). What differs between A and B is which id the design and the new fleets drew (in B a fleet took 2002 first — the command block was applied in a different order), which design was queued atSys[272](978 vs 962), how the thirteen ships were split into fleets (B has one more fleet,ModCountfour higher,Maint2,500 lower), and theShipRecsper-design counts that follow. That is the AI's build/fleet-assignment layer, plus id allocation downstream of it. - AD's variation was not a research pick. Player[32] entered turn 28 with
ResTNm = 'BIO_TerBac'and completed it; the pick is deferred to the next turn. AS's was: its Player[32] entered turn 16 withResTNm == ''(PlyrIdx 1 inas-turn15-spydeployed.sav), exactly the shape row 326 recorded onturn1-state. - AR's Player[32] enters turn 40 with
ResTNm == ''(ar-oracle-A-post.sav, PlyrIdx 1). By the AS precedent that is a pick turn.
So the three lanes measured three different things: AD a heavy build/fleet/colony turn, AS a pick turn, AR two quiet-consumer turns. The seed was per-process in all three. It showed in two.
4. The readings, ruled
| reading | verdict | what falsifies it |
|---|---|---|
| 1 — convergent by luck: every AI decision happened to land the same regardless of seed | Rejected as stated, and the half-truth in it is reframed. The agreement is not a random pick landing twice; it is the AI not reaching a consumer whose outcome set is larger than one. The saves show why (no pick, no design, forced ship placement), so it is explicable, not lucky. What is true: the same lineage becomes exposed again one turn later. | A per-client draw ledger (probe 3) showing a non-singleton-outcome site firing on AR's turns 38/39 with the same return addresses as on AD's turn 28 — i.e. the same decision being made with the outcome coinciding. I predict it will not show that. |
| 2 — the state pins the AI: eliminated players, exhausted research, no live decisions | Wins, restated as "no exposed decision reached". Player[32] is alive, rich, researching, building; it simply had no decision on those two turns whose result depends on the client stream. Exposure is a property of (state, turn), decidable from the pre-turn save for the research consumer and observable after the fact (NumDes, completions, NumOwn) for the others. |
Probe 1: if ar-oracle-A-post → turn 40 agrees across two processes, the pick went through producer A/B and the predicate needs the producer gate — the reading survives, the predicate narrows. If it disagrees in the TechTree leaves, the predicate is confirmed. |
| 3 — a non-seed per-process cause behind AD/AS that AR's state does not trigger | Not excluded on AD's state. AS's variation has the row-326/360 signature exactly. AD's is a reordering plus one different choice in the command block — the shape an ASLR-ordered container would also produce, and the shape the 09-08 resolution withdrew for the research pick but never tested on a build turn. Row 360 pinned an early-game turn. | Probe 2: pinned seeds on ad-turn27, two processes. Identical ⇒ dead. Different ⇒ alive, and the diff localises it; that becomes a new resolution trigger, because C-exact would then be false on rich states. |
| 4 — non-equivalent comparisons | Excluded (§2). | — |
Inference vs measurement, marked. Measured: the three transitions above, the design bodies, the
pre-turn ResTNm values. Inference: that the build/fleet consumer draws on the client stream at all
(the six direct NextInt sites in the AI band are three in DesignNameGen_Read and three in the
schedule family at 0x0069dbxx; cl_RandRange/cl_Chance façade calls and any inlined draw are
not in that list — rule 16), and that AS's and AD's variation share a cause. Probes 2 and 3 convert
both.
One consumer with a fuse, worth writing down. 0x0069dbb0 draws NextInt(37) once per agent,
lazily, and schedules something at now + 3 + rand(0..37). If agent+0x36c is not persisted
(the 35 StrategyAIAgent tags do not obviously carry it), it is re-drawn on every load — a
per-process quantity that cannot fire inside a two-turn window from load and can fire on any
turn from the third onward. AR's two-turn pair is structurally shielded from it; AR's six-turn R1 was
not, and R1 was one process. This is the concrete reason a certification cannot be extended by
turns even in principle. Inference; the ledger reads it.
5. The standing claims
| claim | verdict | scope / correction |
|---|---|---|
Row 326 / resolution 09-08: the AI client seed is per-process; variation on turn1-state is a seed effect |
survives | Scope is now explicit: the seed exists on every turn; it is visible only on exposed turns. The seed is a fact about the process; exposure is a fact about the (save, turn). |
| Row 360: pinned seeds collapse three processes to one | survives, with a scope | Proved on turn1-state (early game, five build orders, one candidate walk). Not yet proved on a rich turn — probe 2. |
| Lane AD §5 / row 415: "no oracle pair for this state; the variation is the AI's decisions" | survives with a qualification | The variation is the AI's build/fleet-assignment/colony layer and the id allocation downstream of it — not the design content, not a research pick (ResTNm held). Its consumer is unidentified. AD's attribution "the per-process AI seed" is the likeliest cause and is untested on that state (probe 2). |
| Lane AS §5.1: 22 leaves, the research pick, the known per-process seed | survives unchanged | Pre-turn ResTNm == '' confirmed from as-turn15-spydeployed.sav; the pick turn was predictable from the input. |
| Lane AR §6: "a rung-A oracle pair … AD's result is a fact about that state, not the lineage or the engine; no explanation offered" | survives, and is now explained | The explanation is §3. AR's refusal to infer was right and the inference would have been wrong in both obvious directions ("the AI is forced here" / "luck"). |
AR §6.1: probes=8 + draw_sites + boundary ledger is behaviour-neutral at whole-save granularity |
survives, scoped | On a state with no exposed decision. It is the strongest neutrality statement available for that instrument; it says nothing about an instrument's effect on an exposed decision, which no lane has measured. |
| AR §7: "this state now has an unconditional rung-A pair" | qualified | Conditional on the procedure (two turns, one peaceful auto-resolve, this build), and on the load→turn precondition for the single-turn form (§5). Not unconditional; nothing is. |
Backlog §2 Rung A: canonical pair turn2-state → turn3-state |
survives | AR's pair joins it as the first trade-raid pair, after the precondition is discharged. |
| Backlog §2 Rung C-exact: "nothing else per-process reaches the turn" | survives as a measured property of one turn; open on rich turns | Probe 2 is the test. If it fails, C-exact is restated as "given seeds and whatever else is per-process", and that something must be named. |
| Resolution 09-08 §6: "combat turns are not yet known to be cross-process reproducible" | survives; one datum added | AR's turn 38 carried an encounter query auto-resolved peacefully and reproduced across three processes. "Peacefully" almost certainly bypasses RunCombatRound and its per-process consumer, so this does not discharge the warning; it shows the query/resolution plumbing is reproducible. Inference on the bypass. |
| Rule 26's control discipline | survives; gets a corollary | §7. |
6. The probes, in order
Probe 2 first — pinned seeds on the heavy turn. VM146 (free). ad-turn27-two-raiders.sav,
aiseed=pin (lane CB's shim.cfg.cbpin mechanism — the ctor-argument overwrite, not
airng.pin_seed, which re-seeds at bracket entry and is a declared perturbation), two fresh
processes, one End Turn each, compare. The save has seven non-human players, so use the wildcard
(aiseed.values=*=<hex>) or list every net id from one aiseed=log run first; a half-applied pin
set is refused by design. Every other hook off. Prediction, committed: the two autosaves are
byte-identical; state_checksum prints IDENTICAL over ~67k leaves. If they differ: reading 3 is
alive on rich states, the diff localises the non-seed input, and C-exact is restated — that is a
resolution trigger, not a lane result. Cost: two loads, two turns, ~25 minutes on that guest.
Probe 1 — the predicate's own prediction. VM145 (free), two runs.
(1b, the precondition) load ar-oracle-A-pre.sav (Frame 38, 15b99255…), hooks=off, End
Turn once. Prediction: (Autosave).sav = 7a8b3d5e…. Holding ⇒ the single-turn pair is
certified as load→turn and enters determinism-hashes.txt. Failing ⇒ the pair is valid only as the
two-turn procedure from turn 37, and the resave canonicalisation (determinism-oracle.md,
round-trip section) is the first suspect.
(1, the exposure test) load ar-oracle-A-post.sav (turn 39, 7a8b3d5e…) in two fresh
processes, hooks=off, End Turn once, resolve any query peacefully in both. Prediction: the two
files differ, confined to Player[32] TechTree/*, ResTNm, otch, Events,
turnstats/…/tch and Summary/Checksum; /Sim/RNG, /Sim/trdmgr, every Player[16] leaf and
every player-0 fleet identical. If they agree: producer A or B supplied the target (as for
player 32 on turn1-state) and the predicate needs the producer gate — one run with lane L4's
airesearch=on dump names which producer returned non-null. Either outcome is a result.
Probe 3 — the per-client draw ledger, on both states. Lane Z's RngLedger shape keyed on
this == StrategyClient+0x134 per AI client, return-address attributed, on ad-turn27 → 28 and on
ar-oracle-A-pre → 39. The sites that fire on AD's turn and not on AR's are the consumers behind
the build/fleet variation; the bound of each NextInt gives its outcome-set size, which is the
predicate in machine-readable form. This is the C-exact prerequisite row 360 already names — not
new work, the next rung of it, now with two states that make it decisive. Prediction: AR's turn
39 shows per client the surrender cl_Chance (one word, 0 % — forced) and the composer's price
query (ship-design-composer.md §5.6 shape); AD's turn 28 shows those plus sites in the fleet-task
and build paths with bounds > 0.
Do not spend a static lane on the build consumer before probe 3 has named its return addresses (rule 18).
7. Rule 26, corollary (c) — draft for method-rules.md
Append to rule 26, after (b):
(c) A control that agrees certifies a procedure, not a state — and it means "no exposed decision was reached", never "the AI is deterministic here." Three lanes in one day:
ad-turn27 → 28varied in 94 leaves (the AI's build, fleet-assignment and colony choices on a turn where thirteen ships completed, a design was created and a system colonised);as-turn15 → 16varied in 22 (a research pick, on a turn the AI entered withResTNm == '');ar-turn37 → 39, the same lineage as AD ten turns on, agreed byte-for-byte across three processes — on two turns where the target was held then completed, no design was created and two freighters a turn joined existing fleets. The per-process seed was present in all three. It reaches the save only through a decision whose outcome set is not a singleton given the state, and whether such a decision is reached is a predicate on the pre-turn save — rule 28's shape:ResTNm == ''names a pick turn;NumDesmoving names a design turn; a batch of completions names a fleet-assignment turn; one consumer (0x0069dbb0) has a 3–40-turn fuse and cannot show inside two turns of a load. So: record the pair as (save, procedure, hashes) and write the exposure facts next to the hashes; never extend a certified pair by a turn without its own two-process agreement (ar-oracle-A-postenters turn 40 withResTNm == ''and is predicted to vary); and when a control does vary, decode which consumer was reached before reasoning from the leaves — "the AI varies per process" is a fact about a turn, not about the engine.
Ranked by damage: none this time. AR applied the discipline unprompted and refused the inference; that is why this is a corollary and not rule 29. Rule 23 already carries the general principle ("a statement about the states that occurred"), and rule 26 already demands the two-process agreement; (c) adds only the predictive tool and the standing instruction not to extend.
8. Course
VM146 — probe 2, now. Brief, one paragraph: Load ad-turn27-two-raiders.sav in two fresh
processes with the AI client seeds pinned by lane CB's aiseed=pin (wildcard or all seven net ids
from a prior aiseed=log run; the shim refuses a partial pin set), every other hook off, one End
Turn each. Compare sha256 and state_checksum --floats bits --mask none. Prediction committed above:
IDENTICAL. If not, do not analyse — post the leaf diff and stop; that is a resolver case. Do not
compare any pinned file to AD's unpinned files (rule 19: the pin is a declared perturbation).
VM145 — probe 1, now. Brief: Two runs from saves on disk, hooks=off, no build needed.
(1b) ar-oracle-A-pre.sav + one End Turn: expect 7a8b3d5e…. (1) ar-oracle-A-post.sav + one End
Turn in two fresh processes: expect the files to differ inside Player[32]'s research leaves and
nowhere else; localise with state_checksum and report the leaf list whichever way it goes. Record
the pre-turn ResTNm of every AI player next to each hash. If a query appears, Auto Resolve Peacefully in both.
Lanes AP (VM144) and AZ (VM141) — no redirect; one addition to each brief. Any hooks=off
control you take: record, next to the hashes, each AI player's pre-turn ResTNm, NumDes, NumOwn
and the number of ships completing that turn. If the two processes disagree, localise with
state_checksum and name the consumer class (pick / design / fleet-assignment) from the leaves
before reading any number off the run; your numbers are valid on the sub-tree that agrees, as AD's
were.
Probe 3 goes to whichever of VM145/VM146 frees first, as a lane with lane Z's ledger and
this recorded — it is the C-exact prerequisite and RB/CB's capture format should carry its output.
Backlog §2, Rung A bullet — append:
Second pair, first to exercise the trade-raid roll:
ar-oracle-A-pre.sav(turn 38) →7a8b3d5e…(lane AR, three processes, one instrumented), four raiders parked,OnAllCombatDone_Tail= 4 words, no encounter. Entersdeterminism-hashes.txtonce one load→End Turn run reproduces the hash (probe 1b). The two-turn form fromar-turn37-816raiders.savis also certified but carries a peaceful auto-resolve between the turns. Do not extend either by a turn: Player[32] enters turn 40 withResTNm == ''— a predicted research-pick turn.
Docs to correct in place (rule 11): determinism-oracle.md — add the exposure paragraph
(§3/§4 here) under "Qualified"; determinism-hashes.txt — AR's pair after probe 1b, with the
exposure facts on the same line; raid-gate-multiplicity.md §5 — footnote that the variation is the
build/fleet layer with the design content identical, consumer unidentified, pin probe queued.
Proposed campaign/board.md rows
New row:
| SEED EXPOSURE IS A PREDICATE ON THE PRE-TURN SAVE - why AR's control agreed where AD's and AS's did not | meta | verified | high | 100% | 2026-09-09 | Resolver, on lane AR's falsified P7 (`findings/resolutions/2026-09-09-seed-exposure-is-a-predicate.md`). Three lanes, three controls, one mechanism: the per-process AI client seed (row 326) is present on EVERY turn and reaches the save ONLY through a decision whose outcome set is larger than one given the state. Read off the saves on disk: **AD 27->28** - Player[32] completed BIO_TerBac (no pick: ResTNm held), created a design (NumDes 46->47; the two "Bravestar Mk 3" bodies are BYTE-IDENTICAL apart from DesID 2002/2018), colonised a system (NumOwn 15->16), completed THIRTEEN ships into five new fleets - and A/B differ in the build choice at Sys[272] (978 vs 962), the fleet split (B one fleet more, ModCount 1496 vs 1500), and id allocation ORDER downstream. **AS 15->16** - Player[32] entered with ResTNm == '' and picked (64 vs 62). **AR 37->38, 38->39** - Player[32] held BIO_EnvTail then completed it (pick deferred), NumDes constant at 47, two freighters a turn into EXISTING Freighters fleets, one encounter auto-resolved peacefully: ~100 leaves moved per turn, all forced, three processes agree. READING: not luck, not a pinned AI - no EXPOSED decision reached; explicable from the pre-turn save. ResTNm == '' names a pick turn (rule 28's shape); NumDes/NumOwn/batch completions name the others; 0x0069dbb0 has a 3-40-turn fuse and cannot show within two turns of a load. **Player[32] enters turn 40 with ResTNm == '' - AR's pair MUST NOT be extended by a turn.** RUNG A RULING: AR's pair is certified for its procedure; the single-turn form `ar-oracle-A-pre.sav -> 7a8b3d5e...` is the standalone's first trade-raid pair ONCE one load->End Turn run reproduces the hash (probe 1b, VM145). OPEN: the build/fleet consumer behind AD's variation is UNIDENTIFIED and reading 3 (a non-seed per-process input) is NOT excluded on rich turns - row 360 pinned an early-game turn only. PROBES: (2) VM146, `aiseed=pin` on ad-turn27 x2 fresh processes, predict IDENTICAL - if not, resolver case; (1) VM145, ar-oracle-A-post + 1 End Turn x2, predict DIFFER in Player[32] TechTree/ResTNm only; (3) per-client draw ledger on both states - the C-exact prerequisite, now decisive. No rule 29: rules 23/26 produced the right behaviour (AR refused the inference); rule 26 gets corollary (c) |
Edits to existing rows:
- Row 424 (AR's oracle pair) — append:
SCOPED by the resolver 2026-09-09: the agreement is explained (no exposed AI decision on turns 38-39: target held then completed, no design, forced ship placement) and it does NOT transfer - Player[32] enters turn 40 with ResTNm == ''. Use the second turn, ar-oracle-A-pre.sav -> 7a8b3d5e..., as the standalone's pair after probe 1b reproduces it by load. The peaceful auto-resolve on turn 38 reproduced across three processes but almost certainly bypasses RunCombatRound; the combat-turn warning (resolution 09-08 §6) stands. - Row 415 (AD's oracle row) — append:
EXPLAINED IN PART 2026-09-09 (resolver): the variation is the AI's build/fleet-assignment/colony layer and the id-allocation order downstream of it - NOT the design content (byte-identical apart from DesID) and NOT a research pick (ResTNm held). Consumer unidentified; the pin probe on this state (VM146) decides whether it is the seed at all. - Row 326 — append:
The shape recurs and is now a predicate: pick turns (ResTNm == '' at turn start: turn1-state, as-turn15) and heavy build turns (ad-turn27) expose the seed; quiet-consumer turns (ar-turn37 -> 39) do not. Resolver 2026-09-09. - Row 360 — append:
SCOPE: proved on turn1-state (early game). The rich-turn test is ad-turn27 pinned, queued on VM146. - Row 62 — VM145: probe 1 (two saves on disk, hooks=off, no build); VM146: probe 2 (
aiseed=pinon ad-turn27). VM140 untouched.