docs(architecture): plan frame roots and terminal session start

Define the remaining ordered-startup cuts: complete session command/input ownership before frame publication, atomically publish the update/render pair, and make live-session Start the final operation.

Co-authored-by: Codex <codex@openai.com>
This commit is contained in:
Erik 2026-07-22 18:32:55 +02:00
parent 7771c07fb6
commit 7fa60971e2
2 changed files with 228 additions and 1 deletions

View file

@ -290,7 +290,9 @@ ledger only after the complete pipeline is live.
spawn-claim DAT range memo has a focused owner. `GameWindow.cs` is 2,479 raw
lines. App Release passes 3,420 tests / 3 skips; the complete Release suite
passes 7,792 tests / 5 skips with the same 17 warnings tracked by #228. I.8
frame-root publication and terminal session start is the active cut.
frame-root publication and terminal session start is the active cut. Its
detailed session-binding, atomic-root, and terminal-start plan is
[`2026-07-22-gamewindow-slice-8-checkpoint-i8-frame-roots-session-start.md`](2026-07-22-gamewindow-slice-8-checkpoint-i8-frame-roots-session-start.md).
Checkpoint I remains active until I.9 closes the complete nine-phase pipeline.
## 6. Automated acceptance

View file

@ -0,0 +1,225 @@
# GameWindow Slice 8 — Checkpoint I.8 Frame Roots and Session Start
**Status:** Active
**Parent:** `2026-07-22-gamewindow-slice-8-checkpoint-i-ordered-composition.md`
**Scope:** Complete Phase 7's session-facing owners, then implement ordered
composition Phases 8 and 9.
## 1. Outcome
Finish the production startup graph without changing accepted input, update,
render, network, portal, or UI behavior:
1. complete Phase 7 before any frame root is visible;
2. construct update and render roots locally and publish the pair atomically;
3. start the optional live session as the absolute final startup operation.
The current ordering defect is structural: `GameWindow.OnLoad` publishes the
frame pair before the combat/diagnostic command targets and sole gameplay input
subscriber are attached. I.8 moves those pre-frame owners into the Phase-7
result, so native callbacks can never observe an incomplete input/command
graph.
This is an ownership move. Retail algorithms and wire behavior remain
unchanged, so no divergence-register row is added.
## 2. I.8a — complete session/player composition
### 2.1 Focused session runtime factory
Add `LiveSessionRuntimeFactory` under `AcDream.App/Net`. It owns the existing
domain-specific construction of:
- `LiveSessionHostBindings`;
- reset manifest bindings;
- selection and entered-world callbacks;
- event and command routers;
- inventory, character, and social session bindings.
The factory receives focused owners and state slots, never `GameWindow` and
never a callback to a substantial window method. Move the existing reset and
router bodies verbatim. Preserve the exact reset order and the existing
retail citations around player-module identity/shortcut/component cleanup.
Add `DesiredComponentSnapshotState` beside `ShortcutSnapshotState` so session
routers mutate one focused state owner. `GameWindow.DesiredComponents` remains
an ABI-compatible read-only projection over that owner. Existing
`LocalPlayerIdentityState`, `LocalPlayerControllerSlot`, and
`ShortcutSnapshotState` remain canonical; no mirrored values are introduced.
### 2.2 Commands and sole gameplay subscriber
At the tail of `SessionPlayerCompositionPhase`, after player mode and teleport
exist but before result publication:
1. create `LiveSessionHost` through the focused factory;
2. create and bind `LiveCombatModeCommandController`;
3. create and bind `RuntimeDiagnosticCommandController`;
4. create `GameplayInputCommandController` and priority targets;
5. create and attach the sole `GameplayInputActionRouter`.
Add exact-owner `BindOwned` tokens to the combat and diagnostic command slots.
The existing gameplay router already owns both subscriptions transactionally;
Phase 7 scope-owns it immediately after construction and before `Attach`.
Extend `SessionPlayerResult` and its publication seam with the exact
`LiveSessionHost`, command owners, and optional gameplay router. Publication
rejects replacement before changing any field. Failure before publication
disposes the router, detaches command targets, and rolls back the existing
Phase-7 suffix in reverse order.
## 3. I.8b — atomic frame-root composition
Add `FrameRootCompositionPhase` implementing the existing
`IFrameRootCompositionPhase` contract. Its dependencies are focused App owners;
prior phase results supply all resources created during startup.
Preserve the exact current construction order:
1. teleport/login/GL-state and render-live preparation;
2. render resource begin/clear/live phases;
3. weather, sky-PES, world environment, camera, visibility, settings preview,
root, animated-object, and building sources;
4. terrain, PView, scene-pass, and world-scene diagnostics;
5. optional lifecycle automation;
6. retained/devtools/private presentation;
7. render orchestrator;
8. live-frame coordinator, camera frame, and update orchestrator;
9. atomic update/render pair publication as the final Phase-8 action.
Add `GameFrameGraphSlot.PublishOwned`. Its lease withdraws only the exact pair
it published, is idempotent, and cannot withdraw a later replacement. Scope-own
the lease immediately. A failure before publication leaves the slot empty; a
failure after publication withdraws the exact pair unless result publication
has transferred lifetime to the window shutdown owner.
### 3.1 Automation and resource snapshots
Add `WorldLifecycleResourceSnapshotSource` now rather than retaining
`CaptureWorldLifecycleResourceSnapshot` on the window. It samples the same
canonical world, live-runtime, effect, particle, light, script, mesh, texture,
GPU-memory, managed-memory, render-diagnostic, and frame-profiler owners.
This advances the owner-extraction portion of Checkpoint K; K still changes
checkpoint timing, acknowledgement barriers, JSONL validation, and soak
comparison. No checkpoint semantics change in I.8.
`FrameRootRuntimeBindings` owns the optional automation late binding and any
other Phase-8 external edge. It uses reverse, retryable, no-replay cleanup.
Shutdown withdraws the frame graph first, then detaches these frame-owned
bindings before borrowed session/presentation owners retire.
### 3.2 Publication
`FrameRootResult` contains:
- exact update and render roots;
- optional lifecycle automation owner;
- Phase-8 runtime bindings;
- the `LiveSessionHost` borrowed from Phase 7 for terminal start.
`IGameWindowFrameRootPublication` stores only owners needed by steady-state or
shutdown. Replacement is rejected atomically.
## 4. I.8c — terminal start and window cutover
Add `SessionStartCompositionPhase` implementing
`ISessionStartCompositionPhase<FrameRootResult>`. It invokes only
`LiveSessionHost.Start(RuntimeOptions)` and preserves the existing diagnostics
for missing credentials and failed startup.
`GameWindow.OnLoad` ends with:
```text
Phase 7 Compose
Phase 8 Compose and atomic pair publication
Phase 9 Start
return
```
There is no callback attachment, binding, publication, diagnostics setup, or
other work after Phase 9. Delete the old inline frame construction, session
factory/reset/router methods, snapshot method, and terminal status switch.
The existing typed nine-phase `GameWindowCompositionPipeline` remains the
executable order/failure oracle. Production `OnLoad` uses the same phase
interfaces and result chain explicitly because later-phase dependency records
are assembled from earlier concrete results; it must not introduce a retained
mega-context, service locator, or delegate façade around `GameWindow`.
## 5. Ownership and rollback order
Before frame publication, Phase-7 rollback is:
1. gameplay router detach;
2. diagnostic and combat command unbind;
3. remaining session/player bindings;
4. teleport, live session, and streamer teardown.
After frame publication, Phase-8 rollback is:
1. exact frame-pair withdrawal;
2. automation/other frame binding detach;
3. no disposal of resources borrowed from earlier successful phases.
Normal shutdown retains the frozen barrier order:
1. logical input/command quiescence;
2. live-session convergence;
3. physical input callback detach;
4. frame-pair withdrawal;
5. frame then session/player late-binding detach;
6. remaining session, live-entity, effect, render, content, GL, and native
owners.
## 6. Automated gates
### Session/runtime
- exact live-session host construction and reset trace;
- no `GameWindow` field or delegate capture in the focused factory;
- exact-owner combat/diagnostic bind, competing-owner rejection, idempotent
release, and rebind;
- gameplay router attaches before frame publication and rolls back from either
partial subscription;
- failed Phase-7 publication leaves no command/input/session target behind.
### Frame roots
- exact render/update leaf construction order;
- frame slot is empty at every pre-publication fault;
- exact pair publishes once and both native callbacks see the same generation;
- rollback withdraws only the published pair and never a later replacement;
- automation disabled path acquires nothing;
- automation enabled path binds once, detaches exactly, and samples the same
resource values as the former window method;
- frame result publication rejects replacement atomically.
### Terminal start and structure
- terminal start runs only after frame publication and every input/command
attachment;
- missing credentials and failed starts preserve current diagnostics;
- no operation follows `Start`;
- `GameWindow` contains no live-session binding factory, frame-root
construction body, resource-snapshot algorithm, or direct frame-pair
publication;
- no backend dependency enters Core and panels remain on UI abstractions;
- App Release tests, clean solution Release build, and complete Release suite
pass;
- behavior/order, architecture/ownership, and adversarial failure reviews are
clean.
## 7. Commit sequence
1. `docs(architecture): plan frame roots and terminal session start`
2. `refactor(app): complete session startup composition`
3. `refactor(app): compose atomic frame roots`
4. `refactor(app): make session start terminal`
Each implementation commit is independently buildable and preserves the
protected pre-existing `TransitionTypes.cs`, `.test-out/`, and `logs/` changes.
I.9 performs the complete Checkpoint-I corrected-diff review and documentation
closeout after these cuts land.