sots-re/ghidra/addresses.d/lane-l3.json
alex 7d51767e87 lane L3: both containers filled, and filling them does not make the tail draw
Three lanes could not build this workload. VM144 built both halves from a cold main
menu on a stock, unmodified install -- no data file touched, no save edited -- and the
answer to the question they were built to ask is no.

TRADE. The premise everyone carried, that trade needs station construction plus its
tech, is wrong about the station: StrategyVars.txt makes a trade station a +2-routes,
+25%-income bonus, and NumTradeRoutesSupported has a floor of 1 per owned system, so
the population thresholds scale the count and do not gate it. The gate is one tech,
CCC_FTLEcon, and Zuul cannot research it at all. 20 routes and 6 trade sectors by
turn 4; 21 by turn 13.

SPY. Lane W3: "no lane has identified which UI produces a spy-program entry." It is
the fleet panel's Special menu, and the reason nobody found it is that the ship a spy
docks with is the Cruiser REPAIR AND SALVAGE mission section -- nothing in the UI
calls it a tender or mentions spies. Prediction S1 holds: the container grows at Build
Spy while the craft is still docked (tdep=-1, atto=<tender>), so no enemy colony and no
asteroid belt are on the critical path, which is what every earlier cost model assumed.

THE MEASUREMENT. With 21 routes, 6 sectors and 1 spy craft live, lane H's eleven entry
probes report the four outer tail callees entered exactly once per turn, as always, and
SpyManager::Slot13RngCallee, TradeManager::Slot13RngCalleeA and CalleeB entered ZERO
times -- this turn and across all seven instrumented turns, every probe installed=true.
The RNG ledger and the standalone's generator model do NOT need extending on account of
either container being non-empty. The next condition is active contents, not present
contents: tsnumflt=0 on every sector and spyon=0 on the spy.

WHAT ELSE FELL OUT. The trade-route vector is torn down and rebuilt every turn inside
ServerTradeManagerImpl::vslot9 (lane V2's phase-23 call 5 of 8, previously "draw-free"
and unexplained) -- an agreement, dropped rather than re-minted, as is the AI2 growth
helper. Two addresses are minted, both trapped live and both `mapped` not `verified`
because ReVa was unreachable: ShipAction_BuildSpy 0x00789620, a sibling of lane B6's
stack-built-fptr-table entry 0x120 bytes away, which is why no call-graph sweep ever
found this writer; and ServerSpyManager_CreateSpyCraft 0x008383c0.

And a correction with teeth: `spies2` is 0 in all 28 systems of a save that DOES have a
spy. The natural reading of lane W's count-0-in-11-saves was "no save has ever had one".
That reading is dead; spies2 is not the spy list, or it only fills for a deployed spy.

The research click path is written down for the first time (§4): clicking a tech node is
a PREVIEW, the bottom-left button confirms, Esc leaves without confirming, and the tree
pans only on a right-drag of about 600 px. That, not the tech cost, is what stopped
three lanes.

Saves: human-turn{5,8}-traderoutes, human-turn11-spytechs, human-turn15-spyprogram --
all --strict clean, 0 errors, 0 warnings.
2026-09-08 19:46:16 -04:00

21 lines
2.7 KiB
JSON

{
"_note": "Lane L3 (2026-09-08). Every entry here was trapped LIVE with hardware data-write watchpoints on the spy-program vector's _Myfirst/_Mylast, on the first turn in this campaign on which a spy craft was ever created, and then resolved to a function start against dumps/functions.json. ReVa/CT111 was unreachable this session (ReVa CONNECTION_CLOSED), so no body was read in Ghidra and every prototype below states only what the trap measured plus what an already-verified neighbour entry establishes. Status is `mapped`, not `verified`, for exactly that reason. Evidence: verify/results/shim/l3/l3-spy-run-watch.txt, findings/subsystems/trade-and-spy-workload.md.",
"entries": [
{
"name": "ShipAction_BuildSpy",
"addr": "0x00789620",
"convention": "__thiscall",
"prototype": "void (ShipAction* this, ...) /* THE `Build Spy` SHIP-ACTION HANDLER -- the writer at the top of the only call chain that has ever grown Game::ServerSpyManager's spy vector. Trapped live: with a debug breakpoint on spyManager+0x10/+0x14 and a `Build Spy` order issued from the fleet panel's Special menu, the single allocation of that vector arrived as 0x00789620+0x53 -> 0x008383c0+0x9c -> 0x0059f1a0+0x5f -> 0x00483410+0x7c/+0x82, on the turn thread, inside the End Turn that applied the order. REACHABILITY: same indirection class as its sibling ShipBorneBuildQueue_ProcessTurn 0x00789500 (lane B6) -- 0x120 bytes away, zero direct call sites, no vtable slot; both are entries in the STACK-BUILT function-pointer table the ship-action dispatcher (lane T's 0x007b9c4b site, dispatched from StrategyServer 0x007dc92b/0x007dc952/0x007dcb0c) indexes by action type. NOT READ IN GHIDRA: the body, the action-type index and the argument list are unknown; what is measured is the entry's position in the chain and the fact that no other path grew the container across 7 instrumented turns */",
"status": "mapped",
"source": "findings/subsystems/trade-and-spy-workload.md (lane L3 2026-09-08)"
},
{
"name": "ServerSpyManager_CreateSpyCraft",
"addr": "0x008383c0",
"convention": "__thiscall",
"prototype": "void (Game::ServerSpyManager* this, ...) /* The spy-craft creator: the only frame between the Build Spy ship action and the push_back that grows the manager's vector at this+0x10..0x18. Trapped at +0x9c calling 0x0059f1a0 with that vector; the element it appends is the Game::SpyCraft whose serialized record then appears under `spymgr`/`spy` with sid=1, sown=<player id>, atto=<tender ship id>, tdep=-1. NOT READ IN GHIDRA: whether it also does the payment, the tender bookkeeping and the event post, or delegates them */",
"status": "mapped",
"source": "findings/subsystems/trade-and-spy-workload.md (lane L3 2026-09-08)"
}
]
}