acdream/docs/research/2026-07-26-slice-j3-4-canonical-object-lifetime.md

112 lines
4 KiB
Markdown

# Slice J3.4 closeout — canonical entity/object lifetime
## Outcome
J3.4 is complete at:
```text
5ef8b5371d8990f0380acd939e71cd711289d429
```
`AcDream.Runtime.Entities.RuntimeEntityObjectLifetime` is now the one
presentation-free owner of the live session's:
- canonical `RuntimeEntityDirectory`; and
- canonical `ClientObjectTable`.
The graphical host, session router, retained UI, inventory interaction,
paperdoll, magic, cooldown, and diagnostic owners borrow those exact
instances. `GameWindow` no longer allocates or publicly owns a live object
table, and `LiveEntityRuntime` no longer allocates its own entity directory.
## Transaction boundary
CreateObject and DeleteObject retain the established retail-facing synchronous
order.
For an accepted create:
1. Runtime accepts or refreshes the exact canonical incarnation.
2. The Runtime lifetime group applies the retained-object mutation.
3. The group revalidates the exact canonical record and
`CreateIntegrationVersion` before, during, and after callbacks.
4. App continues graphical hydration only while the same acceptance remains
current.
For an authoritative delete:
1. Runtime issues one exact `RuntimeEntityDeleteAcceptance`.
2. The active canonical identity is retired.
3. The acceptance commits retained-object removal exactly once.
4. App completes the retryable graphical/resource teardown suffix.
The acceptance rejects replay and use by another Runtime instance.
## Important lifecycle distinction
An authoritative server delete and an offscreen/dormant prune are not the same
operation.
- Authoritative DeleteObject removes the retained `ClientObject`.
- Dormant liveness pruning withdraws the graphical/live projection but keeps
retained object information.
A focused regression test exposed an early implementation that deleted object
information during every unregister. The final implementation carries an
explicit `removeRetainedObject` decision and keeps freshness authority in
Runtime. This preserves existing behavior without a timing guard or retry
workaround.
## Architecture checks
- Runtime can construct the lifetime group without App, UI, Silk, OpenAL,
Arch, or ImGui.
- Two Runtime groups can own conflicting GUIDs and objects independently.
- Production App source guards reject `new ClientObjectTable()` and
`new RuntimeEntityDirectory()`.
- Studio/sample-data tables remain independent fixture owners.
- There is no copied inventory model, asynchronous seam, extra input frame, or
backend dependency in Runtime.
- Session reset clears the Runtime-owned object table before graphical
projection teardown, matching the established retryable manifest order.
## Verification
Final automated results:
- Runtime tests: 118 passed;
- Core `ClientObjectTable` focus: 86 passed;
- Core `ObjectTableWiring` focus: 6 passed;
- inventory/item/paperdoll/magic/cooldown/runtime-adapter focus: 273 passed;
- hydration/runtime/reset/composition focus: 172 passed;
- App tests: 3,762 passed / 3 skipped;
- complete Release solution: 8,453 passed / 5 skipped;
- Release build: pass, with only the 17 pre-existing Core warnings.
Exact-binary connected evidence:
```text
logs/connected-world-gate-20260726-055713/report.json
```
The route used two sessions and seven checkpoints. Both processes exited
gracefully with code zero. It reported zero failures, zero render-scene shadow
mismatches, zero pending deltas, zero pending live teardown, and zero pending
retirement/publication/upload work. The only warning was the route's expected
25 world-edge landblock misses.
## Rollback
```text
git revert 5ef8b5371d8990f0380acd939e71cd711289d429
```
Do not revert J3.3 as a shortcut for a J3.4 failure.
## Next boundary
J3.5 publishes one monotonic, per-session entity/object delta stream from
committed Runtime state. Both direct/no-window and graphical hosts must observe
the same sequence and borrow the same views. It must replace the current App
event reconstruction without adding a second queue, copied world, or frame of
latency.