The notification when a thread finishes
With notifications on, the phone buzzes for two things only: the agent finished with nothing queued behind it, or it needs you, with a question or an approval.
Why you would use it
It is the point of turning notifications on. What matters is which endings buzz and which stay quiet, so the phone is worth listening to.
How to use it
- Turn notifications on for the device.
- Send work and put the phone away.
- Tap the notification when it arrives to land in that thread.
What you see
The notification's title is the thread's title plus what happened:
| Ending | Title | Body |
|---|---|---|
| Finished | <thread> · done |
the last thing the agent said, or Finished. |
| Blocked on an approval | <thread> · needs you |
the tool and target it is asking about |
Stopped on a question, or after v-code wait |
<thread> · needs you |
the last paragraph with a ? in it, or the last paragraph |
- The notification itself is drawn by the operating system, not by the app, so there is no screenshot of it here. What the app owns is the bell that turns it on (see turn-on-notifications) and the thread it opens when you tap it.
- The body is collapsed to one line and clipped at 180 characters with
…. - The app's own mark heads the notification. On Android the small status-bar glyph is a white silhouette of the same mark.
- The picture on the right is the tab's agent: Claude, Codex, opencode or Cursor. A tab on another agent shows none there, and Android may then draw the first letter of the site's address in its place.
- One live notification per thread: a thread that finishes twice replaces its own row rather than stacking, and the replacement still alerts.
- Opening the thread in the app also clears it: its notifications leave the tray once the tab is on screen with the app in front, whether you tapped the notification or switched to the tab yourself. In the split view every pane counts as on screen.
- Tapping it dismisses it. If the app is open it comes forward on that thread; if
it is closed it opens on
/?thread=<id>, and the app strips that parameter after honouring it once. A tab made since the app last loaded opens once its box lists it, within 30 seconds; until then the app stays on the tab it opened with. - In the app on app.fezu.dev every box on your account can notify you, once
it runs a release with the app's notifications. Tapping
opens the thread on the box it came from:
/?thread=<id>&box=<box id>when the app is closed.
What stays quiet:
- A thread waiting out a usage limit. It resumes by itself; the tab shows when.
- A thread whose agent crashed or exited. The tab shows the failure.
- A turn that drains straight into the next queued submission.
- A turn with work still queued behind it.
- A turn that ends while a background shell or subagent is still running, a reply ending on a question included. The agent picks up again when that work reports back, and the end of that turn buzzes. An approval still buzzes straight away.
- The end of a turn while background work that stopped has not been reported yet: the shell ended while the agent was idle or compacting its context. The turn the agent starts to read it buzzes instead, or a minute after the work stopped if no such turn comes.
- A turn that ends within 10 seconds of a background shell or subagent changing. claude can mark a subagent done and start it again a moment later, so the buzz waits for 10 quiet seconds.
- A turn you stopped by hand: you were holding the phone.
- A closed thread.
- The thread you are looking at, on the screen that is looking at it. Another device, or the same one with the screen off, still buzzes. Safari, and every browser on an iPhone or iPad, buzzes for it anyway: Safari turns notifications off for the app after three pushes that show nothing.
Limits and known gaps
- Two turns ending inside the 1200ms settle window produce one notification.
- Background work holds the
· donefor 30 minutes from its start at most. A shell that never ends, such as a dev server the agent left running, gets its· doneat that mark if the thread is still idle. A subagent that runs longer than that buzzes· donewhile it works. - A notification older than an hour is dropped by the push service (
TTL: 3600). A "finished" past that is noise. - A phone that was offline gets the latest state per thread rather than a screen
of stale ones: each push is topic-tagged
thread-<id>. - With nobody subscribed, nothing is sent and no key file is written.
- A push service answering 404 or 410 means that device is gone: the server drops the subscription. Any other failure (503, a timeout) keeps it.
- A payload the worker cannot read still buzzes, with a fallback title
VCodeand the bodyA thread finished.A push that shows nothing makes Chrome post its own "this site has been updated in the background" instead. - Payloads are capped at the single-record size in
lib/push.js; an oversized one is refused rather than truncated.
Related
- turn-on-notifications
- tab-status: the same states on the tabs
- where-notifications-work
- usage-limit-pause-and-retry: a pause that stays quiet
- stop-a-running-turn: the one ending that stays quiet on purpose
- close-and-reopen-tabs: a closed thread never notifies
- permission-levels: the
approval card a
· needs younotification is about - watch-pull-request: the notifications a watched pull request sends
- pin-snooze-done: a done tab sends none