# GameWindow Slice 8 Checkpoint K — canonical soak snapshots **Status:** Active 2026-07-22. **Parent:** [`2026-07-22-gamewindow-slice-8-composition-lifecycle.md`](2026-07-22-gamewindow-slice-8-composition-lifecycle.md), Checkpoint K. **Integrated baseline:** `31e6e192`; Checkpoints I–J are complete, `GameWindow.cs` is 1,625 raw lines, App Release passes 3,441 tests / 3 skips, and the complete Release suite passes 7,813 tests / 5 skips. **Issue:** [`#232`](../ISSUES.md#232--nine-stop-soak-process-memory-gate-lacks-canonical-owner-snapshots). **Behavior rule:** this checkpoint changes diagnostic capture and connected-gate evidence only. It does not change rendering, streaming, gameplay, resource budgets, or the existing process working/private-memory thresholds. ## 1. Outcome Make every scripted `checkpoint ` a deferred, acknowledged render-frame barrier. A checkpoint is written only after private presentation and the normal render diagnostics phase have both observed the same immutable `RenderFrameOutcome`. Its JSON contains the canonical world/reveal/resource owner snapshot and that exact frame outcome. The script cannot execute the next command until serialization and both writes succeed, fail, or are explicitly cancelled during shutdown. The nine-stop soak then consumes exactly nine ordered checkpoints, gates canonical owner stability at the Caul return → Caul plateau same-location pair, labels server-controlled entity/animation population changes as workload warnings, and retains process residency as an unchanged secondary guard. ## 2. Runtime contract ### 2.1 Acknowledgement token Replace the synchronous automation method with a request contract equivalent to: ```csharp enum RetailUiAutomationCheckpointStatus { Pending, Succeeded, Failed, Cancelled, } interface IRetailUiAutomationCheckpoint { RetailUiAutomationCheckpointStatus Status { get; } string? Error { get; } } bool TryRequestCheckpoint( string name, out IRetailUiAutomationCheckpoint? checkpoint, out string error); ``` The production token also retains the assigned request sequence and validated name across the update → render edge. Only the controller can transition it, exactly once, from Pending to a terminal state. `RetailUiAutomationScriptRunner` stores one token together with the active command index. While Pending, repeated ticks return without enqueueing again or advancing the command. Success clears the token and advances once. Failure or cancellation clears it and stops on the token's exact error. Disposal still releases held input; runtime shutdown is responsible for cancelling queued tokens. ### 2.2 FIFO request owner `WorldLifecycleAutomationController` becomes the sole FIFO owner and an `IDisposable` frame-phase participant: - validation failure creates no request and consumes no sequence; - accepted requests receive one monotonic sequence and enter one FIFO; - a successful render drains accepted requests in order; - each request serializes one `WorldLifecycleCheckpoint` containing its sequence/name, current reveal state, the exact current `RenderFrameOutcome`, and one canonical resource snapshot; - Succeeded is published only after the JSONL append and named JSON write both complete; - capture/serialization/I/O failure marks only that request Failed with contextual sequence/name error and does not throw out of rendering; - shutdown marks every still-pending request Cancelled with an explicit error; - enqueue after shutdown fails synchronously and cannot create an orphan token. The controller is adopted by `FrameRootRuntimeBindings` separately from its retained-UI late binding, so the binding detaches and pending requests cancel under the existing retryable frame-root lifetime. ### 2.3 Post-diagnostics render phase Add a narrow `IRenderFramePostDiagnosticsPhase` with a no-op implementation. `RenderFrameOrchestrator` calls it exactly once after: 1. resource preparation; 2. world rendering; 3. private presentation and screenshots; 4. `IRenderFrameDiagnosticsPhase.Publish`; 5. then checkpoint drain; 6. finally the existing GPU-flight close. If an earlier render phase fails, post-diagnostics is not called and the FIFO remains pending for the next successful frame. An unexpected post-phase throw uses the existing render failure/recovery path, although production capture and I/O failures are represented on tokens rather than thrown. No previous-frame diagnostic value is paired with a current-frame owner snapshot: `WorldLifecycleResourceSnapshotSource.Capture(RenderFrameOutcome)` takes visible/total landblocks from the supplied outcome and reads the already- published aggregate FPS/frame-time snapshot only after diagnostics runs. ## 3. Artifact and soak schema `WorldLifecycleCheckpoint` adds the exact frame outcome. Existing reveal and resource fields retain their names. The route adds these nine commands in this order at the end of each settled destination block: 1. `caul-baseline` 2. `sawato-baseline` 3. `rynthid` 4. `aerlinthe` 5. `sawato-return` 6. `holtburg` 7. `caul-return` 8. `sawato-plateau` 9. `caul-plateau` `run-connected-r6-soak.ps1` reads the JSONL only after the route completes and requires one row for every expected name, exact sequence 1–9, exact order, and the current process id. It embeds those records in the report. Every checkpoint hard-gates zero: - pending live teardowns; - pending landblock retirements; - staged mesh uploads and bytes; - composite warmup work. The same-location Caul return → Caul plateau comparison requires exact equality for deterministic owner/cache counts and bytes: loaded/visible/total landblocks, materialized live owners, teardown/retirement queues, VFX binding/owner/script/ light counts, mesh render-data/atlas/estimated bytes, staged work, tracked GPU bytes/buffers/textures, and composite/particle texture ownership. Connected `WorldEntities`, `AnimatedEntities`, `LiveEntities`, particles, and active scripts may legitimately change with authoritative population or transient effects; those deltas remain named workload warnings, not silent exclusions. Managed used/committed deltas are reported diagnostically. Existing working/private-memory, update-p95, and allocation-p50 thresholds remain byte- for-byte unchanged as the secondary residency/performance guard. ## 4. Implementation sequence 1. Add token states and change the automation runtime/script runner to the one-token-per-command polling contract. Cover delayed success, repeated pending ticks, failure, cancellation, invalid request, and disposal while pending. 2. Refactor `WorldLifecycleAutomationController` into the FIFO request owner; pass the frame outcome into snapshot capture and write it into artifacts. Cover FIFO order, sequence stability, write failure, no duplicate drain, shutdown cancellation, and enqueue-after-dispose. 3. Add the post-diagnostics phase to `RenderFrameOrchestrator`, wire the controller through `FrameRootCompositionPhase`, and adopt its lifetime separately from the late UI binding. Pin exact phase order, skipped drain on prior failure, post-phase failure recovery, and partial-composition cleanup. 4. Add the nine route commands. Parse/validate JSONL in the soak, attach the canonical checkpoints to the report, add zero-work and same-location owner gates, and preserve the old process/performance formulas verbatim. 5. Run behavior/order, architecture/ownership, and adversarial failure review passes. Correct findings and re-run focused App tests, App Release, Release build, and the complete Release suite. 6. Run two fresh-process connected nine-stop routes before closing #232. Both must exit gracefully, produce exact ordered checkpoints, pass canonical owner/cache gates, and pass the unchanged process residency guard. 7. Reconcile architecture, roadmap, milestones, issues, AGENTS/CLAUDE, and durable memory; commit Checkpoint K as its own bisectable diagnostic unit. ## 5. Automated acceptance - one checkpoint command creates one request, one sequence, and one artifact; - a pending token blocks all later script commands without duplicate enqueue; - render failure delays rather than loses or duplicates the request; - diagnostics publication precedes same-frame capture; - independent accepted requests drain FIFO and retain name/sequence identity; - capture/write failure reaches the script as the exact failed-token error; - shutdown reaches pending scripts as explicit cancellation; - no controller/runtime reference points back to `GameWindow`; - all nine route names and sequences are exact and appear in the soak report; - canonical pending/staging/warmup work is zero at every checkpoint; - Caul return → plateau deterministic owners/caches are unchanged, while authoritative workload deltas are explicitly warned; - working/private-memory thresholds and update/allocation formulas are unchanged; - focused, App, and complete Release suites pass with no new warnings. No visual gate is required for K because it changes diagnostic observation only. Checkpoint L owns the final connected framebuffer and user visual gate.