sots-re/findings/subsystems
alex 1893751ffa PAR: roll parity -- an AI client's per-turn RNG word count is not fixed at any scope
The hypothesis under test was the lockstep discipline: that each run of an AI client consumes a
fixed number of draws regardless of the path it takes, so a reimplementation could keep the
generator aligned with the right COUNT and order of draws while getting the decisions wrong.

It is false, and it fails at four scopes. Measured with a new bracket on
StrategyClient::OnResumePlaying over the per-client generator at +0x134, six runs across VM140 and
VM145, five fresh processes; every unpinned run's autosaves are byte-identical to the published
oracle, so the instrument is behaviour-neutral (rules 19 and 26 both discharged).

  across clients   turn2->turn3: 3 / 0 / 0 words for AI players 32 / 496 / 512; human 0
  across turns     client 32: 3 words on turn 2, 7 on turn 1
  across processes client 512 makes ONE cl_RandRange call on turn 1 -- the research-target
                   tie-break at 0x006a8495, phase 18 -- and it cost 1 word in one process and
                   3 in another, because RNG_NextInt is an unbounded rejection loop
  per site         RNG_Chance costs ZERO words at p<=0 and p>=1

Twenty-one live draw sites in an AI turn, in twelve functions (plus two provably dead ones); two
fired on the reference turn, three on turn 1. Only three are unconditional, and all three only
given that their enclosing function was called. Six of client 32's seven turn-1 words come from
the ship-design composer 0x006ad700, which is also where the only loop-carried draw lives.

Also: cl_RandFloat 0x00579c70, a third cl_* RNG facade, found twice independently. It reaches
RNG_NextFloat by a TAIL JUMP, so no rel32 sweep for the entry points can see it -- which is why
ai-turn-logic.md 5's 'zero NextFloat calls from the AI module' reads as true and is not. All 29
call sites of the three facades are inside the AI band: the cl_* RNG facade is AI-only surface.

