Commit graph

361 commits

Author SHA1 Message Date
alex
f1306713d1 lane BT merged: --relabel-new-ids ships with both acceptance halves and five refusing guards 2026-09-09 04:13:35 -04:00
alex
d46b3f8391 state_checksum: --relabel-new-ids, comparing a pair modulo this turn's new id labelling
Implements the 2026-09-09 fleet-id-order resolution, section 3 item 1.  Given the
pre-turn save, compute the ids new in each post-turn save, match the client-minted
(node nibble != 0) new fleets by a key that does not mention the id -- (LocID or
FPlan destination, sorted ship-id set) -- build the bijection pi, rewrite every
fleet reference, compare the master id lists as sets, mask /Summary/Checksum with
its reason on the line, and print pi.

Acceptance, both halves:
  bp-pinA vs bp-pinB     IDENTICAL modulo pi = {1970<->1986}   (35 leaves -> 0)
  ad-oracle-A vs -B      REFUSED, then DIVERGED: 94 leaves     (unchanged)

Five guards, every one refusing rather than degrading: only ids absent from the
pre-turn save; only non-zero node nibbles; pi must permute one set; content keys
must correspond one-to-one and be unique per side; and no leaf anywhere may hold a
permuted id at an unmodelled site (matched on raw bytes, not the reader's typed
value).  A refusal rewrites nothing and falls back to the ordinary comparison.

Three corrections to the specification from contact with the data, in
findings/subsystems/relabel-new-ids.md section 4: FtName is an id-attached label
and needs the same treatment as the id; relabelling the Flt[] keys is the wrong
operation (exchange the bodies -- the fleet table is id-ordered and identical in
both saves); a node's new-id set spans object kinds.

Default path proven unchanged: pre- and post-change modules agree on the root
digest, coverage, mask hits and every (path, digest) in the tree over all 43 saves
under two policies, and on 5,602 lines of CLI stdout across every mode.

Also fixes a pre-existing, unrelated test failure: the re-save localisation test
enumerated pairs over sorted filenames and hard-coded the direction 4 -> 0, which
a later corpus addition reversed.  Suite 38 -> 62 tests, all passing.
2026-09-09 04:12:01 -04:00
alex
2338ad40dd board: the gather ordering contract is bound in the engine 2026-09-09 03:41:44 -04:00
alex
d6f725a7ae lane BU merged: H1 confirmed, the visit key is fleet->Location, the outcome set is two heap pointers 2026-09-09 03:39:27 -04:00
alex
696935ea2a lane BU: H1 confirmed - the fleet-visit order is ascending fleet->Location, and the two-file outcome set is the two orderings of two heap pointers
Three fresh processes on ad-turn27 with the seeds pinned, hooking the two
single-caller per-element callees of the assignment walk.

  * ascending fleet->Location: 6 of 6 multi-element sequences
  * ascending element address (the committed prediction P3): 0 of 6
  * ascending fleet id / systemId / minimum ship id: 0 of 6 each

Three processes gave three different orders of the same six fleets, and every
difference is a pair whose Location addresses exchanged relative order. Runs 1
and 2 wrote byte-identical autosaves and still visited differently. Run 3
flipped the branch and its two Location addresses flipped with it: it is
byte-identical to lane BP's run B, runs 1 and 2 to BP's A and L.

So P3 is falsified as written and its hypothesis class, H1, is confirmed with
a sharper key. H1b is excluded on this path.

Second finding the static read had missed: the fleets already carry their new
ids when the walk first touches them, so the mint is upstream in the gather.
That moves the engine's canonicalisation point by one level.

rule 26(d) and rule 19 are both met by measurement rather than argument: an
instrumented pinned run reproduced an unpinned natural run byte for byte,
twice.
2026-09-09 03:38:22 -04:00
alex
232550595d lane BU: run 1's result reshapes the prediction; the run-2 test committed before run 2 finished
Run 1 falsified P3 as written -- the walk is NOT ascending element address,
0 of 5 sequences -- and handed back a sharper key: it is lexicographically
ascending in (fleet->Location*, fleet*), 5 of 5. Both are heap addresses.

Run 1 also found something the static read had missed: the newly minted fleet
ids are ALREADY on the fleet objects when the assignment walk claims them, so
the id-to-group pairing is decided upstream of AssignFleetsAndIssueOrders.

The cross-process test that separates 'the Location pointer is the key' from
'the Location pointer is a correlate' is committed here, while run 2 was still
loading and before its autosave existed.
2026-09-09 03:25:02 -04:00
alex
ca6782f4ff lane BU: the fleet-visit-order prediction, committed before the run
Stage 2 of the chain lane BR unblocked. H2 (an RNG draw) is dead by
measurement, so the visit order over the ship groups is either a function of
the walked elements' addresses (H1) or of nothing in particular (H1b).

The committed prediction is P3: the visit order is ascending element address,
and across two processes the element order differs exactly where the visit
order differs.

Also the bounded static read this lane took to place the hook: the walk is a
plain index walk of a std::vector<StarFleet*> whose _Mylast is refetched every
iteration, bracketed by two loops over the same vector that call one function
each -- and those two functions have exactly ONE caller each in the whole
image. So the hook is two ordinary function entries plus a bracket, not a
mid-function patch of a loop body whose first instruction is a branch target.
Rule 17 discharged: the body is 0x006c16c0-0x006c247a ret, with a four-entry
jump table living past the ret at 0x006c247c.

