--- id: PLN-0058 ticket: system-os-domain-facades title: SystemOS Domain Facades First Wave status: open created: 2026-05-15 ref_decisions: [DEC-0026] tags: [runtime, os, services, api-surface, lifecycle, fs] --- ## Briefing Implement the first wave of `SystemOS` domain facades required by `DEC-0026`. `SystemOS` remains the OS ownership boundary, but callers must access behavior through domain views instead of root-level methods or public internal fields. ## Source Decisions - `DEC-0026`: `SystemOS` must expose method-based domain facades for lifecycle, sessions, VM, filesystem and window operations, while keeping `log(...)` on the root. - Related: `DEC-0025` keeps lifecycle coordination under `SystemOS`. - Related: `DEC-0024` keeps services owned or mediated by `SystemOS`. ## Target Create these first-wave access shapes: ```rust os.lifecycle().suspend_task(task_id) os.sessions().create_vm_game_task(app_id, title) os.vm().initialize(vm, cartridge) os.vm().tick(vm, signals, hw) os.fs().mount(backend) os.window().set_focus(window_id) os.log(level, source, tag, msg) ``` After this plan, migrated domains must no longer require public direct access to `task_manager`, `process_manager`, `window_manager`, `vm_runtime`, `fs`, `fs_state`, `memcard`, `open_files` or `next_handle`. ## Scope - Add facade/view types under `crates/console/prometeu-system/src/os/`. - Add `SystemOS` methods: - `lifecycle()` - `sessions()` - `vm()` - `fs()` - `window()` - Move root lifecycle methods behind `lifecycle()`. - Move task/process session creation behind `sessions()`. - Move VM initialization/ticking/reset or execution helpers behind `vm()`. - Move filesystem mount/open/read/write/close entry points behind `fs()` when the operation exists at OS level. - Move window operations behind `window()`. - Keep `SystemOS::log(...)` at root. - Migrate firmware, Hub and tests to facade access. - Make migrated internal `SystemOS` fields private. ## Out of Scope - Changing service ownership established by `DEC-0024`. - Changing lifecycle semantics established by `DEC-0025`. - Introducing `os.lifecycle` as a direct public field. - Background lifecycle semantics. - New filesystem syscall behavior beyond exposing existing OS-owned operations. - Diagnostics/crash report persistence. - Redesigning Hub UI or app switching. - Replacing VM runtime tests that intentionally test `VirtualMachineRuntime` directly. ## Execution Plan 1. Create facade modules and view types. - Target files: - `crates/console/prometeu-system/src/os/mod.rs` - `crates/console/prometeu-system/src/os/system_os.rs` - new facade modules under `crates/console/prometeu-system/src/os/` - Define mutable view structs such as `LifecycleFacade<'a>`, `SessionsFacade<'a>`, `VmFacade<'a>`, `FsFacade<'a>` and `WindowFacade<'a>`. - Each facade should borrow the needed `SystemOS` internals and must not own duplicated state. 2. Add `SystemOS` facade accessors. - Add `SystemOS::lifecycle(&mut self) -> LifecycleFacade<'_>`. - Add `SystemOS::sessions(&mut self) -> SessionsFacade<'_>`. - Add `SystemOS::vm(&mut self) -> VmFacade<'_>`. - Add `SystemOS::fs(&mut self) -> FsFacade<'_>`. - Add `SystemOS::window(&mut self) -> WindowFacade<'_>`. - Keep `SystemOS::new(...)` and `SystemOS::log(...)` on the root. 3. Move lifecycle operations. - Target existing logic in `crates/console/prometeu-system/src/os/system_os.rs`. - Move or delegate: - `set_foreground_task` - `suspend_task` - `resume_task` - `close_task` - `crash_task` - The facade must preserve typed `LifecycleError` behavior. - Callers should use `os.lifecycle().crash_task(...)` rather than `os.crash_task(...)`. 4. Move session creation operations. - Move or delegate: - `create_vm_game_task` - `create_vm_shell_task` - `create_native_shell_task` - These operations may call the lifecycle facade internally to foreground newly created tasks. - Firmware should use `ctx.os.sessions().create_vm_game_task(...)` and `ctx.os.sessions().create_vm_shell_task(...)`. 5. Move VM operations. - Move or delegate: - `initialize_vm` as `os.vm().initialize(...)` - `tick_vm` as `os.vm().tick(...)` - Include reset access if needed to remove direct `os.vm_runtime.reset(...)` from firmware. - Preserve VM runtime behavior and logging. 6. Move filesystem operations. - Move or delegate existing root filesystem operations: - `mount_fs` as `os.fs().mount(...)` - `unmount_fs` if still present, even though `DEC-0026` only names mount/open/read/write/close for the target surface. - Expose OS-owned open/read/write/close only if those operations already have a suitable service-level implementation; otherwise leave them as explicit follow-up within the facade module without inventing new behavior. - Keep filesystem state private to `SystemOS`/facade internals. 7. Move window operations. - Target: - `crates/console/prometeu-system/src/services/window_manager.rs` - `crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs` - firmware launch tests and cartridge loading. - Provide facade operations: - `add_window` - `set_focus` - `focused_window` - `close_window` - Add any narrow helper needed to preserve existing behavior such as removing all windows, but keep it under `window()` rather than exposing `window_manager`. 8. Encapsulate migrated fields. - In `SystemOS`, remove `pub` from migrated internals once callsites have moved: - `vm_runtime` - `process_manager` - `task_manager` - `window_manager` - `fs` - `fs_state` - `memcard` - `open_files` - `next_handle` - Keep `log_service` private unless a plan proves a public log handle is required. - Avoid adding compatibility root methods for the old surface. 9. Update tests. - Move `SystemOS` lifecycle tests to facade calls. - Update firmware tests to observe state through facades or domain-specific inspection helpers rather than direct internal fields. - Preserve direct `VirtualMachineRuntime` tests where they test the VM runtime service itself, not `SystemOS`. ## Acceptance Criteria - `SystemOS` exposes `lifecycle()`, `sessions()`, `vm()`, `fs()` and `window()`. - Root `SystemOS` keeps `new(...)` and `log(...)`. - Lifecycle callsites use `os.lifecycle()`. - Session creation callsites use `os.sessions()`. - VM initialization/tick/reset callsites use `os.vm()`. - Window callsites use `os.window()`. - Existing root methods migrated by this plan are removed or made private. - Migrated internal fields no longer remain public on `SystemOS`. - No facade duplicates service state. - Existing behavior remains unchanged. ## Tests / Validation - Run `cargo test -p prometeu-system`. - Run `cargo test -p prometeu-firmware`. - Run `discussion validate`. - Confirm with search that migrated callsites no longer use: - `os.task_manager` - `os.process_manager` - `os.window_manager` - `os.vm_runtime` - `os.suspend_task` - `os.resume_task` - `os.close_task` - `os.crash_task` - `os.initialize_vm` - `os.tick_vm` - `os.create_vm_game_task` - `os.create_vm_shell_task` ## Risks - Borrowing may require facades to expose narrow methods rather than returning long-lived mutable references. Keep facades short-lived and method-based. - Some tests currently inspect internal fields directly. Prefer domain-level inspection helpers over keeping fields public. - Filesystem `open/read/write/close` may not all exist as OS-level operations yet. Do not invent new filesystem semantics while implementing the facade. - Removing all public internals in one change can be broad. If a field cannot be hidden without unrelated redesign, document the temporary exception in the implementation and leave a follow-up plan. ## Affected Artifacts - `crates/console/prometeu-system/src/os/**` - `crates/console/prometeu-system/src/programs/prometeu_hub/**` - `crates/console/prometeu-system/src/services/window_manager.rs` - `crates/console/prometeu-firmware/src/firmware/**` - `discussion/index.ndjson` - `discussion/workflow/plans/PLN-0058-systemos-domain-facades-first-wave.md`