docs(architecture): plan canonical soak snapshots
Define the deferred checkpoint acknowledgement, post-diagnostics frame phase, exact nine-stop artifact schema, canonical owner gates, and unchanged process-residency guard for Checkpoint K. Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
parent
31e6e192b3
commit
2862622ba2
2 changed files with 198 additions and 1 deletions
|
|
@ -0,0 +1,196 @@
|
|||
# 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 <name>` 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.
|
||||
|
|
@ -36,7 +36,8 @@ audit.
|
|||
owner and prove all partial-load/reentrant/retry paths. Detailed plan:
|
||||
[`2026-07-22-gamewindow-slice-8-checkpoint-j-lifetime-shutdown.md`](2026-07-22-gamewindow-slice-8-checkpoint-j-lifetime-shutdown.md).
|
||||
- [ ] K — in a separate #232 commit, add canonical owner snapshots to every soak
|
||||
checkpoint without weakening the process-memory guard.
|
||||
checkpoint without weakening the process-memory guard. Detailed plan:
|
||||
[`2026-07-22-gamewindow-slice-8-checkpoint-k-canonical-soak.md`](2026-07-22-gamewindow-slice-8-checkpoint-k-canonical-soak.md).
|
||||
- [ ] L — corrected-diff reviews, focused and full Release gates, connected
|
||||
lifecycle/soak, framebuffer comparison, documentation, memory, and final
|
||||
visual handoff.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue