Risk-Tiered Approvals
Sparkle classifies every action an agent takes by how risky it is, then interrupts you only for the things a human actually needs to weigh in on. Safe work runs on its own. A questionable change waits in the app. Something genuinely destructive reaches out and grabs you, on your screen and on your phone, before it runs.
Two states turn RED because they block on you: waiting (the agent asked a question on-screen, shown as "Needs you") and approval (a risky action is pending, shown as "Approve?"). Everything else stays calm and keeps building.
How it works
Sparkle reads two signals to decide an agent's status: the live terminal output (what's actually on screen) and Claude Code lifecycle hooks (events the engine fires when it needs permission for a tool). The hooks are authoritative. The screen scraper can only escalate a calm agent to red when there is a real prompt waiting, which kills the false positives you'd get from Claude merely talking about something risky in prose.
The three marketing tiers:
- safe runs automatically. Reading files, running tests, listing a directory. No interruption.
- caution surfaces in the app. Worth a glance, not worth a phone call.
- dangerous interrupts you, then pushes a notification, then sends an SMS, then emails you. The louder the channel, the more dangerous the action.
Think of it like a smart smoke alarm that knows the difference between toast and a real fire. Most of what an agent does is harmless, so Sparkle just lets it happen. When an agent reaches a fork in the road and needs a human, that agent turns red in your sidebar with one of two short labels:
- "Needs you" means the agent asked you a plain question and is waiting for your answer. This is the waiting state.
- "Approve?" means the agent wants to do something risky and is asking permission first. This is the approval state. Nothing happens until you tap Approve or Reject.
A terminal is the old text-only window where commands run the instant you hit enter, with no one checking whether that was a good idea. Sparkle puts a thoughtful layer on top, so you get asked before the scary thing happens, not after. You will never have to know which actions are dangerous; the app already does.
This is the safety net that lets you actually walk away. Kick off several parallel agents, close the laptop, and trust that the only time you get pulled back in is when a decision genuinely needs you. Two things go red and demand attention: a question ("Needs you") and a pending risky action ("Approve?"). Everything green or gray is fine, leave it alone.
The trick that makes this usable instead of annoying: hooks are the source of truth, not a dumb keyword match on the screen. So when Claude says the word "delete" in a sentence, you don't get spammed. You get the red flag when there's an actual permission prompt on the line. Approvals reach your phone too, so "away from the keyboard" doesn't mean "blocked until I'm back." See the mobile app for the 3-second approve-from-anywhere card.
Mechanically: a status engine (engine/statusEngine.ts) fuses PTY output with
Claude Code lifecycle hooks. On a settle event, it asks screenAwaitsInput(screen);
if a prompt is up it picks approval when a risky action was recently seen
(sawRecentRisk), otherwise waiting. Risk is flagged by an approval_needed hook
event, and permission notifications are matched by a deliberately narrow regex
(/\b(permission|approve|allow)\b/i in engine/hookEvents.ts) so an idle ping is
not confused with a real "approve this tool?" request.
The design rule worth noting: the hook layer is authoritative and the screen scraper
is escalate-only. It can promote idle to red on a live prompt, never the reverse.
That asymmetry is what makes the thing trustworthy at fleet scale, you don't get
false reds off conversational text, and you don't get a missed real one. Status is
routed through engine/statusRouter.ts; the RED token is #e0533f
(AGENT_STATUS.waiting / .approval in the UI tokens).
The two RED states
Both block on a human, both render in RED (#e0533f), and both count toward the
dock badge so you always know how many agents want you:
| State | Label | Means |
|---|---|---|
| waiting | "Needs you" | The agent asked a question and is waiting for your answer. |
| approval | "Approve?" | A risky or dangerous action is pending your sign-off. |
Why it matters
You are about to let software build itself while you make coffee. That only works if you trust it not to do something catastrophic behind your back. Risk-tiered approvals are that trust: the boring, safe stuff just happens, and the genuinely scary stuff politely stops and asks first. You don't need to become an expert in what's dangerous. Sparkle already sorts it for you and only taps you on the shoulder when it truly matters.
Autonomy without a kill switch is just praying. This is the kill switch, automated and ranked. You get the leverage of a running fleet without the 2 a.m. horror of discovering an agent force-pushed or wiped something while you slept. Interrupts are ranked by danger, so a yellow nudge in the app and a red SMS feel different on purpose. You learn to ignore the calm ones and act on the loud ones.
The value is signal discipline. Anyone can fire a notification on every tool call; that trains you to ignore them. Sparkle's contribution is the ranking plus the hooks-authoritative, escalate-only scraper, so the red ones are real and the quiet ones stay quiet. You're interrupted for the small set of actions that actually need a human judgment, ordered by blast radius. That's the difference between an alert system you trust and one you mute.
vs. the 1980s terminal
A terminal has no concept of risk. It will run dropdb --force the instant you
hit enter, with no risk assessment, no tiering, no second opinion, and absolutely no
way to ask you from your phone. The blinking cursor treats "list files" and "destroy
production" as exactly the same kind of request: yours, so it's fine.
The old way assumed the person typing always knew what they were doing. That's a scary assumption when you're new. Sparkle replaces "the computer trusts you completely" with "the computer checks the dangerous stuff with you first," which is exactly the safety rail a new builder wants.
The terminal's honesty is also its problem: it does precisely what you said, even when "what you said" came from an agent that was confidently wrong. Sparkle keeps the speed for safe work and inserts a gate only where the downside is real. Same raw power underneath, minus the irreversible-mistake tax.
The shell enforces nothing. No policy layer, no notification fabric, no remote approval path. Sparkle adds exactly that, classification at the action level, an edge-triggered status engine, and channels that reach you off-machine, without taking the terminal away. It's still right there underneath when you want it.