docs: S4 contract — AdjustOffset's AD-65/AD-66, snap_to_plane pinned from the binary
snap_to_plane @0x00509c50 semantics extracted at scoping: XY preserved, Z re-solved so the offset lies in the plane, no-op under the 0.0002 |N.z| epsilon — versus our orthogonal projection, which is exactly the cos-squared downhill shortfall AD-65 recorded. Branch polarity pinned from the test ah,0x41 idiom at 0x0050a4fa: into-plane subtracts, away-from-plane snaps. AD-66's port carries a mandatory regression scenario: the original substitution was empirically motivated (uphill contact-flap), so the contract requires that exact scenario as a test and a full STOP if the faithful port genuinely reds it — re-filing the divergence as deliberate is the session lead's call, not the implementer's tune. Priority note: S4 jumps ahead of S1B in the overnight queue on felt value — 25-50% downhill XY shortfall is daily-feel, while S1B's over-inclusion is zero-felt fidelity. The campaign's membership-before-query ordering is about masking, and an over-inclusive residual masks nothing downstream. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
52aea775b9
commit
2edfc70467
1 changed files with 83 additions and 0 deletions
83
docs/research/2026-08-07-s4-adjustoffset-contract.md
Normal file
83
docs/research/2026-08-07-s4-adjustoffset-contract.md
Normal file
|
|
@ -0,0 +1,83 @@
|
|||
# S4 contract (Campaign S) — AdjustOffset's two substitutions: AD-65 + AD-66
|
||||
|
||||
**Date:** 2026-08-07 (overnight). **Scoped by:** the session lead.
|
||||
**Implementer:** one Sonnet agent. **Review:** dual Opus. **This is FEEL
|
||||
work** — the morning slope-feel gate covers it; nothing here can be
|
||||
visually accepted overnight.
|
||||
|
||||
Both rows live in `Transition.AdjustOffset`
|
||||
(`src/AcDream.Core/Physics/TransitionTypes.cs`), retail
|
||||
`CTransition::adjust_offset` @0x0050a370. One function, one slice.
|
||||
|
||||
## AD-65 — the away-from-plane arm must SNAP, not project
|
||||
|
||||
**Retail, pinned at scoping (pseudo-C 272300–272340 + 271852):** in the
|
||||
non-sliding path (`sliding_normal` not set), retail computes
|
||||
`arg3 = dot(offset, contact_plane.N)` and branches on it @0x0050a4fa with
|
||||
`test ah,0x41`:
|
||||
|
||||
- `arg3 <= 0` (moving INTO the plane): `offset -= N * arg3` — the
|
||||
component subtraction (block @0x0050a529).
|
||||
- `arg3 > 0` (moving AWAY): `Plane::snap_to_plane(&contact_plane, &offset)`
|
||||
@0x0050a50e. Semantics @0x00509c50, verbatim: if `|N.z| <= 0.000199999995f`
|
||||
do NOTHING; else `offset.z = -(offset.x*N.x + offset.y*N.y) / N.z`
|
||||
(the `d` terms cancel algebraically — show this in your pseudocode doc).
|
||||
**XY is PRESERVED; only Z is re-solved so the offset lies in the plane.**
|
||||
|
||||
acdream's `else` arm (the one whose comment already names snap_to_plane
|
||||
without calling it) does `result -= N * collisionAngle` in BOTH directions —
|
||||
an orthogonal projection that shrinks XY by the cos²θ factor AD-65 recorded
|
||||
(25% at 30°, 50% at 45°). Port the branch exactly: subtraction arm for
|
||||
`<= 0`, snap for `> 0`, including the |N.z| epsilon no-op.
|
||||
|
||||
**Watch item carried from #32 (read before coding):** the #32 fix narrowed
|
||||
last-known-contact-plane validity, and `AdjustOffset` consumers sit in its
|
||||
blast radius (research doc §3.5). Your tests must cover the case where the
|
||||
contact plane is the ONLY valid plane and where none is valid.
|
||||
|
||||
## AD-66 — the safety push-out uses the BARE radius
|
||||
|
||||
Byte evidence already in the register row (do not re-derive, but DO read the
|
||||
row): retail loads the bare `global_sphere->radius` for BOTH the trigger
|
||||
comparison (`0050a5c4 fld [ecx+0xc]`, then subtracts F_EPSILON) and the
|
||||
`zDist` numerator (`0050a5dc fsubr [ecx+0xc]`), dividing by
|
||||
`contact_plane.N.z` (`0050a5df fdiv [esi+8]`). Neither site multiplies by
|
||||
N.z. acdream substitutes `naturalRestingDist = radius * ContactPlane.Normal.Z`
|
||||
in both places, with a long code comment arguing the sphere-origin geometry.
|
||||
|
||||
**The comment's argument may be geometrically sincere, but the register's
|
||||
posture is decided: retail-faithful first.** Port the bare radius in both
|
||||
sites. THEN — because the original substitution was empirically motivated
|
||||
("the uncorrected threshold broke ValidateWalkable's contact check on steep
|
||||
slopes and flickered the Falling animation while running uphill") — your
|
||||
test set MUST include the scenario the old comment claims regresses: a mover
|
||||
running uphill on a steep-but-walkable slope, asserting no contact-flap
|
||||
across ticks. If that test genuinely reds with the faithful port, STOP —
|
||||
do not tune, do not blend. Report the failing scenario in full; the session
|
||||
lead decides (that outcome would mean the register row's risk column was
|
||||
right and the divergence may be re-filed as deliberate rather than fixed).
|
||||
|
||||
## Deliverables
|
||||
|
||||
1. Pseudocode doc first (`docs/research/2026-08-07-s4-pseudocode.md`) for
|
||||
`adjust_offset`'s full branch tree — including the sliding-normal arm
|
||||
@0x0050a42a (cross products + normalize_check_small) which you must VERIFY
|
||||
against our existing port and report on, but not change unless it
|
||||
diverges.
|
||||
2. The two fixes above, minimal diff, comments carrying the addresses.
|
||||
3. Conformance tests: exact-value tests for snap (XY preserved, Z re-solved,
|
||||
epsilon no-op), for the into-plane subtraction, for bare-radius trigger +
|
||||
numerator; the uphill no-flap scenario; sabotage-verify the snap test by
|
||||
re-instating the projection and watching it redden.
|
||||
4. Full suite `dotnet test AcDream.slnx -c Release -m:1` green, totals
|
||||
reported; nothing committed.
|
||||
|
||||
## Scope — OUT
|
||||
|
||||
Registers/ISSUES (session lead). `calc_friction` (S5, separate). Anything
|
||||
outside `AdjustOffset` and its tests.
|
||||
|
||||
## Process
|
||||
|
||||
Only `C:\Users\erikn\source\repos\acdream`, absolute paths, no subagents.
|
||||
Contradictions between this contract and the source: STOP and report.
|
||||
Loading…
Add table
Add a link
Reference in a new issue