acdream/docs/research/2026-08-02-cutover-route-inventory.md
Erik 27e05b99e4 docs(physics): plan the placement production cutover
The continuation executor (5db3de3c) completed the dormant residence
mechanism; the cutover is the campaign leg that makes it production truth.
The committed 8-route inventory maps every duplicate placement authority in
both hosts with exact call chains, confirms the placement-receipt observer
seam is fully built but unattached, and surfaces five pre-cutover gaps the
shipped mechanism cannot yet express (executor-to-channel bridge, atomic
controller/body publication, the 1,880 B/op activation budget, Runtime-side
live-input derivation, the portal-authority adapter). The plan decomposes
the cutover into C0-C5 bisectable slices under the campaign's standing
contract/dual-review/gate discipline, ending at the connected routes and
the user visual matrix that retire AP-1/AD-1.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 04:10:38 +02:00

64 KiB

Production cutover — 8-route inventory (2026-08-02)

Repo: C:\Users\erikn\.codex\worktrees\af5e\acdream, branch codex/port-claude-agents, HEAD 9ad590dc. READ-ONLY research; this file is the only write target.

Sources read first:

  • docs/research/2026-08-02-runtime-continuation-executor-handoff.md (executor mechanism, complete/dormant)
  • docs/research/2026-07-31-remaining-physics-campaign-handoff.md sections "What remains" (prereqs A-E) and "Production route cutover" (routes 1-8)
  • docs/research/2026-07-31-canonical-set-position.md (1,880 B/op allocation finding, line 327-333)
  • scratchpad runtime-surface.md sections 8-9 (GameRuntime construction, the two legacy RegisterEntity call sites)

Key confirmed facts carried in from the map:

  • RuntimeInitialCreateResidenceState/executor is a COMPLETE, TESTED, but 100% UNWIRED mechanism. Grep confirms (map file, line 545-549) the ONLY two production Create call sites are:
    • src/AcDream.Runtime/Session/RuntimeLiveEntitySessionController.cs:76Entities.RegisterEntity(spawn) (headless/direct-host)
    • src/AcDream.App/World/LiveEntityRuntime.cs:537_entityObjects.RegisterEntity(...) (graphical/App) Neither calls RegisterEntityWithInitialResidence. CompleteInitialCreateResidence/ AcknowledgeInitialCreateResidenceAdoption have NO production caller anywhere.
  • GameRuntime.cs:180-183 constructs RuntimeEntityObjectLifetime once as context.EntityObjects. BindEventContext at GameRuntime.cs:266-269 supplies the generation function () => generationReset.ActiveRetiringGeneration ?? context.Session.Generation.
  • 1,880 B/op measured on the warmed dormant placement commit/ack route vs a 2,048 B cap (docs/research/2026-07-31-canonical-set-position.md:327-333) — explicit 4B2 activation blocker, not yet resolved (pool/remove envelopes or record an approved budget).

Cross-cutting: observer-seam status (grep results)

