The gyro's sway slew (@004b275c) was already reconstructed and already
read the cell the master perf writes -- swayBias -- which nothing had
ever written. So the mechInstability member I added to the gyro in
5.3.127 was a duplicate of that same cell, the second such mistake this
arc after realMaxSpeed/runSpeedMax. The lesson repeats: grep our own
tree for an existing carve before adding a member for a binary offset.
Merged, and the loop closes: the instability model now publishes into
swayBias, so an unstable mech shakes its pilot harder through code that
was already correct and waiting for a writer. Also corrected: the
binary's impaired gate has three terms where ours had two -- a gyro
destroyed outright swings to the impaired sway base, not only an
unpowered or heat-failed one.
Verified on the rig (BT_SWAY_LOG): bias arrives, the angle slews toward
base+bias and stays inside the authored band, zero faults.
AND THE LOG IMMEDIATELY EARNED ITS KEEP. It showed impaired=1 for an
entire clean run. Instrumenting the three terms: state=0, heat=0 -- so
the new term is inert and correct -- but watchdog=0 where Ready is 4.
PowerWatcher::UpdateWatch falls back to 0 when its watched link resolves
NULL, and watchedLink is default-constructed and bound NOWHERE in the
tree, for PowerWatcher and HeatWatcher alike.
So the whole watcher family is inert: every watcher resolves NULL, every
PowerWatcher reports its target unpowered, and the gyro has been sitting
on its destruction-grade sway base since the sway model landed --
invisibly, until this log existed. The fix needs the streamed watch
index and a real ctor bind; guessing a binding is precisely what this
project forbids, so it is recorded with its evidence for the next
sitting rather than improvised now.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>