How do you stay aware of what your AI coding agents are doing?

by

I've been running Claude Code, Cursor, and Codex pretty heavily for the last few months and I keep hitting the same loop:

1. Start a task in one agent

2. Switch to something else (Slack, Twitter, another terminal)

3. Come back 30-40 minutes later

4. Agent finished 35 minutes ago. Or worse, it's been waiting for my approval the entire time.

The more agents I run, the worse it gets. There's no unified way to know what's happening across them.

Curious what other people's setups look like:

- Do you just keep terminals visible and check manually?

- Built any custom notification scripts?

- Use something like ntfy or Pushover?

- Just... accept the wasted time?

I've been building something in this space (push notifications + approval flows for AI agents) and I'm trying to understand if everyone's workflow is as janky as mine, or if some of you have figured out something clever.

Would love to hear what's working and what's not.

5.1K views

Add a comment

Replies

Best

I mostly rely on terminal notifications + desktop notifications, but it's honestly still pretty easy to miss when an agent finishes or gets stuck waiting for approval. Once you start running multiple agents, context switching becomes the real bottleneck rather than inference speed.

 

Your last line is the diagnosis everyone in this thread keeps arriving at from different angles: once you're running multiple agents, the bottleneck stops being inference speed and becomes context switching. The models got fast enough that they're no longer the constraint, you are, specifically your ability to move attention between them without dropping something. That's not a compute problem, it's a human-bandwidth problem, and no faster model fixes it.

And you've spotted why terminal-plus-desktop notifications still let things slip: they're on the machine and they fire once. A desktop notification is easy to miss because it competes with everything else on screen and then it's gone, so if you're heads-down in one agent when another finishes, the ping vanishes into the pile. It's better than nothing, but it's still a single event you can miss, not a state that persists until you deal with it.

The other half is that they're per-surface, terminal notifications know about that terminal, desktop notifications know about that app, but nothing gives you one answer to "which of my agents needs me right now." So context switching stays expensive because you're still the one assembling the full picture from scattered pings.

That's the exact gap Pushary closes, one inbox across your agents, blocked fires loud and answerable from your phone, done sits in a glanceable list so it doesn't get lost. Free to try if you want to point it at your setup, . Curious though, of the two you mentioned, is it the finished ones you miss more or the stuck-waiting ones? The stuck ones are usually the costlier miss since they're frozen while you assume they're working, but I'd rather hear which actually bites you.

Great question, and I'm glad Aadil is building in this space. The "unified awareness" problem is real. I've been thinking about this from the perspective of shared context layers what if agents could maintain a central "worldview" that all other agents reference? It wouldn't solve the notification problem, but it would at least ensure that when you switch contexts, everyone's operating from the same understanding.

The janky part for me is exactly what you described: time wasted waiting. With agent orchestration tools like cmux and herdr, we're starting to see better handoff mechanisms, but it's still nowhere near as smooth as it could be. The ideal would be context-aware agent allocation agents that understand when they're blocked waiting for human input and surface that intelligently rather than silently burning CPU waiting for approval.

What's your take on the trade-off between unified context (cleaner but more overhead) vs. decentralized awareness (agents doing their own thing, but harder to track)?

 

Direct answer to your trade-off: it's a false binary as stated, and the resolution is that they're not two options, they're two layers that want opposite architectures. Execution should be decentralized, agents doing their own thing in isolation is a feature, not a bug, because independence is what lets them run in parallel without stepping on each other. But awareness should be centralized, because the whole point is one place that answers "who needs me." So the honest design isn't "pick one," it's decentralized execution with a centralized observability layer sitting above it. The mistake is coupling those, either forcing agents to share execution state (overhead, contention) or letting awareness stay as scattered as the agents (untrackable). Separate the layers and the trade-off mostly dissolves.

Your shared-worldview idea is the interesting one though, and I want to push on it because I think it's solving a real problem but a different one than notifications, and it has a hidden cost. A central worldview all agents reference gets you consistency, everyone operating from the same understanding, which is genuinely valuable for correctness. But shared mutable context is also a coordination hazard: the moment multiple agents can read and write a common worldview, you've got the same problem databases spent decades on, concurrent writes, stale reads, one agent acting on a worldview another just invalidated. And worse for agents specifically, a wrong belief in the shared worldview propagates to everyone, so one agent's confident mistake becomes every agent's premise. Decentralized agents fail independently; agents on a shared worldview can fail correlated, which is the scarier failure mode. So the overhead you named isn't just performance, it's blast radius.

The framing I'd offer: shared worldview is powerful for read-mostly context (conventions, architecture, the stable facts that rarely change) and dangerous for fast-changing state (what each agent is doing right now), because the churny stuff is exactly where consistency is expensive and staleness bites. So maybe the split is: centralize the slow, stable context that benefits from being shared, and keep the fast, volatile per-agent state decentralized but observable from one layer, without forcing it into a shared writable store. Shared truth for what's stable, unified visibility for what's live, and don't confuse the two.

And your last point is the one I care most about and think is under-appreciated: agents "understanding when they're blocked and surfacing that intelligently rather than silently burning CPU." That's the real unlock, and it's harder than it sounds because a blocked agent and a thinking agent look identical from outside, so "understand it's blocked" has to mean the agent declares the block as an explicit state, not something inferred from silence. Once it's declared, surfacing it intelligently is routing. Before it's declared, it's detective work. That declaration is the seam everything else hangs on.

The layering distinction—centralized observability, decentralized execution—clicks. That difference between stable context and volatile state is probably where most tools either scale or hit a wall. Interested to see how this plays out in practice.

 

Yeah, and I think the wall is usually one specific mistake: putting volatile state into the shared layer because it feels like context. Someone reasons "well, what each agent is doing is context too," writes it into the same store as the conventions and architecture, and then discovers they've built a distributed system with contention on the hottest data. The stable stuff wants to be shared because it barely changes. The live stuff wants to be observed, not shared, because it changes constantly and nobody needs to write to it.

Easy test I keep coming back to: if two agents wrote to it at once, would you care? If yes, it's volatile state and it belongs in the observability layer, read-only, per-agent. If no, it's stable context and it can be shared safely.

Genuinely enjoyed this exchange, you asked the question that made me articulate the split properly. Let me know if you build on the worldview idea, I'd want to see where you land on the correction path.

 That distinction between volatile agent state and stable shared context is useful. I'm still thinking through the correction path rather than pretending I've solved it. My current instinct is that corrections need clear ownership and traceability, not just another shared memory layer. I'll share where I land.

the real problem isn't monitoring what agents are doing, it's knowing whether what they did was actually correct. most people run an agent, see it "completed" and move on without verifying the output. we're going to need review layers that are as automated as the agents themselves, otherwise the speed gains just create faster mistakes.

 

"Faster mistakes" is the whole risk in two words, and it's the failure nobody prices in. Ten times the output with unchanged review capacity isn't ten times the productivity, it's ten times the unreviewed surface area, and the errors compound quietly because each one gets built on before anyone checks. Speed without verification isn't leverage, it's just accelerating in the dark.

And the "see completed and move on" habit is the real vector, because "completed" is a claim the agent makes about itself, and self-reported done routinely diverges from actually-correct. The most common version isn't malice, it's optimistic self-summarizing, the agent says tests passed because it believes they did. So the green check is testimony, not evidence, and treating testimony as verification is how the mistakes get through looking clean.

Your conclusion is right and it's the frontier: review has to become as automated as the generation, or the human stays the bottleneck and quietly starts rubber-stamping. The split I keep landing on is that some of "correct" is mechanically checkable, exit codes, real test output, does it match the spec, and that half should never reach human eyes unverified. The rest is judgment, is this the right approach, did it miss a case the tests don't cover, and that's the irreducible part where a human genuinely has to think. The win is making sure human attention only lands there, instead of being burned on things a check could have caught.

Where I sit honestly: Pushary compresses the eval rather than performing it, the handoff carries the diff, the real test output, what's unverified, so you're judging from second one instead of reconstructing context. That shortens the distance to the check. Automating the check itself is the harder frontier and it sounds much closer to what you're building at AISA. Curious, when you've tried automating the correctness check, is the wall that "correct" is too fuzzy to encode, or that writing the checks costs more than the eyeballing they replace? Those are very different problems and I can't tell which one actually stops people.

The most useful signal for me isn't "finished" vs "blocked"; it's whether human attention is now critical. A status layer that distinguishes active work, quiet builds, queued approvals, and failures would keep notifications from becoming noise. Each alert should also carry the smallest decision context—what changed, the blast radius, and a safe default—so I can act without reopening the whole session. The hard part is trust: miss a real block and you lose time, but alert too often and people mute it. Confidence labels for inferred states could make a cross-tool layer much more usable.

 

"Whether human attention is now critical" is a better organizing principle than the state names, and you're right that it's a different axis. Finished versus blocked describes what the agent is doing. Attention-critical describes what you need to do, and those don't map one-to-one, a blocked agent on a trivial approval isn't critical, a finished agent whose output gates three other things might be. Sorting by agent-state is convenient; sorting by whether a human is actually the missing input is the thing that saves you.

Your four-way split does the real work there, and quiet builds is the one most people miss, because that's precisely the state that gets misread as blocked. Long silent subprocess and waiting-on-approval look identical from outside, so a layer that can't tell them apart either cries wolf on builds or misses real stalls. Naming it as its own state rather than lumping it into "quiet" is what makes the rest tractable.

And "smallest decision context, with a safe default" is sharper than what I'd been aiming at. What changed and blast radius I had. The safe default is the addition, because it converts the notification from a question into a proposal you can accept or override, which is a much lower-effort decision under interruption. Answering "what should I do here" from a lock screen is hard; ruling on "here's what I'll do unless you say otherwise" is easy.

The confidence-label point is the one I'll actually take away, because it dissolves the trust dilemma you named. Miss a real block, lose time; alert too often, get muted. Labeling inferred states as inferred lets a cross-tool layer alert on weaker signals without spending the same trust, because a flagged guess that's wrong costs credibility differently than a confident assertion that's wrong. That matters concretely: Codex exposes a native approval event so "blocked" there is declared, while Cursor's approval is a UI event that never reaches the shell, so anything I say about it is inference. Presenting both with the same confidence is how the channel gets muted. Labeling them honestly is how it survives.

Curious where you'd want the line drawn: should a low-confidence inferred block still push, just marked as uncertain, or stay quiet in the list until something corroborates it? That's the exact call I keep going back and forth on.

 I’d keep a low-confidence inferred block visible, but not push it by default. One weak signal is usually “watching,” not “interrupt now.”

I’d escalate to a push when the cost of waiting is clearly higher than the cost of one interruption—for example, when it has sat unchanged past an expected window, a downstream task is waiting on it, or a deadline is close.

So I’d separate the state from the delivery policy: an inferred block can exist in the list early, with its confidence shown; notification urgency should depend on confidence, impact, and whether the signal is getting corroborated. That feels like the best way to avoid both silent misses and noisy alerts.

 

"Separate the state from the delivery policy" is the clean answer and it dissolves the thing I was stuck on. I was treating confidence as a threshold for whether to alert, one number gating a binary. You're saying confidence gates delivery, not existence, so a weak inferred block still lands in the list immediately, visibly uncertain, and only crosses into a push when something makes waiting expensive. State is cheap, interruptions aren't, and I was pricing them the same.

The escalation triggers you listed are the sharp part, especially the downstream-task one. Time-since-unchanged is the obvious tell, deadline proximity is fine, but a downstream task waiting is a real impact signal rather than a proxy for one, that's the case where a low-confidence guess earns a push despite being a guess, because the cost of being right and silent is compounding. Confidence stays low, impact carries it over the line.

And corroboration as an escalation path is the piece I hadn't put together: a single weak tell is "watching," but a weak tell that keeps holding, plus a second independent one, is a stronger claim without ever needing a native hook to confirm it. That gives Cursor a real path, since its approval is a UI event that never reaches the shell, so I'll never get a declared block there. But stalled-plus-stdin-idle-plus-unchanged-past-window, accumulating, is a legitimately promotable signal. Inference that earns its way up rather than pretending to certainty at the start.

Taking this whole thing into the design. Genuine question, last one: when an inferred block sits in the list showing low confidence, would you actually want it labeled as inferred, or is showing a confidence value enough? I keep wondering if surfacing the provenance ("guessed, not declared") matters to people or if it's just noise once there's a number attached.

 I’d label it explicitly as inferred. A confidence value answers “how sure”; provenance answers “what kind of evidence,” and those are different decisions for a user. In the list, “Inferred · low confidence” is enough, with the evidence expandable on demand. For a push, I’d include the short reason too—something like “stdin idle + unchanged for 18m”—because the user needs to judge urgency without reopening the session. That keeps the default surface honest without turning every weak signal into a dashboard of badges.

