acdream/docs/research/2026-08-02-runtime-continuation-executor-handoff.md
Erik 9ad590dcc7 docs(physics): hand off placement continuation executor
Synchronize the architecture doc, milestones, roadmap, and ISSUES with the
continuation-executor behavior commit (5db3de3c): the residence system is
now a complete dormant mechanism, both independent reviews PASS, and the
next boundary is the all-host production cutover. The admission handoff
gains its superseded banner; the successor handoff records the executor's
ownership, the retail anchors proven during review (the wire-contact gate,
queue-by-parent-GUID relation replay, HasAnims semantics), the seven new
register rows, exact test totals, the rollback command, and the cutover
checklist. #275 filed for the post-cutover legacy-Position unification.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-08-02 03:52:30 +02:00

211 lines
11 KiB
Markdown

# Runtime initial-placement continuation executor handoff - 2026-08-02
## Purpose and exact stopping point
Behavior commit `5db3de3c7ab2c6350d11af7f34b852464fc1e0f9` implements the
Runtime continuation executor: the missing mechanism that, once an entity's
initial authored placement is acknowledged, adopts that placement exactly
once, applies the retail Create tail, replays deferred missing-parent work,
and drains the admission checkpoint's mixed continuation FIFO in exact
arrival order with retail route decisions made at execution time. The
residence system built by `38fd4b8d` (residence/FIFO) and `30012361`
(admission) is now COMPLETE as a mechanism: an entity can enter the world
through it and every packet accepted while its placement was pending is
applied exactly once, in order, with retail semantics.
This checkpoint deliberately does NOT cut the graphical or headless
production routes over — `RuntimeLiveEntitySessionController.cs` (headless)
and App's `LiveEntityRuntime` still call legacy `RegisterEntity`, and no host
calls `Execute`. It does not begin AP-22 or AD-10 and does not retire
AP-1/AD-1. The executor is exercised by deterministic Runtime tests only, so
no connected visual gate was required.
This file supersedes the executor-boundary portions of
[`2026-08-01-runtime-initial-placement-admission-handoff.md`](2026-08-01-runtime-initial-placement-admission-handoff.md).
## Exact workspace and Git state
- Worktree: `C:\Users\erikn\.codex\worktrees\af5e\acdream`
- Branch: `codex/port-claude-agents`
- Behavior checkpoint: `5db3de3c7ab2c6350d11af7f34b852464fc1e0f9`
- Documentation checkpoint: the commit containing this file
- The same eight unrelated dirty paths as the admission handoff remain
intentionally unstaged; never stage by blanket.
- No push or merge is part of this checkpoint.
## What the executor owns
`RuntimeInitialCreateContinuationExecutor` (constructed inside
`RuntimeEntityObjectLifetime` beside the residence state; internal
`InitialCreateExecution`; generation bound through `BindEventContext`) owns,
per exact `RuntimeEntityKey` + lease:
- the synchronous, retry-idempotent `Execute` transaction:
`Complete` -> `AdoptCompletedPlacement` (consumes the acknowledged initial
placement exactly once, resolving the `HasRetainedCompletion` deadlock so
later authored placements for the key can begin, with `PlacementAdopted`
keeping the completed entry current) -> AfterEnterWorld hook request
(local player, exactly once) -> deferred replay -> strict-sequence FIFO
drain -> `ConsumeExecuted` release (adoption-revision-checked; `Revised`
re-drains only the tail);
- per-continuation applies through gate-less instance seams on
`InboundPhysicsStateController` (`ApplyAccepted*Snapshot`) that read and
write the ONE snapshot store — the legacy fused paths are re-expressed as
gate + the same shared merge bodies, so there is no drift and no second
canonical snapshot;
- execution-time Position routing via
`RuntimeAuthoritativePositionRouteClassifier.ClassifyAcceptedPosition`
with live inputs: the retained wire packet's own `IsGrounded` bit as the
server-asserted contact (never the local body), the data-driven
`(MotionTableId ?? Physics?.MotionTableId)` animation proxy (AP-130), live
distance/`UsePositionFromServer`, and the record's committed cell — driving
authored placements for SetPosition routes through the canonical
`RuntimeSetPositionState` Begin/Watch/resume lifecycle with a retryable
`AwaitingContinuationPlacement` yield (a contention flavor with no pending
token means "retry Execute later");
- atomic `SameIncarnationCreate` envelopes: per-stage index idempotency,
buffered publication flushed in stage order after the final stage (AD-59),
the object-table apply via the accepted-spawn seam (result observed; a
nested replacement abandons), and the three-branch resident-cell
disposition (TS-63);
- missing-parent replay, both flavors, keyed by parent GUID exactly as
retail's `QueueBlobForObject`/`ProcessObjectNetBlobs`: raw child Creates
AND queued accepted parent relations, drained in the initial tail with
whole-bucket atomic detach, per-entry exception containment
(`ReplayFailureCount`/`LastReplayFailure`), typed outcomes
(Registered/ReDeferred/Rejected; ParentApplied/DeferredAwaitingParent/
DiscardedStaleParent), and cancellation-aware restore windows whose tokens
record every cancellation fired while a batch is detached (ABA-safe;
a cleared token restores nothing);
- the field-masked executor baseline: each apply re-syncs ONLY the tracked
fields its own mutations moved, before publication, so external mutations
are detected in every quiet window and publish-callback;
- one shared abandonment routine on every non-retryable exit: forgets any
pending continuation placement (cancellation published), retires the
residence through the lifetime choke point, discards progress, returns a
typed status — the combined ownership ledger (residences, executor
progress, deferred buckets, replay windows, placement watches) converges,
and residence retirement notifies the executor
(`BindRetirementNotification`);
- an ordered immutable execution receipt/trace carrying every fact a cutover
host needs: per-action kind/sequence/stage, Position route facts
(disposition, constrain phase, teleport-hook phase, stop-interpolation,
zero-velocity, preserve-heading, send-position-immediately, unparent),
replay outcomes, and resident-cell dispositions.
## Retail anchors proven this slice
Beyond the admission handoff's eight anchor functions:
- retail's local-ordinary interpolate gate is
`UsePositionFromServer && wire-contact``PositionPack` bit 0x4 →
`has_contact` (pseudo-C 284654) → `UnpackPositionEvent` arg5 (93092) →
the gate at 93044. The earlier research note's "isForce" reading was a
misnomer disproven during review; the shipped classifier was correct.
- `ProcessObjectNetBlobs` detaches the whole per-GUID bucket before
dispatching (93617 → 93649) — mirrored by the detach/restore windows.
- missing-parent relations are QUEUED by parent GUID (standalone parent
handler 0x004535D0: lookup 92312, queue 92326; `QueueBlobForObject`
0x005092D0's GUID-keyed placeholder bucket 271082-271088) — never
discarded; the round-4 discard was overturned on this evidence.
- `HandleReceivedPosition`'s `HasAnims` gate (92992) is animation-queue
presence (`CSequence::has_anims` = non-empty list), anchoring AP-130.
- the same-incarnation tail order and resident-cell cleanup
(93865..93943) are mirrored stage-for-stage, with the claimedCell==0
destruction branch proven structurally unreachable for admitted envelopes
(every envelope carries a WeenieDescription by shape).
## Divergence register
Rows filed in the behavior commit: **AD-59** (envelope buffered live-record
events), **AD-60** (executor canonical cell semantics — wire positions never
directly commit residency), **AP-130** (HasAnims MotionTableId proxy),
**AP-131** (legacy Position merge's unconditional placement-frame/parent-
clear flags — retired by construction at cutover), **AP-132** (parent
incarnation gating vs retail's pointer-only GUID replay), **TS-62** (no live
ConstrainTo binding in the dormant slice — trace-only), **TS-63**
(resident-cell abandonment/delegation split). AP-1 and AD-1 remain open
until the cutover. Issue **#275** tracks the post-cutover unification of the
legacy Position path onto the classifier.
## Validation
- Focused executor/residence/classifier gate: **161/161**.
- Complete Runtime project: **903/903** (829 baseline + 74 slice tests).
- Complete Release solution: **10,696 passed / 4 intentional skips / 0
failed** (`-m:1`, installed `acdream.pak`); Release build 0 errors,
21 pre-existing test-project warnings.
- `git diff --check` clean; the eight unrelated dirty paths untouched.
- Independent reviews (both read-only, both required to PASS): the
retail-conformance reviewer and the architecture/adversarial reviewer each
ran four passes across five implementation rounds. Finding classes fixed
at root cause along the way: wire-vs-body contact source; two-store
snapshot divergence; WeenieDescription wholesale-overwrite; non-converging
abandonment; reentrant mid-drain residence retirement; the
acknowledged-completion leak that would have blocked all future placements
for a key; per-field baseline blessing; replay exception containment and
detached-batch resurrection; and the stale-parent discard overturned in
favor of retail's queue-by-parent-GUID replay. Final verdicts: RETAIL
REVIEW: PASS; ARCHITECTURE REVIEW: PASS (three residual NOTEs, all
defense-in-depth observations, none blocking).
## Production routes intentionally unchanged
Graphical Create still flows through `LiveEntityRuntime.RegisterEntity`;
headless still uses `RuntimeLiveEntitySessionController`'s legacy
`RegisterEntity`; no production code calls
`RegisterEntityWithInitialResidence` or `Execute`. The residence+executor
system is a complete, reviewed, dormant mechanism awaiting the cutover.
## Next implementation boundary — the production cutover
Route graphical AND headless registration through the residence+executor
owner together, then every Create, Position, ForcePosition, Parent, Pickup,
withdrawal, delete, remote-movement, projectile-correction, and dropped-item
edge through the same transaction. Hosts project immutable Runtime results
only; they may not resolve a second placement or create another body. Delete
the legacy duplicate paths only after parity tests pass (this retires AP-131
and closes #275 by construction). Run the exact lifecycle/reconnect and
canonical nine-stop connected routes, two-client observation, and the user
visual matrix. Only then retire AP-1 and AD-1.
Cutover-specific notes from this slice:
- The execution receipt carries every route fact a host must bind — the
constrain phases and stop-interpolation/zero-velocity flags (TS-62), the
teleport-hook phases, and the send-position-immediately echo.
- `AwaitingContinuationPlacement` has two flavors: pending token (host must
prepare/submit/acknowledge the placement, then retry Execute) and
contention (no pending token; retry Execute after the conflicting
operation resolves).
- The dormant placement path's 1,880-bytes/operation allocation budget
(2,048 cap) remains the standing 4B2 activation blocker for
frame-frequency traffic; resolve or budget it before the cutover routes
high-frequency Position traffic through the owner.
After the cutover: **AP-22** (authored collision shapes;
`ShadowShapeBuilder` sole authority), then **AD-10** (remote contact-plane
projection), then the final automated + connected matrix and ledger
synchronization close the campaign; vendor Slice 5 resumes after.
## Rollback
```powershell
git revert 5db3de3c7ab2c6350d11af7f34b852464fc1e0f9
```
The documentation checkpoint containing this file is separate and may be
reverted independently. Do not revert the `38fd4b8d`/`30012361` foundation
beneath it without a separately proven defect.
## Resume checklist
1. Continue in the exact worktree/branch above; confirm `git log` contains
`5db3de3c` and the documentation commit containing this file.
2. Preserve the eight unrelated dirty paths; never `git add -A`.
3. Read this file, the admission handoff, and
`docs/architecture/acdream-architecture.md`.
4. Re-run the focused gate before modifying execution code:
the Residence + Classifier + Executor filter must report 161/161.
5. Begin ONLY the production cutover checkpoint. Do not fold AP-22, AD-10,
or vendor work into it.