acdream/docs/plans/2026-07-21-gamewindow-slice-6-update-frame-orchestration.md
Erik e91f310279 refactor(update): cut over the frame orchestrator
Reduce GameWindow.OnUpdate to one typed orchestration call and remove transitive window callbacks from teardown, liveness, teleport placement, live presentation, auto-entry, and entity packet routing. Preserve the frozen retail object/network order while making the production owner graph explicit and testable.
2026-07-22 03:31:38 +02:00

29 KiB

GameWindow Slice 6 — update-frame orchestration

Status: Active 2026-07-21. Parent program: docs/architecture/code-structure.md, Slice 6. Baseline: d4ecac1d; GameWindow.cs is 8,811 raw lines, 247 fields, and 153 methods. Release baseline: 7,054 passed / 5 skipped. The connected lifecycle gate and synchronized nine-stop resource soak both pass. Behavior rule: This is an ownership extraction. Preserve the accepted retail object/network order, asynchronous streaming-readiness adaptation, portal transit, input semantics, and camera presentation. A defect exposed by the boundary receives its own deterministic oracle and bisectable fix; it is never hidden behind a retry, delay, suppression flag, or reordered callback.

Progress ledger

  • A — freeze the complete production phase graph and introduce the typed orchestration contract plus structural/order guards.
  • B — extract the pre-network live-object presentation phase and the non-advancing post-network spatial reconciler; remove callbacks into GameWindow from RetailLiveFrameCoordinator.
  • C — extract streaming-origin convergence, observer selection, dungeon collapse, streaming tick, and rescued-entity rebucketing.
  • D — extract dispatcher/raw-mouse/combat input sampling without changing movement-command or UI-capture semantics.
  • E — extract the complete local-player teleport owner and wire it between the existing post-network liveness and player-mode auto-entry phases.
  • F — extract the shared player-mode lifecycle plus fly/chase/player camera presentation and cut production over to one UpdateFrameOrchestrator.
  • G — delete the old OnUpdate bodies, callback facades, and obsolete frame state; run focused corrected-diff reviews after each ownership edge.
  • H — full Release suite, connected lifecycle/reconnect gate, synchronized resource soak, documentation, durable memory, and line/field/method closeout.

Every checked checkpoint is committed as one bisectable architectural unit. Documentation records the exact commit and accepted test count as work lands.

Checkpoint A introduced the internal AcDream.App.Update contract, one typed UpdateFrameClock/IPhysicsScriptTimeSource, the twelve-phase outer-order oracle, exact teardown and invalid-delta tests, and guards against a transitive GameWindow clock capture. Production now publishes PES time once per update; 18 focused Release tests and the full 2,709-test App project pass, and all three corrected-diff reviews are clean.

Checkpoint B moved the complete local/ordinary/static/effect body into LiveObjectFrameController, made RetailLiveFrameCoordinator's object → inbound batch → command → spatial-reconcile barrier fully typed, and removed animation/runtime/projectile back-references to GameWindow. GameWindow.cs is now 8,716 raw lines. The corrected diff passes 239 focused Release tests, the 2,732-test App suite, and the full 7,090-test Release suite (5 fixture/environment skips); all three independent reviews are clean.

Checkpoint C moved retained origin convergence, readiness, observer selection, sealed-dungeon collapse, streaming publication, and persistent live-projection rescue into StreamingFrameController. Production keeps streaming publication ahead of input and the live object/network barrier, so a same-frame CreateObject can enter the newly resident bucket. The focused 146-test Release selection, 2,754-test App suite, and complete 7,112-test Release suite (5 fixture/environment skips) pass. Login-before-position, portal hold, outdoor and sealed/SeenOutside EnvCells, pending recenter, exact rescue rebucketing, GUID deletion, and session reset are pinned; all three corrected-diff reviews are clean. GameWindow.cs is now 8,569 raw lines.

Checkpoint D moved semantic hold delivery, movement sampling, autorun, instant mouse-look, cursor capture, raw filtering/idle handling, and combat intent into GameplayInputFrameController and focused typed owners. Devtools keyboard capture pauses all gameplay movement without clearing the autorun latch; retained chat suppresses held keys while autorun continues. Every focus, teleport, camera/player-mode, reset, and shutdown boundary now releases mouse-look through one lifecycle path and clears stale RMB orbit state. Production combat requests, automatic hostile selection, UI-capture probes, and movement-truth diagnostics no longer retain callbacks into GameWindow. The 2,787-test App suite and complete 7,145-test Release suite pass (5 fixture/environment skips); all three corrected-diff reviews are clean. GameWindow.cs is now 8,205 raw lines.