I ran into the same issue after using multiple agents. What helped me most was keeping each agent focused on a single task and using desktop notifications whenever one finished or needed approval. I also ask agents to leave a short summary of what they changed before moving on. It cuts down a lot on context switching and makes it much easier to jump back in. A simple dashboard showing the status of all active agents would be really useful.

 

Three solid moves there, and the one doing the most work is probably the third. One-task-per-agent keeps the context small enough to hold. Notifications on finish/needs-approval flips you from polling to being told. But the short summary before it moves on is what actually kills the context-switch cost, because the expensive part of jumping back in isn't the switch, it's the reload, reconstructing what the agent was even doing. A summary means you read conclusions instead of re-deriving them.

The dashboard you're wishing for is the natural next piece, with one caveat worth naming: a dashboard you have to remember to open eventually becomes another thing you forget to check. The version that works is one that stays quiet and taps you when something crosses into blocked, with the full status view there for when you want it rather than something you're obligated to watch.

That combination is basically what Pushary is, one status view across your agents, blocked pings loud, done sits in a list, and the summary rides along with the notification so you're not opening the terminal to find out what changed. Free to try, , and your setup is a clean fit since you're already producing summaries.

Curious, are your desktop notifications per-tool, or have you got one place they all land? That's usually where the wishing-for-a-dashboard feeling starts.

I made a free app for this.. to see what they're doing in terminals since they keep making things more invisible..

 

Nice, and "they keep making things more invisible" is a fair complaint, the trend has been toward hiding terminal detail behind nicer UI, which is great until the thing you need to see is exactly what got abstracted away.

I'll take a look at Buttons. Genuine question since you built it: are you reading the terminal output to figure out what's happening, or hooking into the agents directly? That's the fork I keep hitting, output-reading works everywhere but can't cleanly tell "waiting for approval" from "thinking hard," while hooks give you a declared state but only on tools that expose them. Curious which way you went and whether you found a clean signal for the blocked case.

 I never used hooks in the app, just fed recent terminal output (and sometimes a screenshot or two) to a model and instructed it to reply with one of a few options, i'd prompt it like "Your job is to figure out if this AI coding agent got stuck. What does it look like? Did it stop for no reason? Is it asking to approve something? Is it still working and we should leave it? Respond with one of these options" I think what I did is have it use two snapshots or two screenshots separated by time (or just sampling the recent text output with a time delay) then an AI model can usually figure out what's up if its not moving after a while and it can figure out if it needs a simple nudge like "still working?" to be sent + enter, or if it stopped, and if it is thinking it just will add a bigger time delay and check again later.
I have barely tested this feature just since I didn't really need to use it, but its called idle detect and has sections of the settings where you can set specific AI models for that inc. vision model. Might be a little glitchy since I barely tested it.

The way I set up the agent control is CLI first but can fallback to MCP. CLI is easy because really all it needs is the command and -h and it'll know what to do, I have some simple security just a token that changes, but all you have to do is click one button, then paste, and all that contains is the cli command + token + basic usage info. So nothing really hooks into a harness or modifies anything.

I actually made the app for totally different reasons.. i wanted a normal user interface, and I like to click with a mouse, I wanted to set buttons to frequent commands I type (like linux update commands or claude --danger... ) i can't remember keyboard shortcuts (well i can, but don't want to - and literally 99.9% every other terminal app acts like its in a competition for who can remove the most information from the UI! I couldn't find any that didn't force you to edit .json files just to change the color or font) So the agent control, was just an annoying problem I kept having (invisible terminal commands) and so what I tend to do is add a feature/thing right when I need it.

