#131 false lock FIXED: miss-means-miss -- the pick answers only for drawn geometry

Night-12 field report (Ronin/Conn Man/Oracle, blackhawk-correlated): lock
ring lit with the reticle visibly off the mech + no-reg complaints.  Root
cause: TWO port stand-ins answered where the 1995 card (which cast against
the DRAWN geometry) would miss -- the pick's any-object sphere fallback and
the caller's whole-mech AABB fallback.  The regime that exposes them: a
LEVEL boresight over a SHORT mech -- the blackhawk's mesh tops out below
eye-ray height, so the ray clears every triangle but pierces the fat cull
spheres; the ring lights with the reticle above the mech's head (the
operator watched exactly this on the sweep bench).  Careful aimed-down fire
rides triangles, which is why Oracle's per-panel audit passed on the same
build.

Fix: MechSegmentPick returns 1=drawn-geometry hit / 0=TRUE MISS / -1=no
render tree; the sphere may answer ONLY for a mesh the reader cannot parse
(pm==0 -- currently none exist: counters objs/invFail/noTri all clean);
the AABB survives ONLY as the pre-tree replicant grace.  A readable mesh
the ray misses is a MISS -- no lock.

Verified (2-node vs bhk1 at 100u, all runs on force-relinked string-
verified exes after today's stale-link flake):
- LEVEL lock-sweep: 0 locks all run (pre-fix: lock band from 168 sphere
  answers; picksrc tri=0 sphereFB=168).
- DOWN-PITCHED sweep: locks return 100%% tri-sourced (tri=158 sphereFB=0),
  landing on real parts (rarm/ldleg/rdleg) with honest gaps.
- Full zone-walk matrix: tri=18874 sphereFB=0 box=0; victim took 156 hits
  across 16 zones incl. both side torsos -- combat un-regressed.

New instruments (all env-gated): BT_LOCK_SWEEP=<axis> torso pan (the
operator-visible lock-envelope bench), [locksweep] transition log,
BT_LOCK_ENVELOPE synthetic unit-sweep probe, [picksrc]/[pickbox] source
telemetry with objs/invFail/noTri localization counters.
Bench: scratchpad/night12/zonewalk_bhk.sh.

NOTE for the field: locking is now strictly TIGHTER (ring = reticle truly
on the machine).  If era testers feel the pods were more forgiving,
Draco's "slight lock linger" memory becomes a deliberate investigation
(sourced hysteresis), not an accidental sphere halo.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
Joe DiPrima
2026-08-05 11:12:43 -05:00
co-authored by Claude Fable 5
parent f279e38707
commit 546aabd5ba
5 changed files with 325 additions and 6 deletions
+25
View File
@@ -604,6 +604,31 @@ void
analogTwistAxis = s_forceTwist;
}
}
// #131 LOCK-SWEEP (BT_LOCK_SWEEP=<axis 0..1>, default 0.12): pan the torso
// in a slow triangle wave between the twist limits, so the REAL boresight
// sweeps across a stand-off target and past both edges -- the operator-
// visible lock-envelope instrument (watch the ring light/die; the
// [locksweep] log in mech4 records the twist at each lock transition).
{
static float s_lockSweep = -1.0f;
if (s_lockSweep < 0.0f)
{
const char *lsw = getenv("BT_LOCK_SWEEP");
s_lockSweep = lsw ? (float)atof(lsw) : 0.0f;
if (lsw != 0 && s_lockSweep <= 0.0f) s_lockSweep = 0.12f;
if (s_lockSweep > 1.0f) s_lockSweep = 1.0f;
}
if (s_lockSweep > 0.0f)
{
effectiveTwistRate = baseTwistRate;
// flip direction at the limits (small margin so we visibly cross
// past the target and dwell OFF it at the extremes)
static float s_dir = 1.0f;
if (currentTwist >= horizontalLimitLeft - 0.05f) s_dir = -1.0f;
if (currentTwist <= horizontalLimitRight + 0.05f) s_dir = 1.0f;
analogTwistAxis = s_dir * s_lockSweep;
}
}
// TORSO GATE PROBE (BT_TORSO_LOG): why is the twist rate zero?
if (getenv("BT_TORSO_LOG"))