1. Outcome and non-goals

At slice exit, GameWindow.OnUpdate starts the profiler scope and delegates one host delta to UpdateFrameOrchestrator. GameWindow composes concrete owners; it no longer selects a streaming observer, advances animations/effects, samples raw mouse input, sequences inbound network traffic, advances portal transit, or updates gameplay cameras.

The owner graph is explicit rather than a list of anonymous callbacks:

UpdateFrameOrchestrator
  ├── live teardown convergence           retry retained tombstones
  ├── UpdateFrameClock                    normalized host time / PES clock
  ├── StreamingFrameController            residence/readiness pre-pass
  ├── GameplayInputFrameController        semantic input + mouse/combat intent
  ├── RetailLiveFrameCoordinator          retail SmartBox object barrier
  │     ├── LiveObjectFrameController     local/ordinary/static/effect tails
  │     ├── LiveSessionController         inbound network drain
  │     ├── RetailLocalPlayerFrame        CommandInterpreter position tail
  │     └── LiveSpatialReconciler         non-advancing authoritative refresh
  ├── LiveEntityLivenessController        expiry after accepted inbound state
  ├── LocalPlayerTeleportController       local transit/reveal/tunnel state
  ├── PlayerModeAutoEntry                 one-shot ready-world entry
  ├── PlayerModeController                enter/exit/current-player lifetime
  └── CameraFrameController               fly/chase/player presentation

Concrete names may be narrowed during checkpoint A's source audit, but the ownership boundaries and order do not change. The orchestrator receives a small immutable per-frame input and concrete phase owners. It does not receive a hundred delegates, one mega IUpdateFrameServices context, or a service locator, and no transitive update collaborator calls a substantial method back on GameWindow.

This slice does not change simulation rate, object quantum rules, movement speed, interpolation, streaming radii, reveal readiness, portal visuals, particle range, combat cadence, key bindings, camera formulas, render order, or shutdown order. It adds no GL work and does not move retained-UI timers out of their render seam. Slice 7 owns the draw graph; Slice 8 owns final composition and Silk callback cleanup.

2. Retail oracle and accepted adaptation

The object/network barrier is pinned by 2026-07-19-r6-update-object-order-pseudocode.md:

  • CPhysicsObj::update_object @ 0x00515D10 applies the strict object quantum;
  • CPhysicsObj::UpdatePositionInternal @ 0x00512C30 advances the PartArray, position/physics candidate, then processes semantic hooks;
  • CPhysicsObj::UpdateObjectInternal @ 0x005156B0 runs Detection → Target → Movement → CPartArray::HandleMovement → Position → Particle → Script;
  • SmartBox::UseTime @ 0x00455410 advances object/physics time before the inbound queue and then calls CommandInterpreter::UseTime;
  • gmSmartBoxUI::UseTime @ 0x004D6E30 owns UI/viewport time outside that object barrier.

At the retail host level, Client::UseTime @ 0x00411C40 calls UIElementManager::UseTime before SmartBox::UseTime; the UI time broadcast reaches gmSmartBoxUI::UseTime. Retail also publishes player-camera work from the physics/player callback rather than from one post-network camera tail. acdream currently advances teleport/UI-camera presentation after its object/network/command barrier. Slice 6 preserves that existing order as registered TS-53; it does not cite gmSmartBoxUI as proof that the current post-network placement is retail-exact.

acdream preserves two documented presentation adaptations:

  1. only semantic AnimationDone executes at retail's in-object hook slot; every other captured animation hook retains the current deferred path after final root, part, and equipped-child poses are published, including particles, audio, lights, translucency, CallPES, and default-script chaining (TS-50);
  2. shared particle simulation and PhysicsScript queues tick once per host update after both worksets rather than once per object's admitted quantum. This also means the current shared Particle → Script order does not reproduce the static workset's retail Script → Particle → hooks order (TS-51).

Asynchronous landblock streaming has no one-call retail equivalent. Its convergence pre-pass remains before inbound CreateObject dispatch so a newly accepted projection can find a resident bucket in the same frame. This pre-pass does not advance an object's retail clock. WorldRevealCoordinator remains the single login/portal readiness owner.

