# 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.