acdream/docs/research/2026-08-03-c4-handoff/NEXT-AGENT-PROMPT.md
Erik 22a5c95400 docs: next-agent handoff prompt for C4 routes 2-7
Self-contained continuation prompt for the placement cutover. Records the
worktree/branch/HEAD (and that main is still at c7d5fc14 with these commits
unmerged, per the user's direction to work in the worktree), the read-first
list, binding rules, the 10,844/4/0 baseline to measure against, the 10
commits landed on this branch, and the work order: route 2 from its pinned
contract, route 3 with #280 beside it, routes 4-7 folding in #276/#277, C5
closeout, then AP-22 and AD-10.

Carries the two things a fresh session would otherwise have to rediscover:
route 2 is a seam-building slice rather than a wiring job (the accepted-Position
classifier's only production consumer is route 1's Create continuation), and
the complete-suite-before-every-commit gate that the #281-#284 regressions
bypassed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-03 14:43:56 +02:00

199 lines
9.9 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.

# Next-agent prompt — C4 placement routes 27
Continue the acdream placement cutover from the 2026-08-03 regression-cleanup
checkpoint. The code is modern; behaviour must remain retail-faithful.
## Where to work
```text
C:\Users\erikn\source\repos\acdream\.claude\worktrees\peaceful-visvesvaraya-e0a196
```
Branch `claude/acdream-physics-divergence-5aa784`, expected HEAD
`f2b06f378738474b0861e4d990d17f9645e07615`.
**The user directed that work happen in this worktree, not in `main`.**
`main` is still at `c7d5fc14` — the 10 commits below are NOT merged. Do not
merge, rebase, or push unless the user explicitly asks. Preserve the main
worktree's untracked research/tooling files.
## Read before editing
1. `CLAUDE.md` and `AGENTS.md`.
2. `docs/research/2026-08-03-c4-route-2-contract.md` — **the pinned contract
for your first task.** It is the whole ramp-up for route 2.
3. `docs/plans/2026-08-02-placement-cutover.md` — the C4/C5 campaign plan.
4. `docs/research/2026-08-02-cutover-route-inventory.md` — the 8-route,
both-host call-chain inventory with exact file:line for every duplicate
authority. THE map for routes 37.
5. `docs/plans/2026-08-03-recent-regression-cleanup.md` — closed; explains the
three defects fixed this session and why.
6. `docs/ISSUES.md`#276, #277, #280 (open); #281#284 (closed this session).
7. `docs/architecture/retail-divergence-register.md` rows AP-1, AP-22, AP-131,
AP-133, AD-1, AD-10, AD-60, TS-28.
## Binding rules
- Retail is the oracle. Grep
`docs/research/named-retail/acclient_2013_pseudo_c.txt` by named
`class::method` BEFORE any fresh decompilation.
- Preserve the Runtime-owned, presentation-independent architecture. Graphical
and headless hosts use the same canonical owners.
- Root causes only. No timeouts, grace periods, suppression flags,
catch-and-swallow, duplicated placement writers, or test-only bypasses.
- The user's live observations outrank green automated tests.
- Never `git add -A`, `git add .`, `git reset --hard`, or
`git checkout -- <path>`. Stage exact paths only.
- Each independent fix is its own bisectable commit recording root cause and
evidence; issue and divergence ledgers update in that same commit.
- **Run the COMPLETE Release solution suite green before every commit.** Not a
focused subset. Every regression cleaned up this session shipped because a
commit was gated on focused tests while the full suite was red. It costs
~30 seconds:
```
$env:ACDREAM_PAK_PATH='C:\Users\erikn\Documents\Asheron''s Call\acdream.pak'
dotnet test AcDream.slnx -c Release -m:1
```
- Close the client gracefully before reconnecting to ACE at `127.0.0.1:9000`.
The user manages client lifecycle; if a rebuild is lock-blocked, ASK.
- Launch visual gates in **Release**, with `ACDREAM_RETAIL_UI=1` (the user
prefers the retail GUI).
## Baseline
Complete Release solution at HEAD: **10,844 passed / 4 skipped / 0 failed**
(App 4,058/3, Bake 15, Cli 4, Content 124, Core.Net 762, Core 4,247/1,
Headless 79, Runtime 1,012, UI 543). Treat any deviation as a regression you
introduced.
## Completed on this branch (10 commits)
| Commit | What |
|---|---|
| `6dcb94ac` | Restored the world-frame precondition across 5 first-entry fixtures; added `RuntimeWorldFrameTests` |
| `98e9f9e8` | Modelled the post-`f24532ad` effect cell / canonical body frame in 2 rendering fixtures |
| `95ebc03a` | Filed #282#284 + cleanup plan |
| `97d11e6c` | **#284** — parked placements name their cause; terminal on the contradictory state |
| `3c36b4cc` | **#282** — one cell owner (`WorldEntity.VisibilityCellId`); register row AP-133 |
| `0c14c402` | Connected visual acceptance for #282/#284 |
| `898ff18b` | #283 reachability probe (`ACDREAM_PROBE_WORLD_FRAME=1`) |
| `89cf1e66` | **#283** — measured UNREACHABLE; permanent invariant instead of a restructure |
| `2ef02f8c` | Closed the cleanup plan |
| `f2b06f37` | **Pinned the route 2 contract** (your starting point) |
Context worth carrying: the handoff that started this session claimed "six
selected fixture failures". The measured baseline was **43** — the App suite
was fully green at `01f4791e` and `670f307c` broke 28 tests in one commit,
while the Runtime suite lost 13. All were stale fixtures, fixed without
weakening a single assertion. Three real product defects (#282#284) were
found in the same sweep and are now closed.
## Work order
### 1. Route 2 — ForcePosition (start here)
Execute `docs/research/2026-08-03-c4-route-2-contract.md`.
Scoping is already done and it is **not** a small wiring job:
`RuntimeAuthoritativePositionRouteClassifier.ClassifyAcceptedPosition` produces
the retail-exact ForcePosition route but has exactly ONE production consumer —
`RuntimeInitialCreateContinuationExecutor.cs:1948`, route 1's Create
continuation. A live local player receiving a Position has no Runtime consumer
at all. You must build the accepted-Position execution seam, then cut App over.
Two duplicate authorities to delete:
- `LocalForcePositionTransaction` (blip + pre-commit outbound ack);
- the generic tail at `LiveEntityNetworkUpdateController.cs:1264-1281`, which
independently writes position/cell/rotation to the render entity and
rebuckets the SAME accepted Position.
Named behaviour change to call out in the commit: the outbound
`AutonomousPosition` ack currently fires BEFORE any canonical commit, and the
trailing `isCurrent()` only suppresses the continuation — the packet has
already gone. Retail makes it `SendPositionImmediately`, an output of the
executed route.
Retail: `SmartBox::HandleReceivedPosition` @0x00453FD0 — the FORCE_POSITION
early return (~92932) precedes `unset_parent` (~92990) and the
`!HasAnims`-gated `SetPlacementFrame` (~92992).
### 2. Route 3 — portal placement
`RuntimeWorldTransitState` → `RuntimePortalPlacementAuthority` adapter. Delete
`LocalPlayerTeleportPlacement.Place`
(`LocalPlayerTeleportController.cs:214-278`), which does its own resolve, body/
cell write, world-entity write, rebucket and host-notify, and then calls
`AcknowledgePortalMaterialized` AFTERWARDS — a rubber stamp, not a gate.
Re-sequence so the acknowledgement is the actual gate.
#283 is already settled, so the origin question is closed going in; the
permanent guard is `LiveWorldOriginState.EnsureAgreesWithRuntimeFrame`.
### 3. #280 — portal destination prefetch (land beside route 3)
The reveal gate is a hardcoded 3×3 landblock neighbourhood
(`WorldRevealReadinessBarrier.OutdoorNeighborhoodRadius = 1`, 576 m) while the
configured view is 11×11 to 31×31 (2,1125,952 m) depending on quality preset
— so the viewport opens on ~1.4% of the visible world on High and the user
watches the rest stream in. Compounded by `BeginOriginRecenter` detaching every
resident landblock (no reuse) and `MaxCompletionsPerFrame` 26.
Port retail's mechanism, not a bigger magic number: `CellManager::PreFetchCells`
@0x00455820, `LScape::PreFetchCells` @0x00505660, `CLandBlock::PreFetchCells`,
`CLandBlockInfo::PreFetchCells`, `SmartBox::UseTime` @0x00455410 while
`blocking_for_cells`, and the `TAS_TUNNEL_CONTINUE` resume/reveal ordering.
Use the configured quality/view-distance window; hold ONE generation-scoped
reservation across terrain, statics/buildings, EnvCells, render publication,
composites, and collision. Keep the wait cue responsive. Never reveal early on
a timeout; never wait for an impossible "all dynamic objects delivered" marker.
### 4. Routes 47
- **4** — remote Create/Position; delete `RemoteTeleportController`/`Placement`
and the inline MoveOrTeleport duplicate. Retires AP-131.
- **5** — authoritative projectile correction.
- **6** — drops + split-recovery marking.
- **7** — pickup, parent detach, delete/GUID-reuse residue.
Fold in #276 (`SpawnPlacementSettler` must commit the settle's resolved
`CellId`) and #277 (far Create needs a real service-window/cell-less lifecycle
instead of relying on ACE's broadcast radius) where their route becomes
authoritative. #284's parked-placement counts were deliberately NOT folded into
`IsConverged` because #277 documents a legitimate session-long park — wire them
into the connected gates when #277 makes "legitimately parked" definable.
### 5. C5 closeout
Delete every superseded writer; focused + complete suites; lifecycle/reconnect;
canonical nine-stop soak **on the final binary** (read `report.json`, require
`Passed=true`, zero failures, all checkpoints, `waitCueShown=false`, no pending
publication/retirement/reveal debt, no render-shadow mismatch, graceful exit);
two-client observation; user visual matrix. Then retire AP-1, AD-1, AP-131 and
AD-60's legacy half.
### 6. Then AP-22, then AD-10
- **AP-22** — `ShadowShapeBuilder` as the sole authority for authored Setup
collision shapes. Preserve authored cylinder order; authored spheres when no
cylinders; cylinder-first for mixed; truly shapeless means no shadow. Remove
invented `Setup.Radius` cylinders, `Radius * 2` heights, sphere-to-cylinder
coercion, across graphical/headless/static/live together.
- **AD-10** — remote slope projection through the real retained transition
contact plane. Prove remote motion uses the complete sweep, remove
terrain-normal preprojection, let `CTransition::adjust_offset` project
against the actual collision plane. Preserve interpolation queues,
authoritative correction replacement, Hidden state, network cadence.
Then the final movement/collision matrix and ledger/architecture/roadmap/
milestones/memory/`CLAUDE.md`/`AGENTS.md` updates. Vendor Slice 5 resumes only
after the campaign is genuinely closed.
## Reporting
For every fix report: reproduction, retail evidence (named symbol + address),
plain-language root cause, files/lines, the fix, tests, commit SHA, complete
build/test numbers, user visual result where required, and which issues or
divergence rows were closed, narrowed, or left open.
Do not describe the campaign as complete while any C4 route, #280, the
final-binary soak, AP-22, AD-10, or a required user visual gate remains.