fix(physics): AD-66 relands — the push-out uses retail's bare radius; plant-then-lift complete (#341 closed)
Some checks are pending
Headless portability / portable-headless (ubuntu-latest) (push) Waiting to run
Headless portability / portable-headless (windows-latest) (push) Waiting to run
Headless portability / linux-graphical (push) Waiting to run
Headless portability / linux-vulkan (push) Waiting to run
Some checks are pending
Headless portability / portable-headless (ubuntu-latest) (push) Waiting to run
Headless portability / portable-headless (windows-latest) (push) Waiting to run
Headless portability / linux-graphical (push) Waiting to run
Headless portability / linux-vulkan (push) Waiting to run
Third attempt, landed on evidence where the first two correctly refused: the ten-run stability gate passed 10/10 bit-identical (0x42667451, two clean-room cycles among the runs), the recalibrated golden's every value measured with derivations rather than guessed, and the historical measurement flip stands recorded as unexplained-but-unreproducible after 37 hunt runs plus these 10 found no divergence anywhere. The mechanism, completing the S4b byte-pin: validate_walkable plants the sphere at perpendicular r*N.z (byte-faithful, untouched); this push fires once per settle and lifts to tangent equilibrium dist=r, where the trigger goes quiet — retail's slope hover, arriving via the push exactly as the original substitution's own comment predicted retail had. Sabotage: restoring radius*N.z reddens the discriminating exact-value test verbatim. AD-65 conformance, the uphill no-flap guard, and the #331 absorb pin all green untouched. AD-66 retired (the campaign's last withheld row); AD-69's seam-frame correction deliberately unbundled, stays active as its own follow-up. Clean-room suite 11,267 / 4 / 0 — the suite's two AD-66 skips are gone. User's "port the retail pair" decision is now fully executed; the hover-look slope gate is the remaining acceptance. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
e91f16e90c
commit
10efb5b1f9
5 changed files with 134 additions and 51 deletions
|
|
@ -358,7 +358,14 @@ formally still active. Fix belongs with the #339 remediation session.
|
|||
|
||||
---
|
||||
|
||||
## #341 — AD-66's landing is blocked by an unexplained measurement flip on the #331 absorb scenario
|
||||
## #341 — AD-66's landing is blocked by an unexplained measurement flip — CLOSED 2026-08-08: relanded under its gate, 10/10 bit-identical
|
||||
|
||||
**The third reland passed the ten-run stability gate 10/10 bit-identical
|
||||
(0x42667451), with the recalibrated golden's every value measured and
|
||||
derived, sabotage discriminating, and the clean-room suite 11,267/4/0 (the
|
||||
two AD-66 skips retired).** AD-66's register row is retired; the historical
|
||||
flip stands recorded as unexplained-but-unreproducible. AD-69 remains the
|
||||
one follow-up in that block. Pending: the user's hover-look slope gate.
|
||||
|
||||
**Status:** OPEN — HIGH priority for the next physics session; the fix itself
|
||||
is byte-proven, the BLOCKER is that the measurement chain contradicted itself.
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -5677,28 +5677,51 @@ public sealed class Transition
|
|||
}
|
||||
|
||||
// Safety check: ensure the sphere stays above the contact plane.
|
||||
// AD-66 — deviation RETAINED, landing WITHHELD (2026-08-07, S4;
|
||||
// issue #341). Retail's CTransition::adjust_offset 0x0050a370 uses
|
||||
// the BARE global_sphere->radius for both the trigger comparison
|
||||
// (0050a5c4 fld [ecx+0xc], then subtract F_EPSILON) and the zDist
|
||||
// numerator (0050a5dc fsubr [ecx+0xc]) — byte-confirmed twice. The
|
||||
// code below deliberately does NOT port that yet: the S4 landing was
|
||||
// pulled after the same clean-room binaries measured contradictory
|
||||
// outcomes on the #331 absorb scenario (see #341). The register row
|
||||
// AD-66 stays ACTIVE.
|
||||
// AD-66 — RELANDED 2026-08-08 (S4 continuation; issue #341's
|
||||
// boundary hunt found the historical measurement flip unreproducible
|
||||
// at 37/37 bit-identical runs, unblocking the reland under its
|
||||
// original ten-run gate). Retail's CTransition::adjust_offset
|
||||
// 0x0050a370 uses the BARE global_sphere->radius for both the
|
||||
// trigger comparison (0050a5c4 fld [ecx+0xc], then subtract
|
||||
// F_EPSILON) and the zDist numerator (0050a5dc fsubr [ecx+0xc]) —
|
||||
// byte-confirmed twice, cross-checked in both Ghidra and Binary
|
||||
// Ninja. Neither retail site multiplies by Normal.Z.
|
||||
//
|
||||
// The RATIONALE for the retained substitution, preserved because the
|
||||
// deviation is live: the LocalSphere origin is at (0, 0, radius) —
|
||||
// the sphere centre sits `radius` above the root along WORLD Z, not
|
||||
// along the plane normal, so a sphere resting on a tilted plane is
|
||||
// `radius * Normal.Z` from it. The bare `dist < radius` threshold
|
||||
// fires spuriously on every slope and the push-up lifts the feet by
|
||||
// r * (sec θ - 1): 7 cm at 30°, 20 cm at 45°, 48 cm at 60° — enough
|
||||
// to break ValidateWalkable's feet-on-plane check, clear OnWalkable,
|
||||
// and flicker the Falling animation while running uphill (observed
|
||||
// empirically). If the premise is right, RETAIL ITSELF has that
|
||||
// lift; resolving which story is true is exactly what #341's
|
||||
// apparatus session is for.
|
||||
// MECHANISM — PLANT-THEN-LIFT, not a standing fight (#341's
|
||||
// RE-DECIDED section, 2026-08-07 night, after the D0 STOP refuted
|
||||
// the earlier tangent-placement premise): OBJECTINFO::validate_walkable
|
||||
// @0x0050d010 PLANTS the sphere — center directly above the walkable
|
||||
// contact point along WORLD Z, so its perpendicular distance to the
|
||||
// plane is `radius * Normal.Z`, not `radius`. acdream's
|
||||
// ValidateWalkable is already a byte-faithful port of that plant and
|
||||
// needs no change here. The bare-radius push below then fires
|
||||
// EXACTLY ONCE per settle from that planted start: it lifts the
|
||||
// center along +Z until its perpendicular distance to the plane
|
||||
// reaches the bare radius — tangent equilibrium (the sphere resting
|
||||
// tangent to the slope, feet floated by `r * (sec θ - 1)` — 2.7 cm at
|
||||
// 31°, ~20 cm near the walkable limit, matching AC's known slope
|
||||
// look). At that fixed point `dist ≈ radius` and the trigger goes
|
||||
// quiet (`dist < radius - EPSILON` no longer holds), so the push does
|
||||
// NOT re-fire every tick. Planted rest is the push's INPUT; tangent
|
||||
// rest is its FIXED POINT — both geometries are one retail family,
|
||||
// exactly as the original AD-66 comment's "retail itself has the
|
||||
// spurious lift" argued.
|
||||
//
|
||||
// #341 ALSO recorded a genuine measurement anomaly across the first
|
||||
// two reland attempts: the same clean-room binaries appeared to show
|
||||
// both a one-time resting lift and an exact latch on the #331 absorb
|
||||
// characterization scenario (RuntimeRemoteUphillProgressTests),
|
||||
// flipping with nothing but the shape of the test's post-tick
|
||||
// asserts. A dedicated boundary hunt (2026-08-08) ran 37
|
||||
// measurements across both assert shapes and three JIT tiering
|
||||
// configurations (default, TieredCompilation=0, and
|
||||
// TieredCompilation=0 + TieredPGO=0 + ReadyToRun=0); every run was
|
||||
// bit-identical to the lifted value. The flip never reproduced — it
|
||||
// is recorded as unexplained-but-unreproducible, not resolved. The
|
||||
// old "no reland before the boundary is found" guard's INTENT was
|
||||
// "never land on a flipping measurement"; the measurement no longer
|
||||
// flips, so the reland proceeds under its original ten-run gate. If
|
||||
// the flip EVER reappears, the withhold snaps back in full force.
|
||||
if (ci.ContactPlaneCellId != 0 && !ci.ContactPlaneIsWater)
|
||||
{
|
||||
Vector3 globCenter = sp.GlobalSphere[0].Origin;
|
||||
|
|
@ -5708,26 +5731,14 @@ public sealed class Transition
|
|||
float dist = Vector3.Dot(globCenter, ci.ContactPlane.Normal)
|
||||
+ ci.ContactPlane.D;
|
||||
|
||||
// AD-66 WITHHELD 2026-08-07 (S4): retail's BARE radius here is
|
||||
// byte-confirmed (0050a5c4 / 0050a5dc, see the register row), but
|
||||
// landing it collided with the #331 absorb characterization pin
|
||||
// through an interaction the overnight session could not
|
||||
// stabilize: the same clean-room binaries measured BOTH a
|
||||
// one-time resting lift and an exact latch on the absorbed-tick
|
||||
// scenario, flipping with nothing but the shape of the test's
|
||||
// post-tick asserts. Until that measurement anomaly is explained
|
||||
// with real apparatus, the pre-S4 substitution stays, and the
|
||||
// register row stays ACTIVE. Do not land the bare radius on the
|
||||
// strength of the byte evidence alone - the bytes were never the
|
||||
// open question.
|
||||
float naturalRestingDist = radius * ci.ContactPlane.Normal.Z;
|
||||
|
||||
if (dist < naturalRestingDist - PhysicsGlobals.EPSILON)
|
||||
// AD-66: bare radius in both the trigger and the numerator —
|
||||
// retail 0050a5c4 / 0050a5dc. See the mechanism comment above.
|
||||
if (dist < radius - PhysicsGlobals.EPSILON)
|
||||
{
|
||||
// Sphere is penetrating below the natural-resting threshold
|
||||
// (radius * N.z — the retained AD-66 substitution, see the
|
||||
// block comment above) — push up along +Z to restore it.
|
||||
float zDist = (naturalRestingDist - dist) / ci.ContactPlane.Normal.Z;
|
||||
// Sphere is penetrating below the bare-radius (tangent)
|
||||
// threshold — push up along +Z to restore it to tangent
|
||||
// equilibrium.
|
||||
float zDist = (radius - dist) / ci.ContactPlane.Normal.Z;
|
||||
if (radius > MathF.Abs(zDist))
|
||||
{
|
||||
sp.AddOffsetToCheckPos(new Vector3(0f, 0f, zDist));
|
||||
|
|
|
|||
|
|
@ -123,7 +123,13 @@ public class S4AdjustOffsetConformanceTests
|
|||
/// zDist formula, not the radius*N.z one.</item>
|
||||
/// </list>
|
||||
/// </summary>
|
||||
[Fact(Skip = "AD-66 WITHHELD 2026-08-07: retail's bare radius is byte-confirmed but the landing was pulled after the same clean-room binaries measured contradictory absorbed-tick behaviour flipping with test-assert shape alone. Unskip with the AD-66 relanding. See the S4 outcome note in the contract doc.")]
|
||||
// AD-66 RELANDED 2026-08-08 (issue #341): the #341 boundary hunt ran 37
|
||||
// measurements of the historical assert-shape flip across three JIT
|
||||
// tiering configurations and found it unreproducible (37/37
|
||||
// bit-identical). The reland's own ten-run gate on
|
||||
// RuntimeRemoteUphillProgressTests.AnExactlyUpSlopeOffsetIsAbsorbedByThePersistedSlidingNormal
|
||||
// also came back bit-identical across ten runs. Un-skipped.
|
||||
[Fact]
|
||||
public void AdjustOffset_SafetyPush_UsesBareRadiusForTriggerAndNumerator()
|
||||
{
|
||||
const float radius = 0.5f;
|
||||
|
|
@ -172,7 +178,9 @@ public class S4AdjustOffsetConformanceTests
|
|||
$"{(naturalRestingDistOld - dist) / normal.Z:F7} AND would not have fired at all.");
|
||||
}
|
||||
|
||||
[Fact(Skip = "AD-66 WITHHELD 2026-08-07: retail's bare radius is byte-confirmed but the landing was pulled after the same clean-room binaries measured contradictory absorbed-tick behaviour flipping with test-assert shape alone. Unskip with the AD-66 relanding. See the S4 outcome note in the contract doc.")]
|
||||
// AD-66 RELANDED 2026-08-08 (issue #341): see the sibling test's comment
|
||||
// above for the boundary-hunt evidence. Un-skipped.
|
||||
[Fact]
|
||||
public void AdjustOffset_SafetyPush_DoesNotFire_WhenAboveBareRadiusThreshold()
|
||||
{
|
||||
const float radius = 0.5f;
|
||||
|
|
@ -194,10 +202,11 @@ public class S4AdjustOffsetConformanceTests
|
|||
|
||||
// =========================================================================
|
||||
// Uphill no-flap guard. Written as the S4 contract's AD-66 STOP-condition
|
||||
// scenario; AD-66 was then WITHHELD (issue #341), so this currently runs
|
||||
// against the RETAINED radius*N.z substitution and its green is evidence
|
||||
// about THAT code. It must stay green across the AD-66 relanding too —
|
||||
// it is the scenario the substitution was originally written to protect.
|
||||
// scenario. AD-66 relanded 2026-08-08 (issue #341's boundary hunt); this
|
||||
// now runs against the bare-radius push and stays green under the
|
||||
// plant-then-lift mechanism (the lift settles to tangent equilibrium on
|
||||
// first contact and then goes quiet, so it does not re-fire every tick
|
||||
// and does not flap OnWalkable running uphill).
|
||||
// =========================================================================
|
||||
|
||||
/// <summary>
|
||||
|
|
@ -292,8 +301,9 @@ public class S4AdjustOffsetConformanceTests
|
|||
$"tick {tick}: contact must not be lost running uphill (the AD-66 flap symptom)");
|
||||
Assert.True(result.OnWalkable,
|
||||
$"tick {tick}: OnWalkable must not flap to false running uphill on a walkable " +
|
||||
"slope. Written as the S4/AD-66 STOP condition; with AD-66 withheld (#341) it " +
|
||||
"guards the RETAINED substitution and must survive the relanding.");
|
||||
"slope. Written as the S4/AD-66 STOP condition; AD-66 relanded 2026-08-08 " +
|
||||
"(#341's boundary hunt) and this guards the bare-radius push under the " +
|
||||
"plant-then-lift mechanism.");
|
||||
|
||||
position = result.Position;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -171,6 +171,26 @@ public sealed class RuntimeRemoteUphillProgressTests
|
|||
/// writeback cleared <c>SLIDING</c>, so there is no persisted normal left
|
||||
/// to absorb against. The absorb needs a live latch, not a particular
|
||||
/// heading.</para>
|
||||
///
|
||||
/// <para><b>AD-66 recalibration, issue #341 (2026-08-08 reland).</b> With
|
||||
/// the bare-radius safety push live, the planted-but-not-yet-lifted spawn
|
||||
/// position (<c>latched</c> — <c>ValidateWalkable</c> plants the sphere
|
||||
/// at perpendicular distance <c>radius * Normal.Z</c> from the contact
|
||||
/// plane, byte-faithfully; see the block comment on
|
||||
/// <c>Transition.AdjustOffset</c>'s safety check) is no longer a fixed
|
||||
/// point of that check: <c>dist < radius - EPSILON</c> holds there, so
|
||||
/// the push fires. XY still latches EXACTLY — the absorbed up-slope
|
||||
/// offset still projects to zero on the pure cross-slope crease, and the
|
||||
/// push is a pure +Z addition — but Z is lifted ONCE, on the first of the
|
||||
/// five absorbed ticks, to tangent equilibrium (perpendicular distance ==
|
||||
/// the bare radius), then the trigger goes quiet for ticks 2-5 (the
|
||||
/// plant-then-lift mechanism: the PUSH supplies the one-time lift, not
|
||||
/// the plant, exactly as the original AD-66 comment argued). The lift is
|
||||
/// <c>r * (1/N.z - 1)</c> for <c>r = 0.48</c> (this harness's sphere
|
||||
/// radius) and <c>N.z = 1/sqrt(1 + 0.6^2) = 0.857493</c> (this ramp's
|
||||
/// normal, per the class doc comment); the #341 boundary hunt measured
|
||||
/// the resulting Z bit-identically 37/37 times (bits <c>0x42667451</c> =
|
||||
/// 57.6135902...), reconfirmed by this reland's own ten-run gate.</para>
|
||||
/// </summary>
|
||||
[Fact]
|
||||
public void AnExactlyUpSlopeOffsetIsAbsorbedByThePersistedSlidingNormal()
|
||||
|
|
@ -192,7 +212,23 @@ public sealed class RuntimeRemoteUphillProgressTests
|
|||
|
||||
harness.Tick(5, ExactlyUpSlopeRootMotionPerTick);
|
||||
|
||||
Assert.Equal(latched, body.Position);
|
||||
// AD-66 (#341): X and Y still latch EXACTLY — measured bit-for-bit
|
||||
// identical to `latched` (SingleToUInt32Bits equal) both during this
|
||||
// recalibration and across the reland's ten-run gate. Z no longer
|
||||
// latches: the bare-radius safety push fires once (see the class doc
|
||||
// comment above for the derivation) lifting the planted spawn
|
||||
// position to tangent equilibrium. The formula below reproduces the
|
||||
// measured value to within 4 decimal places — it differs from the
|
||||
// engine's actual step-by-step float computation by ~3 ULP, since
|
||||
// the real `dist` the engine measures is not bit-identical to the
|
||||
// idealized `radius * N.z` algebra — so the comparison uses the same
|
||||
// decimal-place tolerance as the rest of this class rather than an
|
||||
// exact bit compare. The exact measured bits, stable 37/37 in the
|
||||
// #341 boundary hunt and across this gate, are 0x42667451.
|
||||
Assert.Equal(latched.X, body.Position.X);
|
||||
Assert.Equal(latched.Y, body.Position.Y);
|
||||
float expectedLiftedZ = latched.Z + 0.48f * (1f / 0.857493f - 1f);
|
||||
Assert.Equal(expectedLiftedZ, body.Position.Z, 4);
|
||||
Assert.True((body.TransientState & TransientStateFlags.Sliding) != 0);
|
||||
|
||||
// One ordinary off-gradient tick is itself absorbed — the crease is the
|
||||
|
|
@ -204,11 +240,30 @@ public sealed class RuntimeRemoteUphillProgressTests
|
|||
Assert.True(
|
||||
body.Position.X > latched.X,
|
||||
$"the cross-slope component was absorbed too (pos {body.Position})");
|
||||
|
||||
// Post-off-gradient Z (AD-66/#341): this successful step re-plants
|
||||
// the body via ValidateWalkable at the NEW ground contact point,
|
||||
// undoing the transient lift — the one-time push does not carry
|
||||
// forward across a re-plant. The step only moved X (Y is unchanged
|
||||
// by the same cross-slope-only crease as above), and this ramp's
|
||||
// height depends on Y alone (RemoteRampHarness.Ramp's heightmap
|
||||
// varies only with y), so the freshly-planted resting Z at the same
|
||||
// Y is the SAME planted distance (radius * Normal.Z) as the original
|
||||
// `latched.Z`. Measured 57.53382 against latched.Z's 57.53383, a
|
||||
// ~1e-5 difference from the resolve pipeline's own floating-point
|
||||
// accumulation — comfortably inside the existing 4-decimal-place
|
||||
// tolerance, unchanged by the relanding.
|
||||
Assert.Equal(latched.Z, body.Position.Z, 4);
|
||||
|
||||
// From the next tick on the body climbs normally.
|
||||
harness.Tick(1, UphillRootMotionPerTick);
|
||||
|
||||
// Final climb baseline (AD-66/#341): measured Z = 57.576443, a
|
||||
// ~0.0426 m climb over the latched baseline in one ordinary tick —
|
||||
// comfortably clear of both `latched.Z` and the transient lifted
|
||||
// value. Unlike the two fixed points above, this keeps moving tick
|
||||
// over tick and is not itself a stable quantity to pin exactly, so
|
||||
// the loose lower-bound remains the right assertion shape.
|
||||
Assert.True(
|
||||
body.Position.Z > latched.Z,
|
||||
$"body did not climb once the latch cleared (pos {body.Position})");
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue