# P2 pickup handoff β€” door / building-shell collision = BSP Path 5 grounded step-up > **πŸ”΄ CORRECTED 2026-06-04 β€” the localization below (the step-up CLIMB) was WRONG; B1 is FIXED.** > An `ITestOutputHelper` capture of B1 (xunit swallows `Console.WriteLine`) proved the climb code > (`find_walkable`/`AdjustSphereToPlane`/`step_sphere_down`/`DoStepUp`/`DoStepDown`) is **correct** and > matches ACE exactly. The real B1 bug was the **A6.P4 near-miss dispatch in `BSPQuery.FindCollisions` > Path 5 (Contact branch)**, which diverged from retail three ways: (1) recorded a near-miss > `NegPolyHit` **unconditionally** β€” retail gates both `set_neg_poly_hit` calls behind > `if (num_sphere > 1)` (`acclient_2013_pseudo_c.txt:323852`); (2) checked the foot near-miss before > the head's (retail checks the head/sphere1 first); (3) reversed the `neg_step_up` mapping (retail: > head index0β†’FALSE/slide, foot index1β†’TRUE/step-up, per `SPHEREPATH::set_neg_poly_hit` :323279). > For B1's single foot sphere the spurious near-miss β†’ outer `!NegStepUp β†’ Collided` β†’ revert β†’ the > mover wedged at x=0.1, never reached the wall to step up. **Verbatim fix committed (`abbd761`):** > the gate+order+mapping now match retail; B1 climbs (footβ†’(0.6,0,0.25)); the Holtburg door blocks > faithfully (slab `(0,-1,0)` normal) when the scenario has a real floor. > > **Remaining red (NOT simple flips β€” all separate from B1):** > - `Apparatus_Grounded_50cmOffCenter` β€” its tick-0 `(0,0,1)` "block" is a **synthetic-test artifact**: > the apparatus sets `terrain=-1000` so the only BSP is the door slab; the contact-maintenance > step-down finds no floor underfoot β†’ false Collided/revert, then the mover walks through. With a > real floor (`terrain=0`) the door blocks faithfully at Yβ‰ˆ11.5 with `(0,-1,0)`. Fix = give the > grounded test a real floor + assert the block normal is the door's Β±Y (NOT the tick-0 `(0,0,1)` > contact-maintenance hiccup, which is a separate cold-seed first-frame artifact). Do **NOT** just > flip to `Assert.True(blocked)` β€” that blesses the artifact. > - `LiveCompare_DoorOffCenterWalkthrough_Tick13558` / `_DoorBlocksFromOutside_Tick22760` β€” compare > against captured **buggy-live** positions; a correct fix makes the harness diverge (blocks earlier). > Re-baseline to the corrected behavior or retire as documents-the-bug. > - `D4_AirborneMover_TallWall_PersistsSlidingNormalAcrossFrames` β€” **airborne (Path 6)**, a separate > sliding-normal-persistence issue, unrelated to the Path 5 grounded near-miss. Pre-existing. > > See `memory/project_p2_door_stepup_findings.md`. **Next: USER VISUAL GATE** (walk through a cottage > door cleanly; step up a stair) β€” the authoritative P2 acceptance. The original (wrong) analysis is > retained below for the record. > **Canonical pickup for the next session.** Branch `claude/thirsty-goldberg-51bb9b` > (do NOT branch/worktree; do NOT push without asking; NEVER `git stash`/`gc`). PowerShell on > Windows; launch logs are UTF-16. Read this FIRST. ## State both altitudes - **Milestone:** M1.5 β€” Indoor world feels right. - **Effort:** the VERBATIM spatial-pipeline port (master plan: `docs/superpowers/specs/2026-06-03-verbatim-spatial-pipeline-port-master-plan.md`). - **P1 (membership) = DONE.** Proven to already match retail; the "0/11 lag" was a cdb capture artifact. Merged to `main` + pushed to both remotes (HEAD `f0d37d8`). See `docs/research/2026-06-03-p1-membership-swept-advance-handoff.md` (RESOLVED banner) + `memory/project_retail_membership_criterion.md`. - **P2 (door / building-shell collision) = IN PROGRESS, root cause LOCALIZED.** The fix is the next step. - **Next concrete step:** read+compare acdream `find_walkable`/`step_sphere_down` vs retail `BSPTREE::step_sphere_down` (pc:323665) + `find_walkable`, pin the step-up CLIMB divergence, and drive `B1_GroundedMover_LowStep_StepsUp` + the door apparatus REDβ†’GREEN. ## TL;DR (the P2 finding) All **5 failing Core tests** localize to **BSP Path 5 (the grounded `Contact + StepSphereUp` branch)**: | Test | Symptom | |---|---| | `BSPStepUpTests.B1_GroundedMover_LowStep_StepsUp` | grounded mover wall-slides a **walkable 0.25 m step** instead of stepping up (`CurPos.Z` stays 0). The cleanest isolation of the bug. | | `BSPStepUpTests.D4_AirborneMover_TallWall_PersistsSlidingNormalAcrossFrames` | airborne tall-wall sliding-normal count (`Expected: 2`) β€” Path 4/5 sliding-normal family. | | `DoorCollisionApparatusTests.Apparatus_Grounded_50cmOffCenter_FrontApproach_DocumentsBug` | synthetic door + grounded off-center: now blocks at tick 0 with an `(0,0,1)` up-normal + goes airborne (Path 5 step-up artifact, not a faithful door block). | | `DoorBugTrajectoryReplayTests.LiveCompare_DoorOffCenterWalkthrough_Tick13558` | replay of captured live tick diverges from the engine (documents-the-bug). | | `DoorBugTrajectoryReplayTests.LiveCompare_DoorBlocksFromOutside_Tick22760` | same, outdoor-block tick. | These have been the documented baseline RED set for a while (they are P2's target). They did NOT regress this session β€” P1's work only touched conformance tests + docs. ## Root cause β€” PRECISELY localized (the whole upstream chain is verified faithful) For B1 (the cleanest case), the path is reached + dispatched correctly; the divergence is deep in the climb. Verified faithful and ruled out this session (DO NOT re-investigate these β€” see DO-NOT-RETRY): 1. **Path 5 dispatch is reached.** `BSPStepUpFixtures.MakeGroundedTransition` sets `State = Contact | OnWalkable` + `StepDown=true` β€” but that `StepDown` is `ObjectInfo`'s flag; the Path 3 dispatch gates on the `SpherePath.StepDown` flag (only set during a step-down probe), so the **main sweep correctly lands in Path 5's `Contact` branch** (`BSPQuery.cs:1814`). 2. **Recursion guard passes.** `if (engine is not null && !path.StepUp && !path.StepDown) return StepSphereUp(...)` (`BSPQuery.cs:1848`) β€” on the main sweep both `SpherePath` flags are false β†’ `StepSphereUp` β†’ `DoStepUp` IS called on the wall hit. 3. **`DoStepUp` (`TransitionTypes.cs:3254`) = faithful port of retail `CTransition::step_up` (pc:273099).** Same structure: clear contact-plane, `stepDownHeight = OnWalkable ? StepUpHeight : 0.04`, `walkableAllowance = OnWalkable ? GetWalkableZ() : LandingZ`, call `DoStepDown(...)`, return its result. (acdream adds a restore-contact-plane-on-failure block β€” benign.) 4. **`DoStepDown` (`TransitionTypes.cs:3074`) = faithful port of retail `CTransition::step_down` (pc:272946).** Skips the down-offset when `StepUp` is set, runs `TransitionalInsert(5)`, accepts iff `OK && ContactPlaneValid && ContactPlane.N.z >= walkableZ`, then placement-validates. **So the divergence is INSIDE the step-up climb:** `DoStepDown` β†’ `TransitionalInsert(5)` β†’ Path 3 `step_sphere_down` β†’ **`find_walkable`'s upper-floor find + sphere-up-adjust when `sp.StepUp=true`**. It fails to locate/lift onto the 0.25 floor within the 0.30 budget β†’ `DoStepDown` returns false β†’ `StepUpSlide` β†’ wall-slide β†’ `Z=0`. The retail oracle for the climb is `BSPTREE::step_sphere_down` (`@ 0x53a210` pc:323665) + `BSPNODE/BSPLEAF::find_walkable` + `adjust_sphere_to_plane`. acdream code map: `BSPQuery.StepSphereUp` (`:1372`), `BSPQuery.step_sphere_down` (`:1206`), `BSPQuery.find_walkable` (`:693`), `BSPQuery.AdjustSphereToPlane` (search it), `Transition.DoStepUp` (`:3254`), `Transition.DoStepDown` (`:3074`). ## ⚠ TOOLING NOTE (cost me a probe cycle β€” don't repeat) **xunit swallows `Console.WriteLine`.** The built-in `ACDREAM_DUMP_STEPUP=1` trace (in `DoStepUp`) and the `[step-walk]` probe (`PhysicsDiagnostics.ProbeStepWalkEnabled`) both print via `Console` β†’ they do NOT surface in `dotnet test ... -l "console;verbosity=detailed"`. The tests that DID show output used `ITestOutputHelper` (`_out.WriteLine`). So to trace which climb condition fails (`TransitionalInsert(5)` result / contact-plane / `N.z` / placement), **add an `ITestOutputHelper`-based trace to B1 (or a focused harness) β€” don't rely on the `Console` probes inside the engine.** ## DO-NOT-RETRY (verified faithful this session) 1. Path 5 dispatch / the Contact-branch reachability β€” confirmed B1 reaches Path 5. 2. The recursion guard / `StepSphereUp` call β€” confirmed `DoStepUp` is called. 3. `DoStepUp` vs retail `step_up` β€” faithful, ruled out. 4. `DoStepDown` vs retail `step_down` β€” faithful, ruled out. The bug is downstream in `find_walkable`/`step_sphere_down`'s **step-up adjust**. Start there. ## Next steps (evidence-first β€” the door saga burned many SPECULATIVE fixes; do NOT repeat) 1. **Read+compare** acdream `BSPQuery.find_walkable` (`:693`) + `step_sphere_down` (`:1206`) + `AdjustSphereToPlane` against retail `BSPTREE::step_sphere_down` (pc:323665) + `BSPNODE/BSPLEAF:: find_walkable` + `adjust_sphere_to_plane`. Focus on the `step_up==1` path: how retail lifts the sphere onto a step within `step_down_amt`, and where acdream fails to. 2. **Instrument B1 with `ITestOutputHelper`** (Console is swallowed β€” see tooling note) to pin which condition fails: does `TransitionalInsert(5)` return OK? is `ContactPlaneValid` set? is the landing `N.z >= walkableZ`? does placement (`TransitionalInsert(1)`) reject? `B1` is sub-second, headless. 3. **Fix the climb verbatim** (cite the decomp anchor), drive `B1` GREEN, then `B2` (must still block the 5 m wall), then the door apparatus (`Apparatus_Grounded_50cmOffCenter…` flips to block-not-walkthrough β†’ rewrite its assertion to `Assert.True(blocked) && pos.Y < 12.0`), then the 2 `LiveCompare` ticks, then `D4`. 4. **Definitive cross-check if the decomp is ambiguous:** cdb-attach to retail at a Holtburg cottage doorway, break on `CTransition::step_up`/`step_down`/`BSPTREE::step_sphere_down`, walk a low step + the door, capture what retail does. PDB MATCHES; tooling in `tools/cdb/` (CLAUDE.md "Retail debugger toolchain"). Needs the user's retail client up + walking. 5. **User visual gate:** at a doorway, walk through cleanly (foot Y stable, no oscillation), walls block; step up a low step (cottage stair) climbs. ## Test baseline (going into the P2 fix) Core **1309 pass / 5 fail / 1 skip** β€” the 5 are exactly this P2 target (`Apparatus_Grounded…`, `LiveCompare_DoorOffCenterWalkthrough_Tick13558`, `LiveCompare_DoorBlocksFromOutside_Tick22760`, `BSPStepUpTests.D4…`, `BSPStepUpTests.B1…`). Conformance 60 pass / 1 skip / 0 fail. App 177 green. ## Parked (do NOT touch without explicit user approval) - **(a)–(d) membership cleanups** β€” approval-gated refactors of WORKING code (CLAUDE.md "don't replace working retail-faithful logic without approval"): (a) remove redundant `ResolveCellId` (already out of the prod per-frame path; survives only in the `DataCache==null` test fallback); (b) unify the forked `find_env_collisions`; (c) replace the `CheckBuildingTransit` bridge with intrinsic building stabs in `find_transit_cells`; (d) make the per-cell ObjCell graph the collision authority (collision still uses the landblock-wide `ShadowObjectRegistry`). The one soft spot: outdoorβ†’indoor `0031↔0170` building-entry is live-clean but NOT conformance-locked (rides on `CheckBuildingTransit`). - **Render residuals (P3/P4)** β€” the VISIBLE doorway seam is now in the render path: the flap = camera-collision residual (chase eye drifts out of the cell β†’ viewer-cell flips; master-plan P3, `SmartBox::update_viewer`); the void = unported PView seal (P4). Membership (physics) is correct. See `docs/research/2026-06-03-p1-visual-gate-render-residuals.md`. Master-plan order: P2 β†’ P3 β†’ P4. --- ## FRESH-SESSION PROMPT (copy-paste) ``` Continue the VERBATIM retail spatial-pipeline port for acdream. Branch claude/thirsty-goldberg-51bb9b (do NOT branch/worktree; do NOT push without asking; NEVER git stash/gc). PowerShell on Windows; launch logs are UTF-16. STATE: M1.5 (Indoor world feels right). P1 membership = DONE (proven to already match retail; the "0/11 lag" was a cdb capture artifact; merged + pushed, HEAD f0d37d8). P2 (door/building-shell collision) = IN PROGRESS, root cause LOCALIZED to BSP Path 5 grounded step-up. The fix is the job. READ FIRST (canonical, in order): 1. docs/research/2026-06-03-p2-door-stepup-handoff.md (THIS handoff β€” the localization, the DO-NOT-RETRY list, the tooling note, the next steps). 2. docs/superpowers/specs/2026-06-03-verbatim-spatial-pipeline-port-master-plan.md (Β§3 P2; Β§1/Β§2 B3/B4). 3. docs/research/2026-05-25-door-bug-partial-fix-shipped.md (the door saga state + its do-not list). THE FINDING: all 5 failing Core tests localize to BSP Path 5 (grounded Contact + StepSphereUp). For B1 (cleanest: a grounded mover wall-slides a walkable 0.25 m step with a 0.30 m budget, Z stays 0), the whole upstream chain is VERIFIED FAITHFUL + correctly reached β€” Path 5 dispatch, the recursion guard, DoStepUp (= retail CTransition::step_up pc:273099), DoStepDown (= retail step_down pc:272946). The divergence is INSIDE the step-up CLIMB: DoStepDown β†’ TransitionalInsert(5) β†’ Path 3 step_sphere_down β†’ find_walkable's upper-floor find + sphere-up-adjust when sp.StepUp=true. It fails to lift onto the 0.25 floor β†’ StepUpSlide β†’ wall-slide. DO NOT RE-INVESTIGATE (verified faithful): Path 5 dispatch, the recursion guard, DoStepUp, DoStepDown. DO NOT speculate on the BSP fix without apparatus (the door saga burned many speculative fixes). TOOLING: xunit swallows Console.WriteLine β€” the ACDREAM_DUMP_STEPUP / [step-walk] probes don't surface in the runner; instrument B1 with ITestOutputHelper to trace the climb conditions. THE JOB (P2 fix, evidence-first): 1. Read+compare acdream BSPQuery.find_walkable (:693) / step_sphere_down (:1206) / AdjustSphereToPlane vs retail BSPTREE::step_sphere_down (pc:323665) + BSPNODE/BSPLEAF::find_walkable + adjust_sphere_to_plane, focused on the step_up==1 climb. Pin the divergence (instrument B1 with ITestOutputHelper if needed). 2. Port the climb verbatim (cite the anchor). Drive REDβ†’GREEN: B1 (steps up), then B2 (still blocks the 5 m wall), then DoorCollisionApparatusTests.Apparatus_Grounded_50cmOffCenter (flips to block β€” then rewrite its documents-the-bug assertion to Assert.True(blocked) && pos.Y < 12.0), then the 2 LiveCompare ticks, then D4. 3. If the decomp is ambiguous: cdb-attach to retail at a cottage doorway (break on step_up/step_down/ step_sphere_down) β€” needs the user's retail client. PDB matches; tools/cdb/. 4. USER VISUAL GATE: walk through a doorway cleanly (foot Y stable, walls block); step up a cottage stair (climbs). TEST BASELINE: Core 1309 pass / 5 fail (the P2 target above) / 1 skip; Conformance 60 pass / 1 skip; App 177 green. PARKED (need explicit approval): the (a)-(d) membership cleanups + the render residuals (P3/P4 β€” the visible doorway flap/void). Do NOT speculate a Path-5 fix before the climb divergence is pinned with evidence. ```