From 4b986af94dc44946e2dfba4a8b5d58cac83c941c Mon Sep 17 00:00:00 2001 From: Joe DiPrima Date: Tue, 11 Aug 2026 18:16:39 -0500 Subject: [PATCH] KB: gotcha section 25 (same-pass edge latch sampling deferred state -- the #162 double-credit class) + decomp-reference gains the synchronous mode-9 timing fact (part_012.c:14761 reads it flipped in-pass) and the 4/8-node mirror-convergence bench record Co-Authored-By: Claude Fable 5 --- context/decomp-reference.md | 10 ++++++++-- context/reconstruction-gotchas.md | 17 +++++++++++++++++ 2 files changed, 25 insertions(+), 2 deletions(-) diff --git a/context/decomp-reference.md b/context/decomp-reference.md index f333335..bed77e1 100644 --- a/context/decomp-reference.md +++ b/context/decomp-reference.md @@ -334,10 +334,16 @@ From the weapon `.SUB` records + the charge-curve `.data` constants (PE-parsed a `{+0x290=0, +0x258=0}` lives in **FUN_004c012c = DropZoneReply**'s tail (part_013.c:10519-23) — NOT the VehicleDead arm (the #81-era port misattribution, corrected 2026-08-11). Latch asymmetry: the entry latch (FUN_0049fb54) tests modes **2|9** while the death-tail gate - accepts **9|10** (part_012.c:14761). `advancedDamageOn(+0x264)` ← the mission egg's + accepts **9|10** (part_012.c:14761). **The mode-9 write is SYNCHRONOUS within the damage + pass** [T1 — 14761's gate reads it already flipped in the same call]: the sender one-shot + only holds because of this timing. The port deferred it to the per-frame UpdateDeathState + and a same-frame direct+splash double-lethal re-ran the death block (duplicate kill credit + — the 4-node retest catch, fixed 1b6d247 by running the transition inline at the death + tail; gotcha §25). `advancedDamageOn(+0x264)` ← the mission egg's per-pilot `advancedDamage=` key (every stock egg stamps 1 on every page); Player update record replicates ONLY currentScore(+0x1c8) + dropZoneLocation — killCount/deaths never - cross the 1995 wire. + cross the 1995 wire (the port's #45 record extension mirrors them owner→replicant; benched + convergent at 4 and 8 nodes, kd4_bench/kd8_stress). - **HeatableSubsystem** @0x50E41C: {3, "ToggleCooling"→@004ad6f8}. **Disassembled 2026-07-20** (`tools/disas2.py 0x4ad6f8`): a per-subsystem coolant on/off TOGGLE (NOT a multi-level "cycle priority" — that's the emergent effect, not the mechanism): diff --git a/context/reconstruction-gotchas.md b/context/reconstruction-gotchas.md index 0552956..41ee0d8 100644 --- a/context/reconstruction-gotchas.md +++ b/context/reconstruction-gotchas.md @@ -997,3 +997,20 @@ Rules: producer's deposits with operands → cross-reference the operand SHAPE (pure local −z, magnitude = distance/dt, echo at ring-length) against the writers. Each trap eliminated a theory the previous data had made plausible; three plausible theories died on operands. + +## §25 — A same-pass edge latch sampling DEFERRED state: synchronous in the binary, next-tick in the port +**(2026-08-11, the #162 4-node retest double-credit.)** The binary's death processing writes +`movementMode 9` **inside the damage pass itself** — its own tail gate (part_012.c:14761) reads +the mode already flipped in the same call. The port put the mode write in the per-frame +`UpdateDeathState`, one tick later — and a comment at the death tail *asserted* the write was +synchronous, so nobody looked. Consequence: TWO lethal deliveries of one salvo (direct + splash, +2 ms apart, no sim tick between) each sampled `destroyedAtEntry = (mode==2||9)` as 0 and re-ran +the whole death block — duplicate kill credit + duplicate VehicleDead. Invisible at 2 nodes +(clean kills deliver ONE lethal hit); needs crowds + overlapping splash — the 8-player field +shape. **Rule:** when a binary function's OWN later code observes state it wrote earlier in the +same pass, the port's write must be equally synchronous — a per-frame deferral silently converts +an edge latch into a race. Sibling of the alarm-vs-mode trap (#108/#162): both are "the latch +sampled a cell whose write timing differs from the binary's". Fix shape: run the once-per-death +transition inline at the destruction edge (mech.cpp death_tail → `UpdateDeathState(0)`), keep the +per-frame caller for maintenance. Verified: kd4_bench 9/9/9/9 + kd8_stress 26/26/26/26, both +SWALLOWED=0 (the receiver dedup tripwire now never fires — no duplicate is ever GENERATED).