docs/03-lifecycle-attention.md

03 — Lifecycle & Attention Models

Lifecycle (what the agent is doing) and attention (whether the human must look) are independent axes. Both are first-class in the data model, IPC, and UI.

Agent lifecycle

text
1unknown → working ⇄ blocked → done
2 │ │ │ │
3 │ ▼ ▼ ▼
4 │ failed failed (terminal)
5 ▼
6 idle ⇄ working
7 │
8 └── exited (process gone; orthogonal to task outcome)
StateMeaningTypical sources
unknownno adapter signal yetnew pane, generic shell
workingagent is making progresshooks (PreToolUse), process running, spinner/title
blockedwaiting on human (input/permission)hooks (PermissionRequest), OSC notify, idle+prompt heuristics
doneturn/task completedhooks (Stop), notify hook, exit 0 of one-shot
idlealive, nothing runninghooks (SessionStart before prompt), prompt-readline state
failederrorednon-zero exit, error hook payload
exitedPTY child gonewaitpid/pipe EOF (keeps last lifecycle as last_lifecycle)

Transitions are adapter-driven; explicit events always override heuristics. Every transition emits agent.<state> with the previous value and the source.

Attention

StateMeaningUI treatment
nonenothing to seeneutral
unreadoutput/activity since last seensubtle dot
input_requiredagent asked a questionattention ring
permission_requiredapproval gate openstrong ring
warningnon-fatal problemamber indicator
errorfailure needs triagered indicator

Severity order: error > permission_required > input_required > warning > unread > none. A pane shows its highest outstanding item.

Canonical examples

Situationlifecycleattention
agent mid-turnworkingnone (subtle activity only)
agent asks questionblockedinput_required
approval dialog openblockedpermission_required
turn finished, not yet seendoneunread
turn finished, user revieweddonenone
tool error, agent retryingworkingwarning
agent crashedfailederror
plain shell, new outputidleunread

Clearing rules

  • Ordinary attention clears only on explicit user interaction with that pane: focusing it, marking read, or replying. Visibility of the workspace/tab is not enough.
  • mark_seen(pane) records last_seen_at=now and keeps lifecycle untouched. It clears ordinary attention and emits attention.cleared. An unanswered decision and its required attention survive reading, focusing, notification clicks, and default attach. An answer or agent transition resolves the decision. See ADR-0012.
  • New signals re-raise attention (attention.created).
  • Desktop notifications are suppressed when the target pane is already focused; clicking one focuses workspace+tab+pane and acknowledges reading.
  • "Jump to next unread" walks panes ordered by severity then recency.

Sidebar summary (per workspace)

Each sidebar row derives from its panes, never from telemetry:

  • name, repo/branch, agent kinds present
  • worst lifecycle (blocked > failed > working > done > idle)
  • worst attention (severity order above)
  • latest explicit message (notification/hook summary, not scraped text)
  • time since last attention change