125 lines
5.1 KiB
Markdown
125 lines
5.1 KiB
Markdown
---
|
|
id: PLN-0144
|
|
ticket: foreground-stack-game-pause-shell-vm-backed
|
|
title: Suspend Resident Game When Shell Takes Foreground
|
|
status: done
|
|
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`
|