# Pickup prompt — post-#137-corridor session: the #176/#177 render pair (paste into a fresh session) **Read `claude-memory/project_render_pipeline_digest.md` FIRST** (Option A — one DrawInside(viewer_cell); binding DO-NOT-RETRY table), then **ISSUES #176 and #177**, then this file. The physics digest (`claude-memory/project_physics_collision_digest.md`) carries the full 2026-07-06 collision saga if background is needed — do NOT reopen it. ## Where we are (2026-07-06 end of session) **The #137 Facility Hub corridor collision arc is DONE, user-gated** ("not collision anymore. Good." / "Looks good"). Branch `claude/vigorous-joliot-f0c3ad` (worktree), 10 commits ahead of `e73e45da`, NOT merged to main. All suites green (Core 2562 / App 713 / UI 425 / Net 385). | Commit | Fix | |---|---| | `a11df5b8` | BSPQuery Contact-branch stub slide responses leaked sliding normals (the absorbing wedge). Retail's BSP layer never writes `collision_info.sliding_normal` — only `validate_transition` 0x0050ac21; body persistence success-only (`SetPositionInternal` 0x005154c2). | | `e8651b38` | `slide_sphere` opposing-normals branch returned OK; retail returns COLLIDED_TS (0x0053762c). The "phantom wall" normal was SYNTHETIC (negated movement). PortalSide-poly theory refuted. | | `d4869154` | `CheckOtherCells` queried remaining cells at a stale pre-climb center (P2 lesson one loop deeper) — the seam shake. Per-iteration `footCenter = sp.GlobalSphere[0].Origin` refresh. | | `aa96d7ad` | The collision capsule topped out at 1.2 m (callers passed `sphereHeight: 1.2f`; head sphere center 0.72). Dat Setup 0x02000001: spheres (0,0,0.475)+(0,0,1.350) r=0.48, top 1.83 = Height 1.835. Callers now pass 1.835. Register TS-46. The window climb. | **#137 stays OPEN for the DOORS half only** (block/pass per open state). The #175 door-pose fix (2026-07-05) still needs its user gate — ask for it whenever the user is next at the hub double door (closed blocks AT the visual panels from both sides, no embed, no phantom wall). ## NEXT ARC: #176 + #177 (render, both filed 2026-07-06 from the gate session) - **#176 — purple flashing on dungeon floors at cell seams, camera-angle dependent.** Survives all physics fixes → render-side. Magenta/purple = the placeholder-texture class ([[feedback_ui_resolve_zero_magenta]]). - **#177 — stairs between levels pop in/out.** Invisible from the corridor looking into the stair room, appear on entering, vanish on the last step running down. The #119 visibility class, dungeon edition. Anchor cells: the transit `0x8A020182 → 0x8A020183` drops z −6 → −9 on stairs (launch-137-gate2.log). **The load-bearing topology fact both issues share (discovered this session):** Facility Hub corridor FLOORS are portal polygons — PortalSide floor-portals to under-rooms (e.g. 0x8A02016E visual polys 1/3/5 → 0x011E, horizontal at z=−6, spanning the whole floor; 0x011E is a hall at z=−12). Level connections run through these floor-portals. "Purple at the seams" is purple exactly where portal surfaces meet, and the stairs' rooms hang off the same portal graph — suspect the render portal-flood/portal-surface handling of HORIZONTAL portals. **⚠️ The id-space trap (cost this saga a wrong mechanism):** `CellPortal.PolygonId` indexes the VISUAL polygon table (`CellStruct.Polygons`), NOT `PhysicsPolygons`. Same ids in both tables are UNRELATED polygons. ## Tooling built this session (reuse, don't rebuild) - `Issue137CorridorSeamInspectionTests` — dat-inspection theories (add `InlineData` cells as needed): portal spans (`CorridorCell_PortalPolygonWorldSpans`), full-vertex poly dumps (`WindowShaft_FullPolyDump`), physics-BSP leaf membership, hit-normal candidate sweep (use |align| — winding flips), `HumanSetup_CollisionSpheres_DatTruth`. - `Issue137CorridorSeamReplayTests` — dat-backed `PhysicsEngine` corridor harness (`BuildCorridorEngine`: hydrate THREE portal rings or ring-3 cells are invisible to the flood — why clean-room replays kept passing). In-test probe capture pattern: `Console.SetOut(StringWriter)` + `PhysicsDiagnostics.Probe*Enabled = true` → line-diff offline vs live. - Live probe logs (worktree root, PowerShell Tee = UTF-16, `tr -d '\000'` before grep): `launch-137-seam-probes.log` (790 MB, step-level), `launch-137-gate2.log`, `launch-137-gate3.log`, `resolve-137-seam-capture.jsonl` (body snapshots, untracked). ## Physics DO-NOT-RETRY highlights from today (full table in the digest) - No `SetSlidingNormal` in the BSP/sphere layer; opposing branch returns Collided; failed transitions never write body sliding state. - The absorbed exactly-anti-parallel frame against a persisted sliding normal is RETAIL behavior — fix normal PROVENANCE, not the abort. - No height-budget check in the step-down accept — retail's climb cap is `adjust_sphere_to_plane`'s walk_interp −0.5 overshoot bound (0x00538210) + the placement insert rejecting the HEAD in solids. - Probe-field misreads: `[neg-poly]`/`[neg-poly-dispatch]` print `stepUp=` = NegStepUp (dispatch class), NOT sp.StepUp. `[walkable-nearest]` is a logger, not the decision-maker. - Remaining registered leaks (rows exist, fix later): TS-45 (`SphereCollision`'s SetSlidingNormal tail), TS-4 (Path-6 steep-tangent), TS-46 (scalar sphere approximation; remotes use human dims). ## Launch protocol (unchanged) Build green first; PowerShell launch with the env block from CLAUDE.md (+ `ACDREAM_PROBE_RESOLVE=1 ACDREAM_PROBE_CELL=1` for gates), background + Tee to `launch-*.log`. The user manages client lifecycle. Graceful close → ACE session clears in ~5 s; hard kill → ~3 min. The test character may be saved in odd places after collision testing (last session it was inside the window alcove and ACE bounced it to Holtburg — the user portals back).