3. Fixed production phase order

The complete host-update graph is frozen as follows:

  1. retry canonical live-entity teardown tombstones; an AggregateException is logged and later phases continue, while any other exception propagates;
  2. normalize the host delta, advance the shared PES clock once, and publish it;
  3. advance pending origin retirement/recenter, select the observer, tick streaming, and rebucket rescued persistent entities;
  4. tick InputDispatcher, consume one raw mouse sample, and advance combat attack intent;
  5. enter the non-reentrant inbound-event envelope and advance the pre-network live-object phase:
    • local object and pre-network movement/jump output;
    • queued selection/use output after movement edges;
    • ordinary live objects;
    • the distinct static-animation workset;
    • equipped children and static hook completion;
    • fades, every deferred non-AnimationDone hook, and current effect/light anchors;
    • particle visibility and particle simulation;
    • PhysicsScript queues;
  6. drain inbound session traffic inside one GpuWorldState.MutationBatch;
  7. run the local player's post-network CommandInterpreter position check;
  8. perform the ordinary post-network non-advancing root/child/emitter/light reconcile;
  9. advance liveness expiry from the absolute client timer;
  10. activate/tick local teleport transit. A Place edge commits the player and live root, immediately performs its own non-advancing reconcile, then notifies world reveal and continues tunnel state;
  11. evaluate one-shot player-mode auto-entry;
  12. update fly or chase/player camera presentation. If the local player was first created by this frame's inbound pass, publish its non-advancing projection, immediately reconcile a second time, then update the camera.

Those three reconcile edges—ordinary post-network, teleport Place, and inbound-created-player projection—are separate accepted production edges. Any future consolidation is a behavior change with its own oracle, not part of this extraction.

An invalid/non-positive host delta becomes zero for the PES/object/particle/ tunnel delta but never blocks inbound traffic, absolute-time liveness, recenter convergence, or camera-state publication. Raw mouse idle uses its independent monotonic input clock. A missing gameplay camera/input owner never suppresses outer phases; the streaming controller may skip observer-driven streaming when it has no valid live or offline observer, while origin retirement still advances. Devtools keyboard capture pauses player/camera control including autorun; retained chat capture suppresses held WASD while autorun continues; mouse capture ends mouse-look but does not suppress keyboard, combat, network, streaming, teleport, or teardown.

4. Architecture and interfaces

4.1 Per-frame input

Use an immutable value equivalent to:

public readonly record struct UpdateFrameInput(double HostDeltaSeconds);

Derived facts are read by their owning controller from stable runtime owners or from a narrowly typed state source. Do not pass GameWindow, expose its private fields wholesale, or create a service locator. Mutable player/session owners that legitimately change during login are represented by one focused state/source interface per domain, not anonymous closures into window methods.

UpdateFrameClock is constructed before any materializer/network owner that needs the current PES time. It owns the normalized host/PES clock and exposes a narrow CurrentScriptTime source; _physicsScriptGameTime does not remain a GameWindow field captured by later owners. Absolute liveness time and raw mouse idle time remain distinct monotonic sources and are not derived from the normalized simulation delta.

4.2 Object phase

LiveObjectFrameController owns the body currently in AdvanceLiveObjectRuntimeCore. It composes existing focused owners and keeps their retail order; it does not absorb their algorithms or identity maps. LiveSpatialPresentationReconciler owns the current no-time refresh body. RetailLiveFrameCoordinator depends on those typed owners plus the existing session and local-player owners. Its public Tick remains the one explicit object → network → command → reconcile barrier.

RetailInboundEventDispatcher continues wrapping the complete object phase. Reentrant packets queue until the current object's manager tail completes. The hot path remains allocation-free after warmup.

The extraction inventory includes the complete transitive update graph, not only RetailLiveFrameCoordinator: RetailLocalPlayerFrameController loses substantial window captures in favor of a focused local-player slot, movement input source, outbound owner, and projection owner; LiveEntityAnimationPresenter receives a concrete animation-presentation context instead of retaining GameWindow as ILiveAnimationPresentationContext; scheduler clock/player/projectile sources are similarly narrow. Existing small value/policy callbacks are acceptable only when they do not call a substantial body back on the window or create a second identity/state owner.

4.3 Streaming phase

