prometeu-runtime/discussion/lessons/DSC-0035-task-owned-shell-windows/LSN-0044-task-window-liveness-belongs-to-the-task.md
bQUARKz 82a3380426
All checks were successful
Intrepid/Prometeu/Runtime/pipeline/head This commit looks good
Intrepid/Prometeu/Runtime/pipeline/pr-master This commit looks good
housekeeping
2026-05-15 15:51:41 +01:00

113 lines
3.7 KiB
Markdown

---
id: LSN-0044
ticket: task-owned-shell-windows
title: Task Window Liveness Belongs to the Task
created: 2026-05-15
tags: [runtime, os, task, window-manager, shell, lifecycle]
---
# Task Window Liveness Belongs to the Task
## Context
The Prometeu OS model separates execution, navigation, and visual presence:
```text
Process = technical execution
Task = navigable presence
Window = visual presence of the task
```
Before `DSC-0035`, shell execution used a generic `focused_window_active`
signal. That signal only answered whether any window was focused. It did not
prove that the focused window represented the shell task currently driven by
`ShellRunningStep`.
The implemented contract replaced that generic signal with a task-owned window
predicate:
```text
os.windows().focused_window_belongs_to_task(task_id)
```
## Key Decisions
### Shell liveness requires the task's own focused window
**What:** `ShellRunningStep` continues only when the task is foreground and the
global focused window is owned by `WindowOwner::Task(task_id)`.
**Why:** A shell task in foreground must have its own visual presence. Any
focused window is not enough; the focused window must belong to the same task.
**Trade-offs:** This v1 rule is strict. It does not preserve a shell task under
focused overlays, minimized windows, background execution, or app switcher
state. Those behaviors need their own explicit contracts.
### Window ownership is queried through the window facade
**What:** `WindowFacade` exposes
`focused_window_belongs_to_task(task_id)`.
**Why:** The question is about the global focused window and its owner. It is a
window-domain query, not a lifecycle transition.
**Trade-offs:** Firmware still coordinates across domains: it asks the window
facade for ownership and then calls lifecycle when the predicate is false.
### Lifecycle still owns state transitions
**What:** When the shell task loses its eligible focused window,
`ShellRunningStep` closes the task through `os.lifecycle().close_task(task_id)`
before returning to `HubHome`.
**Why:** Returning to Hub without lifecycle closure would leave task and process
state dependent on implicit cleanup.
**Trade-offs:** A visual close becomes a lifecycle event for foreground shell
apps. That is correct for v1 shell apps, but it must not be generalized to
background services without a separate decision.
## Patterns and Algorithms
Use this split when OS behavior crosses services:
```text
WindowFacade
answers questions about windows, focus, and ownership
LifecycleFacade
changes TaskState and ProcessState
Firmware step
coordinates policy between the two domains
```
The useful pattern is not "windows close tasks". The pattern is:
1. derive a visual-presence predicate from the window domain;
2. let the firmware step decide what the predicate means in that state;
3. perform lifecycle transitions through `SystemOS` lifecycle.
## Pitfalls
- Do not use a generic "some window is focused" signal as a task liveness
contract.
- Do not treat `Hub` or `Overlay` windows as shell task windows.
- Do not model game cartridges as `WindowManager` windows. Games remain
fullscreen `GameRunningStep` sessions.
- Do not add overlay preservation, minimization, app switcher, or background
service behavior as incidental side effects of shell liveness.
- Do not return to Hub without closing the shell task through lifecycle.
## Takeaways
- Task-owned shell windows bind shell liveness to the task's own visual
presence.
- Ownership predicates belong in the window facade; state mutation belongs in
lifecycle.
- Strict v1 semantics are easier to evolve than an implicit "active window"
concept.
- Future overlay or background behavior should be introduced by explicit
policy, not by weakening the shell liveness predicate.