prometeu-runtime/discussion/workflow/plans/PLN-0058-systemos-domain-facades-first-wave.md
2026-05-15 06:25:04 +01:00

224 lines
8.2 KiB
Markdown

---
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`