diff --git a/docs/plans/2026-07-26-modern-runtime-slice-j8.md b/docs/plans/2026-07-26-modern-runtime-slice-j8.md index a4aadb35..576d82ad 100644 --- a/docs/plans/2026-07-26-modern-runtime-slice-j8.md +++ b/docs/plans/2026-07-26-modern-runtime-slice-j8.md @@ -54,6 +54,41 @@ It must not construct an App adapter, duplicate entity directory, duplicate object table, duplicate gameplay owner, second clock, second transit owner, or second session controller. +### Canonical per-generation reset contract + +The audit found one production seam that must land before the direct host can +prove reconnect honestly. `GameRuntime` owns every canonical per-session +child, but the graphical `LiveSessionResetManifest` currently invokes those +children one by one and interleaves them with App-only teardown. A no-window +host that copied that list would create a second lifecycle definition and +would not prove the Slice-K host can reuse the graphical runtime. + +J8 therefore adds one Runtime-owned, retryable generation-reset transaction. +The exact public contract has these phases: + +1. reset the root's canonical transit, communication, inventory, action, + character, movement, object-table, and other per-generation state in the + existing accepted order; +2. call `RuntimeEntityObjectLifetime.BeginSessionClear()` exactly once and + expose the returned exact-incarnation retirement set to one borrowed host + retirement boundary; +3. let the graphical host retire App render/physics/animation projections and + drain their queued removals, while the no-window host immediately retires + the same canonical records without constructing projections; +4. require `CompleteSessionClearIfConverged()` before clearing the canonical + player identity and permitting a new generation; +5. retain every incomplete suffix after callback failure so the same reset can + be retried without replaying a completed retirement. + +The host boundary acknowledges projection retirement only. It owns no +canonical dictionary, reset cursor, generation number, or cleanup order. +App-only mouse capture, retained UI, camera, particle visibility, renderer, +audio, input, and diagnostics remain outside the Runtime transaction. The +graphical `LiveSessionResetManifest` invokes the Runtime transaction at its +existing projection-safe point; `NoWindowGameRuntimeHost` invokes that same +transaction with an immediate canonical-only acknowledgement. There is no +test-only production injection API and no alternate reset manifest. + The host applies already-decoded deterministic packets through the same Runtime owner APIs that the graphical session route uses. Core.Net parser correctness remains covered by Core.Net wire fixtures; J8 verifies ownership, ordering, @@ -104,6 +139,13 @@ increasing within a generation and restart only when the generation changes. ### J8.1 — one direct root host +- Add the Runtime-owned generation-reset transaction and its narrow borrowed + host-retirement acknowledgement. +- Replace the child-by-child canonical portions of App's reset bindings with + that transaction while preserving every App-only stage and the current + projection-before-identity order. +- Prove first reset, callback-fault retry, duplicate reset, and populated-root + reconnect converge without replaying completed entity retirement. - Add a reusable test-only `NoWindowGameRuntimeHost`. - Move the existing J5 direct-host scenario onto `host.Runtime` rather than separately constructing six owners. @@ -114,8 +156,9 @@ increasing within a generation and restart only when the generation changes. - Prove the test assembly/process loads no App, UI, Silk.NET, OpenAL, Arch, ImGui, or renderer/audio/window type. -Gate: the direct root host constructs, captures a checkpoint, and converges -without a presentation assembly or duplicate owner. +Gate: graphical and no-window session reset use the same Runtime transaction; +the direct root host constructs, captures a checkpoint, resets a populated +generation, and converges without a presentation assembly or duplicate owner. ### J8.2 — deterministic transport/content lifecycle @@ -180,6 +223,10 @@ extracting gameplay again. - duplicate CreateObject and GUID reuse across reconnect; - observer throws during entity, inventory, chat, command, movement, or portal dispatch; +- generation reset fails before host retirement, during one projection + retirement, during the drain acknowledgement, and after canonical + convergence but before identity clear; +- reset retry does not replay an already retired canonical incarnation; - route creation succeeds but activation fails; - detach throws once, then succeeds; - portal cancellation before readiness, after readiness, and with each host