#82 FINAL LAYER: the peer body-channel trn-lock -- a circling limper skated because the peer's turn-arm had no walk-demand yield and the trn speed exit read a dead replicant mapper cell

The master limped clean (218x gimp-cycle records, zero trn) -- a _ReturnAddress
trap on SetAnimationState(4) proved ALL peer trn arming came from the port's own
mech4 turn-step block, not the type-3 reader.  Two dead ends, one root:
- mech4 peer arm: gated on !wantsWalk (standSpeed < bodyTargetSpeed), exits trn
  when walking demand appears -- the leg twin's authentic precedence
  (part_012.c:12013, the Standing speed test outranks the turn test).
- mech2 body case 4: bspd reads bodyTargetSpeed on ReplicantInstance; the local
  mapper's speedDemand is a dead cell on a peer (reads 0 forever -> no exit).
Verified 2-node timeline: arena circle replicant 218x state-24 / 0x state-4
(was 116x trn churn), grass circle 235-clean, knockdowns bounded, 0 deaths.
Diagnostics kept: BT_TRNTRAP ra-trap, BT_ANIMIND_CAP, [gimpfeed], [replgimp]
extension.  KB: locomotion.md trn-lock entry + the dead-mapper-cell lesson.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QRjrTQpJd6u9XyfnUbTB3v
This commit is contained in:
Joe DiPrima
2026-07-30 18:26:15 -05:00
co-authored by Claude Fable 5
parent 14ff3519ac
commit e91d447405
8 changed files with 231 additions and 15 deletions
+90 -6
View File
@@ -90,6 +90,7 @@
//
#include <bt.hpp>
#include <intrin.h> // _ReturnAddress -- the #82 trn-armer trap
#include <AUDCMP.hpp> // AudioComponent -- the foot-plant step-intensity broadcast
#include <AUDSRC.hpp> // AudioSource -- footstep-source identification
#include <AUDLVL.hpp> // AudioResource::GetAudioLevelOfDetail
@@ -250,11 +251,33 @@ void
// StateIndicator::SetState's Verify(state<stateCount). [T2]
if (state >= 0 && state < 0x21)
{
// DIAG (BT_TRNTRAP): who arms state 4 on a REPLICANT? Module-relative
// ra (symbolize: tools/symcrash.py) -- the #82 trn-lock armer hunt.
if (state == 4 && getenv("BT_TRNTRAP")
&& GetInstance() == ReplicantInstance)
{
static int s_tt = 0;
if (s_tt++ < 60)
{
char ttbuf[96];
sprintf(ttbuf, "[trntrap] mech=%d ra=btl4+0x%lx",
(int)GetEntityID(),
(unsigned long)_ReturnAddress()
- (unsigned long)GetModuleHandleA(0));
DEBUG_STREAM << ttbuf << std::endl << std::flush;
}
}
// #78 audio-flake diag: print the LIVE indicator address once per mech
// so a session's [attrbind] ptr can be checked against it (stale-bind
// hypothesis: watchers bound to a recreated mech's dead indicator).
if (getenv("BT_AUDIO_SPATIAL")) { static int s_ai=0;
if (s_ai++ < 6 || (state >= 22 && state <= 27 && s_ai < 200))
// BT_ANIMIND_CAP: the 200-print budget hid every post-1-minute state
// (two #82 investigations mis-read the silence as "never entered") --
// raise it for state-timeline diagnosis.
static int s_aiCap = -1;
if (s_aiCap < 0) { const char *c = getenv("BT_ANIMIND_CAP"); s_aiCap = (c && *c) ? atoi(c) : 200; }
if (s_ai++ < 6 || (state >= 22 && state <= 27 && s_ai < s_aiCap)
|| (s_aiCap > 200 && s_ai < s_aiCap))
DEBUG_STREAM << "[animind] mech=" << (int)GetEntityID()
<< " &animationState=" << (void*)&animationState
<< " inst=" << (int)(GetInstance() == ReplicantInstance)
@@ -833,8 +856,35 @@ Scalar
// alias (an AV); controlsMapper is the typed mirror of roster slot 0. A mech
// with no mapper reads demand 0 (idles) -- matching a zeroed binary roster.
MechControlsMapper *mppr = MappingMapper(); // roster slot 0 (task #7)
// REPLICANT DEMAND FEED (#82 final root, 2026-07-30): a replicant's LOCAL
// mapper cell is a dead 0 (input never drives it), so every demand
// threshold in this machine failed on peers -- from STAND the walk-begin
// could never fire and the trn state churned on the turn signal forever
// ("lifting legs in an alternating turning fashion"). It never mattered
// while a peer was mid-cycle (clip-end chains keep cycles going, which is
// why straight-line/grass limpers replicated fine) -- it bit the moment a
// KNOCKDOWN recovery dropped the replicant to STAND. The binary replicant
// reads a LIVE demand here (its mapper cell replicates with the subsystem
// records); the port's replicated equivalent is bodyTargetSpeed (@0x6b4 --
// every update record's speedDemand writes it on RX). [gimpfeed]-probe
// proof: AdvanceLegAnimationGimp never even runs on replicants, so THIS
// driver is the peer's one and only leg machine.
Scalar commandedSpeed =
(mppr != 0) ? mppr->speedDemand : 0.0f;
(GetInstance() == ReplicantInstance) ? bodyTargetSpeed
: (mppr != 0) ? mppr->speedDemand : 0.0f;
// DIAG (BT_GIMPFEED): 1 Hz -- the NORMAL driver is the only leg machine a
// replicant runs; print every threshold operand it sees.
if (getenv("BT_GIMPFEED") && GetInstance() == ReplicantInstance)
{
static Scalar s_gfAcc = 0.0f; s_gfAcc += time_slice;
if (s_gfAcc >= 1.0f) { s_gfAcc = 0.0f;
DEBUG_STREAM << "[gimpfeed] cmd=" << commandedSpeed
<< " bts=" << bodyTargetSpeed
<< " standSpeed=" << standSpeed
<< " state=" << (int)legStateAlarm.GetLevel()
<< " gl=" << ([](Mech *m){ extern int BTMechGimpLevel(void*); return BTMechGimpLevel(m); })(this)
<< std::endl << std::flush; }
}
Scalar distance = 0.0f;
// binary: legAnimationState@0x3b0 IS legStateAlarm's level (one field; the
@@ -1251,7 +1301,15 @@ Scalar
// re-enter walk on the same frame.
{
MechControlsMapper *bm = MappingMapper();
const Scalar bspd = (bm != 0) ? bm->speedDemand : 0.0f;
// REPLICANT: the local mapper's speedDemand is a dead cell (nothing
// writes it on a peer -- reads 0 forever, so a peer that entered trn
// could NEVER take the speed exit = the #82 trn-lock). The peer's
// commanded speed is the REPLICATED demand (bodyTargetSpeed@0x6b4,
// stamped by every record RX) -- same source the peer Standing case
// walks on, so entry and exit judge the same number.
const Scalar bspd = (GetInstance() == ReplicantInstance)
? bodyTargetSpeed
: (bm != 0) ? bm->speedDemand : 0.0f;
if (standSpeed < bspd || bspd < ZeroSpeed) // walk / reverse (leg-symmetric)
{
bodyStateAlarm.SetLevel(0);
@@ -1613,12 +1671,38 @@ Scalar
// straight at the speedDemand cell.
MechControlsMapper *gimpMppr = MappingMapper();
static Scalar s_nullDemand = 0.0f; // no mapper -> demand 0, writes inert
ReconMotionSource *motionSource = gimpMppr
? (ReconMotionSource *)&gimpMppr->speedDemand
: (ReconMotionSource *)&s_nullDemand;
// REPLICANT DEMAND FEED (#82 final root, 2026-07-30): a replicant's LOCAL
// mapper demand is a dead 0 (no input ever drives it), so every speed
// threshold in this machine read 0 on peers -- in particular the trn exit
// (standSpeed < commandedSpeed) could NEVER fire, and a gimped replicant
// that staggered through stand->trn was LOCKED in turn-in-place forever
// (the observed "lifting legs in an alternating turning fashion" skate;
// unblinded [animind] timeline: SIX transitions in 3 minutes, ending at
// state 4). The binary's replicant reads a LIVE demand here because the
// mapper's speedDemand cell replicates with the subsystem records; the
// port's replicated equivalent of that same value is bodyTargetSpeed
// (@0x6b4 -- every update record's speedDemand writes it on RX). Feed
// the machine from it on replicants; the gimp caps that write back
// through the source are transient there (the next record rewrites it),
// and masters keep the authentic live mapper cell.
ReconMotionSource *motionSource =
(GetInstance() == ReplicantInstance)
? (ReconMotionSource *)&bodyTargetSpeed
: gimpMppr
? (ReconMotionSource *)&gimpMppr->speedDemand
: (ReconMotionSource *)&s_nullDemand;
Scalar distance = 0.0f;
extern int BTMechGimpLevel(void *mech_v); // mechdmg.cpp (gotcha #23)
int mode = BTMechGimpLevel(this); // binary this+0x40 = gimp level
// DIAG (BT_GIMPFEED): 1 Hz -- what demand does this machine actually see?
if (getenv("BT_GIMPFEED") && GetInstance() == ReplicantInstance)
{
static Scalar s_gfAcc = 0.0f; s_gfAcc += time_slice;
if (s_gfAcc >= 1.0f) { s_gfAcc = 0.0f;
DEBUG_STREAM << "[gimpfeed] repl cmd=" << motionSource->commandedSpeed
<< " bts=" << bodyTargetSpeed << " state=" << legAnimationState
<< " standSpeed=" << standSpeed << " mode=" << mode << std::endl << std::flush; }
}
// RE-SYNC alarm -> state member (see AdvanceBodyAnimationGimp note).
legAnimationState = (int)legStateAlarm.GetLevel();
int state = legAnimationState; // this+0x3b0