Record the exact f46ddb5c rollback, 8,441-test Release gate, and seven-checkpoint connected lifecycle/reconnect pass. Update the canonical project state and pin J3.3's exact-key App projection-store execution plan.
Co-authored-by: Codex <codex@openai.com>
133 lines
5.5 KiB
Markdown
133 lines
5.5 KiB
Markdown
# Modern runtime J3.3 — exact-key App projection store
|
|
|
|
**Status:** READY AFTER J3.2 CONNECTED GATE
|
|
**Parent:** `2026-07-25-modern-runtime-slice-j3.md`
|
|
**Required base:** `f46ddb5cdb1e145752bea49aeb1d62bfe71284d3`
|
|
|
|
## 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.
|