docs(runtime): close deterministic world lifecycle gate

Record the passing capped and uncapped connected evidence, coordinator ownership, graceful reconnect contract, current test baseline, and the remaining human-only visual gates. Keep AGENTS.md synchronized with CLAUDE.md and distill the durable reveal-lifecycle lesson into project memory.
This commit is contained in:
Erik 2026-07-21 00:00:31 +02:00
parent f7b09617c5
commit e02acb870c
8 changed files with 121 additions and 49 deletions

View file

@ -108,19 +108,24 @@ movement queries.
## Current state ## Current state
**M3 — Cast a spell ACTIVE; automated implementation complete 2026-07-15.** Retail cast intent, **M3 — Cast a spell ACTIVE; automated implementation and connected
component/target gates, live enchantment wire, Magic-scoped input, spell bar, spellbook, component single-client gates complete.** Retail cast intent, component/target gates,
book, effect indicators, shared main-panel switching, and positive/negative effects UI are implemented over the Step-9 projectile/DAT-effect live enchantment wire, Magic-scoped input, spell bar, spellbook, component
foundation. The 2026-07-20 R6 complete-root-Frame/object-workset cutover is automated-test complete; book, effect indicators, shared main-panel switching, and positive/negative
three independent conformance/architecture/adversarial re-reviews are clean, the Release build succeeds effects UI are implemented over the Step-9 projectile/DAT-effect foundation.
(the clean documentation audit exposes 17 pre-existing test-project warnings, #228), and the full suite The R6 complete-root-Frame/object-workset cutover and its unattended
is 6,457 passed / 5 skipped. Its unattended seven-destination seven-destination input/portal/performance rebaseline pass. The 2026-07-20
connected input/portal/performance rebaseline also passes without an interactive desktop. Remaining deterministic world-lifecycle gate additionally protects fresh login,
ownership cleanup and registered TS-50/TS-51 timing residuals stay carried. **Next:** connected R6 outdoor/world-edge/dungeon travel, same-location revisit, exact graceful
locomotion/collision/projectile/teleport visual gate, then the final two-client disconnect, and uncapped fresh-process reconnect with JSON/PNG artifacts.
portal-out/materialization observer gate. **Carried:** #153, #116, R6 residuals, and the deferred Release builds; 6,480 tests pass / 5 skip (17 tracked warnings, #228).
Modern Pipeline track (MP1b+). **Next:** the R6 locomotion/collision/projectile/teleport local visual
Start magic work at `claude-memory/project_magic_ui_and_casting.md`; detailed state is below. rebaseline when a local view is available, then the final two-client
portal-out/materialization observer gate. **Carried:** #153, #116, remaining
R6 ownership cleanup, TS-50/TS-51, Modern Pipeline MP1b+, and #225's
lifestone/particle alpha visual gate.
Start magic work at `claude-memory/project_magic_ui_and_casting.md`; start
render/streaming work at `claude-memory/project_render_pipeline_digest.md`.
Documentation entry point: [`docs/README.md`](docs/README.md). Documentation entry point: [`docs/README.md`](docs/README.md).

View file

@ -106,19 +106,24 @@ movement queries.
## Current state ## Current state
**M3 — Cast a spell ACTIVE; automated implementation complete 2026-07-15.** Retail cast intent, **M3 — Cast a spell ACTIVE; automated implementation and connected
component/target gates, live enchantment wire, Magic-scoped input, spell bar, spellbook, component single-client gates complete.** Retail cast intent, component/target gates,
book, effect indicators, shared main-panel switching, and positive/negative effects UI are implemented over the Step-9 projectile/DAT-effect live enchantment wire, Magic-scoped input, spell bar, spellbook, component
foundation. The 2026-07-20 R6 complete-root-Frame/object-workset cutover is automated-test complete; book, effect indicators, shared main-panel switching, and positive/negative
three independent conformance/architecture/adversarial re-reviews are clean, the Release build succeeds effects UI are implemented over the Step-9 projectile/DAT-effect foundation.
(the clean documentation audit exposes 17 pre-existing test-project warnings, #228), and the full suite The R6 complete-root-Frame/object-workset cutover and its unattended
is 6,457 passed / 5 skipped. Its unattended seven-destination seven-destination input/portal/performance rebaseline pass. The 2026-07-20
connected input/portal/performance rebaseline also passes without an interactive desktop. Remaining deterministic world-lifecycle gate additionally protects fresh login,
ownership cleanup and registered TS-50/TS-51 timing residuals stay carried. **Next:** connected R6 outdoor/world-edge/dungeon travel, same-location revisit, exact graceful
locomotion/collision/projectile/teleport visual gate, then the final two-client disconnect, and uncapped fresh-process reconnect with JSON/PNG artifacts.
portal-out/materialization observer gate. **Carried:** #153, #116, R6 residuals, and the deferred Release builds; 6,480 tests pass / 5 skip (17 tracked warnings, #228).
Modern Pipeline track (MP1b+). **Next:** the R6 locomotion/collision/projectile/teleport local visual
Start magic work at `claude-memory/project_magic_ui_and_casting.md`; detailed state is below. rebaseline when a local view is available, then the final two-client
portal-out/materialization observer gate. **Carried:** #153, #116, remaining
R6 ownership cleanup, TS-50/TS-51, Modern Pipeline MP1b+, and #225's
lifestone/particle alpha visual gate.
Start magic work at `claude-memory/project_magic_ui_and_casting.md`; start
render/streaming work at `claude-memory/project_render_pipeline_digest.md`.
Documentation entry point: [`docs/README.md`](docs/README.md). Documentation entry point: [`docs/README.md`](docs/README.md).

View file

@ -98,7 +98,7 @@ production runtime failure.
**Acceptance:** A non-incremental Release solution build reports zero warnings **Acceptance:** A non-incremental Release solution build reports zero warnings
and zero errors without suppressing analyzers or weakening nullable checking; and zero errors without suppressing analyzers or weakening nullable checking;
the full 6,457-pass / 5-skip suite remains green. the full 6,480-pass / 5-skip suite remains green.
--- ---
@ -7445,8 +7445,14 @@ equivalent of retail `SmartBox::UseTime` keeping position completion behind
`CellManager::blocking_for_cells`. Both paths invalidate destination texture `CellManager::blocking_for_cells`. Both paths invalidate destination texture
readiness, prepare composites after mesh publication, and require the same readiness, prepare composites after mesh publication, and require the same
render-plus-collision predicate. Focused login/barrier tests and the complete render-plus-collision predicate. Focused login/barrier tests and the complete
Release suite pass; capped connected visual verification remains the final Release suite pass. The user confirmed the capped first-login reveal, and the
gate. follow-up deterministic connected gate now repeats fresh login plus five
portal/dungeon transitions, returns to the same outdoor location, closes with
the retail character-logoff/transport-disconnect handshake, and reconnects in
a fresh uncapped process. All six saved PNGs show complete geometry; all
structured checkpoints report ready render/composite/collision domains and
zero reveal invariant failures or pending teardown/upload/warmup work. See
`docs/plans/2026-07-20-automated-world-lifecycle-gate.md`.
**Research:** **Research:**
`docs/research/2026-07-16-portal-completion-pseudocode.md` §2. `docs/research/2026-07-16-portal-completion-pseudocode.md` §2.

View file

@ -722,6 +722,16 @@ thread, never from the streaming worker. This is acdream's asynchronous equivale
`SmartBox::UseTime` holding position completion while `SmartBox::UseTime` holding position completion while
`CellManager::blocking_for_cells` is set. `CellManager::blocking_for_cells` is set.
`WorldRevealLifecycleTelemetry` is an observation seam owned by the
coordinator, not a second lifecycle state machine. It records generation-scoped
edges and rejects a normal-world viewport observed before canonical readiness.
`WorldLifecycleAutomationController` consumes only coordinator snapshots plus
resource counters; `FrameScreenshotController` performs the requested
default-framebuffer readback after world and retained UI draw on the render
thread. The external connected gate launches normal Release processes and
observes these artifacts, but never mutates streaming, physics, GL, or entity
state from a worker thread.
### Teleport cell identity at the streaming boundary ### Teleport cell identity at the streaming boundary
The network and physics layers carry retail's complete `Position`: an The network and physics layers carry retail's complete `Position`: an

View file

@ -67,7 +67,7 @@ accepted-divergence entries (#96, #49, #50).
|---|---|---|---|---|---| |---|---|---|---|---|---|
| AD-38 | Outgoing teleport viewports retire when retail's quantized animation level exceeds the last captured visible level 1022 (index 96), suppressing levels 1023/1024 up to 20.2 ms before retail's literal `elapsed >= 1.0` state edge. Incoming fades retain the exact timer. | `src/AcDream.Core/World/TeleportAnimSequencer.cs` (`OutgoingViewportReachedTerminalProjection`) | An uncapped 2000 FPS pass can publish the finite tunnel at levels 1023/1024 even though the paired 2013 retail capture switches viewports after 1022. The table-level cutover preserves the captured visible viewport ordering without throttling the application. | Exit sound, viewport replacement, and logout tunnel entry can occur at most two easing-table quanta (about 20.2 ms) earlier than retail's logical timer. | `UIGlobals::GetAnimLevel @ 0x004EE540`; `gmSmartBoxUI::UseTime @ 0x004D6E30`; paired retail/acdream captures documented in `docs/research/2026-07-15-retail-portal-space-pseudocode.md` | | AD-38 | Outgoing teleport viewports retire when retail's quantized animation level exceeds the last captured visible level 1022 (index 96), suppressing levels 1023/1024 up to 20.2 ms before retail's literal `elapsed >= 1.0` state edge. Incoming fades retain the exact timer. | `src/AcDream.Core/World/TeleportAnimSequencer.cs` (`OutgoingViewportReachedTerminalProjection`) | An uncapped 2000 FPS pass can publish the finite tunnel at levels 1023/1024 even though the paired 2013 retail capture switches viewports after 1022. The table-level cutover preserves the captured visible viewport ordering without throttling the application. | Exit sound, viewport replacement, and logout tunnel entry can occur at most two easing-table quanta (about 20.2 ms) earlier than retail's logical timer. | `UIGlobals::GetAnimLevel @ 0x004EE540`; `gmSmartBoxUI::UseTime @ 0x004D6E30`; paired retail/acdream captures documented in `docs/research/2026-07-15-retail-portal-space-pseudocode.md` |
| AD-1 | Lost-cell machinery replaced by recoverable outdoor demote (**#107** safety net) + outdoor-restore `max(terrainZ, z)` under-terrain lift; retail goes `GotoLostCell` | `src/AcDream.Core/Physics/PhysicsEngine.cs:553` (+ :808) | acdream has no lost-cell state machine; outdoor landcell is the recoverable equivalent; the #107 auto-entry hold should make the demote branch unreachable | Gap in the hold → player committed to outdoor terrain inside/under a building (fake-grounded spawn, fall-through); a legit below-heightmap server restore is silently lifted — upward warp vs server | `GotoLostCell` pc:283418; `SetPositionInternal` 0x00515bd0, pc:283892-283945 | | AD-1 | Lost-cell machinery replaced by recoverable outdoor demote (**#107** safety net) + outdoor-restore `max(terrainZ, z)` under-terrain lift; retail goes `GotoLostCell` | `src/AcDream.Core/Physics/PhysicsEngine.cs:553` (+ :808) | acdream has no lost-cell state machine; outdoor landcell is the recoverable equivalent; the #107 auto-entry hold should make the demote branch unreachable | Gap in the hold → player committed to outdoor terrain inside/under a building (fake-grounded spawn, fall-through); a legit below-heightmap server restore is silently lifted — upward warp vs server | `GotoLostCell` pc:283418; `SetPositionInternal` 0x00515bd0, pc:283892-283945 |
| AD-2 | Async readiness gates replace retail's synchronous destination cell load. **#229 refinement (2026-07-20):** login and F751 portal-space exit now share `WorldRevealReadinessBarrier`, so neither path can expose the normal viewport until the same render-publication, composite-texture, and collision domains converge. A hydratable indoor claim requires its owning Near-tier static/EnvCell mesh set, destination composites, and exact EnvCell physics (`IsSpawnCellReady`); an outdoor claim requires those render domains plus terrain/collision residency for the priority near ring. Hard-recenter generations and tier-aware completion application prevent stale overlapping loads/unloads or Far/Near jobs from opening or erasing the gate; mesh upload remains separate from balanced landblock ownership. Claims beyond NumCells still take the loud forced-placement path. The portal hold→materialize→regain-control lifecycle remains owned by `TeleportAnimSequencer`. | `src/AcDream.App/Streaming/WorldRevealReadinessBarrier.cs`; `src/AcDream.App/Rendering/GameWindow.cs` (login auto-entry + TAS transit tick); `src/AcDream.App/Streaming/StreamingController.cs` (`IsRenderNeighborhoodResident`); `src/AcDream.App/Streaming/GpuWorldState.cs` (`IsRenderReady`); `src/AcDream.App/Rendering/Wb/LandblockSpawnAdapter.cs`; `src/AcDream.Core/Physics/PhysicsEngine.cs` (`IsSpawnCellReady`, `IsNeighborhoodTerrainResident`) | This is the asynchronous equivalent of retail leaving `SmartBox::position_update_complete` false while `CellManager::blocking_for_cells` is set: neither initial login nor portal arrival may reveal an empty collision world, a terrain-only Far shell, or a published-but-not-drawable GPU landblock. Indoor does not require a terrain heightmap, only the owning render landblock and exact EnvCell. | Gate opens early → grey/untextured first login or portal reveal, free-fall, wrong-cell rooting, or missing scenery; predicate never satisfies (streamer/DAT/upload failure) → login remains behind the world render gate, while portal transit reaches its existing loud timeout/forced-placement diagnostic. | `SmartBox::UseTime` 0x00455410; `gmSmartBoxUI::EndTeleportAnimation` 0x004D65A0 | | AD-2 | Async readiness gates replace retail's synchronous destination cell load. **#229 refinement (2026-07-20):** login and F751 portal-space exit now share `WorldRevealReadinessBarrier`, so neither path can expose the normal viewport until the same render-publication, composite-texture, and collision domains converge. A hydratable indoor claim requires its owning Near-tier static/EnvCell mesh set, destination composites, and exact EnvCell physics (`IsSpawnCellReady`); an outdoor claim requires those render domains plus terrain/collision residency for the priority near ring. Hard-recenter generations and tier-aware completion application prevent stale overlapping loads/unloads or Far/Near jobs from opening or erasing the gate; mesh upload remains separate from balanced landblock ownership. Claims beyond NumCells still take the loud forced-placement path. `WorldRevealCoordinator` owns this shared lifetime; diagnostic telemetry observes its generation without defining another readiness path. The portal hold→materialize→regain-control lifecycle remains owned by `TeleportAnimSequencer`. | `src/AcDream.App/Streaming/WorldRevealCoordinator.cs`; `src/AcDream.App/Streaming/WorldRevealReadinessBarrier.cs`; `src/AcDream.App/Rendering/GameWindow.cs` (owner wiring + draw eligibility); `src/AcDream.App/Streaming/StreamingController.cs` (`IsRenderNeighborhoodResident`); `src/AcDream.App/Streaming/GpuWorldState.cs` (`IsRenderReady`); `src/AcDream.App/Rendering/Wb/LandblockSpawnAdapter.cs`; `src/AcDream.Core/Physics/PhysicsEngine.cs` (`IsSpawnCellReady`, `IsNeighborhoodTerrainResident`) | This is the asynchronous equivalent of retail leaving `SmartBox::position_update_complete` false while `CellManager::blocking_for_cells` is set: neither initial login nor portal arrival may reveal an empty collision world, a terrain-only Far shell, or a published-but-not-drawable GPU landblock. Indoor does not require a terrain heightmap, only the owning render landblock and exact EnvCell. | Gate opens early → grey/untextured first login or portal reveal, free-fall, wrong-cell rooting, or missing scenery; predicate never satisfies (streamer/DAT/upload failure) → login remains behind the world render gate, while portal transit reaches its existing loud timeout/forced-placement diagnostic. | `SmartBox::UseTime` 0x00455410; `gmSmartBoxUI::EndTeleportAnimation` 0x004D65A0 |
| AD-3 | Outdoor seeds always walk the transit array (retail skips the walk when the seed CLandCell is null/unloaded); per-cell lookups no-op on unhydrated data | `src/AcDream.Core/Physics/CellTransit.cs:503` | Equivalence argument: with nothing hydrated every lookup inside the walk no-ops, so the result matches retail's skipped walk | Near partially-streamed landblocks, building-transit promotion silently can't fire until structs hydrate — membership stays outdoor while the player is inside a building | `CObjCell::find_cell_list` 0052b535-0052b56c (null-CLandCell case) | | AD-3 | Outdoor seeds always walk the transit array (retail skips the walk when the seed CLandCell is null/unloaded); per-cell lookups no-op on unhydrated data | `src/AcDream.Core/Physics/CellTransit.cs:503` | Equivalence argument: with nothing hydrated every lookup inside the walk no-ops, so the result matches retail's skipped walk | Near partially-streamed landblocks, building-transit promotion silently can't fire until structs hydrate — membership stays outdoor while the player is inside a building | `CObjCell::find_cell_list` 0052b535-0052b56c (null-CLandCell case) |
| AD-4 | `point_in_cell` against an unhydrated CellBSP returns false (skip) rather than the null-node "inside" default; retail never queries unloaded cells | `src/AcDream.Core/Physics/CellTransit.cs:588` | The null-node default would make an unhydrated cell spuriously claim every point; skipping is the conservative streaming-safe choice | During hydration, a point genuinely inside a not-yet-loaded cell resolves outdoor/stale — transient membership misclassification driving wrong collision set and render root | `CEnvCell::find_visible_child_cell` :311397; cell-BSP vtable[0x84] | | AD-4 | `point_in_cell` against an unhydrated CellBSP returns false (skip) rather than the null-node "inside" default; retail never queries unloaded cells | `src/AcDream.Core/Physics/CellTransit.cs:588` | The null-node default would make an unhydrated cell spuriously claim every point; skipping is the conservative streaming-safe choice | During hydration, a point genuinely inside a not-yet-loaded cell resolves outdoor/stale — transient membership misclassification driving wrong collision set and render root | `CEnvCell::find_visible_child_cell` :311397; cell-BSP vtable[0x84] |
| AD-5 | Outdoor `point_in_cell` is an identity compare against the global XY-column cell from `LandDefs.AdjustToOutside` (no per-cell containment test) | `src/AcDream.Core/Physics/CellTransit.cs:865` | Landcells are disjoint 24 m columns — identity-compare against the column under the sphere centre is exactly equivalent to retail's per-candidate test | If block-origin/lcoord math is wrong at a landblock seam, the compare silently never matches — outdoor membership freezes at boundaries (the pre-#106 symptom) | `find_cell_list` pick pc:308788-308825; `CLandCell::point_in_cell` (get_block_offset pc:308804) | | AD-5 | Outdoor `point_in_cell` is an identity compare against the global XY-column cell from `LandDefs.AdjustToOutside` (no per-cell containment test) | `src/AcDream.Core/Physics/CellTransit.cs:865` | Landcells are disjoint 24 m columns — identity-compare against the column under the sphere centre is exactly equivalent to retail's per-candidate test | If block-origin/lcoord math is wrong at a landblock seam, the compare silently never matches — outdoor membership freezes at boundaries (the pre-#106 symptom) | `find_cell_list` pick pc:308788-308825; `CLandCell::point_in_cell` (get_block_offset pc:308804) |

View file

@ -1,6 +1,6 @@
# acdream — strategic roadmap # acdream — strategic roadmap
**Status:** Living document. Updated 2026-07-20. **M3 active; automated implementation and connected single-client magic/portal gates complete.** M2's connected demo loop is complete. M3 now has the retail cast-intent/component/target lifecycle, exact live enchantment wire state, scoped Magic input, retained spell bar, spellbook, component book, positive/negative effects panels with authored rows and selected-spell details, the complete seven-control gameplay indicator strip and its Character Information/Link/Vitae detail pages, and shared `gmPanelUI` geometry/switching over the Step 9 projectile/PhysicsScript/particle/portal foundation. The next gate is a local visual rebaseline of the new R6 object-frame path; the final M3 requirement is the two-client portal-out/materialization observer gate. Issue #225's lifestone/particle alpha comparison is a separate rendering visual gate. **Status:** Living document. Updated 2026-07-20. **M3 active; automated implementation and connected single-client magic/portal gates complete.** M2's connected demo loop is complete. M3 now has the retail cast-intent/component/target lifecycle, exact live enchantment wire state, scoped Magic input, retained spell bar, spellbook, component book, positive/negative effects panels with authored rows and selected-spell details, the complete seven-control gameplay indicator strip and its Character Information/Link/Vitae detail pages, and shared `gmPanelUI` geometry/switching over the Step 9 projectile/PhysicsScript/particle/portal foundation. Fresh-login and portal world reveal are additionally protected by a deterministic capped/uncapped connected lifecycle gate with screenshots, resource snapshots, exact graceful disconnect, and fresh-process reconnect. The next gate is a local visual rebaseline of the new R6 object-frame path; the final M3 requirement is the two-client portal-out/materialization observer gate. Issue #225's lifestone/particle alpha comparison is a separate rendering visual gate.
**Purpose:** One source of truth for where the project is and where it's going. Every observed defect or missing feature has a named phase that owns it; when something looks wrong in-game, look here to find the phase that'll address it. Implementation details live in per-phase specs under `docs/superpowers/specs/`, not in this file. **Purpose:** One source of truth for where the project is and where it's going. Every observed defect or missing feature has a named phase that owns it; when something looks wrong in-game, look here to find the phase that'll address it. Implementation details live in per-phase specs under `docs/superpowers/specs/`, not in this file.
--- ---
@ -34,9 +34,14 @@ active enchantment, then recall through the DAT-driven portal presentation.
effects, spellbook/component-book filtering and deletion, favorite spell effects, spellbook/component-book filtering and deletion, favorite spell
bar interaction, recall, portal-space presentation, and retained indicator bar interaction, recall, portal-space presentation, and retained indicator
pages. pages.
4. **Pending local visual gate:** locomotion, collision, projectile, and 4. **Done (automated connected gate):** one canonical world-reveal lifecycle
now covers fresh login, outdoor/world-edge/dungeon transitions,
same-location revisit, graceful logout, and uncapped fresh-process
reconnect. The gate records structured readiness/resource checkpoints and
full-frame PNGs, and rejects early world visibility or stranded owners.
5. **Pending local visual gate:** locomotion, collision, projectile, and
teleport comparison after the R6 complete-root-Frame/object-workset cutover. teleport comparison after the R6 complete-root-Frame/object-workset cutover.
5. **Pending two-client visual gate:** portal-out/materialization observer 6. **Pending two-client visual gate:** portal-out/materialization observer
presentation before M3 closes, including #218's finished Hidden silhouette, presentation before M3 closes, including #218's finished Hidden silhouette,
fully rendered destination reveal, and no indoor stop-time position snap. fully rendered destination reveal, and no indoor stop-time position snap.
@ -567,6 +572,7 @@ behavior. Estimated 1726 days focused work, 35 weeks calendar.
- **Portal/resource lifetime correction 2026-07-18; connected stress gate passed, final visual gate pending.** `LiveEntityLivenessController` ports retail's 25-second leave-visibility destruction queue over canonical live records, cancels expiry for spatially resident or owned objects, and uses holtburger's conservative 384-unit envelope where ACE supplies no client-visible PVS leave event. The broader integration balances generation-scoped appearance/live/landblock/effect/UI/portal owners, bounds DAT/decoded/standalone/composite/atlas/mesh residency, performs incremental mesh-arena migration, and defers GL deletion or slot reuse through three frames of GPU fences. Render/UI scratch storage is reused with hysteretic trimming. No visual range or quality setting was reduced. The final seven-destination connected route cut peak working/private memory from 2,954.5/3,502.3 MiB to 1,493.4/1,969.5 MiB, returned Caul to 1,030.6/1,638.2 MiB, held 125153 FPS locally through the final dwell, and produced no WER/driver reset. AP-69 is narrowed rather than retired because exact ObjCell PVS and explicit preview lifetimes remain. - **Portal/resource lifetime correction 2026-07-18; connected stress gate passed, final visual gate pending.** `LiveEntityLivenessController` ports retail's 25-second leave-visibility destruction queue over canonical live records, cancels expiry for spatially resident or owned objects, and uses holtburger's conservative 384-unit envelope where ACE supplies no client-visible PVS leave event. The broader integration balances generation-scoped appearance/live/landblock/effect/UI/portal owners, bounds DAT/decoded/standalone/composite/atlas/mesh residency, performs incremental mesh-arena migration, and defers GL deletion or slot reuse through three frames of GPU fences. Render/UI scratch storage is reused with hysteretic trimming. No visual range or quality setting was reduced. The final seven-destination connected route cut peak working/private memory from 2,954.5/3,502.3 MiB to 1,493.4/1,969.5 MiB, returned Caul to 1,030.6/1,638.2 MiB, held 125153 FPS locally through the final dwell, and produced no WER/driver reset. AP-69 is narrowed rather than retired because exact ObjCell PVS and explicit preview lifetimes remain.
- **Render-thread CPU and high-refresh pacing correction 2026-07-19; automated/review/connected gates passed, final translucency visual gate pending.** Software pacing now uses one reusable Windows high-resolution waitable timer instead of scheduler-quantized `Thread.Sleep`; the permanent profiler attributes that wait as `pace`. Wb keeps exact stable far-to-near alpha order while using a radix key, avoids immediate SSBO packing for deferred transparent objects, packs each eight-light set, caches immutable selection descriptors, and retires historical material groups only after one complete unused frame across every landscape/dynamics/paperdoll draw scope. A fixed dense-Caul sample improved from roughly 912 ms CPU to 5.36.2 ms without reducing view distance, particles, textures, streaming radius, or other quality. The corrected post-review uncapped route waited for every materialization and held a full visibility sweep through one dedicated profiler window at all seven destinations. Returned dense Caul (about 21,024 visible entities) measured 3.0/4.9 ms CPU p50/p95 and 2.0/3.4 ms GPU while turning, then 3.8/5.0 ms CPU and 2.6/3.2 ms GPU stationary (241 FPS title sample). First/return Caul memory was 939.8/1,438.3 and 1,034.8/1,630.5 MiB working/private; the highest stationary sample was 1,065.0/1,660.6 MiB in Holtburg, and the client exited gracefully. With pacing disabled (`pace=0`) and title samples reaching 844 FPS, RDP did not refresh-cap engine throughput. UI automation now uses a command-local compensated clock, preserving sub-millisecond frame deltas and exact long-duration sleep/timeout boundaries. - **Render-thread CPU and high-refresh pacing correction 2026-07-19; automated/review/connected gates passed, final translucency visual gate pending.** Software pacing now uses one reusable Windows high-resolution waitable timer instead of scheduler-quantized `Thread.Sleep`; the permanent profiler attributes that wait as `pace`. Wb keeps exact stable far-to-near alpha order while using a radix key, avoids immediate SSBO packing for deferred transparent objects, packs each eight-light set, caches immutable selection descriptors, and retires historical material groups only after one complete unused frame across every landscape/dynamics/paperdoll draw scope. A fixed dense-Caul sample improved from roughly 912 ms CPU to 5.36.2 ms without reducing view distance, particles, textures, streaming radius, or other quality. The corrected post-review uncapped route waited for every materialization and held a full visibility sweep through one dedicated profiler window at all seven destinations. Returned dense Caul (about 21,024 visible entities) measured 3.0/4.9 ms CPU p50/p95 and 2.0/3.4 ms GPU while turning, then 3.8/5.0 ms CPU and 2.6/3.2 ms GPU stationary (241 FPS title sample). First/return Caul memory was 939.8/1,438.3 and 1,034.8/1,630.5 MiB working/private; the highest stationary sample was 1,065.0/1,660.6 MiB in Holtburg, and the client exited gracefully. With pacing disabled (`pace=0`) and title samples reaching 844 FPS, RDP did not refresh-cap engine throughput. UI automation now uses a command-local compensated clock, preserving sub-millisecond frame deltas and exact long-duration sleep/timeout boundaries.
- **World-reveal lifecycle gate and graceful reconnect shipped 2026-07-20.** `WorldRevealCoordinator` is now the single App owner for login/portal begin, canonical render+composite+collision readiness, materialization, normal-world visibility, completion, and cancellation. Diagnostic telemetry observes that owner by generation; it does not duplicate the readiness formula. Retained automation can wait on semantic lifecycle edges, write JSON checkpoints, and capture the complete framebuffer after world and UI draw. The connected Release gate covers login → Aerlinthe → Rynthid → Facility Hub → Holtburg → Aerlinthe, closes through retail's `0xF653` character-logoff plus transport `Disconnect`, proves ACE accepted the exact client endpoint, then performs an uncapped fresh-process reconnect. The final run passed all checkpoints and six PNGs with zero reveal invariant failures or pending teardown/upload/warmup work; the reconnect sampled 172.7 FPS / 5.79 ms on this host. Release build and 6,480 tests pass / 5 skip. See `docs/plans/2026-07-20-automated-world-lifecycle-gate.md`.
**Reference docs:** `docs/research/retail-ui/00-master-synthesis.md` + slices 01-06. Every AC-specific behavior has a decompiled FUN_ / DAT_ citation. **Reference docs:** `docs/research/retail-ui/00-master-synthesis.md` + slices 01-06. Every AC-specific behavior has a decompiled FUN_ / DAT_ citation.
@ -920,7 +926,8 @@ diagnostic scaffolding, not yet the final collision system.
PositionManager facade remains the final R6 ownership cleanup. PositionManager facade remains the final R6 ownership cleanup.
Final 2026-07-20 gate: three independent retail/architecture/adversarial Final 2026-07-20 gate: three independent retail/architecture/adversarial
re-reviews are clean; Release builds successfully with 17 known test-project re-reviews are clean; Release builds successfully with 17 known test-project
warnings tracked by #228; the repository suite is 6,457 passed / 5 skipped. warnings tracked by #228; the repository suite is 6,480 passed / 5 skipped
after the world-reveal gate additions.
The unattended connected Release rebaseline also The unattended connected Release rebaseline also
passes: seven portal materializations across Caul, Sawato, Rynthid, passes: seven portal materializations across Caul, Sawato, Rynthid,
Aerlinthe, Holtburg, and same-location revisits; production-dispatcher turn, Aerlinthe, Holtburg, and same-location revisits; production-dispatcher turn,
@ -1446,7 +1453,7 @@ OpenGL ceiling; revisit macOS only if a supported graphics backend is chosen.
## Cross-cutting work tracked in parallel ## Cross-cutting work tracked in parallel
- **Test coverage.** Each phase lands with layer-matched unit and integration tests in `tests/`. Current Release baseline: 6,457 passed / 5 intentional skips (2026-07-20). - **Test coverage.** Each phase lands with layer-matched unit and integration tests in `tests/`. Current Release baseline: 6,480 passed / 5 intentional skips (2026-07-20).
- **Memory files.** Live subsystem state and digests are indexed by `claude-memory/MEMORY.md`; stable engineering references remain under `memory/`. Canonical program status stays in milestones/roadmap/issues. - **Memory files.** Live subsystem state and digests are indexed by `claude-memory/MEMORY.md`; stable engineering references remain under `memory/`. Canonical program status stays in milestones/roadmap/issues.
- **`CLAUDE.md` discipline.** Check all four references (ACE, ACViewer, WorldBuilder, Chorizite) before committing to an approach. WorldBuilder is the closest stack match and should be checked first. - **`CLAUDE.md` discipline.** Check all four references (ACE, ACViewer, WorldBuilder, Chorizite) before committing to an approach. WorldBuilder is the closest stack match and should be checked first.

View file

@ -9,17 +9,21 @@ foundation is hardened through Step 9. Spellbook/component-book filtering,
favorite spell bar, connected casting/enchantment effects, and portal-space favorite spell bar, connected casting/enchantment effects, and portal-space
presentation have passed their single-client visual gates. The corrective bounded presentation have passed their single-client visual gates. The corrective bounded
render/resource-lifetime integration passed its seven-destination connected render/resource-lifetime integration passed its seven-destination connected
stress gate without a crash or cumulative collapse. The remaining M3 visual stress gate without a crash or cumulative collapse. A second deterministic
requirement is the final two-client portal-out/materialize observer gate. The world-lifecycle gate now protects fresh login, outdoor/world-edge/dungeon
new R6 object-update cutover has passed its unattended connected input/portal/ travel, same-location revisit, exact graceful disconnect, and an uncapped
performance rebaseline; its locomotion/collision/projectile/teleport visual fresh-process reconnect with canonical readiness snapshots and saved PNG/JSON
gate remains for the next local viewing session before that observer gate. artifacts. The remaining M3 visual requirement is the final two-client
portal-out/materialize observer gate. The new R6 object-update cutover has
passed its unattended connected input/portal/performance rebaseline; its
locomotion/collision/projectile/teleport visual gate remains for the next local
viewing session before that observer gate.
Carried: Carried:
#153 far-teleport residual, #116 slide-response, the remaining R6 ownership cleanup plus #153 far-teleport residual, #116 slide-response, the remaining R6 ownership cleanup plus
registered TS-50/TS-51 timing residuals (the complete-root-Frame/object-workset registered TS-50/TS-51 timing residuals (the complete-root-Frame/object-workset
cutover is automated-test complete 2026-07-20; three independent re-reviews are cutover is automated-test complete 2026-07-20; three independent re-reviews are
clean, Release builds with 17 known test-project warnings tracked by #228, and clean, Release builds with 17 known test-project warnings tracked by #228, and
6,457 tests pass / 5 skip), and 6,480 tests pass / 5 skip after the world-reveal gate), and
the deferred Modern Pipeline track (MP1b+). The separate #225 shared-alpha the deferred Modern Pipeline track (MP1b+). The separate #225 shared-alpha
implementation has passed connected lifetime/performance gates and awaits only implementation has passed connected lifetime/performance gates and awaits only
its lifestone/particle visual comparison. its lifestone/particle visual comparison.

View file

@ -1,6 +1,6 @@
# Automated world-lifecycle gate # Automated world-lifecycle gate
**Status:** In progress (2026-07-20) **Status:** Complete (2026-07-20)
**Owner:** M3 stabilization / R6 rendering-lifecycle rebaseline **Owner:** M3 stabilization / R6 rendering-lifecycle rebaseline
**Depends on:** `WorldRevealReadinessBarrier`, retained-UI automation, **Depends on:** `WorldRevealReadinessBarrier`, retained-UI automation,
`FrameProfiler`, connected local ACE `FrameProfiler`, connected local ACE
@ -133,10 +133,45 @@ frame time separately.
## Completion evidence ## Completion evidence
- focused App tests for every lifecycle invariant; - Focused App tests cover readiness composition, stale generations,
- full Release solution build and test suite; cancellation, duplicate lifecycle edges, early-visible rejection, artifact
- two-process connected lifecycle report with screenshots and JSONL timeline; capture, automation timeouts, and resource snapshots.
- accepted capped and uncapped same-session metrics; - `dotnet build AcDream.slnx -c Release` succeeds. The complete repository
- `GameWindow` extraction retains the exact accepted lifecycle trace; suite is 6,480 passed / 5 skipped; the 17 existing test-project warnings
- roadmap, issues, architecture, divergence register, memory, `AGENTS.md`, and remain tracked by issue #228.
`CLAUDE.md` agree on the resulting ownership and remaining visual gates. - The final two-process connected report passed with no failures. The capped
process completed fresh login, Aerlinthe, Rynthid, Facility Hub, Holtburg,
and an Aerlinthe revisit in 244.424 seconds. The uncapped process then
reconnected the same account and completed in 61.717 seconds.
- Both processes closed through `WM_CLOSE`, received the authoritative
character-logoff confirmation, exited with code 0, and were matched to
ACE's exact client UDP endpoint and `PacketHeader Disconnect` record.
- Every checkpoint had zero pending live teardowns, landblock retirements,
staged mesh uploads, composite warmups, and reveal invariant failures.
- All six PNG artifacts were valid and inspected. Login, indoor dungeon,
dungeon exit, Aerlinthe revisit, and reconnect showed complete world
geometry rather than a grey or partially revealed destination.
- The uncapped reconnect sampled 172.7 FPS / 5.79 ms at the checkpoint; its
latest profiler window measured 5.7 ms CPU p50, 6.1 ms p95 and 5.7 ms GPU
p50, 6.0 ms p95 with zero pacing time. This is machine-specific throughput
evidence, not a cross-display FPS requirement.
- The Aerlinthe revisit retained balanced owners and stayed inside the
documented relative memory/resource tolerances. One circuit is not claimed
as a permanent memory plateau proof; the longer seven-destination R6 soak
remains the endurance gate.
- `WorldRevealCoordinator` now owns the protected lifecycle outside
`GameWindow`; the accepted trace did not change after extraction.
## Landed commits
- `db45b81f` — expose canonical readiness snapshots and lifecycle telemetry;
- `354c2adc` — add deterministic checkpoints and framebuffer screenshots;
- `b03371c0` — add the connected lifecycle/reconnect gate;
- `68578fa5` — port retail graceful character logout and transport disconnect;
- `a4ef5788` — centralize the reveal lifetime in `WorldRevealCoordinator`;
- `f7b09617` — preserve singleton endpoint/checkpoint collections in the gate.
The remaining visual work is deliberately outside this gate: the R6
locomotion/collision/projectile/teleport retail comparison, the two-client
portal-out/materialization observer comparison, and issue #225's translucent
lifestone/particle ordering comparison.