`ComputeBudget`'s savings-interest term is now compared against the running game at
a treasury the corpus actually contains. Three runs on VM146 from turn1-state.sav:
A (widened floats, as shipped) 3,895 calls, 0 diverged, 0 undeclared writes
B (exact decimals, the control) 2,718 calls, 1,359 diverged
The game fills savingsInterest with 499 at a treasury of 50,000, and with 380 at
38,100 -- the exact decimals pay 500 and 381. Every divergence in B lands on a
treasury that is a multiple of 100 and no other state diverges at all, which is
exactly the arithmetic. G3's rule-23 reading is now measured, not inferred, and the
one-money error is shown to propagate into `available` and `researchMoney` too.
The control also settles why the earlier 4,437-call green run was green: slot 5 IS
diffed and the harness CAN see it, so that run simply presented no boundary state.
Coverage is therefore reported as distinct states, not calls: 5 distinct treasuries,
2 of them on the boundary.
Two further rule-23 constants found in the same routine by an operand-width sweep,
corrected, and honestly marked UNVERIFIED because no reference turn can see them:
- the research-yield factor is a widened 0.85f while its two neighbours in the
same product are exact doubles. Boundary: research money a multiple of 40,000;
the run presented 9 distinct values and none is.
- the three research modifiers are summed in single precision, not double.
Boundary: two of the three non-zero; the corpus has shrm = TRM = 0.
Both are pinned by boundary cases in test_economy.cpp that fail with the decimals.
Also verified live, in the same run:
- T31's difficulty-column recovery. The live ServerPlayer+0xf9 / NPC flags on all
eight players are exactly what lane PL's save-only inversion claims, including
the awkward system-owning player that is still ambiguous because it is an NPC.
- BANKRUPTCY_PROTECTION_LIMIT_FACTOR reads 3.29999995 = (float)3.3. Its file image
is zero because the loader fills it at run time, so lane PL-3 had to assume the
value; it is now measured and the assumption was right.
Falsified, and recorded as such: the difficulty-mods record does NOT sit inline at
ServerPlayer+0x36c -- that field is a heap pointer on all eight players. The row IS
reachable from a ServerPlayer (which corrects the hook's standing coverage note),
but the fitted {3.0,1.5}/{1.0,1.0} pair remains unverified. The hook logs the
pointer and does not follow it.
The `verified` column stays 0, deliberately. Every phase this compare touches is
Partial for reasons upstream of it, and promoting one because part of it was checked
is the drift app_test_catalog exists to catch. What moved is models; see
docs/L5-live-verification.md for each one with its coverage.
Gates run separately: clean-room OK, host ctest 54/54, CT111 shim cross-build exit 0.
34 lines
1.4 KiB
Text
34 lines
1.4 KiB
Text
# Lane L5 -- ComputeBudget in compare mode, and nothing else.
|
|
#
|
|
# `hooks=off` short-circuits before ANY hook is installed, so the default has to be `trace` and
|
|
# every other hook is turned off by name. (Lane N's shim.cfg.output documents the same trap.)
|
|
#
|
|
# Paired with shim.cfg.l5control, which is byte-identical except that `hooks=off`, so the
|
|
# rule-19 control and this run differ in exactly one key.
|
|
hooks=trace
|
|
hook.Shim::SelfTest::Fill=off
|
|
hook.Mars::GlobalConsts::LoadFile=off
|
|
hook.Game::WeaponDictionary::Init=off
|
|
hook.Game::SectionDictionary::SectionDictionary=off
|
|
hook.Game::StrategyServer::ProcessFleetMovement=off
|
|
hook.Game::StrategyServer::MoveFleet=off
|
|
hook.Game::TechTree::ProcessResearch=off
|
|
hook.Game::ServerPlayer::OnTechResearched=off
|
|
hook.Game::ServerSystem::ProcessTurn=off
|
|
hook.Game::ServerSystem::GroupOutput=off
|
|
hook.Game::ServerSystem::ComputeTotalOutput=off
|
|
hook.Game::ServerPlayer::ProcessTurn=off
|
|
hook.Game::StrategyHost::Autosave=off
|
|
hook.Game::StrategyServer::ProcessTurn=off
|
|
hook.Game::StrategyServer::OnAllCombatDone_Tail=off
|
|
hook.Game::StrategyServer::ApplyEncounterResult=off
|
|
hook.Game::StrategyServer::NodeLineDecay=off
|
|
hook.Game::EncounterDetect::AssignContacts=off
|
|
hook.Game::EncounterDetect::ProcessTeamRecord=off
|
|
hook.Game::StrategyServer::ProcessNodeSpaceTravel=off
|
|
hook.Game::ServerPlayer::ComputeBudget=compare
|
|
trace.path=C:\SOTS\shim.trace.jsonl
|
|
trace.inline_max=256
|
|
trace.flush=always
|
|
probes=off
|
|
watch=off
|