--- id: PLN-0021 ticket: render-all-scene-cache-and-camera-integration title: Plan - Service Retirement, Callsite Migration, and Regression Coverage status: accepted created: 2026-04-14 completed: tags: [gfx, runtime, render, migration, regression] --- ## Objective Retire `Gfx.render_all()` from the canonical flow, migrate callsites to `FrameComposer.render_frame()`, and add the regression coverage needed to lock the new service model. ## Background `DEC-0014` is explicit that `Gfx.render_all()` must be retired and that `FrameComposer.render_frame()` becomes the canonical frame orchestration entrypoint. This final plan removes the old canonical service shape and validates the migration end-to-end. The same decision also requires the new canonical path to preserve scene-layer tile sizes such as `8x8`, not just `16x16`. ## Scope ### Included - retire `Gfx.render_all()` from the canonical path - migrate frame-loop callsites - align bridge surfaces as needed - add regression coverage for the final service model ### Excluded - HUD integration - future certification behavior for sprite overflow ## Execution Steps ### Step 1 - Migrate frame-loop callsites **What:** Switch runtime frame execution from `Gfx.render_all()` to `FrameComposer.render_frame()`. **How:** - Identify all canonical callsites that currently trigger `Gfx.render_all()`. - Update them to go through `FrameComposer`. - Preserve present/swap behavior after the render call. **File(s):** - `crates/console/prometeu-system/src/virtual_machine_runtime/tick.rs` - any additional runtime frame-loop callsites ### Step 2 - Retire `Gfx.render_all()` from the canonical service surface **What:** Remove the old frame service as the operational entry. **How:** - Remove or deprecate `render_all()` from `Gfx` and `GfxBridge` as the canonical render entry. - Keep only backend-oriented helpers that `FrameComposer` calls. - Ensure the naming and public path converge to Rust-style `render_frame()`. **File(s):** - `crates/console/prometeu-hal/src/gfx_bridge.rs` - `crates/console/prometeu-drivers/src/gfx.rs` ### Step 3 - Add end-to-end regression coverage **What:** Protect the new service model against fallback to the old renderer path. **How:** - Add tests that prove: - frame-loop code calls `FrameComposer.render_frame()` - no-scene frames remain valid - active-scene frames render through cache-backed composition - active-scene frames remain valid for canonical `8x8` scenes - sprite emission and ordering survive the full path - Add assertions or test failures for accidental continued reliance on `Gfx.render_all()`. **File(s):** - runtime tests - driver tests - bridge tests where needed ### Step 4 - Validate full repository behavior **What:** Confirm the migration did not break unrelated systems. **How:** - Run the repository validation command required by current practice. - Keep regression evidence attached to the plan execution. **File(s):** - repository-wide CI / validation entrypoints ## Test Requirements ### Unit Tests - `Gfx` no longer exposes `render_all()` as the canonical operational frame path. ### Integration Tests - runtime tick path renders through `FrameComposer.render_frame()`. - no-scene and active-scene frame modes both remain valid. - runtime tick path remains valid when the active scene uses `8x8` tiles. ### Manual Verification - Run the repository CI path and confirm the final integrated service model is green. ## Acceptance Criteria - [ ] Frame-loop callsites use `FrameComposer.render_frame()`. - [ ] `Gfx.render_all()` is retired from the canonical service path. - [ ] Regression coverage protects against fallback to the old model. - [ ] Repository validation passes after the migration. - [ ] Regression coverage includes the canonical `8x8` world-path case. ## Dependencies - Depends on `PLN-0017`, `PLN-0018`, `PLN-0019`, and `PLN-0020` - Source decision: `DEC-0014` ## Risks - Removing `render_all()` too early can strand intermediate callsites. - Leaving it in place as a canonical path for too long can create a dual-service model that is harder to remove later. - Migrating callsites without `8x8` regression coverage can falsely validate only the legacy `16x16` path.