diff --git a/discussion/index.ndjson b/discussion/index.ndjson index 143d6d40..28bf9780 100644 --- a/discussion/index.ndjson +++ b/discussion/index.ndjson @@ -1,8 +1,8 @@ -{"type":"meta","next_id":{"DSC":44,"AGD":46,"DEC":38,"PLN":142,"LSN":52,"CLSN":1}} +{"type":"meta","next_id":{"DSC":44,"AGD":46,"DEC":38,"PLN":145,"LSN":52,"CLSN":1}} {"type":"discussion","id":"DSC-0043","status":"open","ticket":"system-os-cartridge-switch-orchestrator","title":"SystemOS Cartridge Switch Orchestrator","created_at":"2026-07-03","updated_at":"2026-07-03","tags":["runtime","os","lifecycle","game","cartridge","architecture"],"agendas":[{"id":"AGD-0044","file":"AGD-0044-systemos-cartridge-switch-orchestrator.md","status":"open","created_at":"2026-07-03","updated_at":"2026-07-03"}],"decisions":[],"plans":[],"lessons":[]} {"type":"discussion","id":"DSC-0039","status":"abandoned","ticket":"render-pipeline-family-and-future-3d","title":"Render Pipeline Family and Future 3D","created_at":"2026-06-04","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","architecture","pipeline"],"agendas":[{"id":"AGD-0039","file":"AGD-0039-render-pipeline-family-and-future-3d.md","status":"abandoned","created_at":"2026-06-04","updated_at":"2026-06-04","_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."}],"decisions":[],"plans":[],"lessons":[],"_override_reason":"User explicitly chose to close this agenda without a new decision because DSC-0038 already established enough architecture for future extension, and 3D is intentionally deferred."} {"type":"discussion","id":"DSC-0040","status":"done","ticket":"vm-render-parallel-execution-boundary","title":"VM and Render Parallel Execution Boundary","created_at":"2026-06-04","updated_at":"2026-06-06","tags":["runtime","renderer","vm","concurrency","architecture","perf"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0048","file":"discussion/lessons/DSC-0040-vm-render-parallel-execution-boundary/LSN-0048-render-workers-need-a-closed-packet-contract.md","status":"done","created_at":"2026-06-06","updated_at":"2026-06-06"}]} -{"type":"discussion","id":"DSC-0041","status":"in_progress","ticket":"foreground-stack-game-pause-shell-vm-backed","title":"Foreground Stack, Game Pause, and VM-Backed Shell Coexistence","created_at":"2026-06-05","updated_at":"2026-07-03","tags":["runtime","os","lifecycle","shell","game","vm","foreground","architecture"],"agendas":[{"id":"AGD-0041","file":"AGD-0041-foreground-stack-game-pause-shell-vm-backed.md","status":"accepted","created_at":"2026-06-05","updated_at":"2026-07-03"}],"decisions":[{"id":"DEC-0037","file":"DEC-0037-foreground-stack-and-game-pause-contract.md","status":"accepted","created_at":"2026-07-03","updated_at":"2026-07-03","ref_agenda":"AGD-0041"}],"plans":[{"id":"PLN-0136","file":"PLN-0136-route-desktop-home-key-outside-guest-input.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0137","file":"PLN-0137-implement-systemos-foreground-stack-state.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0138","file":"PLN-0138-specify-foreground-pause-and-home-contract.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0139","file":"PLN-0139-validate-game-home-shell-game-end-to-end.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0140","file":"PLN-0140-deliver-game-pause-resume-and-suspension.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0141","file":"PLN-0141-integrate-render-audio-and-input-pause-boundaries.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]}],"lessons":[]} +{"type":"discussion","id":"DSC-0041","status":"in_progress","ticket":"foreground-stack-game-pause-shell-vm-backed","title":"Foreground Stack, Game Pause, and VM-Backed Shell Coexistence","created_at":"2026-06-05","updated_at":"2026-07-04","tags":["runtime","os","lifecycle","shell","game","vm","foreground","architecture"],"agendas":[{"id":"AGD-0041","file":"AGD-0041-foreground-stack-game-pause-shell-vm-backed.md","status":"accepted","created_at":"2026-06-05","updated_at":"2026-07-03"}],"decisions":[{"id":"DEC-0037","file":"DEC-0037-foreground-stack-and-game-pause-contract.md","status":"accepted","created_at":"2026-07-03","updated_at":"2026-07-03","ref_agenda":"AGD-0041"}],"plans":[{"id":"PLN-0136","file":"PLN-0136-route-desktop-home-key-outside-guest-input.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0137","file":"PLN-0137-implement-systemos-foreground-stack-state.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0138","file":"PLN-0138-specify-foreground-pause-and-home-contract.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0139","file":"PLN-0139-validate-game-home-shell-game-end-to-end.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0140","file":"PLN-0140-deliver-game-pause-resume-and-suspension.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0141","file":"PLN-0141-integrate-render-audio-and-input-pause-boundaries.md","status":"done","created_at":"2026-07-03","updated_at":"2026-07-03","ref_decisions":["DEC-0037"]},{"id":"PLN-0142","file":"PLN-0142-deliver-game-lifecycle-events-to-vm-runtime.md","status":"open","created_at":"2026-07-04","updated_at":"2026-07-04","ref_decisions":["DEC-0037"]},{"id":"PLN-0143","file":"PLN-0143-guarantee-cooperative-pause-budget-tick-before-suspension.md","status":"open","created_at":"2026-07-04","updated_at":"2026-07-04","ref_decisions":["DEC-0037"]},{"id":"PLN-0144","file":"PLN-0144-suspend-resident-game-when-shell-takes-foreground.md","status":"open","created_at":"2026-07-04","updated_at":"2026-07-04","ref_decisions":["DEC-0037"]}],"lessons":[]} {"type":"discussion","id":"DSC-0042","status":"done","ticket":"real-render-worker-establishment","title":"Real Render Worker Establishment","created_at":"2026-06-06","updated_at":"2026-06-20","tags":["runtime","renderer","worker","concurrency","host","hal","architecture"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0049","file":"discussion/lessons/DSC-0042-real-render-worker-establishment/LSN-0049-render-worker-publication-boundary.md","status":"done","created_at":"2026-06-20","updated_at":"2026-06-20"}]} {"type":"discussion","id":"DSC-0038","status":"done","ticket":"render-frame-packet-boundary","title":"Logical Render Pipelines and Command Packets","created_at":"2026-05-25","updated_at":"2026-06-04","tags":["gfx","renderer","runtime","frame-composer","architecture","ui","pipeline"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0047","file":"discussion/lessons/DSC-0038-render-frame-packet-boundary/LSN-0047-typed-render-submissions-preserve-domain-boundaries.md","status":"done","created_at":"2026-06-04","updated_at":"2026-06-04"}]} {"type":"discussion","id":"DSC-0035","status":"done","ticket":"task-owned-shell-windows","title":"Agenda - Task-Owned Shell Windows","created_at":"2026-05-15","updated_at":"2026-05-15","tags":["runtime","os","task","window-manager","shell","lifecycle"],"agendas":[],"decisions":[],"plans":[],"lessons":[{"id":"LSN-0044","file":"discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md","status":"done","created_at":"2026-05-15","updated_at":"2026-05-15"}]} diff --git a/discussion/workflow/plans/PLN-0142-deliver-game-lifecycle-events-to-vm-runtime.md b/discussion/workflow/plans/PLN-0142-deliver-game-lifecycle-events-to-vm-runtime.md new file mode 100644 index 00000000..9ee5c0a5 --- /dev/null +++ b/discussion/workflow/plans/PLN-0142-deliver-game-lifecycle-events-to-vm-runtime.md @@ -0,0 +1,127 @@ +--- +id: PLN-0142 +ticket: foreground-stack-game-pause-shell-vm-backed +title: Deliver Game Lifecycle Events To VM Runtime +status: open +created: 2026-07-04 +ref_decisions: [DEC-0037] +tags: [runtime, os, lifecycle, shell, game, vm, foreground, architecture] +--- + +## Briefing + +`DEC-0037` requires pause/resume to be Game-visible lifecycle events. The +current implementation records `GameLifecycleEvent` values in SystemOS, but no +runtime or VM execution path consumes them. Tests currently prove that the OS +queue contains events, not that the Game/runtime can observe them before +suspension or after resume. + +## Objective + +Deliver Game lifecycle pause/resume events from SystemOS into the VM runtime +boundary in a deterministic, testable way, without exposing Home as guest pad +input or a userland syscall. + +## Dependencies + +- Source decision: `DEC-0037`. +- Fixes the lifecycle event delivery gap found after `PLN-0140` and + `PLN-0141`. +- `PLN-0143` depends on this plan if it needs to prove that the pause event is + consumed before the pause budget expires. + +## Scope + +Included: + +- Define the runtime-facing lifecycle event delivery API for `Pause` and + `ResumeForeground`. +- Move events from the SystemOS queue into the VM/runtime tick boundary. +- Make delivered events observable in tests without creating a broad app event + system. +- Preserve the distinction between lifecycle pause and debugger pause. +- Ensure events are delivered only to the resident Game task they target. + +Excluded: + +- No guest Home input, pad field, intrinsic, or syscall. +- No general userland event bus. +- No background execution while suspended. +- No new Shell lifecycle event model. + +## Non-Goals + +- Do not implement Game-to-Game switching. +- Do not change renderer ownership policy except where tests need to assert + lifecycle event ordering. +- Do not add wall-clock timers or asynchronous callbacks. + +## Execution Method + +1. Add a narrow VM runtime lifecycle inbox. + - What changes: introduce a small data structure for pending/delivered Game + lifecycle events in `VirtualMachineRuntime`. + - How it changes: add methods such as `queue_game_lifecycle_events`, + `take_delivered_game_lifecycle_events`, or a more idiomatic local name + that preserves deterministic frame-boundary delivery. + - File(s): `crates/console/prometeu-system/src/services/vm_runtime/mod.rs`, + `crates/console/prometeu-system/src/services/vm_runtime/tick.rs`, and + focused tests under `crates/console/prometeu-system/src/services/vm_runtime/`. + +2. Route SystemOS events into the VM facade before ticking. + - What changes: `VmFacade::tick` must drain lifecycle events from SystemOS + and pass only events targeted at the currently running resident Game into + the VM runtime lifecycle inbox. + - How it changes: use the existing `LifecycleFacade::take_game_lifecycle_events` + or replace it with an equivalent internal method if borrowing requires a + cleaner API. Do not leave events only observable through + `pending_game_lifecycle_events`. + - File(s): `crates/console/prometeu-system/src/os/facades/vm.rs`, + `crates/console/prometeu-system/src/os/facades/lifecycle.rs`. + +3. Expose deterministic test visibility. + - What changes: tests must be able to assert that `Pause` and + `ResumeForeground` reached the VM runtime boundary. + - How it changes: add test-only or public diagnostic accessors on + `VmFacade`/`VirtualMachineRuntime` for delivered lifecycle events, scoped + to lifecycle validation rather than a guest ABI. + - File(s): `crates/console/prometeu-system/src/os/facades/vm.rs`, + `crates/console/prometeu-system/src/services/vm_runtime/tests.rs`. + +4. Update firmware tests to assert delivery, not only queue presence. + - What changes: existing firmware tests that inspect + `pending_game_lifecycle_events` should assert VM-runtime delivery at the + tick boundary. + - How it changes: after a Game pause/resume flow, verify that the VM/runtime + observed the lifecycle event in order. + - File(s): `crates/console/prometeu-firmware/src/firmware/firmware.rs`. + +## Acceptance Criteria + +- [ ] `Pause` is moved from SystemOS into the VM runtime boundary before + suspension is allowed to complete. +- [ ] `ResumeForeground` is moved into the VM runtime boundary before the Game + is considered visually restored. +- [ ] Tests fail if events remain only in `SystemOS.game_lifecycle_events`. +- [ ] Lifecycle event delivery does not mutate `InputSignals`. +- [ ] Debugger pause remains separate from lifecycle pause. + +## Tests + +- Unit tests in `prometeu-system` proving VM runtime lifecycle event delivery + and drain semantics. +- Firmware tests proving Home request delivers `Pause` to the VM/runtime before + suspension. +- Firmware tests proving resident Game resume delivers `ResumeForeground` + before Game foreground restoration. +- Run `cargo test -p prometeu-system`. +- Run `cargo test -p prometeu-firmware`. +- Run `discussion validate`. + +## Affected Artifacts + +- `crates/console/prometeu-system/src/os/facades/vm.rs` +- `crates/console/prometeu-system/src/os/facades/lifecycle.rs` +- `crates/console/prometeu-system/src/services/vm_runtime/mod.rs` +- `crates/console/prometeu-system/src/services/vm_runtime/tick.rs` +- `crates/console/prometeu-firmware/src/firmware/firmware.rs` diff --git a/discussion/workflow/plans/PLN-0143-guarantee-cooperative-pause-budget-tick-before-suspension.md b/discussion/workflow/plans/PLN-0143-guarantee-cooperative-pause-budget-tick-before-suspension.md new file mode 100644 index 00000000..0ec8a98b --- /dev/null +++ b/discussion/workflow/plans/PLN-0143-guarantee-cooperative-pause-budget-tick-before-suspension.md @@ -0,0 +1,122 @@ +--- +id: PLN-0143 +ticket: foreground-stack-game-pause-shell-vm-backed +title: Guarantee Cooperative Pause Budget Tick Before Suspension +status: open +created: 2026-07-04 +ref_decisions: [DEC-0037] +tags: [runtime, os, lifecycle, shell, game, vm, foreground, architecture] +--- + +## Briefing + +`DEC-0037` requires a Game-visible `Paused` event followed by a bounded +cooperative reaction budget before SystemOS imposes `Suspended`. The current +implementation uses a one-tick budget and advances it before `vm.tick` in +`GameRunningStep`, so the Game can be suspended without any runtime tick in +which it could observe or react to pause. + +## Objective + +Guarantee at least one deterministic VM/runtime delivery point for the Game to +observe pause before forced suspension, while preserving SystemOS authority to +suspend the Game after the budget. + +## Dependencies + +- Source decision: `DEC-0037`. +- Should be executed after or together with `PLN-0142`, because budget tests + must prove delivered lifecycle events, not only queued OS events. + +## Scope + +Included: + +- Fix pause budget ordering so the pause budget cannot expire before the VM + runtime has a delivery point for `Pause`. +- Define the budget in deterministic machine ticks/frames, not wall-clock time. +- Ensure a Game receives no normal gameplay ticks after it reaches + `PausedSuspended`. +- Preserve the existing forced-suspension authority when the budget expires. +- Update tests that currently assert no VM tick occurs immediately after Home. + +Excluded: + +- No guest-controlled cancellation of suspension. +- No background execution after suspension. +- No extension of the pause budget based on host timing. +- No direct visual-return behavior; render restore gating remains covered by + the existing render boundary work. + +## Non-Goals + +- Do not add a general scheduler. +- Do not make pause cooperation mandatory for suspension. +- Do not conflate lifecycle pause with debugger pause. + +## Execution Method + +1. Redefine pause budget state transitions. + - What changes: `ResidentGameState::PauseRequested` must represent a state + in which one or more delivery ticks remain before `PausedSuspended`. + - How it changes: adjust `ForegroundStack::advance_pause_budget` or split it + into explicit methods such as `mark_pause_delivered` and + `advance_pause_budget_after_delivery`. + - File(s): `crates/console/prometeu-system/src/services/foreground.rs`. + +2. Move budget advancement after lifecycle delivery. + - What changes: `GameRunningStep::on_update` must not suspend before the VM + runtime has a chance to receive and process the pause lifecycle event. + - How it changes: reorder the GameRunning update so the event delivery path + runs first, then the budget is advanced, and only a subsequent eligible + boundary can force suspension. + - File(s): `crates/console/prometeu-firmware/src/firmware/firmware_step_game_running.rs`, + `crates/console/prometeu-system/src/os/facades/vm.rs`. + +3. Preserve no-tick-after-suspended behavior. + - What changes: once `ResidentGameState::PausedSuspended` and + `TaskState::Suspended` are reached, the Game must not receive normal ticks, + normal input, or frame pacing. + - How it changes: keep the existing early transition to Hub after suspension + expires, but ensure it occurs after the cooperative pause window rather + than before it. + - File(s): `crates/console/prometeu-firmware/src/firmware/firmware_step_game_running.rs`. + +4. Update tests to match the corrected semantics. + - What changes: tests must stop asserting that the first tick after Home does + zero VM work purely because Home was requested. + - How it changes: assert that the pause event was delivered during the + cooperative window, then assert that a later deterministic tick forces + suspension and no further Game ticks occur. + - File(s): `crates/console/prometeu-firmware/src/firmware/firmware.rs`, + `crates/console/prometeu-system/src/os/system_os.rs`. + +## Acceptance Criteria + +- [ ] A Game receives a deterministic pause delivery point before SystemOS + suspends it. +- [ ] SystemOS still suspends the Game after the bounded budget even if the + Game does not cooperate. +- [ ] A suspended Game receives no normal gameplay ticks, normal Game input, or + frame pacing. +- [ ] Tests prove the order: Home request -> pause delivery -> budget expiry -> + suspension. +- [ ] Debugger pause behavior is unchanged. + +## Tests + +- Unit tests in `prometeu-system` for pause budget transitions. +- Firmware tests for non-cooperative forced suspension after at least one + delivered pause boundary. +- Regression tests proving suspended Game tick count does not advance. +- Run `cargo test -p prometeu-system foreground lifecycle`. +- Run `cargo test -p prometeu-firmware pause`. +- Run `discussion validate`. + +## Affected Artifacts + +- `crates/console/prometeu-system/src/services/foreground.rs` +- `crates/console/prometeu-system/src/os/facades/lifecycle.rs` +- `crates/console/prometeu-system/src/os/facades/vm.rs` +- `crates/console/prometeu-firmware/src/firmware/firmware_step_game_running.rs` +- `crates/console/prometeu-firmware/src/firmware/firmware.rs` diff --git a/discussion/workflow/plans/PLN-0144-suspend-resident-game-when-shell-takes-foreground.md b/discussion/workflow/plans/PLN-0144-suspend-resident-game-when-shell-takes-foreground.md new file mode 100644 index 00000000..3bb7c682 --- /dev/null +++ b/discussion/workflow/plans/PLN-0144-suspend-resident-game-when-shell-takes-foreground.md @@ -0,0 +1,124 @@ +--- +id: PLN-0144 +ticket: foreground-stack-game-pause-shell-vm-backed +title: Suspend Resident Game When Shell Takes Foreground +status: open +created: 2026-07-04 +ref_decisions: [DEC-0037] +tags: [runtime, os, lifecycle, shell, game, vm, foreground, architecture] +--- + +## Briefing + +`DEC-0037` says a suspended resident Game must not receive normal gameplay +ticks, normal Game input, or frame pacing while Hub/Shell owns foreground. The +current `set_shell_foreground` path can mark the resident Game as +`PausedSuspended` in the foreground stack while `TaskManager::set_foreground` +only demotes the previous foreground Game task to `Background`. This creates a +state mismatch if a Shell is opened while the Game has not already gone through +the Home suspension path. + +## Objective + +Make Shell foreground acquisition either require an already suspended resident +Game or perform the necessary OS-owned suspension consistently across +foreground stack, task manager, and process manager. + +## Dependencies + +- Source decision: `DEC-0037`. +- Can be implemented independently of `PLN-0142` and `PLN-0143`, but tests + should be rerun with those fixes if they are executed first. + +## Scope + +Included: + +- Close the mismatch between `ResidentGameState::PausedSuspended` and + `TaskState::Background`. +- Ensure Shell foreground cannot leave a resident Game running or backgrounded. +- Cover both `create_vm_shell_task` and `create_native_shell_task` paths. +- Preserve the rule that only one foreground Shell may exist. +- Keep the normal Home -> Shell flow working. + +Excluded: + +- No direct Shell -> Game return behavior; v1 still returns Shell close to Hub. +- No background Game execution. +- No multiple resident Games. +- No Shell persistence policy changes. + +## Non-Goals + +- Do not broaden Shell lifecycle semantics. +- Do not implement Game-to-Game switching. +- Do not add UI controls for resume. + +## Execution Method + +1. Define the legal Shell foreground precondition. + - What changes: decide in code whether Shell foreground requires the + resident Game to already be `PausedSuspended`, or whether + `set_shell_foreground_task` is responsible for suspending it. + - How it changes: prefer centralizing the invariant in + `LifecycleFacade::set_shell_foreground_task`, because it owns task/process + transitions. + - File(s): `crates/console/prometeu-system/src/os/facades/lifecycle.rs`, + `crates/console/prometeu-system/src/services/foreground.rs`. + +2. Synchronize task/process state when Shell takes foreground. + - What changes: if a resident Game exists and is not already suspended, + mark the Game task and process `Suspended` before or during Shell + foreground transition. + - How it changes: use `process_id_for_task` for the resident Game and call + `task_manager.mark_suspended` and `process_manager.mark_suspended` in the + same lifecycle operation that sets Shell foreground. + - File(s): `crates/console/prometeu-system/src/os/facades/lifecycle.rs`. + +3. Tighten foreground stack behavior. + - What changes: `ForegroundStack::set_shell_foreground` must not silently + hide invalid state transitions. + - How it changes: either reject Shell foreground when the resident Game is + still `Foreground`/`PauseRequested`, or return enough information for the + lifecycle facade to suspend the resident Game explicitly. + - File(s): `crates/console/prometeu-system/src/services/foreground.rs`. + +4. Add regression tests for reachable session paths. + - What changes: create tests that call `create_vm_shell_task` and + `create_native_shell_task` while a Game task is foreground. + - How it changes: assert foreground owner is Shell, resident Game remains + recorded, Game task state is `Suspended`, and Game process state is + `Suspended`. + - File(s): `crates/console/prometeu-system/src/os/system_os.rs`, + `crates/console/prometeu-firmware/src/firmware/firmware.rs` if the + firmware Home/Shell path needs coverage. + +## Acceptance Criteria + +- [ ] A Shell foreground transition cannot leave the resident Game in + `TaskState::Background`. +- [ ] Foreground stack state, task state, and process state agree that the + resident Game is suspended while Shell is foreground. +- [ ] `create_vm_shell_task` and `create_native_shell_task` both preserve the + invariant. +- [ ] Opening a second foreground Shell remains rejected. +- [ ] Closing Shell still returns to Hub/Home, not directly to Game. + +## Tests + +- Unit tests in `prometeu-system` for `set_shell_foreground_task` with a + resident foreground Game. +- Session facade tests for VM Shell and native Shell creation while a Game is + resident. +- Existing firmware Shell close tests must continue to pass. +- Run `cargo test -p prometeu-system foreground lifecycle shell`. +- Run `cargo test -p prometeu-firmware shell`. +- Run `discussion validate`. + +## Affected Artifacts + +- `crates/console/prometeu-system/src/services/foreground.rs` +- `crates/console/prometeu-system/src/os/facades/lifecycle.rs` +- `crates/console/prometeu-system/src/os/facades/sessions.rs` +- `crates/console/prometeu-system/src/os/system_os.rs` +- `crates/console/prometeu-firmware/src/firmware/firmware.rs`