StreamingFrameController owns observer selection and the sealed-dungeon gate. It receives the existing StreamingOriginRecenterCoordinator, StreamingController, LiveWorldOriginState/center state, camera/player state, physics current cell, GpuWorldState, and LiveEntityRuntime through typed seams. It never builds, publishes, or retires a landblock; those remain Slice 5 owners.

The controller preserves:

  • no pre-login hardcoded-Holtburg streaming;
  • real-player-origin readiness before first streaming;
  • destination-origin pinning while in portal space;
  • authoritative player landblock during the login hold;
  • offline fly-camera observation only outside live in-world mode;
  • sealed EnvCell collapse using the cell's own landblock identity;
  • teleport-hold suppression of the stale source-cell dungeon gate;
  • rescued-entity rebucketing after the accepted streaming tick.

4.4 Input and camera phases

GameplayInputFrameController owns per-frame dispatcher hold delivery, UI-capture transitions, raw mouse sample/filter/idle handling, combat attack ticking, and the complete mouse-look/cursor-capture lifetime. It is the single owner of mouse-look state, saved cursor mode, begin/end/hide/restore, and movement teardown across press/release, capture change, focus loss, teleport, session reset, player-mode exit, and shutdown. Action press/release callbacks remain on InputDispatcher and movement stays owned by PlayerMovementController.

PlayerModeController owns enter/exit/toggle construction and the current player-controller, physics-host, chase-camera, and chase-mode slot. Manual input, PlayerModeAutoEntry, and local teleport activation all enter through that one owner. Streaming, camera, local-frame, and teleport owners receive narrow read sources from it; no path calls the substantial current EnterPlayerModeNow/exit bodies back on GameWindow or duplicates player-mode state.

CameraFrameController owns held fly-camera controls, retail chase offsets, post-network player presentation sampling, and both chase-camera updates. It does not own physics, target selection, or camera formulas. The local player created by the inbound pass gets a non-advancing projection before its first draw exactly as today, followed by the current second spatial reconcile before the camera samples that projection.

4.5 Teleport phase

LocalPlayerTeleportController owns only the current local-player transit state machine and presentation edges. It composes TeleportTransitCoordinator, TeleportViewPlaneController, PortalTunnelPresentation, WorldRevealCoordinator, streaming priority, and the session LoginComplete send. Checkpoint E first extracts the currently window-owned local aim, destination, hold/forced, activation, placement, reset, and session-clear state into this owner plus a concrete local placement collaborator where needed. It does not reuse RemoteTeleportPlacement, and network/session sinks do not retain AimTeleportDestination or reset callbacks into GameWindow. LiveEntityLivenessController, tombstone retry, and PlayerModeAutoEntry remain separate focused phases; teleport does not absorb them.

4.6 Composition, thread, and lifetime

The clock and focused dynamic sources are constructed before their first consumer. The final orchestrator is composed exactly once at the end of a successful OnLoad; OnUpdate fails fast if that invariant is broken rather than running a nullable partial graph. Every phase mutates state only on the existing update/render thread. Streaming worker completion remains behind StreamingController.Tick; the extraction adds no lock, task, or async entry.

Phase controllers borrow their input, session, streaming, portal, camera, and render-presentation owners; they do not dispose shared dependencies. Any new event subscription has explicit symmetric detach. During shutdown the update collaborators remain alive through the first-stage LiveSessionController reset, then retire before their underlying input/camera/portal/streaming resources. Existing retryable shutdown ordering remains authoritative.

5. Checkpoints and acceptance

A — contract and guards

  • record the exact production phase graph and every mutable dependency;
  • correct and pin the retail oracle for physics-hook retention/reentrant append, inactive object behavior, and static Script → Particle → hooks; pin the existing TS-50/TS-51 divergences without reordering runtime behavior in this ownership-only slice;
  • add an explicit orchestrator order test covering all twelve phases and the three conditional reconcile edges;
  • pin normalized simulation/PES/particle/tunnel time separately from absolute liveness and raw-mouse idle clocks for NaN, both infinities, non-positive values, and finite values above float.MaxValue;
  • pin missing live/offline camera behavior and the separate devtools keyboard, retained-chat keyboard, and mouse-capture contracts;
  • pin teardown retry success, AggregateException log-and-continue, other exception propagation, and next-frame retry;
  • add source guards that prevent OnUpdate or the coordinator from regaining substantial callback bodies, and prevent any transitive update owner from retaining GameWindow or one mega service context;
  • verify current production traces before cutover.

