docs: C4 handoff for routes 4b-3, 5, 6, 7, 3
Closes #312 as user-confirmed, with the caveat recorded rather than buried: the accepting session's probe capture showed 22 parks and zero park-restores, so the restoration path was not observed executing. If an invisible-remote report recurs, that is where to start. Re-scopes #309 as largely superseded by #312 — the presentation restore is the behaviour its connected check was written to probe. What survives is the narrower faithfulness question: retail's GotoLostCell keeps a lost-cell object hidden until reenter_visibility, where acdream re-shows it on cancel. Adds the handoff itself: branch state and the measured 11,027 baseline, the two known flakes and the standing instruction not to conflate them, per-route scope with the retail addresses and the traps already paid for (teleport_hook runs BEFORE the placement; route 5 has no possible live gate because ACE never sends UpdatePosition for a missile; route 6 needs zero production lines and the campaign plan carries a false premise about create-time effects; route 7 must write the child cell at BOTH the set_parent analog and the per-commit position analog), and the six process rules this session paid for — chiefly that the contract causes the defect, that a slice must split on discovery, and that a green suite and a clean-looking live session are both non-evidence. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
parent
2eb39a0250
commit
3e002993dd
2 changed files with 150 additions and 13 deletions
|
|
@ -32,7 +32,14 @@ the delta-review round on the same route's remediation. Evidence:
|
|||
|
||||
## #309 — Cancelled lost-cell park re-shows the entity where retail would keep it hidden
|
||||
|
||||
**Status:** OPEN
|
||||
**Status:** OPEN — but **largely superseded by #312** (closed `b1f914d5`,
|
||||
2026-08-04). #312 made a cancelled park restore the presentation half as well
|
||||
as the Runtime half, which is the behaviour #309's connected check was written
|
||||
to probe. What remains genuinely open here is the narrower retail-faithfulness
|
||||
question: retail's `GotoLostCell` keeps a lost-cell object HIDDEN until
|
||||
`reenter_visibility` fires on cell arrival, whereas acdream re-shows it on the
|
||||
cancel. Re-scope before running; the original six-step gate is now partly
|
||||
redundant.
|
||||
**Severity:** MEDIUM
|
||||
**Filed:** 2026-08-04
|
||||
**Component:** physics / placement
|
||||
|
|
@ -230,19 +237,16 @@ not allocate a new array per tick.
|
|||
|
||||
## #312 — Cancelled park restored Runtime state but never the presentation half
|
||||
|
||||
**Status:** FIXED `b1f914d5`, **live gate NOT YET EXERCISED**. The 2026-08-04
|
||||
two-client run looked correct to the user, but the probe capture shows 22
|
||||
`[park]` lines (all `cause=unplaceable`) and **zero `[park-restore]` lines** —
|
||||
no park was cancelled, so the restoration path never ran. That session
|
||||
therefore observed the intermittent failure *not reproducing*; it neither
|
||||
confirms nor refutes the fix. Do not close on it.
|
||||
**Status:** CLOSED — fixed `b1f914d5`, **user-confirmed 2026-08-04**.
|
||||
|
||||
**To actually exercise it:** the failing shape needs a park that is then
|
||||
cancelled while the entity is canonically whole. Run with
|
||||
`ACDREAM_PROBE_PARK=1` and look for a `[park-restore] … presentation=True`
|
||||
line for the remote's guid. Absence of that line means the gate did not run,
|
||||
whatever the screen showed. The mechanism is pinned by four tests with a
|
||||
seven-revert discrimination table; what is missing is live confirmation.
|
||||
**Caveat recorded for whoever revisits this:** the probe capture from the
|
||||
accepting session showed 22 `[park]` lines (all `cause=unplaceable`) and zero
|
||||
`[park-restore]` lines, i.e. no park was cancelled during it, so the
|
||||
restoration path itself was not observed executing. The user judged the
|
||||
behaviour correct and closed it. The mechanism is pinned by four tests with a
|
||||
seven-revert discrimination table. If an invisible-remote report recurs, start
|
||||
here and look for `[park-restore] … presentation=True` under
|
||||
`ACDREAM_PROBE_PARK=1` before assuming a new cause.
|
||||
**Severity:** HIGH (a remote player permanently invisible in world and radar)
|
||||
**Filed:** 2026-08-04
|
||||
**Component:** physics / placement / presentation
|
||||
|
|
|
|||
133
docs/research/2026-08-04-session-handoff-c4-remaining.md
Normal file
133
docs/research/2026-08-04-session-handoff-c4-remaining.md
Normal file
|
|
@ -0,0 +1,133 @@
|
|||
# C4 handoff — routes 4b-3, 5, 6, 7, 3 (2026-08-04)
|
||||
|
||||
Written at the end of a long session. **Read this before touching anything.**
|
||||
|
||||
## Where the branch is
|
||||
|
||||
- Worktree `C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-visvesvaraya-e0a196`
|
||||
- Branch `claude/acdream-physics-divergence-5aa784`, HEAD **`2eb39a02`**
|
||||
- **`main` is at `c7d5fc14` and must stay there.** The commits on this branch are
|
||||
deliberately unmerged. Do not merge, rebase, or push unless the user asks.
|
||||
- Complete Release suite: **11,027 passed / 4 skipped / 0 failed**. This is the
|
||||
baseline. Any deviation is a regression you introduced.
|
||||
```
|
||||
$env:ACDREAM_PAK_PATH = "$env:USERPROFILE\Documents\Asheron's Call\acdream.pak"
|
||||
dotnet test AcDream.slnx -c Release -m:1
|
||||
```
|
||||
- Two known flakes — do **not** chase, and do **not** conflate (they have been
|
||||
conflated twice): **#302** `PortalProjectionTests.ClipToRegion_FrameOwnedStore_…`,
|
||||
a GC-allocation assertion in App.Tests; **#308** `NakEmissionTests.LossSoak_…`,
|
||||
a wall-clock deadline in Core.Net.Tests that fails only under full-suite load.
|
||||
|
||||
## What landed this session (all user-accepted)
|
||||
|
||||
| commit | what |
|
||||
|---|---|
|
||||
| `634bc551` | park restore — shipped defect, separate from the feature it was found in |
|
||||
| `2e8e09ac` | route 4b-1, dormant infrastructure |
|
||||
| `7f1c1f5a` | **route 4b-2** — remote far snap; far-snap walk passed |
|
||||
| `204d0ae0` | remote slide on steep faces (#32 remote half) |
|
||||
| `b1f914d5` | presentation restored on cancelled park (#312) |
|
||||
| `2eb39a02` | AP-140 — route remote Positions on contact, not walkability |
|
||||
|
||||
Plus scoping/research commits `07e97939`, `11a87428`, `1b631f12` and doc
|
||||
corrections `f058dfc9`, `97b22b86`, `f4f25795`.
|
||||
|
||||
## What is left, in order
|
||||
|
||||
**4b-3 — remote teleport + cell-less.** ~400-700 production lines. Deletes
|
||||
`RemoteTeleportController` (605 lines), `RemoteTeleportPlacement` (85),
|
||||
`RemoteShadowPlacementSynchronizer` (49) and ~1,709 lines of their tests.
|
||||
Retail: `MoveOrTeleport` @0x00516330's cell-less/teleport branch @0x00516386 →
|
||||
`teleport_hook` @0x005163EF → `SetFlags(0x1012)` @0x00516414 → `SetPosition`
|
||||
@0x00516420 → `return 1` @0x00516438. **`teleport_hook` @0x00514ED0 runs BEFORE
|
||||
the placement** and is `CancelMoveTo` + `UnStick` + `StopInterpolating` +
|
||||
`UnConstrain` + TargetManager teardown + `report_collision_end(this, 1)`
|
||||
@0x00514F31. The classifier already carries
|
||||
`RuntimeTeleportHookPhase.BeforePositionOperation` for that branch
|
||||
(`RuntimeAuthoritativePositionRouteClassifier.cs:410`) and currently
|
||||
records-and-drops it for the remote arm. **4b-3 retires AP-137's cell-less
|
||||
enqueue-vs-place delta** — today acdream enqueues where retail places
|
||||
unconditionally, at any distance.
|
||||
|
||||
**5 — projectile.** ~180 non-comment lines; **half already shipped** (the
|
||||
Create half and the residence-window Position half are canonical). What remains
|
||||
is the post-residence accepted Position, short-circuited before the classifier
|
||||
at `LiveEntityNetworkUpdateController.cs:1428-1448`. Must land **after 4b-2**
|
||||
(done) because it widens `RuntimeRemotePlacementDriveController.OwnsPlacement`,
|
||||
which excludes `ProjectileAuthoritative` today. **No live gate is possible**:
|
||||
ACE never sends `UpdatePosition` for a missile (the one site is commented out at
|
||||
`WorldObject_Tick.cs:333-334`). Test-gated; say so rather than inventing a gate.
|
||||
Scoping: `docs/research/2026-08-04-c4-route-5-scoping.md`.
|
||||
|
||||
**6 — drops. ZERO production lines.** C3c already satisfied it; a dropped item
|
||||
classifies as route 1's shape and both drop flavours converge on
|
||||
`LiveEntityHydrationController.OnCreate`. The campaign plan's "replay
|
||||
create-time effects" requirement is a **false premise** — correct
|
||||
`docs/plans/2026-08-02-placement-cutover.md:98-100`. Retail's "split-recovery
|
||||
marking" is a *selection* transfer (`UIAttemptSplitTo3D` @0x0058D850,
|
||||
`DeclareValid` @0x0058E340), missing but not placement — file outside C4.
|
||||
Scoping: `docs/research/2026-08-04-c4-routes-6-7-scoping.md`.
|
||||
|
||||
**7 — pickup / parent / delete.** ~300-490 lines, one slice, **must not be
|
||||
split**. Retail performs NO placement here (`DoPickupEvent` @0x00452240 =
|
||||
`unset_parent` + `leave_world`; `DoParentEvent` @0x00452290 = `set_parent` +
|
||||
`SetPlacementFrame`), so it **inverts 4b-2's rule: never arm `ConstrainTo`**.
|
||||
The real defect: a parented child's canonical cell has two writers, and acdream
|
||||
re-cells it from a **render tick** (`EquippedChildRenderController.TickChild:408`),
|
||||
so headless parented children stay cell-less forever.
|
||||
**Blocker resolved** — `docs/research/2026-08-04-retail-child-cell-ownership.md`:
|
||||
retail propagates via `enter_cell` @0x00510ed0 recursion **and** an explicit
|
||||
depth-1 child loop in `SetPositionInternal` @0x0051539c-@0x005153d8. `set_parent`
|
||||
@0x00515a90 contains **no** cell write. **The Runtime replacement must write the
|
||||
child's cell at BOTH the `set_parent` analog AND the per-commit position
|
||||
analog** — a `set_parent`-only write is correct at attach and stale on the
|
||||
parent's first cell crossing.
|
||||
|
||||
**3 — portal (local player).** Last. Needs the
|
||||
`RuntimeWorldTransitState` → `RuntimePortalPlacementAuthority` adapter, which
|
||||
does not exist. #280 rides with it.
|
||||
|
||||
## Process rules learned the hard way this session
|
||||
|
||||
1. **The contract causes the defect.** Route 4b-2's round-1 freeze traced
|
||||
directly to my contract saying "arm `ConstrainTo` on refusal" without saying
|
||||
"and still advance the pose." Write what must remain true, not only what must
|
||||
change.
|
||||
2. **Split on discovery.** When a slice uncovers a defect outside its scope,
|
||||
commit it separately *immediately*. 4b-2 carried a shared-core park defect
|
||||
through three extra review rounds because it wasn't split.
|
||||
3. **A green suite is not evidence.** This slice was green at 10,990 / 10,997 /
|
||||
11,004 while containing real defects, twice including a permanently
|
||||
invisible-and-intangible entity.
|
||||
4. **Tests must assert the layer that broke.** #312 shipped because the park
|
||||
restore's tests asserted `InWorld` / clock / residency — exactly the three
|
||||
fields eight reviews had named — while presentation stayed torn down.
|
||||
5. **A clean-looking live session is not a passed gate.** Confirm the code path
|
||||
actually executed (probe line, counter), not just that nothing looked wrong.
|
||||
6. **Stale comments are endemic** — six consecutive slices shipped comments
|
||||
asserting behaviour the code no longer had, including inside the round meant
|
||||
to end it. Verify every comment you touch against the code beside it, and
|
||||
prefer symbol references to line numbers.
|
||||
|
||||
## Open, not blocking
|
||||
|
||||
- **#309** — largely superseded by #312; re-scope before running. What survives
|
||||
is narrow: retail's `GotoLostCell` keeps a lost-cell object hidden until
|
||||
`reenter_visibility`; acdream re-shows it on cancel.
|
||||
- **#32 residuals** — `LeaveGround` chatter bound, the `!Ok` airborne latch, and
|
||||
the `contact_allows_move` watch item (a remote lacking Contact|OnWalkable
|
||||
silently loses action animations — the literal root cause of closed #270). If
|
||||
a "missing attack/cast animation on flat ground" report appears, start there.
|
||||
- **Diagnostic probes are still in the tree** and are marked TEMPORARY:
|
||||
`ACDREAM_PROBE_REMOTE_LANDING`, `ACDREAM_PROBE_REMOTE_SLIDE`,
|
||||
`ACDREAM_PROBE_PARK`. Strip as a family when the physics work settles.
|
||||
|
||||
## Connected-test recipes that worked
|
||||
|
||||
- **Far snap:** stand still; second character runs past ~100 m, stops, turns,
|
||||
runs back. Three or four times.
|
||||
- **Steep slide:** second character jumps onto a sloped roof.
|
||||
- **Park:** move to a landblock not visited this session, have the remote arrive
|
||||
while it is still streaming, have them take a step, then stand still.
|
||||
- Graceful close matters — a hard kill leaves ACE holding the session ~3 minutes.
|
||||
Loading…
Add table
Add a link
Reference in a new issue