--- id: PLN-0023 ticket: frame-composer-public-syscall-surface title: Plan - Composer Runtime Dispatch and Legacy Removal status: accepted created: 2026-04-17 completed: tags: [runtime, syscall, frame-composer, dispatch, migration] --- ## Objective Route the new public `composer.*` syscalls through `FrameComposer`, remove legacy `gfx.set_sprite` handling, and align runtime-side operational behavior with `DEC-0015`. ## Background `DEC-0015` closes the public contract around `composer.*` and requires that `gfx.set_sprite` be removed completely rather than kept as a compatibility shim. The internal `FrameComposer` ownership model already exists from `DEC-0014` and plans `PLN-0017` through `PLN-0021`. ## Scope ### Included - runtime syscall dispatch for `composer.*` - operational mapping from syscall args to `FrameComposer` - removal of legacy `gfx.set_sprite` runtime handling - runtime-facing tests for composer-domain behavior ### Excluded - spec and ABI doc propagation - cartridge/tooling migration - final `make ci` closure ## Execution Steps ### Step 1 - Add runtime dispatch for `composer.*` **What:** Teach VM runtime dispatch to call `FrameComposer` through the new public contract. **How:** - Add dispatch arms for: - `composer.bind_scene` - `composer.unbind_scene` - `composer.set_camera` - `composer.emit_sprite` - Parse arguments exactly as pinned by the HAL metadata. - Return `ComposerOpStatus` for mutating composer-domain syscalls. **File(s):** - `crates/console/prometeu-system/src/virtual_machine_runtime/dispatch.rs` - any adjacent runtime helpers ### Step 2 - Map operational outcomes cleanly onto `ComposerOpStatus` **What:** Make runtime failures and normal outcomes reflect the new composer-domain status model. **How:** - Bind runtime-side operational checks to status outcomes such as: - scene bank unavailable - bank invalid - argument range invalid - layer invalid - sprite overflow if surfaced operationally - Keep non-fatal overflow behavior aligned with `DEC-0015`. **File(s):** - `crates/console/prometeu-system/src/virtual_machine_runtime/dispatch.rs` - `crates/console/prometeu-hal/src/*` as needed for shared status meaning ### Step 3 - Remove legacy `gfx.set_sprite` runtime support **What:** Delete the old public runtime path for slot-style sprite submission. **How:** - Remove dispatch support for `gfx.set_sprite`. - Remove runtime assumptions about `active`, caller-provided indices, and legacy sprite ABI shape. - Keep no private compatibility hook behind the public API. **File(s):** - `crates/console/prometeu-system/src/virtual_machine_runtime/dispatch.rs` - adjacent tests and public syscall references ## Test Requirements ### Unit Tests - runtime dispatch returns `ComposerOpStatus` for bind, unbind, and emit operations - `composer.set_camera` stores the minimal V1 camera coordinates correctly ### Integration Tests - a VM/runtime test can bind a scene, set camera, emit a sprite, reach `FRAME_SYNC`, and render through the canonical frame path - public runtime behavior rejects removed `gfx.set_sprite` declarations/calls ### Manual Verification - inspect dispatch code to confirm all public orchestration now routes through `FrameComposer` rather than a legacy `gfx` sprite syscall path ## Acceptance Criteria - [ ] Runtime dispatch supports all canonical `composer.*` syscalls. - [ ] Mutating composer-domain calls return `ComposerOpStatus`. - [ ] `gfx.set_sprite` is removed from runtime public handling. - [ ] Runtime tests cover scene bind, camera set, sprite emit, and frame rendering through the public path. ## Dependencies - Depends on `PLN-0022` - Source decision: `DEC-0015` ## Risks - Removing legacy handling before all runtime references are migrated can strand tests or bytecode fixtures. - Poor `ComposerOpStatus` mapping could collapse useful operational distinctions into generic failures.