B — object/network barrier

  • move the pre-network animation/effect body into LiveObjectFrameController;
  • move no-time root/child/effect refresh into LiveSpatialPresentationReconciler;
  • replace coordinator callbacks with typed collaborators;
  • preserve semantic/visual hook separation, owner-incarnation revalidation, static-after-ordinary order, ordinary Particle-before-Script, the current shared-tail TS-51 adaptation, and once-per-host tails;
  • delete AdvanceLiveObjectRuntimeCore and ReconcileLiveObjectSpatialPresentation from GameWindow.

Focused tests cover RetailObjectActivityGate and RetailObjectQuantumClock: parented/cell-less/Frozen suspension, inactive Particle/Script-only time, Hidden+Active adjustment/hooks/manager time, and separate ordinary epsilon/Min/Max/Huge plus static epsilon/Huge boundaries. They also cover incomplete physics-hook retention, same-drain animation-hook append, deferred CallPES/default-script/ translucency routing, physics-hook append deferred until the next drain, completed physics-hook removal preserving the snapshotted successor, static hooks, callback GUID reuse, and reentrant inbound packets. Particle then Script must run exactly once for an empty world, multiple ordinary/static owners, invalid delta, and reentrant inbound work; the one published PES clock remains visible from hook capture through the script tick.

Checkpoint B removes the coordinator, animation presenter/scheduler, runtime view, static-root, and projectile callbacks into GameWindow. The callback composition still retained by RetailLocalPlayerFrameController is explicitly deferred: checkpoint D owns its input/capture sources and checkpoint F owns its mutable player-mode/controller/session sources. A structural test permits that one named legacy owner only; D/F must remove the exception before final cutover.

C — streaming frame

  • extract readiness/recenter advancement, observer selection, dungeon gate, streaming tick, and rescued projection rebucketing;
  • test login-before-player-spawn, outdoor/dungeon/portal-hold/offline observer cases, missing live/offline camera sources, and cell-landblock identity;
  • prove same-frame streaming completion precedes CreateObject projection into the resident bucket, unknown pre-login origin enqueues nothing, and recenter retirement continues while ordinary streaming is gated;
  • verify no build/publication/retirement ownership leaks back from Slice 5.

D — input frame

  • extract dispatcher tick, UI mouse-capture edge, raw sample/filter/idle path, combat intent tick, and the one cross-lifetime mouse-look/cursor owner;
  • test capture entry while mouse-look is active, zero-idle drift stop, production action ordering, devtools-vs-chat autorun semantics, mouse-only capture, and focus/teleport teardown;
  • prove every non-input phase still runs under each capture mode;
  • retain diagnostic semantic input as the unattended connected gate seam.

E — local teleport and post-network world frame

  • extract the currently window-owned local-player teleport state and every aim/destination/activation/place/reset/session port before moving its tick;
  • retain liveness and auto-entry as separate orchestrator calls around pending transit activation, readiness/hold, tunnel events, materialization, and reveal completion;
  • test loaded and pending destinations, forced-readiness boundary, same-cell respawn, LoginComplete ordering, delete/reset, and no second reveal owner;
  • pin Place → immediate reconcile → reveal and old-GUID liveness candidate → inbound delete/recreate generation safety;
  • preserve the completed portal visuals and world-reveal barrier unchanged.

Completed 2026-07-22. LocalPlayerTeleportController now owns the full local transit lifetime and its immutable network handoff, while PlayerModeController is the sole writer of controller, physics-host, player-mode, and chase-camera slots. Local animation, shadow synchronization, sealed-dungeon classification, viewport aspect, and approach-completion handoff are focused collaborators rather than window callbacks. Portal entry retires the one-shot auto-entry guard, host publication is transactional, and teleport work revalidates the live generation after every reentrant edge. Focused App/Core tests cover destination readiness, forced holds, same-cell placement, LoginComplete order, reset/disposal, GUID reuse, reentrancy, host rollback, auto-entry idempotence, and completion-mailbox ordering. The full App suite is green at 2,814 passed / 3 skipped. GameWindow.cs is 7,351 lines at this checkpoint, down from the slice baseline of 15,723.

