--- id: PLN-0061 ticket: task-owned-shell-windows title: Plan - Shell Running Lifecycle Integration status: open created: 2026-05-15 completed: ref_decisions: [DEC-0027] tags: [runtime, os, task, window-manager, shell, lifecycle, firmware, tests] --- # Plan - Shell Running Lifecycle Integration ## Briefing Integrate the accepted task-owned window contract into `ShellRunningStep`. `ShellRunningStep` must stop using generic focused-window presence as the liveness contract and must close the shell task through lifecycle when the focused window no longer belongs to that task. ## Decisions de Origem - `DEC-0027` - Task-Owned Shell Windows ## Alvo `ShellRunningStep` continues only when: ```text TaskState::Foreground + os.windows().focused_window_belongs_to_task(task_id) ``` When that predicate is false, the step must call `os.lifecycle().close_task(task_id)` and return `FirmwareState::HubHome`. ## Escopo Included: - Update [firmware_step_shell_running.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs). - Adjust the shell-running path in [prometeu_hub.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs) only if `focused_window_active` becomes unused or misleading. - Add firmware/system tests proving lifecycle closure and Hub return behavior. - Preserve `GameRunningStep` behavior. ## Fora de Escopo - Spec edits; covered by `PLN-0059`. - Adding the window ownership API; covered by `PLN-0060`. - Overlay/modal policy. - Background, minimization, app switcher, dock, or multiple-window behavior. - Treating games as windows. ## Plano de Execucao 1. Depend on `PLN-0060`. Do not update `ShellRunningStep` until `os.windows().focused_window_belongs_to_task(task_id)` exists. 2. Replace the liveness predicate in `ShellRunningStep`. In `firmware_step_shell_running.rs`, keep the existing `TaskState` validation. After `ctx.hub.update_shell_profile(...)`, replace the `outcome.focused_window_active` check with: ```text !ctx.os.windows().focused_window_belongs_to_task(self.task_id) ``` 3. Preserve crash handling order. Keep VM crash handling before window-liveness closure so a crash reported by the shell update remains a crash, not a normal close. 4. Close through lifecycle before returning Hub. When the focused-window ownership predicate is false: - log the closure with task id; - call `ctx.os.lifecycle().close_task(self.task_id)`; - log lifecycle close errors; - return `Some(FirmwareState::HubHome(HubHomeStep))`. 5. De-emphasize or remove `focused_window_active`. If `SystemProfileUpdate.focused_window_active` has no remaining call sites, remove it from `SystemProfileUpdate` and its construction. If another legitimate caller remains, keep it but do not use it for shell task liveness. 6. Add or update tests. Use existing firmware tests in [firmware.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-firmware/src/firmware/firmware.rs) or a nearby test module. Cover: - focused task-owned window keeps the shell path running; - no focused window closes task and returns `HubHome`; - focused `Hub` window closes task and returns `HubHome`; - focused `Overlay` window closes task and returns `HubHome` in v1; - focused window for another task closes task and returns `HubHome`; - lifecycle close changes task to `Closed` and process to `Stopped`; - `GameRunningStep` remains independent from `WindowManager`. ## Criterios de Aceite - [ ] `ShellRunningStep` no longer uses `focused_window_active` as its continuation contract. - [ ] `ShellRunningStep` uses `os.windows().focused_window_belongs_to_task(self.task_id)`. - [ ] A false predicate closes the task through lifecycle before returning `HubHome`. - [ ] `Hub`, `Overlay`, absent focus, and another task's focused window all fail the predicate for the current shell task. - [ ] Game-running behavior is unchanged and remains outside `WindowManager`. ## Tests / Validacao - Run `cargo test -p prometeu-system`. - Run `cargo test -p prometeu-firmware`. - Run a workspace or targeted build command used by this repository if the two crate tests are not sufficient. - Run `discussion validate`. ## Riscos - Current Hub update behavior may close or replace windows during the same tick; tests need to account for the final focused window after `update_shell_profile`. - Removing `focused_window_active` may require small cleanup in system tests or callers. - The v1 overlay behavior is intentionally strict. Do not add overlay preservation logic in this plan.