Record exact projection-store ownership, automated and connected evidence, rollback chain, and the executor-ready canonical object-table plan. Reconcile milestones, roadmap, architecture, divergence pointers, AGENTS/CLAUDE, and durable handoff state. Co-authored-by: Codex <codex@openai.com>
7.6 KiB
Modern runtime J3.3 — exact-key App projection store
Status: COMPLETE 2026-07-25
Parent: 2026-07-25-modern-runtime-slice-j3.md
Required base: f46ddb5cdb1e145752bea49aeb1d62bfe71284d3
Production commits: 420e5eea70fd2c29cf9c8614e6298a1f84d64045,
then exact-spatial correction
e937cc36df39cf6ea1eaba2f9c0243d1929da702
Closeout: docs/research/2026-07-25-slice-j3-3-exact-projection-store.md
Objective
Make every materialized App-side live-object owner use the exact
RuntimeEntityKey (Runtime local ID + INSTANCE_TS) issued by
RuntimeEntityDirectory.
Runtime remains the only server-GUID authority. App may carry GUID as immutable metadata for diagnostics and outbound commands, but no App dictionary may use GUID to decide which incarnation is current.
No asynchronous projection queue, extra input frame, renderer behavior change, or local-ID allocation-order change is permitted.
Fixed model
There are three distinct states:
- Canonical-only registration — Runtime accepted an incarnation, but no graphical host has claimed a local ID. No materialized projection exists.
- Materialized projection — Runtime has claimed the local ID and App owns
exactly one sidecar under the resulting
RuntimeEntityKey. - Retryable teardown — Runtime retains the exact canonical tombstone while App retains only the unfinished teardown suffix for that exact key. A registration that failed before local-ID claim has no graphical tombstone.
A small synchronous construction context may carry a canonical record between registration and materialization. It is not a retained App identity map.
Execution
1. Introduce LiveEntityProjectionStore
- Store materialized sidecars in
Dictionary<RuntimeEntityKey, LiveEntityRecord>. - Resolve GUID only by asking
RuntimeEntityDirectoryfor the current canonical record, reading its exact key, then querying the store. - Reject key reuse, local-ID mismatch, incarnation mismatch, and stale canonical records.
- Preserve insertion order and allocation-free borrowed enumeration.
- Retain teardown progress under the exact key; use canonical-reference storage only for the exceptional pre-materialization registration rollback which has no key.
2. Move sidecar creation to local-ID claim
RegisterLiveEntityreturns canonical registration facts without allocating a graphical sidecar.MaterializeLiveEntityclaims the Runtime local ID at the same point as today, creates the exact-key sidecar, then calls the projection factory.- Same-incarnation refresh before materialization mutates only Runtime state.
- Same-incarnation refresh after materialization resolves the existing sidecar through its exact key.
- Factory, resource-registration, and rollback failures retain exactly the currently unfinished ownership suffix.
3. Re-key every presentation workset
Convert the following from GUID/local-ID-only maps to exact-key maps:
- materialized and visible
WorldEntityprojections; - animation and spatial-animation owners;
- remote-motion and spatial-remote-motion owners;
- projectile and spatial-projectile owners;
- ordinary root object workset;
- effect profile, visibility publication, hydration, and teardown lookups.
Local-ID-only iteration views validate the incarnation through the projection store before yielding. No stale entry can match a replacement that reused the same numeric local ID after wraparound.
4. Cut consumers over to borrowed queries
- Replace direct GUID dictionary access in selection, radar, combat targeting,
local-player animation/mode, teleport, physics update, diagnostics, and
composition with typed
TryGet..., exact-key, or borrowed-enumeration methods. - Keep synchronous press-time reads; do not publish a copied frame snapshot.
- Preserve server GUID in yielded metadata where outbound commands need it.
- Remove
MaterializedWorldEntities,WorldEntities, and component dictionaries once all consumers use the focused queries.
5. Delete the J3.2 compatibility view
- Delete
ActiveRecordView. - Delete
_activeRecordsand every App GUID-keyed live-object/component map. - Remove the detached
LiveEntityRecord(EntitySpawn)fixture constructor; component tests construct exact Runtime identities through a shared fixture. - Add source guards rejecting:
- App
Dictionary<uint, LiveEntityRecord>; - App live-object/component maps keyed by server GUID;
- an App reverse GUID/local-ID map;
- a projection store key other than
RuntimeEntityKey.
- App
6. Failure and parity gate
Exercise:
- create without materialization;
- same-incarnation refresh before and after materialization;
- factory throw before sidecar publication;
- resource register failure with successful and failed rollback;
- loaded/pending rebucket and visibility reentrancy;
- delete/recreate with the same GUID;
- local-ID wraparound and stale-key rejection;
- parent/pickup/Hidden transitions;
- session clear during every projection callback;
- retryable teardown with a live replacement.
Run:
- focused Runtime and App identity/projection tests;
- all App tests;
- Release solution build;
- complete Release tests;
- exact-binary connected lifecycle/reconnect;
- render-scene identity/digest referee at every checkpoint.
Acceptance
- Runtime owns the only GUID/incarnation/local-ID authority.
- Every materialized App owner is keyed by exact
RuntimeEntityKey. - App retains no GUID identity dictionary or reverse local-ID authority.
- A stale key cannot query, update, withdraw, or tear down a replacement.
- Local-ID allocation order is unchanged.
- No new allocation appears in steady-state live-object traversal.
- No callback is delayed to another frame.
- All automated and connected gates pass on the exact commit.
Completion result
All acceptance conditions pass on final exact binary e937cc36.
LiveEntityProjectionStoreis the only materialized App sidecar store and is keyed by exactRuntimeEntityKey.- The temporary
ActiveRecordView,_activeRecords, detached App record constructor, and broad materialized/visibleWorldEntitycollection surfaces are deleted. Borrowed exact-key record views remain for hot traversal and tests. - Hydration, animation, effects, lights, equipped children, remote teleport, render journal, liveness, movement observations, teardown, spatial residence, and visibility transitions carry the exact key.
GpuWorldStateretains the exact key through loaded/pending rebucketing, landblock retirement, origin recentering, quiescence, and reentrant visibility delivery. DAT-static entities remain outside live Runtime identity.- Runtime remains the only current-GUID/incarnation/local-ID authority. App resolves GUID through Runtime and never decides which incarnation is current.
- Synchronous callbacks, allocation order, render ordering, and frame timing are unchanged.
Evidence:
- 104 focused App ownership/streaming tests passed.
- 3,761 App tests passed / 3 skipped.
- 8,444 complete Release tests passed / 5 skipped.
- Release solution build passed.
logs/connected-world-gate-20260725-221008/report.jsonpassed on exact commite937cc36: two sessions, seven checkpoints, two graceful zero-code exits, zero failures, zero render-shadow mismatches, and zero pending deltas.
Exact rollback, newest commit first:
git revert e937cc36df39cf6ea1eaba2f9c0243d1929da702
git revert 420e5eea70fd2c29cf9c8614e6298a1f84d64045
J3.4 is the next clean slice. It moves canonical ClientObjectTable ownership
under the Runtime entity/object lifetime group without moving retained UI,
icons, paperdolls, grids, cooldown drawing, or interaction presentation.