--- id: PLN-0060 ticket: task-owned-shell-windows title: Plan - Focused Window Ownership API status: open created: 2026-05-15 completed: ref_decisions: [DEC-0027] tags: [runtime, os, task, window-manager, shell, lifecycle, code] --- # Plan - Focused Window Ownership API ## Briefing Add the OS/window query required by `DEC-0027`: `os.windows().focused_window_belongs_to_task(task_id)`. This plan owns the system-side API and tests. It does not change firmware control flow; that is covered by `PLN-0061`. ## Decisions de Origem - `DEC-0027` - Task-Owned Shell Windows ## Alvo `WindowFacade` must expose a focused-window ownership predicate that answers whether the global focused window belongs to a specific `TaskId`. ## Escopo Included: - Add a focused ownership query to [window.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-system/src/os/facades/window.rs). - Add a helper in [window_manager.rs](/Users/niltonconstantino/personal/workspace.personal/intrepid/prometeu/runtime/crates/console/prometeu-system/src/services/windows/window_manager.rs) if it keeps the facade thin and testable. - Add unit tests for focused-window ownership in the `prometeu-system` crate. ## Fora de Escopo - Changing `ShellRunningStep`. - Removing `focused_window_active` from `PrometeuHubOutcome`. - Spec edits. - Overlay/modal policy or active-window semantics. - Multiple-window policy beyond querying the single global focused window. ## Plano de Execucao 1. Add `WindowManager::focused_window_belongs_to_task`. In `crates/console/prometeu-system/src/services/windows/window_manager.rs`, implement a method that: - returns `false` when `focused` is `None`; - finds the focused window by `WindowId`; - returns `true` only when its owner is `WindowOwner::Task(task_id)`; - returns `false` for `Hub`, `Overlay`, another task id, or stale focus. 2. Add `WindowFacade::focused_window_belongs_to_task`. In `crates/console/prometeu-system/src/os/facades/window.rs`, expose the public facade method and delegate to the manager/helper. 3. Keep existing facade methods intact. Do not remove `focused_window()` or `windows()` in this plan. Existing call sites may still need them until `PLN-0061` updates firmware. 4. Add tests in `window_manager.rs`. Cover: - no focused window returns `false`; - focused `WindowOwner::Task(task_id)` returns `true`; - focused `WindowOwner::Task(other_task)` returns `false`; - focused `WindowOwner::Hub` returns `false`; - focused `WindowOwner::Overlay` returns `false`; - stale focused id after window removal returns `false`. 5. Add facade-level coverage if existing `SystemOS` tests provide a convenient pattern. If facade-level setup would duplicate manager coverage heavily, keep the unit coverage at the manager level and rely on the facade as a direct delegation. ## Criterios de Aceite - [ ] `os.windows().focused_window_belongs_to_task(task_id)` compiles. - [ ] The predicate returns `true` only for the currently focused `WindowOwner::Task(task_id)`. - [ ] `Hub`, `Overlay`, absent focus, stale focus, and other task owners return `false`. - [ ] No firmware behavior changes are included in this plan. ## Tests / Validacao - Run `cargo test -p prometeu-system`. - Run any narrower test command available for the window manager module if the crate supports it. - Run `discussion validate`. ## Riscos - Directly scanning `windows` by focused id is simple but can hide stale focus bugs. Tests must lock stale focus behavior to `false`. - Adding only a facade method without manager coverage would make the contract harder to verify. Prefer manager tests. - Borrowing through `WindowFacade` must remain short-lived and compatible with existing `SystemOS` facade patterns.