ghidra/addresses.d/bu.json carries the two new names and the agent offset; it
deliberately does not re-declare AssignFleetsAndIssueOrders, which lane AI3
owns.
2026-09-09 03:15:19 -04:00
alex
51243ef8b3 lane BS merged: the per-history residue is an absent Colonize task; BR's generator row scoped to encounter-free turns 2026-09-09 03:14:28 -04:00
alex
1bae6552d6 BS: cross-reference lane BR - the global generator's three-word seed mint reproduces, and it is not the whole story on an encounter turn 2026-09-09 03:13:15 -04:00
alex
3fa3ff942f BS: the per-history residue is a Colonize task the save does not carry - both routes reproduced their hashes under instrument 2026-09-09 03:11:12 -04:00
alex
aa8d3fb39e lane AZ merged: three species short-circuits not one, frac polarity inverted in two published findings, tscr is not a corpus constant 2026-09-09 03:03:25 -04:00
alex
2ad6652eac AZ: correct the archived save's size, stage both states, and add the pre-loss turn-11 save
az-turn23-tarka-comraid.sav is 89,285 B not 73,385 (that number was the
turn-11 file's). Both saves are now on the guest as well as in the repo.
az-turn11-16destroyers.sav is the same game with the 16-destroyer fleet
still alive and Commerce Raiding already in hand - it saves ten turns of
play for anyone retrying the player's own raider, though the AI's first
routes do not appear until turn 16.
2026-09-09 03:00:29 -04:00
alex
dde03ee6a6 AZ: the species gate has THREE conjuncts and the polarity is 0.0 - plus the first Tarka save
Static half, verified and correcting two published sentences:
FUN_00820af0 short-circuits on the ROUTE OWNER being Hiver (0x00820bc2),
on the RAIDER's crew species being Hiver (0x00820bd7), and only then on
SpeciesDef+0x144 (Human, Zuul). The campaign's 'Human or Zuul draws
nothing, every other species draws' is incomplete on both sides. And the
short-circuit sets frac = 0.0, not 1.0 - corrected in ag.json in place.

Live half NOT taken. hooks=off throughout; no instrument was armed. The
workload was built to within one conjunct: az-turn23-tarka-comraid.sav is
the corpus's first Tarka empire, has Commerce Raiding, three AI routes and
five AI Tarka fleets parked on sector nodes with Pos bit-equal, two of
which clear G0-G4. The failed conjunct is G_B3 - the qualifying raiders
own every route, so relation-to-self is 3 and B empties its candidate
list. The next workload is named from that: give player 0 a route sourced
in sector 768, where the AI raider already stands.

tscr reads 127 on this map, not 252/253 - the mask is not a corpus
constant and my own P3 gave the right count for the wrong reason.
2026-09-09 02:58:06 -04:00
alex
96f2da8d2f vmshot: make Pillow optional so --one works anywhere, and document the invocation that supplies it 2026-09-09 02:52:56 -04:00
alex
a0caaa32fa lane BR merged: RNG excluded by measurement, the global generator only mints seeds; first replayable rich-turn record 2026-09-09 02:52:04 -04:00
alex
2ff901e678 BR: RNG excluded by measurement - zero foreign draws in all three AI brackets, and the global generator is drawn 3x in a process to mint the AI seeds; plus the first replayable rich-turn record 2026-09-09 02:51:01 -04:00
alex
15c44711c1 BS: predictions for the per-history residue, committed before the runs 2026-09-09 02:33:01 -04:00
alex
a05f54d2b0 BR: predictions committed before the run - P1-P4 of the fleet-visit-order resolution, on VM146 2026-09-09 02:23:32 -04:00
alex
8552720ea8 rule 11 corrections: AD's 94 leaves decompose 59+35, list 10 is OnCommand_TransferShips, BP's income claim marked as inference 2026-09-09 02:22:24 -04:00
alex
05db2b30af resolver: the residue is fleet VISIT ORDER not id allocation, and the block records it; rule 26 gains (d), my 26(c) over-read corrected 2026-09-09 02:19:33 -04:00
alex
fca5c6cd56 lane BQ merged: load-boundary scope on AR's pair, peaceful auto-resolve is not combat-free, rule 26(c) marked as a screen not a decision procedure 2026-09-09 02:15:42 -04:00
alex
c43f638bc0 BQ: cross-reference lane BP's probe 2 - both lanes landed on the AI fleet layer
BP has a per-PROCESS input (two pinned processes disagree); this lane has a
per-HISTORY input (two load processes agree with each other and disagree
with the continuation). One datum against the ASLR reading as stated: the
exe base was identical in all five VM145 processes (0x00f40000, delta
+11796480), so any image-base hypothesis has to name which allocation it
means. Probe 3's ledger taken twice on ar-oracle-A-pre - once by
continuation, once by load - now speaks to both.
2026-09-09 02:13:22 -04:00
alex
a264529b88 BQ: probe 1 run - the load->turn pair is not the continuation's, and turn 40 varies by COMBAT, not by the research pick
Both committed predictions are wrong, in different and useful ways.

1b FALSIFIED: ar-oracle-A-pre.sav + load + one End Turn gives 4c356f59...,
not 7a8b3d5e... - and gives it byte-for-byte in two fresh hooks=off
processes. 23 leaves apart from AR's continuation, 17 of them one AI fleet
(Zeta Fleet V moved in the continuation and stayed put after a load). So
AR's second hash may NOT enter determinism-hashes.txt as a load->turn pair;
the load form is certified instead. The resave canonicalisation is
exonerated: the pre-turn round trip differs in exactly one leaf,
/CD[1]/NPrvVa, +5.00 per load - which also corrects determinism-oracle.md's
"nothing else varies".

Probe 1: the two files DIFFER, and /Sim/RNG, /Sim/trdmgr and every player-0
fleet are identical as predicted - but ZERO TechTree and ZERO ResTNm leaves
differ. Both processes picked BIO_GrvAdpt. The 144 leaves are a combat at
Venkman: Auto Resolve Peacefully means the human commits no ships, not that
no combat occurs, and the planet's defences killed two raiders in one
process and one in the other.

The producer run (config already on the guest, no build) names why the pick
agreed: producers A and B both returned null, Player[32] reached the
candidate walk, and candidatesTried=1. The outcome set is a singleton by
COUNT, not by producer gate - so ResTNm == '' is necessary for research
exposure, not sufficient.

VM145 restored byte-for-byte and released.
2026-09-09 02:12:15 -04:00
alex
10ddf09cb4 lane BP merged: C-exact false on a rich turn, residue is one fleet-id transposition; rule 26(c) qualified 2026-09-09 02:02:10 -04:00
alex
371f789ade BP: guest released - VM146 restored and hash-verified, hold ended
shim.cfg back to hooks=off, binkw32.dll back to the pre-BP file, both autosaves
restored byte-identical, game process left not running as found.
ad-turn27-two-raiders.sav is deliberately left on disk, so the Load-dialog rows
have moved on this guest.
2026-09-09 01:57:45 -04:00
alex
746a6f29cb BP: probe 2 result - pinned seeds do NOT collapse a rich turn; the residue is one fleet-id transposition
P1 falsified. Two processes with identical pinned AI client seeds produced
different turn-28 autosaves from ad-turn27-two-raiders.sav, so a per-process
input other than the seed reaches a rich turn and C-exact is false on this
state. Resolution trigger, handed back rather than chased.

But the pin did almost all the work. AD's unpinned pair differed in 94 leaves
across designs, ship records, money, both build queues, ModCount, NumFlts,
DesignIDs[] and FleetIDs[]. This pinned pair differs in 35 of 61147, and all 35
are one transposition: fleets 1970 and 1986 exchange their entire contents.
Every decision leaf is identical.

The command block says the same from the input side. Runs L (unpinned) and A
(pinned to L's observed seeds) wrote BYTE-IDENTICAL autosaves, which gives a
noise mask no previous lane could build for this state; against it, A and B
differ in exactly three words - one fleet-move fleetId and two systemIds - and
list 10's fleet ids are in the same order in both. The id counter is
deterministic; what varies is which newly formed ship group each id lands on.

Also measured: the save has seven non-human players and the engine builds THREE
AI clients (RunAI fires 3x, ids 32/496/512); the four NPC factions get no client
and no seed.
2026-09-09 01:56:49 -04:00
alex
1c30a95c9d lane AP merged: P is two species branches not three sites; three gates closed; rule 23 gains predict-at-the-site 2026-09-09 01:36:22 -04:00
alex
f14e845e87 AP: the row-62 replacement text for the board, written out rather than cross-referenced 2026-09-09 01:34:09 -04:00
alex
2ac52350f0 AP: P's three draws are two species branches - 0x00840a3c fires, 0x0088dc43 fires, the deploy NextFloat measured
From as-turn15-spydeployed.sav, 11 End Turns under probes=8. Detection at Frame
22, P at Frame 25: 0x00840a3c 1 call / 1 word, the first firing of any of P's
sites. 0x00840929 and 0x008409c7 are the MORRIGI branch and cannot be reached in
a Human game - correcting every inventory that lists them as three sites behind
one gate. The counter-mission roll 0x0088dc43 fires from Frame 19 (corpus was 0
of 22) and the deploy NextFloat 0x0078c97f is measured with cbh reproducing lane
AS's value bit for bit. Species table decoded, which also names AS's 0.75f as
Zuul and 0.5f as Morrigi. Two corrections to lane AG 3.2 (CnTrd is the target's;
ncp is a scalar counter). PB4 was wrong and is named: the trade-raid roll entered
the tail at Frame 20, re-confirming lane AD's per-fleet model. Control pair
disagrees (three outcomes in six processes) - not a calibration pair - and
probes=8 is byte-identical to a control over 44,438 leaves. Exposure fields
recorded per turn: saturated on this map.
2026-09-09 01:33:23 -04:00
alex
e923d2928c BP: probe 2 prediction, committed before the run
Probe 2 of the 2026-09-09 resolution: pin the AI client seeds on
ad-turn27-two-raiders.sav -- the richest AI turn the campaign owns, and the one
whose hooks=off control varies in 94 leaves -- and run two fresh processes.

Committed prediction: the two autosaves are byte-identical and state_checksum
prints IDENTICAL over ~67k leaves. If they differ, reading 3 is alive on rich
states, C-exact is false on the turns that matter, and that is a resolution
trigger rather than a lane result.

Also records, before any run: the exposure facts for all eight players read off
the input save, and the observation that four AI players enter this turn with
ResTNm == '' while contributing none of AD's 94 leaves -- all four have
NumOwn == 0, so 'ResTNm == emptystring names a pick turn' is necessary and not
sufficient.
2026-09-09 01:10:55 -04:00
alex
be1426630c BQ: probe 1 predictions, committed before either run
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.
2026-09-09 01:04:12 -04:00
alex
947f205867 board: scope the C-exact proof to the early-game turn it was demonstrated on 2026-09-09 00:56:53 -04:00
alex
0029d022f2 resolver: seed exposure is a predicate on the pre-turn save; rule 26 gains corollary (c) 2026-09-09 00:56:38 -04:00
alex
1fecff8af0 AZ: predictions for the raid-intercept species word, committed before the build
The brief's gate ('Human or Zuul draws nothing, every other species draws')
is incomplete in two places, found by reading FUN_00820af0 before touching a
guest: species 1 (Hiver) short-circuits too, and the ROUTE OWNER's species is
a gate of its own. The species enum is read from the InitTable jump table as
bytes: 0 Human, 1 Hiver, 2 Tarkas, 3 Liir, 4 _NPC, 5 Zuul, 6 Morrigi.

Corpus counted against the predicate (rule 28 practice 5): 0 of 30. 24 saves
hold a Tarka AI - a drawing species - but tscr is 253 in every one, so the AI
has no Commerce Raiding and never rolls. The workload has to be built.

Tarkas chosen: the tech data gives it a 100% path to CCC_ComRaid via
CCC_FTLEcon, where Hiver has 0% on both edges.
2026-09-09 00:53:00 -04:00
alex
e935ec5880 lane AR merged: TradeManager+0x0c writer found, the raid pick FIRES, and an oracle pair exists on this state 2026-09-09 00:39:07 -04:00
alex
c37eb0e79b AR: use the existing g_SpeciesDefTable name in the fragment prose 2026-09-09 00:37:43 -04:00
alex
db4fda269f AR: header dates and status line 2026-09-09 00:37:25 -04:00
alex
df9431be64 AR: the raid target pick FIRES - TradeManager+0x0c is the per-system containing-sector table
Decides lane AG's section 3.3 final paragraph, which lane AD correctly reported
it could not separate on sector 832.

STATIC: FUN_00841700 is the writer AG's section 7 lists as not found. It resizes
the +0x0c vector to the length of the systems vector -- the container trfr indexes
-- and fills it with containingSector[system.Idx] = sector. It runs from the
deserialiser, so a loaded save has it populated. G_B1a cannot reject a valid trfr.

LIVE: four raiders parked (2 CR on sector 832, 2 DE on sector 816), probes=8.
Slot13RngCalleeA entered 4x/turn at 4 words every turn; on turn 42 the pick fired
at 0x0088b613, calls=1 words=1, and the tail cost 5 words against 4 elsewhere.
The same run carries its own control: B entered on 832 twice at 0 words.

B costs ONE word, not two: FUN_00820af0's third short-circuit is a flag word
InitTable sets only for Human and Zuul, so AG's committed 3-words-on-success is 2.

Two hooks=off processes gave byte-identical autosaves, and so did a probes=8
process -- an oracle pair and a whole-save byte-neutrality proof for the
instrument, both firsts on this lineage.

Also first firings of 0x008939ee (rule 20's case study) and 0x00820c1b.
2026-09-09 00:36:32 -04:00
alex
f8ff1b6fa9 AP: predictions for the spy program's remaining draws, committed before the build
P's three sites are two mutually exclusive branches on the spy owner's Species;
only 0x00840a3c is reachable from a Human empire. Species table decoded from the
corpus. Predicted trajectory for the 20-turn wait, including the counter-mission
roll 0x0088dc43 firing at Frame 19, and the deploy NextFloat 0x0078c97f.
2026-09-09 00:25:11 -04:00
alex
5e4c27772d lane AS merged: the detection roll fires, spies2 closed, rule 28 grown to six practices 2026-09-09 00:14:24 -04:00
alex
aef3d487f3 AS: correct this lane's own over-claim -- 0x0083ce50 is a shared placement validator, not the spy-deploy path 2026-09-09 00:12:21 -04:00
alex
4a212e25b4 AS: the spy detection roll fires -- 1 word, gated on a usable asteroid belt; spies2 closed
Mars::RNG::Chance at 0x00887c8a, in the BODY of ServerSpyManager::vslot13 (tail
phase 23 call 9), measured at 1 call / 1 word / no_draw_calls=0 / strategic=true
on VM144 at probes=8, with OnAllCombatDone_Tail going 363 -> 364 against 0 on
every turn any lane has measured. The entry probe on SpyManager::Slot13RngCallee
read 0 on the same turn -- that zero was never about the subtree.

Predicate, decoded to save fields: spy.deat != 0 && spy.sdet == -1 &&
sys(deat).ARes2 > 0 && (sys(deat).TerrFl & 1). Corpus count 0 of 22; the failed
conjunct is deat != 0, not the belt -- all 22 corpus saves already had one.

Also: ServerSystem::AddSpy 0x007514c0 writes deat and pushes the spy id into
ServerSystem+0x1cc in the same two instructions, so spies2 is the per-system
DEPLOYED-spy vector; measured non-empty for the first time in the corpus.
And 0x0078c97f, a strategic NextFloat in the SHIPACTION_DEPLOYSPY handler, is in
no existing inventory -- decoded, not measured.
2026-09-09 00:10:49 -04:00
alex
712d184599 AR: predictions for the raid-target-pick verdict, committed before the build
Includes the static decode of FUN_00841700 -- the writer of TradeManager+0x0c that
lane AG's section 7 lists as not found -- stated as a falsifiable prediction (P0)
with the symptom of each way it could be wrong. Also corrects the route count in
ad-turn27-two-raiders.sav: five rt records, trfr 18/16/14/20/14, not three.
2026-09-08 23:12:41 -04:00
alex
7d49e216f1 lane AD merged: the raid roll is per fleet, B's zero is proof-carrying, sector 816 is out of range 2026-09-08 23:02:04 -04:00
alex
6d33a748c5 AD: the trade-raid roll is per fleet - 2 raiders = 2 entries, 2 words; B returns without drawing; no oracle pair (AI-only variation) 2026-09-08 23:00:23 -04:00
alex
de1f168c56 board: Chance modelled in the engine with its zero-word and NaN cases 2026-09-08 22:32:25 -04:00
alex
7eeb68b8bd lane AG merged: gate-indexed audit rows, three gates decoded, tail-rng-ledger 11.1 corrected in place 2026-09-08 22:29:14 -04:00
alex
48db3cc425 lane AG: the gate-indexed RNG audit -- 31 unread-gate rows, 6 new draw sites, the SVSO generator named
One row per statically reachable draw site in BeginProcessTurn u ProcessTurn u
OnAllCombatDone_Tail, each carrying a measured firing or a decoded predicate on
save fields plus the 22-save corpus count. No total is reported: 31 rows (30
distinct sites plus one grouped SVSO row) are unread gates, and that visible
blank column is the deliverable.

Three gates decoded:
  0x0082cdb8 = the addiction spread roll (Chance ADDICTION_SPREAD_ODDS 0.2f);
    corpus 0 of 22 -- nadct is 0 on all 28 systems of all 22 saves. Writer found:
    ServerSystem_BeginAddiction has exactly two callers, both inside vslot15, so
    an INTER-EMPIRE route plus a species addict tech must seed it first.
  0x0088dc43 = the spy counter-mission roll, p = cmo accumulating 0.2f per turn,
    so Chance costs 0 words from the fifth turn on; corpus 0 of 22 by deat/cm.
  0x0088b613 = the raid target pick. RNG_NextInt has no zero-bound early-out, so
    a single-candidate list still draws -- which proves lane AC's B returned
    before the draw. Failed conjunct named: the raider sat on sector 832 while
    all four rt records source in 816/816/768/752. Next workload: sector 816.

Six draw sites no firing-indexed table could hold: five behind
CreateRaidEncounter's empty-candidate-list gate, and 0x00820c1b again from
Slot13RngCalleeB -- so B costs 2 words on a success, not 0.

SVSO generator closed: all 17 drawing overrides use GetGame()->+0x16c.
Rule 17 again: ServerSpyManager_vslot14 really ends at 0x0088dd2b, not 0x0088dd03.
2026-09-08 22:25:52 -04:00
alex
9e39b0051a dashboard: value-domain line as the counterweight to the 99.99%-typed figure 2026-09-08 21:59:34 -04:00
alex
d98f435017 AD: predictions for the trade-raid multiplicity probe, committed before the build 2026-09-08 21:58:50 -04:00