IRuntimePlacementObserver already exists as a Runtime-side interface — it is NOT vaporware, contrary to a naive reading of "prerequisite D" as all-still-to-build:

  • Defined src/AcDream.Runtime/Entities/RuntimeEntityObjectEventStream.cs:18-21 (interface IRuntimePlacementObserver { void OnPlacement(in RuntimePlacementDelta delta); }).
  • RuntimeEntityObjectEventStream (same file) already has the full pub/sub plumbing: _placementObservers array (line 40), SubscribePlacement (119-133, copy-on-write add), UnsubscribePlacement (356-369), dispatch loop (302-310ish inside the drain routine), PublishPlacement (164-171, builds a RuntimePlacementDelta(NextStamp(), placement) and enqueues it through the same ordered synchronous drain as entity/inventory deltas).
  • Public host seam: src/AcDream.Runtime/Physics/RuntimePlacementProjectionChannel.cs (88 lines, read in full) — Subscribe(IRuntimePlacementObserver) (31-32, thin passthrough to _events.SubscribePlacement), Acknowledge(expectedGeneration, token) (51-55, generation-gated call into _setPosition.AcknowledgeProjection), RetryPending (61-67), TryPeek (72-80, non-consuming), PendingCount (82). This channel is constructed once inside RuntimeEntityObjectLifetime's ctor (Placements = new RuntimePlacementProjectionChannel(Events, Physics.SetPosition), per the surface map's file-1 section) and exposed on GameRuntime.Placements.
  • Receipt shape: RuntimePlacementProjectionSnapshot (RuntimeSetPositionState.cs:210-217): Token, Kind (Withdraw|Place|Discard — enum at line 57-61), WorldPosition, Orientation, CellLocalPosition, InContact, OnWalkable.
  • What does NOT exist: grep across src/AcDream.App/**/*.cs and src/AcDream.Headless/**/*.cs for IRuntimePlacementObserver, SubscribePlacement, or Placements.Subscribe returns ZERO matches (confirmed via grep -rln across both trees; the only hits anywhere in the repo outside src/AcDream.Runtime/ are 5 Runtime-test fake-observer classes in tests/AcDream.Runtime.Tests/**, e.g. RuntimeInitialCreateResidenceStateTests.cs:2651, RuntimeSetPositionStateTests.cs:2610/2641 (ThrowingPlacementObserver), RuntimeCollisionPrefixQuiescenceTests.cs:877, RuntimeLocalPlayerPhysicsPublicationStateTests.cs:2326). Neither host has ever constructed a production IRuntimePlacementObserver implementation. Prerequisite D ("Add one graphical and one headless IRuntimePlacementObserver using GameRuntime.Placements") is 100% unbuilt on the host side even though the Runtime-side plumbing it will attach to is complete and tested.

Cross-cutting: connected-gate harness (exact scripts/env)

  • Exact lifecycle/reconnect gate: tools/run-connected-world-lifecycle-gate.ps1 (477 lines, read in full). Drives two sequential AcDream.App.exe sessions against the always-up local ACE (127.0.0.1:9000):
    1. capped session using route script tools/connected-world-lifecycle.route.txt, expects exactly 6 named checkpoints (capped_login, aerlinthe_first, rynthid, facility_hub, holtburg_after_dungeon, aerlinthe_revisit) and 5 screenshots.
    2. uncapped-reconnect session (starts as soon as ACE's own log records the first session's transport Disconnect — no artificial settle delay) using tools/connected-world-reconnect.route.txt, expects one checkpoint uncapped_reconnect. Per-session env (lines 250-281): ACDREAM_DAT_DIR, ACDREAM_LIVE=1, ACDREAM_TEST_HOST=127.0.0.1, ACDREAM_TEST_PORT=9000, ACDREAM_TEST_USER/ACDREAM_TEST_PASS, ACDREAM_RETAIL_UI=1, ACDREAM_FRAME_PROF=1, ACDREAM_UNCAPPED_RENDER (1 for the reconnect leg only), ACDREAM_UI_PROBE_SCRIPT=<route.txt path>, ACDREAM_AUTOMATION_ARTIFACT_DIR=<per-session artifact dir>; several other vars explicitly cleared (ACDREAM_RENDER_BACKEND, ACDREAM_NET_DROP_*, ACDREAM_DUMP_MOVE_TRUTH, ACDREAM_WB_DIAG) to keep the gate a clean baseline. Validate-Checkpoint (140-227) asserts, per checkpoint: reveal readiness/no invariant failures, Runtime environment ownership initialized with exactly one active day group, every transitOwnership counter (bufferedTeleportDestinationCount, pendingTeleportStartCount, activeTeleportCount, acceptedTeleportDestinationCount, activeRevealCount, pendingDestinationReadinessCount, hostProjectionCount, pendingHostAcknowledgementCount) is exactly zero at a stable checkpoint, zero pending live teardowns/landblock retirements/staged mesh uploads/composite warmups, and (optionally) zero collision-shadow mismatches/faults. Client must exit only via graceful WM_CLOSE (Close-ClientGracefully, 85-92) and ACE's own log must record graceful logout confirmed + a PacketHeader Disconnect drop (347-354) — this cutover MUST add placement-owner counters (pending placement receipts, active leases, pending FIFO continuations) to this SAME zero-at-stable-checkpoint discipline, matching the existing transitOwnership/resources pattern, or the gate will not actually prove placement convergence.
  • Canonical nine-stop route: tools/run-connected-r6-soak.ps1 (only first 60 lines read) driving tools/connected-r6-soak.route.txt, 9 named checkpoints in order: caul-baseline, sawato-baseline, rynthid, aerlinthe, sawato-return, holtburg, caul-return, sawato-plateau, caul-plateau (Caul/ Sawato/Holtburg legs additionally "Exercise"d — likely movement stress, not just a static stop). Supports -Uncapped/-DenseTown switches (DenseTown swaps in connected-dense-town.route.txt against a single arwic-dense checkpoint instead). Same env-var family as the lifecycle gate (-SkipBuild, -LoginTimeoutSeconds, -CollisionShadowEvery). Historical evidence of both capped and uncapped passing runs: docs/research/2026-07-25-slice-g5-production-profile.md:38-39 (logs/connected-r6-soak-20260725-105133.report.json / ...-121035.report.json).
  • Both scripts require a pre-existing, already-listening local ACE on UDP 9000 and a live AceLogPath (default C:\ACE\Server\ACE_Log.txt) and will themselves invoke dotnet build ... -c Release unless -SkipBuild.

Cross-cutting: 1,880 B/op allocation budget (4B2 activation blocker)

docs/research/2026-07-31-canonical-set-position.md:327-333: "The warmed immediate commit/ack route currently measures exactly 1,880 managed bytes per operation in the Release Runtime test host (1,000 iterations after 64 warmups); the regression gate caps it at 2,048 bytes. This dormant-path result is an explicit 4B2 activation blocker rather than a claim of allocation-free production readiness: 4B2 must either pool/remove the operation and projection envelopes or record an approved measured budget before routing frame-frequency placement through this owner." Restated verbatim in the executor handoff (docs/research/2026-08-02-runtime-continuation-executor-handoff.md:181-184). Not yet resolved as of this research pass — no commit after 2026-07-31-canonical-set-position.md claims pooling/removal of the operation/projection envelopes, and the executor handoff still calls it "the standing 4B2 activation blocker." This matters most for routes 2 (Local ForcePosition, frame-frequency-ish under repeated corrections), 4 (remote Position, genuinely per-network-tick high frequency), and 5 (projectile per-quantum integration, explicitly excluded from SetPosition routing for exactly this reason per route 5's "Do not route ordinary per-quantum projectile integration through SetPosition").

Cross-cutting: Execute's caller-supplied live inputs are unwired in BOTH hosts

RuntimeInitialCreateContinuationExecutor.Execute takes an in RuntimeInitialCreateExecutionInputs inputs parameter (RuntimeInitialCreateContinuationExecutor.cs:47-49): bool UsePositionFromServer, float PlayerDistance — doc comment (38-46): "Executor-time inputs sampled at the retail decision point. These cannot be retained at admission time because they describe LIVE state (the local player, the current physics simulation)... contact is NOT one of these — it comes solely from the retained wire packet's own IsGrounded bit, never from a live body query." Both fields feed directly into RuntimeAuthoritativePositionRouteClassifier.ClassifyAcceptedPosition's RuntimeAcceptedPositionRouteRequest.UsePositionFromServer/PlayerDistance fields (RuntimeAuthoritativePositionRouteClassifier.cs:137, consumed at line 338 for the LocalPlayer interpolate-vs-not branch and later for the Remote/Projectile near/far 96 m threshold). Grep across src/AcDream.App/ and src/AcDream.Headless/ for UsePositionFromServer returns ZERO source hits (only compiled bin/obj binary matches). Neither host currently computes or tracks a UsePositionFromServer concept anywhere in production code — this is a genuinely new per-call input a cutover caller must supply on every Execute call, not something that can be threaded through unchanged from an existing option/flag. PlayerDistance is likely derivable today from existing local-player/WorldEntity state (it is NOT a new concept — some form of distance-to-local-player computation already exists for other purposes, e.g. streaming radius), but it has never been wired specifically into this call contract either.


Prerequisite C context (atomic local controller/body publication)

Campaign handoff (docs/research/2026-07-31-remaining-physics-campaign-handoff.md:203-221) requires ONE Runtime-owned exclusive/versioned controller/body publication transaction "respected by every canonical body writer" — rejects the prior prototype (a snapshot/rollback lease) as failure-atomic-only, not reentrant-safe (line 143-168: a nested SetPosition/remote-bind/GUID-reuse/ clock-epoch-change/disposal racing the open lease could let the outer rollback erase newer authority or detach a body another owner already uses).

Today's per-host body construction (both confirmed by direct read, both are literally the two things prerequisite C must unify):

  • Graphical: PlayerModeController.BuildControllerAndCamera (src/AcDream.App/Input/PlayerModeController.cs:244-..., only the first ~140 lines read directly by me) constructs new PlayerMovementController(...) (line 259-262) directly against _physics/playerRecord.ObjectClock, wires a MoveToManager facade and EntityPhysicsHost closures over captured locals (267-345+), and stores the result in the App-local _controllerSlot.Controller (not _runtime.MovementOwner.Controller directly at this point in the file — Agent 1's detailed route-1 report is authoritative for exactly where/whether this crosses into RuntimeLocalPlayerMovementState/GameRuntime.MovementOwner).
  • Headless: HeadlessSessionWorldProjection.CreateController (src/AcDream.Headless/Hosting/HeadlessSessionWorldProjection.cs:639-655) constructs new PlayerMovementController(_runtime.EntityObjects.Physics.Engine, record.ObjectClock, PlayerMovementConstructionOptions.From(...)) (642-646), applies physics state/step heights/movement skills (647-652), and is the ONLY production writer of _runtime.MovementOwner.Controller = controller in the entire repo (confirmed by grep — the graphical host does NOT write _runtime.MovementOwner.Controller anywhere findable by that exact token; it may go through a different Runtime seam — flag as an open question for whoever designs prerequisite C: confirm whether the graphical host's built controller is ever actually published into RuntimeLocalPlayerMovementState the same way headless's is, or whether this is itself an existing graphical/headless asymmetry prerequisite C must resolve).
  • HeadlessSessionWorldProjection.SynchronizeLocalPlayer (566-615, read in full) is the duplicate placement authority for headless route 1/8: calls _runtime.EntityObjects.Physics.Engine.Resolve(...) (589-594) then .ResolvePlacement(...) (595-605) directly, then controller.SetPosition(resolved.Position, resolved.CellId, wirePosition) (610-613) and controller.SetBodyOrientation(orientation) (614) — entirely independent of RuntimeSetPositionState/RuntimeInitialCreateResidenceState. HeadlessSessionWorldProjection.BlipLocalPlayer (617-637) similarly calls controller.BlipPosition(...) (633-636) directly with no Runtime placement commit/ack in between — this is the headless twin of route 2's "direct BlipPosition/pre-commit acknowledgement" duplicate authority.

Cross-cutting: accessibility is NOT a blocker (correction of an initial hypothesis)

I initially suspected the residence/executor surface being entirely internal (RegisterEntityWithInitialResidence, InitialCreateResidences, InitialCreateExecution, Execute, CompleteInitialCreateResidence, AcknowledgeInitialCreateResidenceAdoption — confirmed all internal via direct grep of RuntimeEntityObjectLifetime.cs and RuntimeInitialCreateContinuationExecutor.cs:426) might block the graphical host (a different assembly) from calling them at all. This is WRONG — verify before citing it as a gap. src/AcDream.Runtime/AcDream.Runtime.csproj:11-16 declares InternalsVisibleTo for AcDream.Runtime.Tests, AcDream.App, AcDream.App.Tests, AcDream.Core.Tests, acdream-headless, and AcDream.Headless.Tests — both hosts already have full internal-member access to AcDream.Runtime. Route 1's research agent independently confirmed this at the exact same csproj lines. There is no accessibility barrier to either host calling RegisterEntityWithInitialResidence/driving the executor today — the reason nobody does is purely that the call sites haven't been switched yet, not an assembly-boundary problem. Do not resurrect this as a "gap" in the final report.


Route 1 — Initial login and CreateObject (from parallel research agent, spot-checked)

Graphical host chain (wire -> presentation)

  1. src/AcDream.App/Net/LiveEntitySessionController.cs:51-53OnSpawned wire entry, routes CreateObject via RetailInboundEventDispatcher.Run to LiveEntityHydrationController.OnCreate.
  2. src/AcDream.App/World/LiveEntityHydrationController.cs:226-250OnCreate (dormant/stale-generation classification) -> OnCreateCore.
  3. LiveEntityHydrationController.cs:259-262OnCreateCore (under _datLock) calls _runtime.RegisterLiveEntity(spawn).
  4. src/AcDream.App/World/LiveEntityRuntime.cs:526-539, line 537: _entityObjects.RegisterEntity(incoming, RetirePriorProjection) — the LEGACY non-residence call, confirmed exact line from the handoff doc.
  5. src/AcDream.Runtime/Entities/RuntimeEntityObjectLifetime.cs:315-322RegisterEntity -> RegisterEntityCore(incoming, beginInitialResidence:false, ...) — never touches InitialCreateResidences/InitialCreateExecution.
  6. LiveEntityHydrationController.cs:288-294ApplyAcceptedSpawn(...) commits the accepted snapshot (still cellless authority, no position/rebucket yet).
  7. LiveEntityHydrationController.cs:938-1040 (ProjectExactOnce), line 1036: _materializer.TryMaterialize(...).
  8. src/AcDream.App/Rendering/DatLiveEntityProjectionMaterializer.cs:407-427 -> MaterializeProjection (680-857).
  9. Duplicate authorityDatLiveEntityProjectionMaterializer.cs:712-737: _runtime.MaterializeLiveEntity(..., out expectedRecord) with the residence parameter OMITTED, defaulting to LiveEntityMaterializationResidence.LegacyImmediate (LiveEntityRuntime.cs:596-597).
  10. LiveEntityRuntime.cs:589-789 (MaterializeLiveEntity) — constructs the WorldEntity (sets Position/Rotation/ParentCellId directly from wire-decoded world position, ~718-729); because residence is LegacyImmediate not AwaitRuntimePlacement, falls through at line 777 to RebucketLiveEntity(serverGuid, fullCellId).
  11. Duplicate authorityLiveEntityRuntime.cs:792-931 (RebucketLiveEntity): immediately calls _spatial.RebucketLiveEntity(...) (spatial bucket mutation), sets IsSpatiallyProjected/Visible, calls _entityObjects.CommitRebucket(...) (canonical FullCellId/ CanonicalLandblockId write), resets/suspends the object clock — all synchronous, no Runtime placement receipt involved anywhere in this path.
  12. DatLiveEntityProjectionMaterializer.cs:791-820 — builds collision, binds projectile runtime; for static-animating physics objects, RegisterAnimation (859-1021) at 1003-1016 calls _runtime.GetOrCreatePhysicsBody(spawn.Guid, incarnation => new PhysicsBody{...}.SnapToCell(...)) — a SECOND, narrower body-construction duplicate authority (non-player static-animation bodies).
  13. LiveEntityHydrationController.cs:739-759/1070-1098 — publish-ready via ILiveEntityReadyPublisher.Publish.
  14. src/AcDream.App/Input/PlayerModeAutoEntry.cs:214-230 — per-frame guard; once IsPlayerEntityPresent + IsWorldReady (world-reveal, unrelated to any Runtime placement receipt) -> EnterPlayerMode() -> PlayerModeController.EnterFromAutoEntry.
  15. src/AcDream.App/Input/PlayerModeController.cs:126-133,217-242 -> TryEnter -> BuildControllerAndCamera (244-525).
  16. Duplicate authorityPlayerModeController.cs:409-413: _physics.Resolve(playerEntity.Position, initialCellId, Vector3.Zero, 100f).
  17. Duplicate authorityPlayerModeController.cs:422-430: _physics.ResolvePlacement(...) using a locally computed Setup cylinder (_motionBindings.GetSetupCylinder) — no shared "exact Setup mover" step.
  18. Duplicate authorityPlayerModeController.cs:449-480: builds EntityPhysicsHost/MoveToManager, installs via EntityPhysicsHostComposition.SelectStableHostWithoutRebind/InstallOrRebind (src/AcDream.App/Physics/EntityPhysicsHostComposition.cs:16,35) — its own body/controller construction, independent of headless's copy.
  19. Camera — PlayerModeController.cs:440-447: constructs ChaseCamera/RetailChaseCamera, _camera.EnterChaseMode(...) (host-only concern, stays, but must be gated by the Runtime ack not ad-hoc resolve success).
  20. Duplicate authority — final commitPlayerModeController.cs:482-484: playerEntity.SetPosition(initial.Position); playerEntity.ParentCellId = initial.CellId; controller.CommitPreparedPosition(); — direct write, bypasses any Runtime Place receipt.

Headless host chain

Same shape as the graphical route through RegisterEntity/ApplyAcceptedSpawn (RuntimeLiveEntitySessionController.cs:73-95, see Route 8 section above for the full per-line breakdown), then IRuntimeDirectWorldProjection.ProjectSpawn -> HeadlessSessionWorldProjection.SynchronizeLocalPlayer (566-615)/CreateController (639-655) — same duplicate-authority shape as graphical hops 16-20, but a SEPARATELY HAND-WRITTEN copy, not shared code (confirmed by the codebase's own comment at HeadlessSessionWorldProjection.cs:685-689 contrasting itself with "the graphical PlayerModeController.ApplyStepHeights"). No headless equivalent of graphical hops 12-14/19 exists (no WorldEntity/render sidecar/camera).

What each hop must become / capability gaps (route 1)

  • Switch RegisterLiveEntity/OnSpawned from RegisterEntity to RegisterEntityWithInitialResidenceno accessibility blocker (see correction above); this is a pure call-site + follow-up-loop change.
  • DELETE MaterializeProjection's direct RebucketLiveEntity fall-through; pass residence: LiveEntityMaterializationResidence.AwaitRuntimePlacement (the enum value ALREADY EXISTS and is used by other routes via LiveEntityRuntime.cs:765-776/938-1127's TryApplyRuntimePlacementPlace/Withdrawal — this route just isn't plumbed into it yet).
  • DELETE PlayerModeController.cs:409-430 (own Resolve/ResolvePlacement) and 482-484 (direct SetPosition/CommitPreparedPosition); body/controller construction becomes acknowledge-only from the shared Runtime-resolved position.
  • DELETE headless SynchronizeLocalPlayer:589-607 and 610-614 the same way.
  • DELETE the legacy RegisterEntity overload entirely once both hosts move (RegisterEntityWithInitialResidence is already a strict superset).
  • Gap 1 (real): no shared "exact Setup mover" / DAT-preparation API. RuntimeInitialCreateResidenceState.Own only OPENS the placement slot (TryBeginExclusiveAuthoredPlacement); nothing in Runtime resolves a Setup-derived cylinder/sphere-list and feeds it into RuntimeSetPositionState.SubmitPreparedPlacement. Today that DAT read + Resolve/ResolvePlacement call is hand-duplicated with DIFFERENT defaults in App (_motionBindings.GetSetupCylinder) vs. headless (hardcoded DefaultRadius=0.48f/DefaultHeight=1.835f unless _preparedCollision supplies a Setup) — this is exactly prerequisite B, confirmed still open.
  • Gap 2 (real): no shared "atomic Runtime controller/body" owner exists anywhere (RuntimeEntityRecord has storage slots — PhysicsBody, PhysicsHost — but no construction logic); BuildControllerAndCamera and HeadlessSessionWorldProjection.CreateController are two independently written, divergent implementations of the same "build a PlayerMovementController/host from a RuntimeEntityRecord" job. This IS prerequisite C, confirmed still unbuilt in production code.
  • Gap 1 REFINEMENT (verified directly, not from an agent): "no shared Setup mover API" is not quite right — RuntimeSetPositionState.PrepareMover (RuntimeSetPositionState.cs:1079-1133) + RuntimeSetPositionMoverPreparer.TryBuild (RuntimeSetPositionMoverPreparation.cs:69+) already exist as the shared authored-mover-preparation API prerequisite B calls for, and SubmitPreparedPlacement (RuntimeSetPositionState.cs:2041) already requires operation.Record.PhysicsBody is not { } body to be non-null BEFORE a placement can even be submitted — i.e. prerequisite C's body must exist first, structurally enforced. What's genuinely missing is the HOST input: PrepareMover takes a RuntimeSetPositionMoverPreparation whose Setup field is a host-supplied RuntimeSetPositionMoverSetup (Setup table ID + FlatSetupCollision?, RuntimeSetPositionMoverPreparation.cs:23-42) — Runtime does NOT read DAT itself; the host must call IPreparedCollisionSource.ReadSetupCollision(setupId) (already used by headless at HeadlessSessionWorldProjection.cs:668-679) and feed the result in. No production call site anywhere chains ReadSetupCollision -> PrepareMover -> SubmitPreparedPlacement — both hosts instead read Setup DAT/prepared-collision data ad hoc and call PhysicsEngine.Resolve/ResolvePlacement directly, entirely bypassing this already-built pipeline. This is a wiring gap, not a missing-mechanism gap.
  • Gap 3 (real, previously unstated): the executor publishes only generic RuntimeEntityChange via _events.PublishEntity (RuntimeInitialCreateContinuationExecutor.cs:2053-2061), NOT through RuntimePlacementProjectionChannel/Placements — the channel the existing App TryApplyRuntimePlacementProjection/headless placement sinks already consume for OTHER routes. Whether a residence-driven initial commit actually surfaces a Place token on the SAME channel other routes use is unconfirmed/unbuilt — this bridge must be built, not assumed.
  • Confirms the executor handoff's own claim: zero production callers of Execute/RegisterEntityWithInitialResidence today.

Route 2 — Local ForcePosition (from parallel research agent)

Graphical-only (headless equivalent is folded into Route 8's ForcePosition branch, already covered above).

Call chain

src/AcDream.Core.Net/WorldSession.cs:1767 (wire opcode 0xF748 UpdatePosition — same opcode for ordinary and force; "force" is purely a ForcePositionSequence freshness fact) -> WorldSession.cs:1774-1786 raises PositionUpdated -> src/AcDream.App/Net/LiveEntitySessionController.cs:67-69 -> src/AcDream.App/Physics/LiveEntityNetworkUpdateController.cs:1024 OnPosition -> :1035-1048 _authorityGate.TryAcceptPosition -> LiveEntityInboundAuthorityGate.cs:148-206 -> _liveEntities.TryApplyPosition -> PhysicsTimestampGate.cs:181-218 TryAcceptPositionEvent (retail SmartBox::HandleReceivedPosition 0x00453FD0 FORCE_POSITION branch) returns ForcePosition when newer AND teleport == current teleport stamp -> LiveEntityNetworkUpdateController.cs:1101-1117 forceLocal computed -> LocalForcePositionTransaction.Apply (src/AcDream.App/Physics/LocalForcePositionTransaction.cs:10-28, duplicate authority): if (!isCurrent()) return false; blip(); acknowledge(); return isCurrent(); where blip = PlayerMovementController.BlipPosition (src/AcDream.Runtime/Gameplay/PlayerMovementController.cs:1759-1773: _body.SnapToCell, UpdateCellId at :1577-1599 which ALSO publishes the render root via _physics.UpdatePlayerCurrCell) and acknowledge = LocalPlayerOutboundController.SendImmediatePosition (src/AcDream.Runtime/Gameplay/LocalPlayerOutboundController.cs:152-185, sends the outbound AutonomousPosition ack BEFORE any Runtime canonical commit exists — the exact pre-commit-ack bug the campaign handoff names). Falls through unconditionally into the generic tail (LiveEntityNetworkUpdateController.cs:1252-1270, second duplicate authority): entity.SetPosition/ParentCellId/Rotation + _liveEntities.RebucketLiveEntity(...) on the render-facing WorldEntity — a SECOND independent mutation of the SAME accepted Position, parallel to the PlayerMovementController body mutated by the first authority (two-store divergence, the exact bug class the executor handoff says it already fixed for Create).

What becomes what / gaps

  • DELETE LocalForcePositionTransaction outright; its job (validate ownership, blip, ack-once) becomes RuntimeSetPositionState.Apply/ BeginAcceptedPlacement with RuntimeSetPositionOperationKind.LocalAuthoritative.
  • OnPosition's force branch reduces to: classify via RuntimeAuthoritativePositionRouteClassifier.ClassifyAcceptedPosition (its ForcePosition branch — lines 291-313 — already produces exactly SetPositionSimple, PreserveHeading: true, SendPositionImmediately: true — this route kind is FULLY MODELED already, just unused) -> submit through RuntimeSetPositionState -> only call SendImmediatePosition AFTER commit (fixes the ordering bug).
  • BlipPosition becomes acknowledge-only (applies the already-committed Runtime projection instead of being an independent authority).
  • DELETE the generic tail's second entity.SetPosition/RebucketLiveEntity for the local player (1252-1270) — dead code once the host projects only the one canonical result.
  • Gap (confirmed): zero production references to RuntimeAuthoritativePositionRouteClassifier/RuntimeSetPositionState anywhere in src/AcDream.App for Position handling — tracked by issue #275 ("post-cutover unification of the legacy Position path onto the classifier"), cited in both the executor handoff and the divergence register's AP-131 row.
  • Gap (confirmed): "reject a stale host ack" already exists structurally (RuntimeSetPositionState.IsPlacementCurrent/ConsumeAcknowledgedPlacement, exact-token requirement) but is unwired for Route 2.
  • Scope note: the continuation EXECUTOR (Execute/FIFO drain) is scoped to initial-Create admission, not steady-state Position on an already-resident entity — Route 2's correct integration point is RuntimeSetPositionState/InboundPhysicsStateController.ApplyAcceptedPositionSnapshot directly, NOT Execute. The AwaitingContinuationPlacement retry flavors are documented generically but demonstrated only for Create — their applicability to a live ForcePosition is unproven, not just unwired.
  • The 1,880/2,048-byte allocation budget applies directly here: ForcePosition is genuinely frame-frequency-ish traffic.

Route 3 — Portal transit and materialization (from parallel research agent)

LocalPlayerTeleportPlacement exists verbatim (not renamed) inside src/AcDream.App/Streaming/LocalPlayerTeleportController.cs:183-290.

Call chain

Two wire inputs join in RuntimeWorldTransitState: F751 start (WorldSession.cs:1972-1987 opcode 0xF751) -> LiveEntitySessionController.cs:83-85 OnTeleportStarted -> LocalPlayerTeleportController.cs:436-459 gates on LiveLocalPlayerTeleportAuthority.IsFreshStart -> PhysicsTimestampGate.IsFreshTeleportStart and RuntimeWorldTransitState.TryQueueTeleportStart (:426-442). Destination Position rides the SAME wire path as Route 2, then at LiveEntityNetworkUpdateController.cs:1906-1913 (guarded on disposition==Apply && guid==playerServerGuid) calls _localPlayerTeleport.OfferDestination(...) -> RuntimeTeleportDestinationAdapter.cs:15-36 (pure mapping) -> RuntimeWorldTransitState.OfferTeleportDestination (:480-520). Every frame, LocalPlayerTeleportController.Tick (:472-570) drives: TryAimAcceptedDestination/AimDestination (:626-734, classifies via TeleportLandblockTransition.Classify — streaming-only, no world mutation) -> WorldRevealCoordinator.TryBeginPortal -> RuntimeWorldTransitState.TryBeginPortalReveal (mints reveal generation + host projection token). On TeleportAnimEvent.Place: preflight RuntimeWorldTransitState.CanPlacePortalDestination (read-only gate) -> LocalPlayerTeleportPlacement.Place (LocalPlayerTeleportController.cs:214-278, the duplicate authority) -> THEN WorldRevealCoordinator.ObserveMaterialized -> RuntimeWorldTransitState.AcknowledgePortalMaterialized runs AFTER Place has already fully mutated world state — a rubber-stamp, not a gate. On TeleportAnimEvent.FireLoginComplete: _session.SendLoginComplete() (outbound ack) -> RuntimeWorldTransitState.Complete.

LocalPlayerTeleportPlacement.Place (full method, 214-278) mutates in order: _physics.Resolve(...) (own collision placement) -> controller.SetPosition(...) (body+cell) -> entity.SetPosition/ParentCellId/Rotation on WorldEntity -> _liveEntities.RebucketLiveEntity(...) (throws on failure) -> _host.Host?.NotifyTeleported() (retail teleport_hook tail) -> controller.SetBodyOrientation(rotation) -> camera reset (_cameras.Legacy?.Update/_cameras.Retail?.ResetViewerToPlayer, unique to this route vs. Route 2) -> _spatial.Reconcile(). TeleportViewPlaneController (view-plane/FOV easing) is presentation-only, NOT in scope for deletion.

What becomes what / gaps

  • DELETE Place's resolve/controller/world-entity/rebucket/host-notify/ orientation mutations outright; replace with RuntimeSetPositionState.BeginAuthoredPlacement/Apply carrying a populated RuntimePortalPlacementAuthority, then project only the committed result.
  • Re-sequence WorldRevealCoordinator.CanPlacePortalDestination/ ObserveMaterialized to be the ACTUAL gate/confirmation around the canonical commit (not rubber-stamps around a host-owned mutation) — i.e. materialization fires from the Runtime commit callback, not immediately after Place()'s direct mutations.
  • Camera reset and _spatial.Reconcile() become acknowledge-only reactions.
  • Headless has the analogous duplicate authority in HeadlessSessionWorldProjection.PrepareDestination/SynchronizeLocalPlayer (already documented in the Route 8 section above) — must cut over in lockstep, same target (RuntimeSetPositionState).
  • Gap (confirmed, important): RuntimeWorldTransitState (1012 lines, Slice J6) already fully owns reveal generation/sequence/destination-cell, readiness, materialization/completion/cancellation, and the 4-stage host acknowledgement protocol (ProjectionRegistered -> SimulationReleaseProjected -> DestinationReservationReleased -> TerminalProjected) — but ONLY for streaming/render-resource bookkeeping, NEVER for gating an actual placement mutation. RuntimePortalPlacementAuthority (RuntimeSetPositionState.cs:64-78, carrying RevealGeneration/TeleportSequence/RuntimeWorldHostProjectionToken) is a REAL, VALIDATED constructor parameter on RuntimeSetPositionCommand.Portal (validated in BeginAcceptedPlacementCore, :978-984) and LiveEntityRuntime.cs:1162-1171 even has an IsValidPortalPlacementAuthority presentation-side validator — but grep across App and Headless finds ZERO call sites that ever construct one with Present: true. The binding machinery is real but 100% dormant end to end.
  • Missing for Route 3 specifically: (a) the adapter that reads WorldRevealCoordinator's current generation/sequence/destination-cell/host projection token into a RuntimePortalPlacementAuthority; (b) the actual RuntimeSetPositionState.BeginAuthoredPlacement call site using LocalAuthoritative + that authority (does not exist anywhere today); (c) re-sequencing ObserveMaterialized to run from the commit callback.
  • Discard/cancellation semantics (a stale generation/sequence/cell/token must never reveal) look structurally sufficient (RuntimePlacementProjectionKind.Discard, IsPlacementCurrent, RuntimeWorldTransitState.Cancel/BeginHostProjectionSupersession) but are UNEXERCISED together for a real placement — treat as an explicit cutover test, not an assumed-correct combination.
  • Executor scope note: same as Route 2 — the FIFO/Execute mechanism is Create-admission-scoped; Route 3's target is RuntimeSetPositionState directly.

Route 4 — Remote CreateObject and Position (from parallel research agent)

Foundational fact (independently confirmed by this agent AND by direct

grep during this research pass)

InboundPhysicsStateController.cs:596-608's own doc comment states verbatim: "this file's TryApplyPosition is today's only PRODUCTION Position wire caller; the classifier-based path is test-only until a host wires the executor." RuntimeEntityObjectLifetime.TryApplyPosition only enters the classifier/executor path when TryGetPendingInitialResidence finds an in-flight CreateObject continuation (a narrow transient window) — steady-state remote UpdatePosition always falls to the legacy unconditional-merge path with no route-classification concept at all.

Call chain

LiveEntitySessionController.cs:67-69 -> LiveEntityNetworkUpdateController.OnPosition (:1035) -> LiveEntityInboundAuthorityGate.cs:161 TryApplyPosition -> LiveEntityRuntime.cs:2116,2135 -> RuntimeEntityObjectLifetime.cs:1229,1299 steady-state branch -> RuntimeEntityDirectory.cs:478 -> InboundPhysicsStateController.cs:610 (legacy unconditional timestamp-gated merge). Then LiveEntityNetworkUpdateController.cs:1197-1211 computes remoteHardTeleport/remotePlacementRequired from timestamps.TeleportHookRequired and _remoteTeleportController.HasPending; RunRemoteTeleportHook (:1210) -> RemoteTeleportHook.Execute (RemoteTeleportHook.cs:17, CancelMoveTo/ UnStick/StopInterpolating/UnConstrain/NotifyTeleported/ReportCollisionEnd). Then, UNCONDITIONALLY (LiveEntityNetworkUpdateController.cs:1252-1270, duplicate authority, BEFORE any placement/teleport branch runs): entity.SetPosition/ParentCellId/Rotation + RebucketLiveEntity. If remotePlacementRequired: RemoteTeleportController.BeginPlacement (:269) -> TryApply (:117/151) -> Resolve (:278) -> _physics.ResolvePlacement (:303) -> CommitResolved (:320) -> RemoteTeleportPlacement.Apply (RemoteTeleportPlacement.cs:15) -> PhysicsObjUpdate.CommitSetPositionTransition. Else (ordinary MoveOrTeleport): inline classification hand-duplicated in App, LiveEntityNetworkUpdateController.cs:1594-1900 (local constants MaxPhysicsDistance=96f/BodySnapThreshold=4f duplicated for player vs NPC) decides far-snap/near-interpolate/airborne-noop/landing, then entity.SetPosition/ParentCellId/Rotation + LiveEntityShadowPublisher.TryPublishRemote. Ongoing per-tick DR: RemotePhysicsUpdater.cs:220 -> RuntimeRemotePhysicsUpdater.Tick (:61) — interp catch-up + ResolveWithTransition sweep + shadow sync, independent of SetPosition (retail's continuous UpdatePositionInternal — NOT itself a wire route, out of cutover scope).

Duplicate authorities

  • LiveEntityNetworkUpdateController.cs:1252-1270 — position/cell/rotation AND full rebucket, unconditionally, ahead of any classification.
  • RemoteTeleportController.cs:37,77-109_pending dictionary, rollback capture/restore (:94-109,477-569), lost-cell tracking (:529-532) — exactly the bookkeeping the residence+executor's 25-second lost-cell lifetime already owns generically.
  • RemoteTeleportPlacement.cs:43-77 — direct body.SnapToCell, contact-plane fields, PhysicsObjUpdate.CommitSetPositionTransition — a hand-rolled SetPosition commit parallel to RuntimeSetPositionState.
  • LiveEntityNetworkUpdateController.cs:1594-1900 — the "ordinary" MoveOrTeleport classification hand-duplicated in App, when RuntimeAuthoritativePositionRouteClassifier.ClassifyAcceptedPosition ALREADY implements identical near(<96m,Interpolate)/far(SetPositionSimple)/ teleport-advanced(SetPosition)/cellless rules (classifier lines 360-439).
  • RemoteTeleportController.cs:382-475ParkPending/OnProjectionVisibilityChanged re-implements deferred-until-visible placement replay, another thing the executor's FIFO/replay machinery already generalizes.

What becomes what

  • DELETE outright: RemoteTeleportController.cs, RemoteTeleportPlacement.cs, their pending dictionary/rollback/ParkPending, and the pre-placement entity.SetPosition/RebucketLiveEntity at :1252-1270.
  • DELETE + replace with classifier delegation: the inline near/far/airborne/ landing block (:1594-1900) -> route through ClassifyAcceptedPosition + RuntimeSetPositionState Begin/Watch/resume.
  • Reduce to acknowledge-only: RemoteTeleportHook.cs stays as the App-side execution seam, but its trigger condition should come from the classified route's RuntimeTeleportHookPhase, not the App's own remoteHardTeleport flag.
  • RuntimeRemotePhysicsUpdater per-tick DR is OUT of cutover scope (retail's continuous simulation, not a wire route).

Gap

The classifier's Remote branch is FULLY implemented for both ClassifyCreate and ClassifyAcceptedPosition — the only gap is wiring (no production caller ever constructs a RuntimeAcceptedPositionRouteRequest for a Remote entity outside the narrow pending-residence window). The 1,880 B/op budget applies directly here too (remote Position is genuinely per-network-tick frequency).


Route 5 — Projectile authoritative create/corrections (from parallel research agent)

Call chain

Create: DatLiveEntityProjectionMaterializer.cs:807 _projectiles.TryBind -> ProjectileController.TryBind (ProjectileController.cs:133) — constructs/ adopts the shared PhysicsBody (:176-265), calls body.SnapToCell directly (:214/256), then entity.SetPosition/ParentCellId + RebucketLiveEntity (:268-271) and ShadowPositionSynchronizer.Sync (:306) — all ad hoc, no classifier. Vector (launch velocity): LiveEntityNetworkUpdateController.cs:840 OnVector -> ProjectileController.ApplyAuthoritativeVector (:345) -> RuntimeProjectilePhysicsUpdater.ApplyAuthoritativeVector (:207). State (Missile bit): :992 OnState -> ApplyAuthoritativeState (:410) -> RuntimeProjectilePhysicsUpdater.ApplyAuthoritativeState (:252, direct SnapToCell at :288). Authoritative Position correction: LiveEntityNetworkUpdateController.cs:1217-1233 (inside OnPosition, AHEAD of the generic remote path — returns early if handled) -> ProjectileController.ApplyAuthoritativePosition (:508) -> RuntimeProjectilePhysicsUpdater.ApplyAuthoritativePosition (:301, direct body.SnapToCell at :346, CommitProjectileCell at :370, direct ShadowPositionSynchronizer.Sync/Suspend :402-421). Ordinary per-quantum integration: ProjectileController.Tick (:613) -> AdvanceQuantum/ TryBeginQuantum/CompleteQuantum (:761-836) -> RuntimeProjectilePhysicsUpdater.TryBegin/Complete (:37,94) — Complete does direct body.SnapToCell at line 145 + direct shadow sync — correctly NOT routed through SetPosition today, but ALSO not through any shared cell-commit authority; its own ad hoc CommitProjectileCell + shadow write.

Duplicate authorities

  • ProjectileController.cs:214-271 — body construction, SnapToCell, entity.SetPosition/ParentCellId, RebucketLiveEntity, shadow sync — full ad hoc placement authority for missile creation.
  • RuntimeProjectilePhysicsUpdater.cs:145-198 (per-quantum Complete) and :346-421 (ApplyAuthoritativePosition) — BOTH do direct SnapToCell + CommitProjectileCell + shadow sync, bypassing RuntimeSetPositionState entirely; neither distinguishes "ordinary integration" from "authoritative correction" at the cell/shadow-commit layer — only the caller's semantic label differs.

What becomes what

  • DELETE outright: the authoritative-placement code in TryBind's create branch (:214-271) and ApplyAuthoritativePosition (:508-578); and the direct SnapToCell/shadow commit inside RuntimeProjectilePhysicsUpdater.ApplyAuthoritativePosition (:301-424).
  • REPLACE with ProjectileAuthoritative-tagged routes via the classifier driving RuntimeSetPositionState, using "the same Runtime body and exact projectile Setup sphere" — i.e. RuntimeProjectile.Body/CollisionSphere (RuntimeProjectile.cs:10-40) plugged into the shared SetPosition transaction instead of CommitProjectileCell.
  • KEEP UNCHANGED (must NOT route through SetPosition): per-quantum integration (TryBegin/Complete, :37-205) — correctly outside SetPosition today; only its cell/shadow-commit CALL is a candidate to unify onto a shared (non-SetPosition) cell-commit primitive.
  • Reduce to acknowledge-only: ApplyAuthoritativeVector/ApplyAuthoritativeState (:332-478) — smaller scope of change since they don't do placement/rebucket themselves today.

Gap

ProjectileAuthoritative exists TODAY ONLY as an OperationKind label (RuntimeSetPositionState.cs:16), produced generically by the classifier's OperationKind(...) helper for both entry points — it is not a distinct routing rule: ClassifyCreate gives Projectile the exact same SetPosition/InitialCreateFlags route as any non-local entity, and ClassifyAcceptedPosition gives Projectile the IDENTICAL near/far/teleport/ cellless branches as Remote (proven by the test name ProjectilePosition_UsesRemoteMoveOrTeleportClassification, RuntimeAuthoritativePositionRouteClassifierTests.cs:418-436). So: PARTIAL — operation-kind plumbing + generic MoveOrTeleport-shape routing exist; missing is (a) any production wiring at all (same dormancy as route 4), and (b) projectile-specific POLICY (should a "near" wire correction ever return Interpolate for a ballistic body, or always hard-correct?) — today's "never route per-quantum integration through SetPosition" constraint holds only because per-quantum integration never calls the classifier at all (a separate simulation-tick path), not because of an explicit guard.


Route 6 — Drops and unparent-to-world (from parallel research agent)

Graphical-only; no headless drop UI exists.

Call chain

Whole-item/normal drop: ItemInteractionController.ExecutePlacementActions, DropToWorld case (src/AcDream.App/UI/ItemInteractionController.cs:976-993) — optimistic move + send drop; ordinary server CreateObject flows through the normal wire pump: LiveEntityHydrationController.OnCreate/OnCreateCore (:226-299) -> _runtime.RegisterLiveEntity(spawn) -> LiveEntityRuntime.cs:526-556 -> _entityObjects.RegisterEntity(...) (line 537) -> RuntimeEntityObjectLifetime.RegisterEntity (315-322, legacy, beginInitialResidence:false). Split-to-world (ACE omits CreateObject, sends only the new GUID's Position first): ItemInteractionController.cs:994-1015 (SplitToWorld case, raises WorldDropDispatched) -> InventoryWorldDropProjectionController.OnWorldDropDispatched (:81-98, records PendingSplitToWorldProjection) -> wire Position (F748) for the new GUID arrives at LiveEntityNetworkUpdateController.OnPosition:1024-1029, FIRST calls _worldDropProjection.TryRecoverUnknownPosition(update) (1026) -> InventoryWorldDropProjectionController.cs:54-68: builds a synthetic EntitySpawn via PendingSplitToWorldProjection.BuildSpawn (171-209, clones the SOURCE item's full spawn/PhysicsSpawnData, overriding Guid/Position/StackSize/Container/Wielder/Sequence/Parent) -> calls _hydration.OnCreate(spawn) (66) — the IDENTICAL entry point as the ordinary path, converging on the same RegisterEntity call. ShortcutDropPlanner is unrelated to this route (toolbar-slot reshuffling only, never touches position/physics).

Duplicate authority / gap

Neither drop flavor calls Physics.SetPosition.Begin* or RuntimeInitialCreateResidenceState.Begin today — there is no App-vs-Runtime competing mutation for drops specifically; the gap is identical to routes 1-5: RegisterEntityWithInitialResidence is never called from any production path (confirmed by full-repo grep — only self-referential inside RuntimeEntityObjectLifetime's own constructors, as the executor's child-replay delegate, plus tests). Both drop flavors equally bypass the canonical create-placement transaction — this is a wiring gap shared with routes 1-5, not a route-6-specific duplicate.

  • Real, previously-unstated Route-6-specific gap: PendingSplitToWorldProjection.BuildSpawn clones the source's DTO wholesale (correct for Position, which IS explicitly overridden) but presentation-effect replay (create-pop VFX/sound driven off LiveEntityReadyPublisher.Publish/EntityEffectController.ReplayPendingForLiveEntity) has NO SIGNAL today distinguishing "real spawn" from "split continuation" — and the executor's receipt/trace has no field for "this create is a split-recovery continuation, suppress create-time effect replay." This must be ADDED, not just wired — a genuine new capability, not merely dormant.

What becomes what

LiveEntityHydrationController.OnCreate/OnCreateCore switches to RegisterEntityWithInitialResidence for EVERY CreateObject (both flavors) so both acquire a lease and drain through Execute. TryRecoverUnknownPosition's call shape doesn't need to change, but the residence/executor layer needs the new "suppress effect replay for split continuation" capability above. WorldDropDispatch/ShortcutDropPlanner/ ItemInteractionController dispatch (pure UI/wire trigger) is unaffected.


Route 7 — Pickup, Parent, and Delete (from parallel research agent)

Confirms/refutes "Runtime hooks already exist"

Largely CONFIRMED at the App/headless-caller level: none of LiveEntityHydrationController, EquippedChildRenderController, LiveEntityDeletionController, LiveEntityRuntimeTeardownController do their own SetFullCell/SuspendObjectClock/rebucket math — all of it lives inside RuntimeEntityObjectLifetime (TryApplyPickup:805-868, TryApplyParent/TryApplyCreateParent -> shared helper CommitPositionChannelUpdate:1705-1737, TryCommitParent:944-974, CommitAcceptedParentCellless:976-1007, CommitWithdrawal:1401-1422, TryAcceptDelete:1466-1527). App/headless work is exclusively presentation (render subtree, shadows/effects/animation/selection teardown) — legitimate, not duplicated physics authority.

BUT the claim needs an important qualification (previously-unstated finding): every ForgetInitialCreateResidence(...) call in this family (849, 1720-1721, 990, 1411, 1501) cancels a residence lease that is NEVER ACQUIRED anywhere in production (same Route-1/6 finding — RegisterEntityWithInitialResidence unreached), and every paired Physics.SetPosition.Forget(...) cancels a placement transaction that is likewise NEVER BEGUN anywhere in production (BeginAcceptedPlacement/BeginAuthoredPlacement, RuntimeSetPositionState.cs:803,815, zero external callers repo-wide). So today these cancellation calls are structurally present but functionally no-ops against always-empty stateInitialCreateResidences.Forget returns false; PreferCancellation always falls through to the equally-empty "ordinary" receipt. Route 7 is correctly "already cut over" for the parts that currently do anything (SetFullCell/SuspendObjectClock/RefreshSnapshot/ AdvanceXAuthority/CollisionReports/EndChildProjection are genuinely Runtime-owned) — but the specific behavior the campaign doc worries about ("cancel the exact active placement/lost-cell family first") is INERT because there is nothing upstream yet to cancel. Once routes 1-5 wire the create/position path live, these existing calls become live with NO code change required — genuinely pre-built and correctly sequenced already.

Two internal asymmetries flagged for cutover review (new findings)

  • TryCommitParent (944-974) is the ONLY method in the family with NO ForgetInitialCreateResidence/PreferCancellation call at all.
  • CommitWithdrawal (1401-1422) calls ForgetInitialCreateResidence but NOT Physics.SetPosition.Forget/PreferCancellation, unlike Pickup/ CommitAcceptedParentCellless/TryAcceptDelete which cancel both families. Once ordinary placement transactions go live, WithdrawLiveEntityProjectionToCellless (LiveEntityRuntime.cs:1315-1331, calls CommitWithdrawal) could leave an active mover/lost-cell watch dangling. Flag for explicit cutover test, do not assume symmetric with the other four methods.

Headless-specific gap (real, pre-existing, adjacent to but distinct from the cutover)

RuntimeLiveEntitySessionController.OnParentUpdated (216-220) calls ONLY Entities.TryApplyParent directly — headless NEVER calls TryCommitParent/CommitAcceptedParentCellless — there is no headless equivalent of the App parent-realize sequence (EquippedChildRenderController.ResolveAndTryRealize/PrepareAndTryRealize, LiveEntityHydrationController.cs:470 chain) AT ALL. This looks like a live gap independent of the residence/executor cutover — a headless parented child's FullCellId may never clear. Needs new code, not just wiring. HeadlessSessionWorldProjection/IRuntimeDirectWorldProjection has no pickup/parent/delete hook at all (only ProjectSpawn/ProjectPosition/ BeginTeleport/PrepareDestination) — headless has ZERO duplicate placement work for route 7 (consistent with "already cut over" for the parts that do anything).

Gap vs. the executor

"What the executor owns" already anticipates Route 7's "pickup during preparation/deferred residence" and "parent during pending withdrawal" test scenarios via the TryGetPendingInitialResidence/EnqueueDormant branches already present in TryApplyPickup/TryApplyParent — no NEW executor capability is needed for route 7's steady-state (post-create) behavior; the gap is entirely "wire up creates to use residence" (routes 1-3's job). One real gap: the executor's receipt/trace has no concept of "a pickup/delete cancelled my pending residence" — RuntimePlacementCancellationReceipt contents route only to Physics.SetPosition.PublishCancellation, never surfaced to the calling host for observability/testing.


Route 8 — Headless parity (researched directly, not delegated)

Files read in full: src/AcDream.Headless/Hosting/HeadlessSessionWorldProjection.cs (693 lines), src/AcDream.Runtime/Session/RuntimeLiveEntitySessionController.cs (349 lines).

Current production call chain — headless host

Entry: RuntimeLiveEntitySessionController.CreateSink() (56-68) wires a LiveEntitySessionSink whose delegates are the ONLY headless wire-dispatch entry points for entity/position/motion/vector/state/parent/teleport traffic. Each handler below calls straight into RuntimeEntityObjectLifetime (the LEGACY, non-residence overloads — every call passes acknowledgeProjection: null) and then, only for specific cases, into IRuntimeDirectWorldProjection (implemented by HeadlessSessionWorldProjection):

  1. OnSpawned (73-95) — Entities.RegisterEntity(spawn) (75-76, the legacy Create entry point — confirmed by the surface map's grep as one of only two production Create call sites in the repo) → if registration.Canonical present, Entities.ApplyAcceptedSpawn(canonical, integrationVersion, canonical.Snapshot, replaceGeneration: ...) (81-87) → if applied, _worldProjection?.ProjectSpawn(canonical, isLocalPlayer) (90-93) → HeadlessSessionWorldProjection.ProjectSpawn (507-513): no-op for any non-local entity (if (isLocalPlayer) SynchronizeLocalPlayer(record); — line 511-512 IS the entire method body); for the local player, calls SynchronizeLocalPlayer (566-615) which is the duplicate placement authority (see below).
  2. OnPositionUpdated (137-201) — Entities.TryApplyPosition(update, isLocal, forcePositionRotation: localController?.BodyOrientation, currentLocalVelocity: localController?.BodyVelocity, projectionRequiresTeleportHook: false, acknowledgeProjection: null, ...) (144-153, legacy path) → if !isLocal or Rejected, return (154-159) → if disposition is Apply, builds a RuntimeTeleportDestination from the wire position and calls _runtime.TransitOwner.OfferTeleportDestination(destination, timestamps.TeleportAdvanced) (161-184, every accepted local Position is offered to the transit owner as a POTENTIAL portal destination — the transit owner itself decides whether it's actually a portal) → looks up the active record and calls _worldProjection?.ProjectPosition(record, isLocalPlayer: true, disposition) (185-193) → HeadlessSessionWorldProjection.ProjectPosition (515-531): no-op for non-local; if no controller yet, SynchronizeLocalPlayer (525); else only for disposition is ForcePosition does it call BlipLocalPlayer (529-530) — an ordinary Apply disposition with an existing controller does NOTHING here (ordinary interpolation must happen elsewhere, at the physics tick) → back in the session controller, if disposition is ForcePosition, _localPlayerOutbound.SendImmediatePosition(_session, _runtime.MovementOwner.Controller) (194-199, sends the outbound wire ack BEFORE any Runtime placement commit/host-acknowledgement — the headless twin of route 2's "direct BlipPosition/pre-commit acknowledgement") → TryCompletePortal() (200, 243-332) unconditionally at the end.
  3. OnPickedUp/OnMotionUpdated/OnVectorUpdated/OnStateUpdated/OnParentUpdated/OnAppearanceUpdated (118-122, 124-135, 203-207, 209-214, 216-220, 237-241) — thin 1-line pass-throughs to Entities.TryApply*(..., acknowledgeProjection: null, out _), no independent headless placement work.
  4. OnDeleted (97-116) — Entities.TryAcceptDelete(...)Entities.CompleteAcceptedDelete(acceptance)Entities.RetireCanonicalOnly(retired). No independent headless placement work (matches route 7's claim that pickup/parent/delete are already mostly Runtime-owned — see route 7's section for the App-side confirmation).
  5. OnTeleportStarted (222-235) → transit.TryQueueTeleportStart_worldProjection?.BeginTeleport()HeadlessSessionWorldProjection.BeginTeleport (533-537): sets controller.State = PlayerState.PortalSpace directly (no Runtime commit gate) → transit.ActivateQueuedTeleport()TryCompletePortal().
  6. TryCompletePortal (243-332) — a fully Runtime-driven, already-cutover state machine for the portal handshake itself: TryGetAcceptedTeleportDestinationTryBeginPortalRevealTryRegisterHostProjectionAcknowledge(...ProjectionRegistered)_worldProjection?.PrepareDestination(generation, destination) (271-274, the ONE point where the headless host does its own destination-prep work — see below) → transit.AcknowledgeDestinationReadiness(readiness)transit.AcknowledgePortalMaterialized(...)Acknowledge(...SimulationReleaseProjected)transit.RequireDestinationReservationRelease(projection)Acknowledge(...DestinationReservationReleased)transit.AcknowledgeWorldViewportVisible + transit.Complete(generation)Acknowledge(...TerminalProjected)_session.SendGameAction(GameActionLoginComplete.Build())transit.EndTeleport(). This entire sequence is already Runtime-owned generation/token bookkeeping (J6.2-J6.4 landed) — it is NOT a route-8 duplicate authority; it's the shared portal-lifecycle plumbing routes 3 and 8 both sit on top of.

Duplicate authorities — headless (what the residence+executor owner must take over)

  • HeadlessSessionWorldProjection.SynchronizeLocalPlayer (566-615, read in full): _collision.CenterOn(position.LandblockId) (575) → CreateController(record) if none exists (577-578, 639-655 — constructs PlayerMovementController directly, see prerequisite-C section above) → _runtime.EntityObjects.Physics.Engine.Resolve(wirePosition, position.LandblockId, Vector3.Zero, 100f) (589-594) → .ResolvePlacement(resolved.Position, resolved.CellId, DefaultRadius, DefaultHeight, controller.StepUpHeight, controller.StepDownHeight, ObjectInfoState.IsPlayer | EdgeSlide, record.LocalEntityId ?? 0u) (595-605) → controller.SetPosition(resolved.Position, resolved.CellId, wirePosition) + controller.SetBodyOrientation(orientation) (610-614). This is a COMPLETE independent physics resolve + placement commit, entirely bypassing RuntimeSetPositionState. It is the headless mirror of route-1's "Headless performs its own initial resolve/placement/body construction" callout in the campaign handoff.
  • HeadlessSessionWorldProjection.BlipLocalPlayer (617-637): direct controller.BlipPosition(wirePosition, position.LandblockId, wirePosition) (633-636) with zero Runtime commit/ack gating — this is exactly the "direct Blip" duplicate the campaign handoff names for route 8 ("Delete the independent resolve/placement/direct SetPosition and Blip logic in HeadlessSessionWorldProjection"). session controller's _localPlayerOutbound.SendImmediatePosition(...) at RuntimeLiveEntitySessionController.cs:196-198 fires on the SAME ForcePosition branch, before any placement receipt exists — pre-commit ack.
  • HeadlessSessionWorldProjection.PrepareDestination (539-564): calls _collision.CenterOn(destination.CellId) (543) then, if the destination entity is active, SynchronizeLocalPlayer(record) again (544-549) — i.e. portal arrival re-runs the SAME duplicate resolve/placement authority. Also directly sets controller.State = PlayerState.InWorld (550-551) outside any Runtime placement gate.
  • HeadlessCollisionNeighborhood (168-469): NOT a placement-authority duplicate per se (it manages per-landblock collision generation publication/retirement, a different concern from entity placement) but it IS the thing RuntimeSetPositionState/RuntimeInitialCreateResidenceState must be able to wait on (its IsReady/CenterOn gate the destination readiness the residence lease's placement depends on) — this file already looks like a reasonable candidate for the "exact authored mover preparation" (prerequisite B) collision-readiness signal, not something to delete.

What each headless hop must become post-cutover

  • OnSpawned → keep the legacy timestamp-gate call semantics but swap Entities.RegisterEntity(spawn) for Entities.RegisterEntityWithInitialResidence(spawn, ...) (the wrapper already exists per the surface map, just unused) so headless enters the SAME residence lease as graphical; ProjectSpawn becomes acknowledge-only: subscribe an IRuntimePlacementObserver (does not exist yet — see observer-seam section) and, on a Place receipt for this entity's token, set controller.SetPosition/SetBodyOrientation from the IMMUTABLE RuntimePlacementProjectionSnapshot fields only. DELETE SynchronizeLocalPlayer's direct Physics.Engine.Resolve/ResolvePlacement calls (589-605) outright — the sweep must happen exactly once, inside RuntimeSetPositionState, driven by the residence lease.
  • OnPositionUpdated's ForcePosition branch → DELETE the direct BlipLocalPlayer/controller.BlipPosition call (633-636) and the immediate SendImmediatePosition pre-commit ack (196-198 in the session controller); replace with: accept timestamp only (still call TryApplyPosition/TryAcceptDeferredPosition for the timestamp-gate side-effects already established) → begin the Runtime placement (route 2's "LocalAuthoritative" route kind) → wait for the Place receipt via the new headless IRuntimePlacementObserver → apply position from the receipt → THEN send the single outbound ack.
  • PrepareDestination → keep the collision-neighborhood prep (_collision.CenterOn/IsReady) as the readiness signal Runtime's portal-placement authority polls, but DELETE the second SynchronizeLocalPlayer call (548) — arrival placement must come from the SAME Runtime portal-placement commit route 3 defines, not a second independent resolve.
  • CreateController → becomes the headless half of prerequisite C's atomic controller/body publication transaction; must stop being callable ad hoc from three different places (SynchronizeLocalPlayer twice via OnSpawned+PrepareDestination, indirectly via OnPositionUpdated) and instead run exactly once, gated by the same atomic commit graphical route 1 uses.

Route-8-specific capability gap

The residence+executor mechanism (per docs/research/2026-08-02-runtime-continuation-executor-handoff.md, "What the executor owns") is host-agnostic by design — nothing in its API is graphical-only. The concrete gap for route 8 is therefore NOT in the executor; it is that no headless IRuntimePlacementObserver implementation exists to consume GameRuntime.Placements receipts at all (see observer-seam section above — zero hits in src/AcDream.Headless/), so today headless has no mechanism to learn "the Runtime commit landed, project it" even in principle. Headless also has no analog to a "camera" but DOES have the same controller/body atomicity requirement as graphical (prerequisite C applies equally to both hosts — confirmed by the very existence of HeadlessSessionWorldProjection.CreateController as a second, independent constructor of PlayerMovementController next to PlayerModeController.BuildControllerAndCamera).


(routes 1-7 sections below filled in as each parallel research agent reports)