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>
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.mdsections "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.mdsections 8-9 (GameRuntime construction, the two legacyRegisterEntitycall 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:76—Entities.RegisterEntity(spawn)(headless/direct-host)src/AcDream.App/World/LiveEntityRuntime.cs:537—_entityObjects.RegisterEntity(...)(graphical/App) Neither callsRegisterEntityWithInitialResidence.CompleteInitialCreateResidence/AcknowledgeInitialCreateResidenceAdoptionhave NO production caller anywhere.
GameRuntime.cs:180-183constructsRuntimeEntityObjectLifetimeonce ascontext.EntityObjects.BindEventContextatGameRuntime.cs:266-269supplies 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:_placementObserversarray (line 40),SubscribePlacement(119-133, copy-on-write add),UnsubscribePlacement(356-369), dispatch loop (302-310ish inside the drain routine),PublishPlacement(164-171, builds aRuntimePlacementDelta(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 insideRuntimeEntityObjectLifetime's ctor (Placements = new RuntimePlacementProjectionChannel(Events, Physics.SetPosition), per the surface map's file-1 section) and exposed onGameRuntime.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/**/*.csandsrc/AcDream.Headless/**/*.csforIRuntimePlacementObserver,SubscribePlacement, orPlacements.Subscribereturns ZERO matches (confirmed viagrep -rlnacross both trees; the only hits anywhere in the repo outsidesrc/AcDream.Runtime/are 5 Runtime-test fake-observer classes intests/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 productionIRuntimePlacementObserverimplementation. Prerequisite D ("Add one graphical and one headlessIRuntimePlacementObserverusingGameRuntime.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 sequentialAcDream.App.exesessions against the always-up local ACE (127.0.0.1:9000):cappedsession using route scripttools/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.uncapped-reconnectsession (starts as soon as ACE's own log records the first session's transport Disconnect — no artificial settle delay) usingtools/connected-world-reconnect.route.txt, expects one checkpointuncapped_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, everytransitOwnershipcounter (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 gracefulWM_CLOSE(Close-ClientGracefully, 85-92) and ACE's own log must recordgraceful logout confirmed+ aPacketHeader Disconnectdrop (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 existingtransitOwnership/resourcespattern, or the gate will not actually prove placement convergence.
- Canonical nine-stop route:
tools/run-connected-r6-soak.ps1(only first 60 lines read) drivingtools/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/-DenseTownswitches (DenseTown swaps inconnected-dense-town.route.txtagainst a singlearwic-densecheckpoint 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(defaultC:\ACE\Server\ACE_Log.txt) and will themselves invokedotnet build ... -c Releaseunless-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) constructsnew PlayerMovementController(...)(line 259-262) directly against_physics/playerRecord.ObjectClock, wires aMoveToManagerfacade andEntityPhysicsHostclosures over captured locals (267-345+), and stores the result in the App-local_controllerSlot.Controller(not_runtime.MovementOwner.Controllerdirectly at this point in the file — Agent 1's detailed route-1 report is authoritative for exactly where/whether this crosses intoRuntimeLocalPlayerMovementState/GameRuntime.MovementOwner). - Headless:
HeadlessSessionWorldProjection.CreateController(src/AcDream.Headless/Hosting/HeadlessSessionWorldProjection.cs:639-655) constructsnew 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 = controllerin the entire repo (confirmed by grep — the graphical host does NOT write_runtime.MovementOwner.Controlleranywhere 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 intoRuntimeLocalPlayerMovementStatethe 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, thencontroller.SetPosition(resolved.Position, resolved.CellId, wirePosition)(610-613) andcontroller.SetBodyOrientation(orientation)(614) — entirely independent ofRuntimeSetPositionState/RuntimeInitialCreateResidenceState.HeadlessSessionWorldProjection.BlipLocalPlayer(617-637) similarly callscontroller.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)
src/AcDream.App/Net/LiveEntitySessionController.cs:51-53—OnSpawnedwire entry, routesCreateObjectviaRetailInboundEventDispatcher.RuntoLiveEntityHydrationController.OnCreate.src/AcDream.App/World/LiveEntityHydrationController.cs:226-250—OnCreate(dormant/stale-generation classification) ->OnCreateCore.LiveEntityHydrationController.cs:259-262—OnCreateCore(under_datLock) calls_runtime.RegisterLiveEntity(spawn).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.src/AcDream.Runtime/Entities/RuntimeEntityObjectLifetime.cs:315-322—RegisterEntity->RegisterEntityCore(incoming, beginInitialResidence:false, ...)— never touchesInitialCreateResidences/InitialCreateExecution.LiveEntityHydrationController.cs:288-294—ApplyAcceptedSpawn(...)commits the accepted snapshot (still cellless authority, no position/rebucket yet).LiveEntityHydrationController.cs:938-1040(ProjectExactOnce), line 1036:_materializer.TryMaterialize(...).src/AcDream.App/Rendering/DatLiveEntityProjectionMaterializer.cs:407-427->MaterializeProjection(680-857).- Duplicate authority —
DatLiveEntityProjectionMaterializer.cs:712-737:_runtime.MaterializeLiveEntity(..., out expectedRecord)with theresidenceparameter OMITTED, defaulting toLiveEntityMaterializationResidence.LegacyImmediate(LiveEntityRuntime.cs:596-597). LiveEntityRuntime.cs:589-789(MaterializeLiveEntity) — constructs theWorldEntity(sets Position/Rotation/ParentCellId directly from wire-decoded world position, ~718-729); because residence isLegacyImmediatenotAwaitRuntimePlacement, falls through at line 777 toRebucketLiveEntity(serverGuid, fullCellId).- Duplicate authority —
LiveEntityRuntime.cs:792-931(RebucketLiveEntity): immediately calls_spatial.RebucketLiveEntity(...)(spatial bucket mutation), setsIsSpatiallyProjected/Visible, calls_entityObjects.CommitRebucket(...)(canonicalFullCellId/CanonicalLandblockIdwrite), resets/suspends the object clock — all synchronous, no Runtime placement receipt involved anywhere in this path. 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).LiveEntityHydrationController.cs:739-759/1070-1098— publish-ready viaILiveEntityReadyPublisher.Publish.src/AcDream.App/Input/PlayerModeAutoEntry.cs:214-230— per-frame guard; onceIsPlayerEntityPresent+IsWorldReady(world-reveal, unrelated to any Runtime placement receipt) ->EnterPlayerMode()->PlayerModeController.EnterFromAutoEntry.src/AcDream.App/Input/PlayerModeController.cs:126-133,217-242->TryEnter->BuildControllerAndCamera(244-525).- Duplicate authority —
PlayerModeController.cs:409-413:_physics.Resolve(playerEntity.Position, initialCellId, Vector3.Zero, 100f). - Duplicate authority —
PlayerModeController.cs:422-430:_physics.ResolvePlacement(...)using a locally computed Setup cylinder (_motionBindings.GetSetupCylinder) — no shared "exact Setup mover" step. - Duplicate authority —
PlayerModeController.cs:449-480: buildsEntityPhysicsHost/MoveToManager, installs viaEntityPhysicsHostComposition.SelectStableHostWithoutRebind/InstallOrRebind(src/AcDream.App/Physics/EntityPhysicsHostComposition.cs:16,35) — its own body/controller construction, independent of headless's copy. - Camera —
PlayerModeController.cs:440-447: constructsChaseCamera/RetailChaseCamera,_camera.EnterChaseMode(...)(host-only concern, stays, but must be gated by the Runtime ack not ad-hoc resolve success). - Duplicate authority — final commit —
PlayerModeController.cs:482-484:playerEntity.SetPosition(initial.Position); playerEntity.ParentCellId = initial.CellId; controller.CommitPreparedPosition();— direct write, bypasses any RuntimePlacereceipt.
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/OnSpawnedfromRegisterEntitytoRegisterEntityWithInitialResidence— no accessibility blocker (see correction above); this is a pure call-site + follow-up-loop change. - DELETE
MaterializeProjection's directRebucketLiveEntityfall-through; passresidence: LiveEntityMaterializationResidence.AwaitRuntimePlacement(the enum value ALREADY EXISTS and is used by other routes viaLiveEntityRuntime.cs:765-776/938-1127'sTryApplyRuntimePlacementPlace/Withdrawal— this route just isn't plumbed into it yet). - DELETE
PlayerModeController.cs:409-430(own Resolve/ResolvePlacement) and482-484(direct SetPosition/CommitPreparedPosition); body/controller construction becomes acknowledge-only from the shared Runtime-resolved position. - DELETE headless
SynchronizeLocalPlayer:589-607and610-614the same way. - DELETE the legacy
RegisterEntityoverload entirely once both hosts move (RegisterEntityWithInitialResidenceis already a strict superset). - Gap 1 (real): no shared "exact Setup mover" / DAT-preparation API.
RuntimeInitialCreateResidenceState.Ownonly OPENS the placement slot (TryBeginExclusiveAuthoredPlacement); nothing in Runtime resolves a Setup-derived cylinder/sphere-list and feeds it intoRuntimeSetPositionState.SubmitPreparedPlacement. Today that DAT read + Resolve/ResolvePlacement call is hand-duplicated with DIFFERENT defaults in App (_motionBindings.GetSetupCylinder) vs. headless (hardcodedDefaultRadius=0.48f/DefaultHeight=1.835funless_preparedCollisionsupplies a Setup) — this is exactly prerequisite B, confirmed still open. - Gap 2 (real): no shared "atomic Runtime controller/body" owner exists
anywhere (
RuntimeEntityRecordhas storage slots —PhysicsBody,PhysicsHost— but no construction logic);BuildControllerAndCameraandHeadlessSessionWorldProjection.CreateControllerare two independently written, divergent implementations of the same "build aPlayerMovementController/host from aRuntimeEntityRecord" 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, andSubmitPreparedPlacement(RuntimeSetPositionState.cs:2041) already requiresoperation.Record.PhysicsBody is not { } bodyto 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:PrepareMovertakes aRuntimeSetPositionMoverPreparationwhoseSetupfield is a host-suppliedRuntimeSetPositionMoverSetup(Setup table ID +FlatSetupCollision?,RuntimeSetPositionMoverPreparation.cs:23-42) — Runtime does NOT read DAT itself; the host must callIPreparedCollisionSource.ReadSetupCollision(setupId)(already used by headless atHeadlessSessionWorldProjection.cs:668-679) and feed the result in. No production call site anywhere chainsReadSetupCollision->PrepareMover->SubmitPreparedPlacement— both hosts instead read Setup DAT/prepared-collision data ad hoc and callPhysicsEngine.Resolve/ResolvePlacementdirectly, 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
RuntimeEntityChangevia_events.PublishEntity(RuntimeInitialCreateContinuationExecutor.cs:2053-2061), NOT throughRuntimePlacementProjectionChannel/Placements— the channel the existing AppTryApplyRuntimePlacementProjection/headless placement sinks already consume for OTHER routes. Whether a residence-driven initial commit actually surfaces aPlacetoken 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/RegisterEntityWithInitialResidencetoday.
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
LocalForcePositionTransactionoutright; its job (validate ownership, blip, ack-once) becomesRuntimeSetPositionState.Apply/BeginAcceptedPlacementwithRuntimeSetPositionOperationKind.LocalAuthoritative. OnPosition's force branch reduces to: classify viaRuntimeAuthoritativePositionRouteClassifier.ClassifyAcceptedPosition(itsForcePositionbranch — lines 291-313 — already produces exactlySetPositionSimple,PreserveHeading: true,SendPositionImmediately: true— this route kind is FULLY MODELED already, just unused) -> submit throughRuntimeSetPositionState-> only callSendImmediatePositionAFTER commit (fixes the ordering bug).BlipPositionbecomes acknowledge-only (applies the already-committed Runtime projection instead of being an independent authority).- DELETE the generic tail's second
entity.SetPosition/RebucketLiveEntityfor the local player (1252-1270) — dead code once the host projects only the one canonical result. - Gap (confirmed): zero production references to
RuntimeAuthoritativePositionRouteClassifier/RuntimeSetPositionStateanywhere insrc/AcDream.Appfor 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 isRuntimeSetPositionState/InboundPhysicsStateController.ApplyAcceptedPositionSnapshotdirectly, NOTExecute. TheAwaitingContinuationPlacementretry 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 withRuntimeSetPositionState.BeginAuthoredPlacement/Applycarrying a populatedRuntimePortalPlacementAuthority, then project only the committed result. - Re-sequence
WorldRevealCoordinator.CanPlacePortalDestination/ObserveMaterializedto 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 afterPlace()'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, carryingRevealGeneration/TeleportSequence/RuntimeWorldHostProjectionToken) is a REAL, VALIDATED constructor parameter onRuntimeSetPositionCommand.Portal(validated inBeginAcceptedPlacementCore,:978-984) andLiveEntityRuntime.cs:1162-1171even has anIsValidPortalPlacementAuthoritypresentation-side validator — but grep across App and Headless finds ZERO call sites that ever construct one withPresent: 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 aRuntimePortalPlacementAuthority; (b) the actualRuntimeSetPositionState.BeginAuthoredPlacementcall site usingLocalAuthoritative+ that authority (does not exist anywhere today); (c) re-sequencingObserveMaterializedto 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/
Executemechanism is Create-admission-scoped; Route 3's target isRuntimeSetPositionStatedirectly.
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—_pendingdictionary, 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— directbody.SnapToCell, contact-plane fields,PhysicsObjUpdate.CommitSetPositionTransition— a hand-rolled SetPosition commit parallel toRuntimeSetPositionState.LiveEntityNetworkUpdateController.cs:1594-1900— the "ordinary" MoveOrTeleport classification hand-duplicated in App, whenRuntimeAuthoritativePositionRouteClassifier.ClassifyAcceptedPositionALREADY implements identical near(<96m,Interpolate)/far(SetPositionSimple)/ teleport-advanced(SetPosition)/cellless rules (classifier lines 360-439).RemoteTeleportController.cs:382-475—ParkPending/OnProjectionVisibilityChangedre-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-placemententity.SetPosition/RebucketLiveEntityat:1252-1270. - DELETE + replace with classifier delegation: the inline near/far/airborne/
landing block (
:1594-1900) -> route throughClassifyAcceptedPosition+RuntimeSetPositionStateBegin/Watch/resume. - Reduce to acknowledge-only:
RemoteTeleportHook.csstays as the App-side execution seam, but its trigger condition should come from the classified route'sRuntimeTeleportHookPhase, not the App's ownremoteHardTeleportflag. RuntimeRemotePhysicsUpdaterper-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-quantumComplete) and:346-421(ApplyAuthoritativePosition) — BOTH do directSnapToCell+CommitProjectileCell+ shadow sync, bypassingRuntimeSetPositionStateentirely; 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) andApplyAuthoritativePosition(:508-578); and the directSnapToCell/shadow commit insideRuntimeProjectilePhysicsUpdater.ApplyAuthoritativePosition(:301-424). - REPLACE with
ProjectileAuthoritative-tagged routes via the classifier drivingRuntimeSetPositionState, 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 ofCommitProjectileCell. - 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.BuildSpawnclones the source's DTO wholesale (correct for Position, which IS explicitly overridden) but presentation-effect replay (create-pop VFX/sound driven offLiveEntityReadyPublisher.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 state — InitialCreateResidences.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 NOForgetInitialCreateResidence/PreferCancellationcall at all.CommitWithdrawal(1401-1422) callsForgetInitialCreateResidencebut NOTPhysics.SetPosition.Forget/PreferCancellation, unlike Pickup/CommitAcceptedParentCellless/TryAcceptDeletewhich cancel both families. Once ordinary placement transactions go live,WithdrawLiveEntityProjectionToCellless(LiveEntityRuntime.cs:1315-1331, callsCommitWithdrawal) 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):
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) → ifregistration.Canonicalpresent,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, callsSynchronizeLocalPlayer(566-615) which is the duplicate placement authority (see below).OnPositionUpdated(137-201) —Entities.TryApplyPosition(update, isLocal, forcePositionRotation: localController?.BodyOrientation, currentLocalVelocity: localController?.BodyVelocity, projectionRequiresTeleportHook: false, acknowledgeProjection: null, ...)(144-153, legacy path) → if!isLocalorRejected, return (154-159) → ifdisposition is Apply, builds aRuntimeTeleportDestinationfrom 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 fordisposition is ForcePositiondoes it callBlipLocalPlayer(529-530) — an ordinaryApplydisposition with an existing controller does NOTHING here (ordinary interpolation must happen elsewhere, at the physics tick) → back in the session controller, ifdisposition 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.OnPickedUp/OnMotionUpdated/OnVectorUpdated/OnStateUpdated/OnParentUpdated/OnAppearanceUpdated(118-122, 124-135, 203-207, 209-214, 216-220, 237-241) — thin 1-line pass-throughs toEntities.TryApply*(..., acknowledgeProjection: null, out _), no independent headless placement work.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).OnTeleportStarted(222-235) →transit.TryQueueTeleportStart→_worldProjection?.BeginTeleport()→HeadlessSessionWorldProjection.BeginTeleport(533-537): setscontroller.State = PlayerState.PortalSpacedirectly (no Runtime commit gate) →transit.ActivateQueuedTeleport()→TryCompletePortal().TryCompletePortal(243-332) — a fully Runtime-driven, already-cutover state machine for the portal handshake itself:TryGetAcceptedTeleportDestination→TryBeginPortalReveal→TryRegisterHostProjection→Acknowledge(...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 — constructsPlayerMovementControllerdirectly, 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 bypassingRuntimeSetPositionState. 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): directcontroller.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 inHeadlessSessionWorldProjection"). session controller's_localPlayerOutbound.SendImmediatePosition(...)atRuntimeLiveEntitySessionController.cs:196-198fires on the SAMEForcePositionbranch, 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 setscontroller.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 thingRuntimeSetPositionState/RuntimeInitialCreateResidenceStatemust be able to wait on (itsIsReady/CenterOngate 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 swapEntities.RegisterEntity(spawn)forEntities.RegisterEntityWithInitialResidence(spawn, ...)(the wrapper already exists per the surface map, just unused) so headless enters the SAME residence lease as graphical;ProjectSpawnbecomes acknowledge-only: subscribe anIRuntimePlacementObserver(does not exist yet — see observer-seam section) and, on aPlacereceipt for this entity's token, setcontroller.SetPosition/SetBodyOrientationfrom the IMMUTABLERuntimePlacementProjectionSnapshotfields only. DELETESynchronizeLocalPlayer's directPhysics.Engine.Resolve/ResolvePlacementcalls (589-605) outright — the sweep must happen exactly once, insideRuntimeSetPositionState, driven by the residence lease.OnPositionUpdated's ForcePosition branch → DELETE the directBlipLocalPlayer/controller.BlipPositioncall (633-636) and the immediateSendImmediatePositionpre-commit ack (196-198 in the session controller); replace with: accept timestamp only (still callTryApplyPosition/TryAcceptDeferredPositionfor the timestamp-gate side-effects already established) → begin the Runtime placement (route 2's "LocalAuthoritative" route kind) → wait for thePlacereceipt via the new headlessIRuntimePlacementObserver→ 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 secondSynchronizeLocalPlayercall (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 (SynchronizeLocalPlayertwice viaOnSpawned+PrepareDestination, indirectly viaOnPositionUpdated) 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)