--- id: PLN-0062 ticket: prometeu-hub-ui-direction title: Native Shell Launch and Lifecycle Wiring status: done created: 2026-05-15 ref_decisions: [DEC-0028] tags: [hub, ui, shell, system-apps, lifecycle, design-system] --- ## Briefing Implement the OS/Firmware wiring required by `DEC-0028` so the Hub can emit a launch intent for `ShellA` or `ShellB`, and SystemOS/Firmware can create a native Shell task, create a task-owned window, run the Shell state, close through lifecycle, and return to Hub/Home. Source decision: `DEC-0028`. ## Objective Make the launch/close path architecturally correct before the visual slice depends on it: - Hub emits launch intent. - SystemOS/Firmware creates native Shell task/process. - The Shell app has a `WindowOwner::Task(task_id)` window. - Close uses `os.lifecycle().close_task(task_id)`. - `ShellRunningStep` returns to Hub/Home after close. ## Dependencies - `DEC-0028` must remain accepted. - This plan should execute before `PLN-0064`, because the UI buttons need a real launch target. - This plan may execute before or alongside `PLN-0063` if tests can trigger Hub actions without mouse input. ## Scope - Update the Hub update result shape so it can report launch/close actions, not only crashes. - Add native fake Shell app identity for `ShellA` and `ShellB`. - Wire Firmware/SystemOS launch handling from Hub intent to `sessions().create_native_shell_task(...)`. - Create and focus a task-owned window for the launched native Shell task. - Ensure app close routes to lifecycle close, not only window removal. - Preserve the existing task-owned window liveness rule in `ShellRunningStep`. ## Non-Goals - No generic app catalog. - No reusable UI toolkit. - No game cartridge window model. - No background/minimize/overlay preservation semantics. - No controller focus navigation. - No public spec change unless implementation introduces a new public API. ## Execution Method 1. Inspect current launch state. - What changes: identify the exact update path from `HubHomeStep` to `PrometeuHub::update_shell_profile` and `ShellRunningStep`. - How: read the current firmware state transitions and Hub update result. - Files: `crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs`, `crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs`, `crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs`. 2. Replace crash-only Hub output with an action-bearing result. - What changes: extend or replace `SystemProfileUpdate` so it can carry `LaunchNativeShell(ShellA|ShellB)` and close intent while preserving crash reporting. - How: add a small enum local to the Hub/system profile boundary; keep visual components free of lifecycle mutation. - Files: `crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs` and firmware call sites. 3. Handle launch in Firmware/SystemOS. - What changes: when Hub emits launch intent, create the native Shell task through `os.sessions().create_native_shell_task(app_id, title)`. - How: map `ShellA` and `ShellB` to stable local app ids/titles for this fake-app slice. - Files: `crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs`; add helper code in `prometeu-system` only if needed to avoid duplication. 4. Create the task-owned Shell window. - What changes: after task creation, create and focus a window with `WindowOwner::Task(task_id)`. - How: use the existing window facade first; introduce a narrow helper only if the launch sequence becomes duplicated or leaks into visual components. - Files: `crates/console/prometeu-system/src/os/facades/sessions.rs`, `crates/console/prometeu-system/src/os/facades/window.rs`, or firmware step depending on the smallest clean integration point. 5. Route close through lifecycle. - What changes: app/window close must call `os.lifecycle().close_task(task_id)` or emit an equivalent action handled by Firmware/SystemOS. - How: keep window removal separate from lifecycle semantics; do not treat `close_window` as app close. - Files: `crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs`, `crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs`. 6. Add behavior tests. - What changes: add tests proving launch creates native Shell task/window and close returns to Hub. - How: test at SystemOS/Firmware boundary rather than only manager internals. - Files: existing firmware/system test modules, preferably near current lifecycle/window tests. ## Acceptance Criteria - [x] Launching `ShellA` creates a native Shell task/process. - [x] Launching `ShellB` creates a native Shell task/process. - [x] Each launched Shell app receives a focused `WindowOwner::Task(task_id)` window. - [x] Closing the Shell app closes lifecycle state through `os.lifecycle().close_task(task_id)`. - [x] Closing the Shell app returns firmware to `HubHome`. - [x] Hub visual code does not directly mutate task/process managers. - [x] Existing shell liveness behavior remains intact. ## Tests - Unit tests for any new Hub action enum or mapping logic. - SystemOS tests for any new helper/facade that creates native Shell task plus task-owned window. - Firmware tests for HubHome launch to ShellRunning and ShellRunning close to HubHome. - Regression tests for `focused_window_belongs_to_task(task_id)` behavior if touched. ## Affected Artifacts - `crates/console/prometeu-system/src/programs/prometeu_hub/prometeu_hub.rs` - `crates/console/prometeu-firmware/src/firmware/firmware_step_hub_home.rs` - `crates/console/prometeu-firmware/src/firmware/firmware_step_shell_running.rs` - `crates/console/prometeu-system/src/os/facades/sessions.rs` - `crates/console/prometeu-system/src/os/facades/window.rs` - Existing SystemOS/Firmware tests