Positives for the engine: the AI draws from nothing but its own client's generator (foreign_words
0 on every bracket), the human client draws nothing at all, and the per-turn cost is single digits.
Rung B is unaffected. Rung C needs the decisions.
2026-09-08 19:33:00 -04:00
..
.keep.md scaffold RE campaign: board, backlog, findings template, verify tree 2026-09-07 14:40:44 -04:00
ai-client-seed-is-per-process.md L1: CDiff crosses at frame 50, and the AI client seed is fresh in every process 2026-09-08 18:23:19 -04:00
ai-order-capture.md L4: the research tie set -- k = 6, named, and the mechanism measured twice 2026-09-08 18:30:05 -04:00
ai-order-emission.md AI4: what an AI turn emits, and what each command costs in ModCount 2026-09-08 16:27:58 -04:00
ai-stepping-and-passes.md findings: lane AI3 -- the AI stepping order is save player order, and pass 0 writes nothing 2026-09-08 15:29:53 -04:00
ai-task-system.md lane AI2: the AI's task selection loop, the priority table, and the order-method -> TurnCommands map 2026-09-08 14:43:41 -04:00
ai-turn-logic.md lane H: five live probes, the oracle restored, and a harness perturbation bisected to one hook 2026-09-08 13:53:36 -04:00
battle-load-profile.md battle-load: profile filed, bug parked; sampler + resume recipe kept 2026-09-07 16:43:14 -04:00
data-model.md data-model: fix example section path (CRAIC, caught by vfs oracle) 2026-09-07 17:41:45 -04:00
data-parsers.md verify: mars data parsers proven 100% on 1595 files; catalogs; tech-tree graph 2026-09-07 15:22:55 -04:00
determinism-oracle.md determinism qualified: oracle holds only where no AI must choose; Rung B = command-stream replay, Rung C = behavioural AI; canonical pair now turn2->turn3 2026-09-08 18:02:58 -04:00
eventlive-verification.md lane V: live verification of the event-posting model against an advance prediction 2026-09-08 05:59:22 -04:00
events.md lane EV: what a turn actually posts, and two corrections to events.md 2026-09-08 15:40:07 -04:00
formula-gaps.md lane PL: decompose the /Sim/players residual by mechanism; the bankruptcy protection factor is a float32 2026-09-08 16:36:45 -04:00
fpu-precision-sensitivity.md lane F: x87 precision sensitivity measured; STATE_CHECKSUM 3.5 closed 2026-09-08 05:07:53 -04:00
golden-trace-recapture.md lane X: x86 displacement xref scanner; pin sizeof(ObservedTech) and its append site 2026-09-08 04:44:18 -04:00
income-term.md lane C3: ComputeOutput on the turn path -- the money ComputeBudget actually sums 2026-09-08 14:50:50 -04:00
loader-prototypes.md lane S: std::string is 0x1c binary-wide; ObservedTech element fully mapped 2026-09-08 05:09:33 -04:00
money-chain-float-widths.md L5: the money chain's float widths, measured live at a boundary 2026-09-08 17:49:35 -04:00
movefleet-position-rounding.md lane M: MoveFleet position rounding closed; VM140 released; types 2-5 still uncovered 2026-09-08 03:51:39 -04:00
multiplayer-combat.md L2: record the pgrep -f tap141i0 hazard - it kills the guest, not just tcpdump 2026-09-08 18:31:00 -04:00
multiplayer-gamespy.md board: lane L1 - hive creation draws in BeginProcessTurn; CDiff edges played forward; SnLv verified; VM140 free 2026-09-08 18:26:51 -04:00
multiplayer-tier0-verified.md board: lane L1 - hive creation draws in BeginProcessTurn; CDiff edges played forward; SnLv verified; VM140 free 2026-09-08 18:26:51 -04:00
nvo-tshn-visible-owner.md board: lane L5 - reference pair non-deterministic; interest literals verified with a failing control; verified column held at 0 on principle 2026-09-08 17:55:47 -04:00
observedtech-append.md lane S: std::string is 0x1c binary-wide; ObservedTech element fully mapped 2026-09-08 05:09:33 -04:00
output-term.md lane C3: ComputeOutput on the turn path -- the money ComputeBudget actually sums 2026-09-08 14:50:50 -04:00
output-turn-path.md lane G3: civilian growth read and measured; out[6] is not a repair number 2026-09-08 15:53:08 -04:00
path-solver.md lane P2: the path solver read from the instruction stream, and OrderFleetMove's three failure bits 2026-09-08 12:43:34 -04:00
players-residual.md lane PL: decompose the /Sim/players residual by mechanism; the bankruptcy protection factor is a float32 2026-09-08 16:36:45 -04:00
population-growth.md lane G3: civilian growth read and measured; out[6] is not a repair number 2026-09-08 15:53:08 -04:00
rcex-explained.md lane W2: multiplayer Tier 0 played end to end with no server; ModCount/Frame/Status watchpoints; rcex explained 2026-09-08 15:23:52 -04:00
roll-parity.md PAR: roll parity -- an AI client's per-turn RNG word count is not fixed at any scope 2026-09-08 19:33:00 -04:00
running-the-game.md verified: real saves parse; ServerPlayer/StarFleet/StarShip confirmed, ServerSystem conditional gaps listed; game-run recipe 2026-09-07 16:09:28 -04:00
setresearched-cascade.md lane U: the unlock cascade, implemented and live-verified 2026-09-08 06:57:37 -04:00
ship-construction.md findings: ship construction -- the build queue read byte for byte, and the missing destroyer is the AI's 2026-09-08 14:54:03 -04:00
snlv-measured.md board: lane L5 - reference pair non-deterministic; interest literals verified with a failing control; verified column held at 0 on principle 2026-09-08 17:55:47 -04:00
strategic-turn-internals.md lane T2: the treaty-turn stamp, and Player.Status's real writer 2026-09-08 14:52:44 -04:00
strings-and-config.md strings/config: battle-load smoking gun (affinity), lockstep sim, net map, Mods override 2026-09-07 14:58:36 -04:00
system-visibility-prediction.md lane E3: the prediction's outcome, leaf for leaf 2026-09-08 13:39:30 -04:00
system-visibility-record.md W3: NVO.TShn's writer trapped live, its gate named, and 158/158 on the corpus 2026-09-08 16:41:09 -04:00
tech-effects.md b2 static findings: tech effects corrections, full g_TechIdNames dump; contract 176->211 2026-09-08 00:01:04 -04:00
treaty-turn-stamp.md lane T2: re-measure H02 on main 2fd0852 (C3 + B6 merged) -- same +26 / +14 / +12x3, 0 regressed, so the phase is orthogonal to both 2026-09-08 15:04:36 -04:00
turn-command-replay.md RB: lane CB's real capture replays to the same result, and brings the seeds and the heap payloads 2026-09-08 19:07:13 -04:00
turn1-to-turn2-nondeterminism.md L5: the money chain's float widths, measured live at a boundary 2026-09-08 17:49:35 -04:00
turncommands-capture.md CB: record the two planned runs that were not made, and why 2026-09-08 19:26:53 -04:00
ui-screen-map.md board: lane P2 nav classifier; type 2 is the Liir drive, a naming error not a gap 2026-09-08 12:45:27 -04:00
unlock-cascade.md lane K: StrategyServer::OnAllCombatDone_Tail mapped, 36 phases from the instruction stream 2026-09-08 08:47:08 -04:00