Files
BT411/scratchpad/rig_watch.ps1
T
arcattackandClaude Opus 5 26e678e570 #67 part 2, ROOT-CAUSED AND FIXED: 1995 latent uninitialized fields, exposed by the port's allocator
THE HUNT (the deterministic rig repro made it a two-hour arc):
  1. cdb write-watch armed from the Torso ctor (bp plants `ba w4 this+0x21c`
     per torso -- ASLR-proof).  The poison reproduced (atUpd=-1250 this run;
     -3750 and int-15-as-float before)... and the watch stayed SILENT.  Nobody
     writes the garbage.  The field is never INITIALIZED.
  2. Confirmed in our ctor reconstruction: it inits every neighbour but skips
     targetTwist @0x218 and twistAtUpdate @0x21C (the function that zeroes
     them is a death-reset handler, not the ctor).
  3. Confirmed in the BINARY: the real ctor @004b6b0c contains no store to
     either offset -- a genuine 1995 latent bug (uninitialized read on the
     copy path).
  4. Why the pod never showed it: MemoryBlock arenas carve fresh OS-zeroed
     pages, one pool per type, low churn -- first allocations read as zero.
     The engine's own DEBUG_NEW_ON NaN-fill proves the developers knew the
     hazard class.  Why WE show it: mechrecon.hpp's Memory::Allocate shim
     ("a plain heap allocation is behaviour-equivalent" -- false) recycles
     dirty heap.  Replicant torsos spawned with garbage twist targets; the
     limit clamp turned any garbage into FULL TWIST -- rendered "twisted full
     right while not using TT" to every peer (playtest night 4, 3 reporters).

THE FIX -- environmental, class-wide, byte-faithful to the binary's code:
Memory::Allocate / AllocateArray / Alloc now ZERO-FILL, reproducing the pod's
EFFECTIVE allocation semantics for every never-stored field in every
reconstructed factory at once (Torso, Reservoir, all of them).  No ctor gains
stores the binary lacks.

PROVEN on the rig: the replicant thor now spawns cur=0 target=0 atUpd=0
(was cur=-3.31613 = hard against the limit).  Teardown clean.

Ships with part 1 (the dead-reckoning clock fix) in the next zip.  Remaining
on #67 for the next games night: live confirmation that twist TRACKING looks
right in play, and whether the fire-from-centre facet (very plausibly the same
never-stored-field class, now zeroed) is cured with it.

Tools kept: scratchpad/torso_watch.cdb + rig_watch.ps1 (the ctor-armed
write-watch pattern -- reusable for any "who wrote this field" hunt).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-07-27 07:42:37 -05:00

50 lines
2.1 KiB
PowerShell

# Watch-rig: pod B runs UNDER cdb with the torso write-watch script.
$repo = 'C:\git\bt411'
$content = Join-Path $repo 'content'
$scratch = 'C:\Users\EPILECTRIK\AppData\Local\Temp\claude\C--git-bt411\89ab96e9-6cf0-4555-939d-05bf3708745a\scratchpad'
$exe = Join-Path $repo 'build\Release\btl4.exe'
$cdb = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x86\cdb.exe'
if (-not (Test-Path $cdb)) { $cdb = 'C:\Program Files (x86)\Windows Kits\10\Debuggers\x64\cdb.exe' }
$relaylog = Join-Path $scratch 'watch_relay.log'
$pidfile = Join-Path $scratch 'watch_pids.txt'
if (@(Get-NetTCPConnection -State Listen -LocalPort 1520 -ErrorAction SilentlyContinue).Count -gt 0) {
"ABORT: port 1520 in use"; exit 1
}
Remove-Item $relaylog, (Join-Path $scratch 'cdb_torso.log') -ErrorAction SilentlyContinue
$pids = @()
$relay = Start-Process -FilePath 'python' `
-ArgumentList '-u', (Join-Path $repo 'tools\btconsole.py'), '--relay', '1520',
(Join-Path $content '_TWIST.EGG'), '--bind', '127.0.0.1', '--manual-launch' `
-WorkingDirectory $content -PassThru `
-RedirectStandardOutput $relaylog -RedirectStandardError (Join-Path $scratch 'watch.err')
$pids += $relay.Id
Start-Sleep -Seconds 3
$env:BT_START_INSIDE = '1'
$env:BT_DEV_GAUGES = '1'
$env:BT_RELAY = '127.0.0.1:1520'
$env:BT_MATCHLOG = '0'
$env:BT_LOG_APPEND = '1'
$env:BT_TORSO_LOG = '1'
# pod A: normal (the master we ignore)
$env:BT_LOG = 'w_a.log'; $env:BT_SELF = '127.0.0.1:1502'
$a = Start-Process -FilePath $exe -ArgumentList '-egg','_TWIST.EGG','-net','1502' `
-WorkingDirectory $content -PassThru
$pids += $a.Id
Start-Sleep -Seconds 2
# pod B: UNDER CDB with the write-watch (its replicant torso is the victim)
$env:BT_LOG = 'w_b.log'; $env:BT_SELF = '127.0.0.1:1602'
$b = Start-Process -FilePath $cdb `
-ArgumentList '-logo', (Join-Path $scratch 'cdb_torso.log'),
'-cf', (Join-Path $scratch 'torso_watch.cdb'),
'-o', $exe, '-egg', '_TWIST.EGG', '-net', '1602' `
-WorkingDirectory $content -PassThru
$pids += $b.Id
Set-Content -Path $pidfile -Value $pids
"relay=$($relay.Id) podA=$($a.Id) cdb=$($b.Id)"