docs(runtime): close J3.2 canonical identity gate

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>
This commit is contained in:
Erik 2026-07-25 20:14:29 +02:00
parent f46ddb5cdb
commit e18df84437
8 changed files with 306 additions and 8 deletions

View file

@ -1682,8 +1682,13 @@ port in any phase — no separate listing here.
> and retryable teardown into Runtime at `75930787`. Its 79 Runtime tests,
> 3,776 App tests / 3 skips, 8,428-test / 5-skip complete Release suite, and
> exact-binary seven-checkpoint gate pass with graceful exits and zero render-
> shadow mismatches. J3 canonical identity, properties, and object-table
> extraction is now active.
> shadow mismatches. J3.1 moved accepted timestamp/snapshot and parent state.
> J3.2 at `f46ddb5c` now gives Runtime the only canonical GUID/incarnation,
> tombstone, local-ID/reverse, accepted-wire, parent, and operation-version
> maps. Its 110 Runtime tests, 3,758 App tests / 3 skips, 8,441-test / 5-skip
> complete Release suite, and exact-binary seven-checkpoint connected gate pass
> with graceful exits and zero render-shadow mismatch. J3.3 exact-key App
> projection storage is next.
> The historical exact cutover
> rollback remains
> `git revert ef1d263337997bb030eadb7b8e71d73dc659907a`. Slice H is complete:

View file

@ -156,13 +156,21 @@ residency is `0/0/0` at every stable checkpoint and teardown converges. Slice I
gracefully. J2 moved canonical session/transport lifetime and ordered
inbound routing into Runtime at `75930787`; 79 Runtime tests, 3,776 App
tests / 3 skips, 8,428 full Release tests / 5 skips, and its exact-binary
seven-checkpoint gate pass with graceful exits. J3 canonical identity,
properties, and object-table extraction is active under
seven-checkpoint gate pass with graceful exits. J3.1 moved accepted physics
timestamp/snapshot and parent-relation state into Runtime. J3.2 at
`f46ddb5c` now owns the only canonical GUID/incarnation, tombstone,
local-ID/reverse, accepted-wire, parent, and operation-version maps in
Runtime. Its 110 Runtime tests, 3,758 App tests / 3 skips, 8,441 full Release
tests / 5 skips, and exact-binary seven-checkpoint connected gate pass with
graceful exits and zero render-shadow mismatch. J3.3 exact-key App projection
storage is next under
[`2026-07-25-modern-runtime-slice-j.md`](2026-07-25-modern-runtime-slice-j.md).
Slice-I closeout evidence is
[`../research/2026-07-25-slice-i7-closeout.md`](../research/2026-07-25-slice-i7-closeout.md).
Slice-J2 closeout evidence is
[`../research/2026-07-25-slice-j2-session-lifetime-closeout.md`](../research/2026-07-25-slice-j2-session-lifetime-closeout.md).
Slice-J3.2 closeout evidence is
[`../research/2026-07-25-slice-j3-2-canonical-entity-directory-closeout.md`](../research/2026-07-25-slice-j3-2-canonical-entity-directory-closeout.md).
The historical exact G4 visual rollback remains
`git revert ef1d263337997bb030eadb7b8e71d73dc659907a`.

View file

@ -0,0 +1,133 @@
# 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.

View file

@ -5,6 +5,25 @@
**Production base:** `9496c01b`
**J2 production commit:** `75930787741db40a83eab8663e4464dce8d687ba`
## 0. Current checkpoint
| Slice | Status | Commit / evidence |
|---|---|---|
| J3.0 ownership inventory | complete | `b0fecc5f65ed26042c61a1651fb134aeb432c141`; `docs/research/2026-07-25-slice-j3-entity-ownership-inventory.md` |
| J3.1 accepted-wire owners | complete | `f7442d13e9ae7d5b077ffecb1f8a10899ad46edd`; 110 Runtime tests and complete Release parity remain green after J3.2 |
| J3.2 canonical Runtime entity directory | complete | `f46ddb5cdb1e145752bea49aeb1d62bfe71284d3`; 8,441 Release tests / 5 skips and `logs/connected-world-gate-20260725-200749/report.json` pass |
| J3.3 App projection store | next | [`2026-07-25-modern-runtime-slice-j3-projection-store.md`](2026-07-25-modern-runtime-slice-j3-projection-store.md): key every graphical sidecar/workset by `RuntimeEntityKey` and remove the compatibility view |
J3.2 passes the Release solution build and 8,441 complete tests with five
expected skips. Its exact-binary seven-checkpoint connected
lifecycle/reconnect route also passes with graceful exits, zero render-shadow
mismatches, and zero pending deltas. It adds no frame queue, backend
dependency, or gameplay behavior change. The exact rollback for J3.2 is:
```text
git revert f46ddb5cdb1e145752bea49aeb1d62bfe71284d3
```
## 1. Objective
Move the one canonical server-object identity/incarnation owner, accepted
@ -263,3 +282,12 @@ git revert b632672e5ccabfb44c551e08f1c411ab2669c44a
These are J2, J1, and J0 respectively. Do not use them for a J3 sub-slice
failure; record and revert only the exact failing J3 commit.
J3 sub-slices are independently reversible:
```text
git revert f46ddb5cdb1e145752bea49aeb1d62bfe71284d3
git revert f7442d13e9ae7d5b077ffecb1f8a10899ad46edd
```
Revert J3.2 before J3.1 when rolling back both.

View file

@ -0,0 +1,79 @@
# Modern runtime J3.2 canonical entity directory closeout
## Result
J3.2 is complete at production commit
`f46ddb5cdb1e145752bea49aeb1d62bfe71284d3`.
`AcDream.Runtime.Entities.RuntimeEntityDirectory` now owns the only:
- active server-GUID to exact-incarnation map;
- exact-incarnation teardown tombstone map;
- Runtime local-ID allocation and reverse lookup;
- accepted inbound snapshot/timestamp owner;
- parent-relation owner;
- session lifetime epoch and per-GUID operation versions.
`RuntimeEntityRecord` owns the presentation-free canonical spawn, `INSTANCE_TS`,
cell/state authority, retail object clock, authority versions, and the
PhysicsBody/physics-host facts deliberately carried until J5.
App's `LiveEntityRecord` is now a graphical sidecar over that canonical record.
Its temporary dictionary-shaped `ActiveRecordView` stores no GUID map: it asks
Runtime for the current canonical record and resolves the sidecar by record
reference. J3.3 replaces that compatibility seam with an exact
`RuntimeEntityKey` projection store.
No renderer, UI, Silk.NET, ImGui, OpenAL, or App type entered Runtime. No
asynchronous queue or input-frame delay was added.
## Automated acceptance
At the production commit:
- Runtime tests: 110 passed;
- App tests: 3,758 passed / 3 skipped;
- complete Release solution: 8,441 passed / 5 skipped;
- Release solution build: pass.
Coverage includes active-incarnation uniqueness, exact old-generation
tombstones, local-ID wrap/reverse lookup, stale identity release, session epoch
replacement, accepted snapshot authority, separate delete/teardown edges,
resource registration rollback, reentrant clear/delete, GUID reuse, and source
guards that reject presentation/backend state on the canonical record.
## Connected lifecycle acceptance
Raw evidence:
`logs/connected-world-gate-20260725-200749/report.json`.
Result: PASS on the exact production commit.
- Capped process: login, Aerlinthe, Rynthid, Facility Hub, Holtburg after the
dungeon, and Aerlinthe revisit all completed.
- Fresh uncapped process: reconnect completed.
- Seven of seven checkpoints passed.
- Both processes exited gracefully with exit code zero.
- Every checkpoint reported zero render-shadow mismatches and zero pending
render deltas.
- No gate failure was recorded.
- The only warning was 25 expected world-edge landblock misses.
This proves that moving identity, incarnation, tombstone, accepted-wire, and
local-ID ownership into Runtime preserved connected object creation,
same-location revisit, dungeon/outdoor replacement, packet routing, rendering,
and graceful teardown on the exact binary.
## Exact rollback
```text
git revert f46ddb5cdb1e145752bea49aeb1d62bfe71284d3
```
J3.1 remains independently reversible with:
```text
git revert f7442d13e9ae7d5b077ffecb1f8a10899ad46edd
```
When reverting both, revert J3.2 before J3.1.

View file

@ -8,6 +8,31 @@ The accepted J2 binary passes 8,428 Release tests with five skips and the
seven-checkpoint connected lifecycle/reconnect gate at
`logs/connected-world-gate-20260725-193936/report.json`.
## J3.2 ownership checkpoint
Commit `f46ddb5cdb1e145752bea49aeb1d62bfe71284d3` implements the first
canonical split:
- `RuntimeEntityDirectory` owns the only active GUID map, exact-incarnation
tombstones, reverse local-ID map, session lifetime epoch, per-GUID operation
versions, accepted inbound snapshot owner, and parent-relation owner;
- `RuntimeEntityRecord` owns the presentation-free canonical snapshot,
`INSTANCE_TS`, authoritative cell/state/timestamp versions, object clock,
PhysicsBody/physics-host facts carried for J5, and Runtime-issued local ID;
- App's `LiveEntityRecord` is now a projection sidecar around that canonical
record;
- the temporary `ActiveRecordView` is dictionary-shaped only to preserve the
large synchronous App call surface during J3.2. It stores no GUID map and
resolves every lookup through `RuntimeEntityDirectory`; J3.3 deletes it;
- Runtime-only ownership/lifetime tests and App source guards protect the
boundary.
The checkpoint passes 110 Runtime tests, 3,758 App tests with three skips, and
8,441 complete Release tests with five skips. Its exact-binary connected gate
also passes all seven checkpoints with graceful exits, zero render-shadow
mismatches, and zero pending deltas:
`logs/connected-world-gate-20260725-200749/report.json`.
At this baseline:
- `LiveEntityRuntime.cs` is 2,866 lines and is referenced by roughly 100 App