sots-re/tools
alex c224ff2214 lane EV: what a turn actually posts, and two corrections to events.md
Measured over all eleven saves with state_checksum, not derived:

  * the reference pair posts TWO events (turn1->turn2) and THREE (turn2->turn3),
    and only two players in the whole corpus ever hold an event -- the human and
    the one AI empire that owns colonies. The dormant shadow empires pick research
    targets every turn and still post nothing.
  * order within a player is readable off the ids: the build pass posts before the
    research pass. Ids are per player, so no cross-player order is observable.
  * the event type is the EvImg string and it is composed at run time --
    EVENT_ENEMY_INCOMING_Human carries a species suffix, so the type space is not
    an enumeration.

Two corrections in place (rule 11):

  * the turn PostEvent is handed is the FRAME, not ModCount. turn2-state.sav has
    Frame 2 and ModCount 12, and every event it carries is in bucket EvTurn=2. It
    is the post-increment turn: a turn run from a save at turn N posts into N+1.
  * the EVENT_NO_RESEARCH gate: 0x00584e50 is TechTree::CollectResearchedTechs,
    not a ListAvailableTechs, and the middle test is "nothing was researched on
    this turn or later" -- not "no affordable tech". zuul-turn23 exercises it: the
    human posts RESEARCH_COMPLETE on turn 22 with no no-research event that turn,
    then NO_RESEARCH again on turn 23.

ghidra/addresses.d/lane-ev.json records the gate at 0x0089162a with the argument
order re-read from the instruction stream. Validated with tools/gen_addresses.py to
a scratch path (1121 entries, no duplicate); the shared header is NOT regenerated.

tools/standalone_report.py gains --engine-arg (repeatable), so a lane can feed the
standalone the operator inputs a save does not carry -- the data root, the AI
roster, which blocked phases may commit -- instead of hard-coding them. Every run
records what it was given, in the report header and in status.json.
2026-09-08 15:40:07 -04:00
..
cache_functions.py lane X: x86 displacement xref scanner; pin sizeof(ObservedTech) and its append site 2026-09-08 04:44:18 -04:00
dashboard.py lane S2: the standalone scaffold, and the measured distance to the byte-match 2026-09-08 10:35:56 -04:00
DASHBOARD_README.md lane S2: the standalone scaffold, and the measured distance to the byte-match 2026-09-08 10:35:56 -04:00
displacement.py tools/displacement.py: the honest progress metric - what fraction of the game runs on our code, by rung, with coverage caveats attached 2026-09-08 13:08:06 -04:00
gen_addresses.py gen_addresses: per-lane fragment dir; duplicate names are a hard error 2026-09-08 05:55:03 -04:00
gen_stream_schema.py lane G: wire-schema channel — layouts.json -> generated stream schema for sots-engine 2026-09-08 06:29:30 -04:00
max_income_oracle.py lane Y: the standalone's generator against lane Z's calibrated oracle pairs, and the tail's turn record 2026-09-08 11:40:19 -04:00
max_income_predict.py income-term: the output -> money chain read from the instruction stream; the BnkEl oracle goes 6/25 -> 25/25 2026-09-08 13:49:48 -04:00
probe_report.py lane H: five live probes, the oracle restored, and a harness perturbation bisected to one hook 2026-09-08 13:53:36 -04:00
reva_call.py reva_call.py: HTTP fallback for Ghidra when the MCP link drops; claim VM140 for recapture lane 2026-09-08 02:12:16 -04:00
rng_ledger_report.py lane Z: the RNG ledger for one strategic turn, measured end to end 2026-09-08 09:45:06 -04:00
rng_oracle_check.py lane Y: the standalone's generator against lane Z's calibrated oracle pairs, and the tail's turn record 2026-09-08 11:40:19 -04:00
rng_site_report.py Z: per-call-site ledger -- every word of a turn attributed, nothing left over 2026-09-08 10:41:54 -04:00
rtti_map.py lane D: automated struct recovery from the IStreamable serializers 2026-09-08 05:51:37 -04:00
serializers.py lane D: automated struct recovery from the IStreamable serializers 2026-09-08 05:51:37 -04:00
serializers_ghidra.py lane D: automated struct recovery from the IStreamable serializers 2026-09-08 05:51:37 -04:00
serializers_golden.py lane D: automated struct recovery from the IStreamable serializers 2026-09-08 05:51:37 -04:00
standalone_report.py lane EV: what a turn actually posts, and two corrections to events.md 2026-09-08 15:40:07 -04:00
streams.py lane G: wire-schema channel — layouts.json -> generated stream schema for sots-engine 2026-09-08 06:29:30 -04:00
strfootprint.py lane S: std::string is 0x1c binary-wide; ObservedTech element fully mapped 2026-09-08 05:09:33 -04:00
vtable_map.py lane V2: vtable inversion — resolve indirect call edges image-wide 2026-09-08 12:05:05 -04:00
x86disp.py lane X: x86 displacement xref scanner; pin sizeof(ObservedTech) and its append site 2026-09-08 04:44:18 -04:00