# Push notifications ## Know when your agents need attention Grove's dashboard is pull only. You have to be looking at it, and push notifications close that gap. ## Get told when it matters - Your phone buzzes when an agent finishes its turn, asks you something, or its workspace breaks. - Tap one and you land on that workspace. - Grove runs no second status engine. The broker watches the same activity stream the [Activity Dashboard](features-activity.md) already computes for moments worth a buzz. - You choose which triggers reach each channel, and everything is off until you turn it on. ## What fires a notification Each trigger has its own switch. | State | Meaning | Default | |---|---|---| | `waiting` | The turn finished. The agent may need you. | On | | `blocked` | The agent is waiting on a permission prompt or a question. | On | | `error` | The run or init failed. | On | | `idle` | The agent went quiet. | Off | | Event | Meaning | Default | |---|---|---| | `error` | The workspace hit an error. | On | | `orphaned_detected` | Its worktree is gone. | On | | `offline_detected` | Its tmux session vanished. | On | | `created`, `killed`, `paused`, `resumed`, `respawned` | Routine lifecycle verbs. | Off | - `on` lists the agent states that alert, and `on_lifecycle` lists the workspace events. Routine verbs are off by default. - `on_question` adds the prompt and its options to the alert, so you can answer from the tray. - A session already waiting when the daemon starts is recorded without an alert, and a 30 second window stops one state from buzzing twice. - Enable it in any layer of the [config cascade](features-cascade.md). ## Severity: how loudly it lands Every notification carries `low`, `normal`, `high`, or `urgent` severity. - A finished turn is `normal`. - A question, `blocked` state, or workspace `error` is `high`. - An idle agent or routine lifecycle event is `low`. - Gotify maps severity through `priorities` from 0 to 10. - Webhook maps severity through `priorities` on ntfy's scale from 1 to 5. ## Channels Delivery is pluggable across two channels today, and secrets never live in config. Each channel holds the name of the environment variable that carries its token, so a committed `.grove/config.json` stays safe to publish.