acdream/docs/research/2026-06-10-issue113-phantom-stairs-misplaced-cell-handoff.md

102 lines
6.4 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# HANDOFF — #113 phantom exterior staircase (A9B3) / misplaced-interior-cell suspect
**Date:** 2026-06-10 (very late). **Branch:** `claude/thirsty-goldberg-51bb9b`, HEAD `77d7ea1`.
**Pick rationale:** the user's standing directive from tonight — *"we should not have to
verify all houses like this"* — wants systemic fixes. #113 is the cheapest
highest-information probe: if the misplaced-cell hypothesis holds, ONE bug class explains
phantom geometry + containment gaps (#112) + some collision gaps across every affected
house. Rider task: the #112 residual oracle read (same code area, ~30 min).
Read the **physics digest** (`claude-memory/project_physics_collision_digest.md`) first —
its top banners carry tonight's #107/#111/#112 arc. Render digest unchanged except #105.
---
## 1. The issue (user side-by-side vs retail, 2026-06-10)
An A9B3 building (near the #112 hill cottage; NPCs **Aun Kielerea** + **The Sentry**
adjacent; the user stood at ~world (183, 111, 116), which is A9B3-local (183, 81, 116))
shows a **stone-and-wood staircase attached to its exterior wall** in acdream. Retail
shows a plain wall with a window. Screenshots are in the session transcript
(2026-06-10); the spot is trivially re-findable — it's next to the A9B3 hill cottage
with interior cells 0x100/0x103/0x104 at z=116.
**Key fact:** the stairs are NOT pickable — clicks select the NPCs behind them
(`issue112-gate1.log:37032+`). Not a stab/WorldEntity ⇒ building-shell geometry or an
interior EnvCell's geometry drawn outside.
## 2. The hypothesis to test FIRST
**A misplaced interior EnvCell** — an indoor staircase cell whose world transform
(Position.Origin/orientation from the dat, or our application of it) places its geometry
outside the shell. One misplaced cell would unify, at this building:
- the phantom exterior stairs (its geometry pokes through/outside the wall),
- an interior containment dead-zone (#112's gap = the volume is where the geometry
ISN'T — note the #112 scan found a real gap inside the HILL COTTAGE; check whether
the staircase building and the hill cottage are the same building or neighbors),
- missing collision on objects inside (their owning cell volume is elsewhere).
## 3. Attribution plan (cheap, ordered)
1. **ACViewer oracle** (`feedback_acviewer_as_oracle`): open landblock **A9B3** in
ACViewer and look at the same building. Stairs present there too ⇒ shared
dat-interpretation (both projects misread the dat — go to the dat bytes); absent ⇒
OUR transform/draw path (EnvCell world-transform application or the building shell
draw). This single check halves the space.
2. **Identify the building + cell**: dump A9B3's `LandBlockInfo.Buildings` (model id,
Position) + every interior `EnvCell.Position` (`dats.Get<EnvCell>(0xA9B301xx)`).
The conformance harness pattern is ready-made: `ConformanceDats.LoadEnvCell` +
a scratch test with `ITestOutputHelper` (see `Issue112MembershipTests.cs` for the
loader shape; A9B3-local frame: world y + 192, world x unchanged, center A9B4).
Look for a cell whose origin/AABB escapes its building's footprint, and specifically
for a STAIR-shaped Environment near the user's spot (stairs = the EnvironmentId's
CellStruct will have ramp polys).
3. **Cross-check the #112 gap**: the gap point A9B3-local (184.9, 82.5, 116.5) — which
cell SHOULD cover it per the dat layout? If the misplaced cell's correct position
covers the gap, the hypothesis is proven end-to-end.
4. Fix per finding; conformance test the transform (golden origins from the dat).
## 4. Rider: #112 residual (same session, ~30 min)
`Issue112MembershipTests.A9B3CottageGap_..._DocumentsResidual` pins it: at the doorway
gap, the pick demotes via the NORMAL outdoor-candidate path (NOT the removed hatch).
Oracle read needed: retail `CEnvCell::find_transit_cells` (around pc:317499) — is
`add_all_outside_cells` gated on sphere-proximity to the exterior portal POLYGON or on
mere graph reachability? If proximity-gated, tighten our port and flip the
DocumentsResidual assert to keep-curr (`0xA9B30104`). Re-promotion at doorways already
works — this residual self-heals walking in; it's polish, not a stranding.
## 5. Tonight's shipped state (do not redo — see digests + ISSUES.md)
| Issue | State | Commits |
|---|---|---|
| #105 white walls | CLOSED (per-frame texture flush restored) | `c787201` |
| #110 near plane | CLOSED (retail 0.1 re-landed, corner gated) | `d4b5c71` |
| #107 login wedge | CLOSED (snap validation + PortalSpace fix + wire pairs + hold) | `1090189`, `e4f6750` |
| #111 login placement | CLOSED user-gated (claim-authoritative snap, walkable-poly grounding, entity parity) | `5f1eb7c`, `5706e0e`, `2735695` |
| #112 transparent-while-walking | PRIMARY FIX shipped (hatch removed, lateral stab recovery, retail keep-curr); residual documented; live cottage re-walk gate pending | `2d6954e` |
| #113 phantom stairs | FILED (this handoff) | `77d7ea1` |
Key new invariants: server (cell,pos) pairs are VALIDATED at the snap
(`PhysicsEngine.Resolve` head: retail `AdjustPosition` :280009 + walkable-poly grounding
`WalkableFloorZNearest` + `[snap]`/`[spawn-adjust]` log lines, one per login/teleport);
the per-tick pick keeps curr_cell on null result (retail pc:308788-308825) with lateral
stab-graph recovery. ACE persists ITS OWN physics state, not our reports
(`SetRequestedLocation` — ACE source confirmed) — every restore shape it produced
tonight is survivable.
## 6. Ops notes
- Launch protocol: standard PowerShell launch (CLAUDE.md) + `ACDREAM_PROBE_RESOLVE=1`
+ `ACDREAM_PROBE_CELL=1`; tee a log. In-world marker `auto-entered player mode`.
Graceful close ⇒ ~5 s ACE hold; hard kill ⇒ ~3 min exit-29.
- Character `+Acdream` is parked near the A9B3 staircase building (outdoors) — login is
clean with tonight's fixes regardless of where ACE restores.
- ⚠️ Never bulk-edit source with PS5.1 Get/Set-Content (mojibake). Tee logs = UTF-16LE.
- Baseline: Core **1383** green + 4 pre-existing #99-era failures (DoorBugTrajectoryReplay
×2 / DoorCollisionApparatus / BSPStepUp) + 1 skip; App **223** / UI **420** / Net **294**.
Gates that must stay green: P1 membership conformance (FindCellListConformance,
ThresholdPortalCrossing, CottageDoorway, CameraCornerSeal), CornerFloodReplayTests,
Issue107SpawnDiagnosticTests, Issue112MembershipTests.
- After #113: #108 (cellar grass-sweep) + #109 (far-door oscillation) render residuals,
then #99/A6.P4 per-cell shadow architecture (the big systemic debt).