F/G — camera, cutover, and deletion

  • extract player-mode enter/exit/toggle and current-owner state before camera or teleport cutover; retain PlayerModeAutoEntry only as its one-shot readiness guard;
  • extract fly camera, retail chase adjustment, local post-network projection, combat target tracking, and chase-camera publication;
  • pin inbound-created projection → immediate second reconcile → camera, with exact root/child/emitter/light refresh counts and no duplicate time advance;
  • compose UpdateFrameOrchestrator only after all dependencies exist;
  • replace OnUpdate with profiler scope plus one Tick call;
  • remove obsolete frame fields/facades and prove there is no back-reference to GameWindow from an extracted owner;
  • measure line/field/method count. The target is below 8,000 lines, but the ownership/ordering exit criteria outrank the count.

Checkpoint F completed 2026-07-22. CameraFrameController now owns fly held input, retail chase adjustment, the inbound-created-player projection and second reconcile, both chase-camera publications, and combat-target tracking. RetailLocalPlayerFrameController and LocalPlayerProjectionController resolve current identity, session, world, shadow, and player slots through focused typed runtimes instead of callbacks into GameWindow; the camera receives only the two-read player-presentation seam. Projection and frame owners remain composition locals, so the window retains no duplicate lifecycle state. Focused Release tests are green at 37/37, the App suite at 2,820 passed / 3 skipped, and the full suite at 7,179 passed / 5 skipped. All three corrected-diff reviews are clean. GameWindow.cs is 7,160 lines, down 8,563 lines (54.5%) from the 15,723-line slice baseline.

Checkpoint G completed 2026-07-22. GameWindow.OnUpdate now owns only the update profiler scope and one UpdateFrameOrchestrator.Tick call. Teardown, absolute liveness time, local timestamp publication, expiry deletion, player-mode auto-entry, live-origin initialization, Hidden PartArray boundaries, remote teleport placement, and all twelve live-entity session packet routes resolve through typed runtime owners; the former transitive window callbacks and obsolete frame fields are gone. The App suite is green at 2,823 passed / 3 skipped. Focused orchestration, lifecycle, presentation, teleport, origin, and session tests are green, and all three corrected-diff reviews are clean. GameWindow.cs is 7,026 raw lines / 241 fields / 108 methods, down 1,785 lines and 45 methods from the Slice-6 baseline and 8,697 lines (55.3%) from the 15,723-line pre-extraction class.

H — release and connected gates

After all three independent corrected-diff reviews are clean:

  1. run every focused App/Core/Net/UI test project;
  2. run dotnet build AcDream.slnx -c Release;
  3. run the full Release suite;
  4. run the connected lifecycle/reconnect gate;
  5. run the synchronized nine-stop resource soak with movement, turn, jump, combat, portal materialization waits, fatal-log scan, and graceful close;
  6. compare lifecycle, outbound movement, materialization, entity/animation, frame-profile, resource, and teardown traces with the Slice 5 baseline;
  7. audit the divergence register, architecture, milestones, roadmap, issues, AGENTS.md, CLAUDE.md, and durable memory.

The slice requires no new visual behavior. If connected screenshots or traces change, return to the responsible checkpoint; do not defer the difference to Slice 7.

6. Review gate for every checkpoint

After each implementation checkpoint:

  1. run focused tests and inspect the complete diff;
  2. retail-conformance review checks named functions, exact order, Hidden/ quantum semantics, and adaptation boundaries;
  3. architecture review checks dependency direction, absence of a replacement god object/service locator, same-thread mutation, and symmetric teardown;
  4. adversarial review checks independent clocks, callback reentrancy, owner/GUID reuse, login/portal transitions, capture modes, missing observer sources, teardown failures, and early-return phase suppression;
  5. fix every confirmed root cause and repeat review until clean;
  6. build/test Release and commit the checkpoint before starting the next one.

7. Divergence and documentation bookkeeping

TS-50, TS-51, and the newly documented existing host-order TS-53 remain until their exact adaptations are ported; this slice must not overclaim retail parity. IA-14/AD-22 and the lifetime/resource rows are audited against the final owner graph but changed only if their mechanism actually changes. Any newly discovered unavoidable adaptation gets a register row in the same commit. The Slice 6 closeout updates the code-structure table, roadmap, milestones, session docs, and project_gamewindow_decomposition.md with exact commits, test counts, gates, and final metrics.