prometeu-runtime/discussion/workflow/plans/PLN-0060-plan-focused-window-ownership-api.md

106 lines
3.8 KiB
Markdown

---
id: PLN-0060
ticket: task-owned-shell-windows
title: Plan - Focused Window Ownership API
status: done
created: 2026-05-15
completed: 2026-05-15
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
- [x] `os.windows().focused_window_belongs_to_task(task_id)` compiles.
- [x] The predicate returns `true` only for the currently focused
`WindowOwner::Task(task_id)`.
- [x] `Hub`, `Overlay`, absent focus, stale focus, and other task owners return
`false`.
- [x] 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.