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>
180 lines
7.6 KiB
Markdown
180 lines
7.6 KiB
Markdown
# 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:
|
|
|
|
1. **Canonical-only registration** — Runtime accepted an incarnation, but no
|
|
graphical host has claimed a local ID. No materialized projection exists.
|
|
2. **Materialized projection** — Runtime has claimed the local ID and App owns
|
|
exactly one sidecar under the resulting `RuntimeEntityKey`.
|
|
3. **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 `RuntimeEntityDirectory` for 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
|
|
|
|
- `RegisterLiveEntity` returns canonical registration facts without allocating
|
|
a graphical sidecar.
|
|
- `MaterializeLiveEntity` claims 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 `WorldEntity` projections;
|
|
- 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 `_activeRecords` and 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`.
|
|
|
|
### 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`.
|
|
|
|
- `LiveEntityProjectionStore` is the only materialized App sidecar store and is
|
|
keyed by exact `RuntimeEntityKey`.
|
|
- The temporary `ActiveRecordView`, `_activeRecords`, detached App record
|
|
constructor, and broad materialized/visible `WorldEntity` collection
|
|
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.
|
|
- `GpuWorldState` retains 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.json` passed on exact commit
|
|
`e937cc36`: two sessions, seven checkpoints, two graceful zero-code exits,
|
|
zero failures, zero render-shadow mismatches, and zero pending deltas.
|
|
|
|
Exact rollback, newest commit first:
|
|
|
|
```text
|
|
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.
|