# 0019: Attention carries a source, and a guess may not be counted Status: accepted; runtime-observed signals are live. The sidebar said `ATTENTION · 1` from the first commit. It was reading a fixture's `needs_input` flag that no live pane ever set, so the number was frozen at whatever the demo data said and had no relationship to anything running. Replacing it raises the question the usage ledger already answered once: what is a number in this interface allowed to claim? ## The rule Every attention signal carries an `AttentionSource`, and a source that is a guess **may draw a row and may sort it, but may not increment the count**. - `AcpRequest` — the harness asked, over ACP. It said so itself. - `HarnessReported` — a documented status surface reported it. - `RuntimeObserved` — Lumbridge saw it in a process it supervises: an exit, a fault. The only source that produces signals today. - `TitleHeuristic` — inferred from a window title or an output pattern. - `Fixture` — test or demonstration data. The first three count. The last two do not, and `is_countable` is a method on the source rather than a filter at the call site, so a new signal cannot be counted by forgetting to exclude it. This is decision 0012's provenance rule applied to a different claim. The reasoning is the same: a wrong count is worse than no count, because it teaches people to ignore the number, and the number is the whole point of the section. ## What is deliberately unreachable `PermissionRequested` and `QuestionAsked` are declared and never constructed. Those arrive over the ACP client, which does not exist yet. They are written down rather than left out so there is a defined shape for the client to fill — and, more importantly, so nobody is tempted to approximate them with a `TitleHeuristic` that watches for a question mark in the output. A pane that *looks* like it is asking something is not a pane that asked. That signal would be a guess, would therefore not be countable, and the honest version of it is simply not to ship it. ## What a signal replaces One pane wants attention for one reason at a time: a new signal replaces the pane's previous one rather than accumulating, or the count would grow every time a pane was restarted. Signals sort by source first and age second, so the most trustworthy and longest-waiting thing is at the top. Restarting or terminating a pane clears its signal, because the thing that was waiting is no longer waiting. ## The exit code survives `RuntimeEvent::Exited` carries a `u32` code that used to be formatted straight into a sentence and discarded. `AttentionKind::Finished { exit_code }` keeps it, which is what lets the row say "Exited with code 42" rather than "needs attention", and what will later let a finished-successfully signal be told apart from a failure without re-parsing English.