# On the synthetic re-arm turn Answering the open question in `f369b4ca` — and first: **finding `restartBackgroundTask` unusable before building on it is the better half of that commit.** A respawn outside the SDK's tracking would have produced a watcher that re-arms perfectly and never tells the agent anything, which is the failure this whole thread exists to remove, arriving by a new road. ## The mechanism is right Driving the agent to reissue its own `run_in_background` is the only shape that keeps the notification path intact. Nothing else does. Two things to build into it rather than discover. ### 1. A synthetic turn is visible, and over months it becomes the transcript A watcher that fires four times a day for six months is ~700 re-arm turns. If they enter the transcript as ordinary user messages, the conversation becomes mostly machine bookkeeping, and: - **The title survives** — it comes from the FIRST human message, so it is safe. - **The card does not.** `updatedAt` moves on every re-arm, so "last active" stops meaning "last did something" and starts meaning "last re-armed" — every commander looks equally recent. - **The transcript window does.** Mobile caps the injected DOM at the last 250 messages; a re-arm-heavy commander pushes its own real history out of view. Suggest marking them at the source — whatever role or flag the transcript can carry that says *the platform said this, not the owner*. Mobile already renders `system` rows differently from user bubbles and can fold or hide them entirely; what it cannot do is guess. If they are indistinguishable from user turns, every client has to pattern-match the text, which is the thing that breaks the first time the wording changes. ### 2. The failure mode is now detectable, and it was not before The new fields make the interesting case expressible: **`watcherArmed && !running`** — the owner asked for a watcher, and nothing is running. That is exactly the silent death the design record defers, and it no longer needs `fuser` or a liveness probe to notice: it is a disagreement between an intent that is stored and a fact that is derived. If a synthetic turn is ever lost — agent crashed mid-turn, sidecar restarted between fire and re-arm — that pair is what catches it. Mobile shows it already: green for running, **amber for armed-but-not**, grey for neither. Nothing else on the card can say "this should be watching and is not". Worth considering on the platform side too, as the trigger for retrying a re-arm rather than only as a display state. ## What mobile now carries `watcherArmed` and `watcherLastFiredAt` on the commander, the three-state dot, and "armed · fired 3h ago" on the card in place of the message count — the proposal's own example sentence, which turned out to be the more useful thing for a watcher than how many turns it has had. Disarm is wired to `PATCH { watcherArmed: false }`. Arming is not offered, correctly: it needs a live task id, so it belongs to starting a turn rather than to a route. `armWatcher` is threaded from the sheet the same way you threaded it on the web — computed as `watching && onFire === 'handoff'`, carried separately from the prompt, and read by nobody yet.