There is a lot more it does and I went over the top on the themes.. and fonts. It lets you type plain language to have AI generate themes (it works well, can type "halloween" it'll theme the app that way). Its got full settings interface, not a "minimalistic terminal" :) . I can imagine people who hate terminals might download it.

 

This is a genuinely different approach and I think you've stumbled onto something that solves the exact case that beats hooks. Two snapshots separated by time, fed to a vision/text model asking "stuck, waiting, or still working?", sidesteps the whole problem I keep hitting, because it doesn't need the tool to declare anything. Hooks give you a clean signal but only where the tool cooperates. Your method works on any terminal, including the black-box ones, because you're reading the same thing a human reads when they glance over: has this changed, and does the change look like progress or a prompt.

The delta-between-two-snapshots is the clever bit specifically, because a single snapshot can't distinguish blocked from thinking (both look static in one frame), but two frames over time recovers the derivative, movement vs no movement, which is exactly the information the single-frame version loses. That's the thing pure output-scraping usually can't do and hooks do trivially, and you got it back without hooks by adding the time axis. The escalating time delay when it looks like thinking is the right instinct too, back off and recheck rather than false-firing on a long compute.

The honest tradeoff, and you probably know it: it costs a model call per check, it can be wrong (a vision model reading a terminal is a probabilistic judgment, not a declared state), and the "send a nudge to see if it's alive" step is doing something a hook would never need to. So it trades hook-reliability for hook-independence, cheaper to support universally, less certain per call. For the tools that expose real hooks I'd trust the hook; for the ones that don't, your snapshot-diff might genuinely be the least-bad option, which is the exact corner I've been stuck on with Cursor.

And the origin story is the best part, honestly. You built a terminal for people who like buttons and mouse clicks and readable UI, got annoyed by invisible agent commands, and bolted on idle-detect because it was your own itch. That's the right way to build, the feature exists because you hit the wall, not because a roadmap said so. The natural-language theme generator ("halloween" theming the whole app) is over-the-top in the good way, and you're right there's a real audience, the people every other terminal app actively drives away by hiding everything behind a JSON config.

Genuine question about idle-detect, since it's the part that overlaps what I'm building: when the vision model reads a Claude Code approval prompt vs Claude Code mid-thought, how reliably does it tell them apart? Because that's the hard discrimination, an approval prompt and a thinking pause can look pretty similar in a terminal, and if the model handles it well even barely-tested, that's a stronger signal for the snapshot approach than I'd have guessed. Might be worth hardening that feature more than you have, it's solving something the hook-based tools structurally can't.

Use conductor, and add a sound there.
When a agent needs your input question, or when it completes it will play a sound.

 

Conductor plus a completion sound is a clean, low-friction setup, and the audio cue is smart specifically because it's ambient, you catch it without having to be looking, which beats visual notifications when you're heads-down in another window. Sound is one of the few channels that reaches you without stealing the screen you're working on.

The two spots it runs into, worth knowing: a sound tells you something happened but not which of your agents or what it needs, so once you're running a few, you still tab around to find the one that pinged. And it's tied to being near the machine, the sound doesn't follow you when you step away, which is exactly when a stalled agent costs the most.

Where it also gets subtle: "needs input" and "completed" playing the same sound means you can't triage by ear, one's a live stall burning time, one's just done and can wait. Different sounds for those two would already sharpen it a lot.

That's roughly the line between a sound cue and what I'm building, Pushary carries which agent and what it needs into the alert and reaches your phone when you're away, so you can triage without hunting. Free to try if you want, . Curious though, with Conductor, do you get separate sounds for needs-input vs done, or is it one cue for both? Because that distinction alone changes how much the sound actually saves you.

This is definitely a real problem. I use Cursor and Codex quite a bit, and the bigger issue for me isn’t knowing when an agent is finished — it’s knowing when it needs me.

If an agent can keep working for 30 minutes, great. But if it gets blocked 3 minutes in waiting for an approval or a decision, I’ve basically lost 27 minutes without realizing it.

I’d love something that only interrupts me for actionable states: needs approval, needs input, failed, or completed. Especially useful when running multiple agents in parallel.

Push notifications + the ability to approve/respond without going back and finding the right terminal would be genuinely useful.

 

You've drawn the exact right line: the problem isn't knowing when it's finished, it's knowing when it needs you, and those are different signals with very different costs. A finish you find out about late just sits there, harmless. A block you find out about late is the 27 wasted minutes, because the agent froze 3 minutes in and everything after was dead air you assumed was work. The blocked case is the expensive one precisely because it's silent and it looks like progress.

Your list of actionable states is basically the spec, and the discipline is exactly that, only those interrupt. The moment you push on more than needs-approval / needs-input / failed / completed, the channel turns to noise and you mute it, and then the one that mattered dies muted. Restraint is the feature.

One thing worth flagging since you named Cursor specifically: needs-approval detection is genuinely harder there than in Codex. Codex exposes a native approval event, so "it's blocked" is something the tool declares. Cursor's approval is a UI event inside the app that never really surfaces to the outside, so catching it cleanly is the hard part, not the notification. Worth knowing that's where the seam is.

The two things you asked for, push on actionable states and respond without hunting for the right terminal, are exactly what Pushary does, and the "find the right terminal" pain is real once you're parallel, so the notification carries which agent and drops you straight to it. Free to try, , and you're a clean fit running Cursor and Codex together.

Curious, between Cursor and Codex, which one leaves you blind more often on the blocked case? My bet is Cursor for the reason above, but you're running both live and I'd rather hear it than assume.

 Thanks, this is exactly the distinction I was trying to articulate. The "27 wasted minutes" example captures the pain perfectly. Finishing late is usually harmless; silently blocking is expensive because it still looks like progress. Between Cursor and Codex, I'd actually say Cursor leaves me blind more often. Codex exposing approval as a first-class event makes it much easier to know when I need to step in. With Cursor, I sometimes find myself checking back just to see if it's actually working or quietly waiting for me.

What I'm increasingly realizing is that the notification itself isn't the product. The product is reducing context switching by only interrupting on actionable states (needs approval, needs input, failed, completed) and dropping me directly into the right place to resolve it. Everything else just becomes noise.

Curious how you're thinking about this longer term. Do you see Pushary staying focused on terminals, or do you think this eventually expands into a broader coordination layer across multiple AI coding agents?

 

Good, that settles the Cursor question, and it points at something bigger than instrumentation quality.

Look at your four states again. Needs approval, needs input, failed, completed. Every one of them is a state the agent knows it is in and announces. The expensive one you opened with is not on that list and cannot be, because a silent block presents as work in progress. Cursor is the proof: the approval genuinely exists, it just never leaves the app, so there is no event to subscribe to. Four states you can listen for, and a fifth you can only infer.

That fifth one needs a different mechanism, not a better feed. Silence against an expectation rather than a message. It has been quiet for eleven minutes and the last thing it told me was that it was starting. Derived, not received. Which sets a ceiling worth being upfront about: any outside layer is bounded by what the harness emits, and no amount of product work on my end fixes an event that was never sent.

On the longer term, it is already not terminals. Claude Code, Codex, Cursor, and Hermes all go through the same path today, and the reason is not ambition. A control that only works on whichever agent you happen to like this quarter is not a control. It has to sit outside the agent, and outside the agent means it cannot belong to one vendor.

Where I would draw the line is control rather than coordination. I have no interest in orchestrating work across agents, and I think that is a genuinely different product. The thing that generalises is the decision, not the work. Approve, deny, escalate, and a record of who decided are identical no matter which agent asked, and none of them require me to understand what your agent is doing. Orchestration does, which is why it does not generalise cheaply.

The part of your framing I would keep hardest is resolve in place. For approval and input the correct destination is the notification itself, so the terminal never enters it. For failed it is not, and I do not have a good answer there yet.

Which of the four do you actually switch context for? My guess is failed, and that the other three are ones you would happily never open a terminal for again.

 I think your intuition is mostly right. For me, failed is by far the biggest context switch because I usually need logs, output, or the ability to intervene. I don't think a notification can realistically replace the terminal there.

Needs approval is probably the next biggest opportunity. If I can review the proposed action, approve or reject it, and move on without opening Cursor or Codex, that's a real productivity win.

Needs input depends on the complexity. If it's a simple yes/no or a short text response, I'd happily resolve it from the notification. If the agent is asking me to make a design decision or provide significant context, I'm going to open the IDE anyway because I need to see what it's talking about.

Completed is mostly informational. I rarely switch context just because something finished.

Running solo most of the time, but the worst version of this for me isn't the wait, it's coming back to a finished session and realizing it needed my input 20 minutes ago and just sat there. A notification fixes discovery. What I actually want is to know upfront whether a task even should've run unattended in the first place.

 

That's a genuinely different and sharper ask than the rest of this thread, and worth pulling apart because you've jumped a level. Everyone else is optimizing discovery, how fast you find out it stalled. You're asking about prediction, should this have been left alone at all. A notification is reactive, it makes the stall cheaper after it happens. What you want is to not launch the doomed unattended run in the first place, because the best version of "it sat there for 20 minutes" is the one where you knew going in it'd need you and stuck around.

The interesting part is that "should this run unattended" is answerable, at least partially, before you start, because it correlates with things you can assess up front: how well-specified the task is, whether it touches anything that'll hit an approval gate, whether it's the kind of work that tends to hit ambiguous decisions mid-run. A tightly-scoped refactor in files you named is a safe unattended bet. A vague "improve the auth flow" is going to stop and ask you something, and you can smell that before you launch it. So the signal you want isn't a monitor, it's a pre-flight read: this task has N likely approval points, it's under-specified in these spots, expect to be needed.

Where it gets genuinely hard, and I'll be honest that this is the frontier not a shipped feature: predicting mid-run interruptions requires anticipating where the agent will hit ambiguity, and ambiguity is exactly the thing that's hard to see in advance, if you could fully spec it you wouldn't hit it. So the pre-flight can catch the obvious unattended-risks (touches auth, spec is thin, known approval-gated actions) and will miss the surprise ones. The honest version is "this task looks safe to leave / this one will probably need you," not a guarantee.

That reframes what a tool should even do: not just ping you when it stalls, but at launch tell you which bucket the task is in, so you decide up front whether to walk away or stay. Discovery and prediction, and you're right that prediction is the more valuable half because it prevents the dead 20 minutes instead of just shortening it.

Genuine question, since you've clearly thought past the notification: would a pre-flight "this'll probably need you" flag actually change your behavior, would you stay at the desk for the flagged ones, or would you just spec them tighter until they're safe to leave? Because those are two different products, one triages your attention, the other pushes you to remove the ambiguity up front, and I can't tell which is the thing you actually want.

the awareness problem is only half the pain. the bigger half is what happens after you get the ping. if you tap approve from your lock screen without seeing context, youve moved the accountability trail from 'human read the code' to 'human pressed a button while distracted.' the push flow only pays back if the approval is actually informed. the design question worth solving isnt 'how do we notify' but 'whats the smallest legible artifact we can put in the notification so the person can actually consent, not just click.' three lines of the diff plus the intent plus the blast radius, and you have a real signature. anything less and youre building rubber stamp infrastructure.

 

"Rubber stamp infrastructure" is the sharpest possible framing of the failure mode, and it's the thing I most want to avoid building. You're right that a fast approval flow with no context isn't a feature, it's a liability generator, because it manufactures the appearance of oversight while removing the substance. The accountability trail says "human approved," and what actually happened was "human dismissed a notification to get back to what they were doing." That's worse than no approval step, because now there's a record implying scrutiny that never occurred. You've laundered a reflex into a signature.

And the reframe is exactly right: the design question isn't "how do we notify," it's "what's the smallest legible artifact that lets someone actually consent." Consent is the operative word, because consent requires comprehension, and comprehension requires the context to be in the notification itself, not one tap away in a terminal you won't open. The moment the real information lives behind the approval instead of inside it, you've built a system that structurally encourages clicking without knowing, because the path of least resistance is to approve blind. The artifact has to carry enough that the informed choice is the easy one.

Your three-part signature is close to what I've landed on, and the one you named that most people drop is blast radius. Diff plus intent I had, blast radius is the addition that changes it from "here's what it's doing" to "here's what it costs if you're wrong," which is the actual input to a consent decision. A one-line change to a config file and a one-line change to the auth flow can look identical in a diff, and only the blast radius tells you which one deserves the three seconds of real attention. Without it, every approval reads as equally trivial, which trains exactly the reflex you're warning about.

The one thing I'd add to your signature, and it came out of another thread here: the artifact should also carry what the agent didn't verify. Diff, intent, blast radius tell you what it's about to do. "Tests not run on this path" or "assumed X" tells you where the confident-looking change might be hollow. Because the dangerous approval isn't the one that looks risky, it's the one that looks clean and isn't, and the unverified-set is what surfaces that before you sign.

So the real design constraint is: the notification has to make informed consent cheaper than blind consent, or people will rationally choose blind. Genuine question, since you've clearly thought about the legibility threshold: where do you think the line is on the diff, is three lines actually enough, or is three lines sometimes worse than none because it gives false confidence, you saw "a diff," felt informed, and missed that the dangerous part was line four? I keep worrying that a partial artifact can manufacture the same false sense of oversight as no artifact, just more convincingly.