How do you stay aware of what your AI coding agents are doing?
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.


Replies
I’ve been hitting the exact same problem with Claude Code.
My current take is that notifications are useful for “come back now”, but they can also become noisy if agents are constantly doing small tool calls / waiting / resuming.
So I ended up experimenting with something more ambient: a small macOS menu bar app that shows an iPhone Apple Intelligence–style edge glow when an agent is working, and fades out when it’s done.
The idea is not to interrupt you, but to make the agent state visible in your peripheral vision. If the edge is glowing, something is still running. If it disappears, it’s done or waiting.
It currently works via local HTTP hooks, so Claude Code can call `/start`, `/pulse`, and `/stop`. I built it mainly because I kept alt-tabbing just to check whether Claude was still alive.
I open-sourced it here if useful: https://github.com/vector4wang/EdgeGlow
I think push notifications + approval flows solve the “I’m away from keyboard” case, while ambient visual feedback solves the “I’m still at my desk but in another window” case.
Curious if you’ve thought about that distinction in what you’re building.
Pushary
@vector_wang
Synthesized ambient versus push notification distinction, mapped attention-proximity spectrum
The distinction you drew at the end is the most useful frame anyone's brought to this thread, and EdgeGlow is the cleanest expression of half of it I've seen. The edge-glow-via-hooks approach is right because it matches the channel to the attention: when your eyes are already near the screen, the correct signal isn't an interruption, it's something your peripheral vision catches for free. You don't read a glow, you just notice when it stops. That's zero cognitive cost, which is exactly what you want for the "is it still alive" question that doesn't deserve a notification but kept making you alt-tab. You turned a poll into an ambient.
And yes, I've thought about the distinction, but you've stated it better than I had: away-from-keyboard wants push, at-desk-different-window wants ambient. The thing I'd add is that those aren't just two cases, they're two ends of a spectrum keyed to two variables, attention proximity and information density. Ambient is for when your eyes are close and the message is thin ("something's running"). Push is for when your eyes are far and the message is thick ("approve this specific thing"). The failure modes are symmetric and that's the tell: a push notification while you're staring at the screen is annoying because you'd have seen the glow, and a glow while you're at lunch is useless because you can't see it. Same event, wrong channel, depending on where your attention physically is.
Which means the actually interesting layer is the one that picks the channel for you based on where you are. Present at the machine, glow. Away, push. The system should route the same agent-event to ambient or interrupt depending on detected presence, because "where is the user's attention right now" is itself a signal worth reading. Get that right and you never get a redundant push or a glow you can't see.
But here's the one place ambient hits a hard ceiling, and it's exactly the state I care most about: the glow can carry "working" and "done" beautifully, because those are binary and need no payload. It can't carry "blocked, and here's which decision I need," because that one requires content, and color has no bandwidth for content. Your glow tells me to come look. It can't tell me what I'm looking at, so I still pay the reload cost when I get there. That's the seam, ambient is perfect for liveness, weakest for decisions, and decisions are where the time actually dies.
So honestly the two of us are building complementary halves, and the synthesis is nicer than either alone: let the ambient layer absorb all the high-frequency low-stakes noise (the pulsing, the small tool calls, the resuming) so that push can stay sacred and fire only on the rare thing that needs a human with a payload attached. The glow handles "alive," the push handles "decide," and neither one cries wolf because they're not competing for the same events. Your noise worry is real, and ambient is actually the cure for it, not a rival to the notification.
Starred the repo, by the way. Genuine question: with /start, /pulse, /stop, how are you deciding when the agent is "blocked waiting on input" versus just "thinking for a while", because from the outside both look like a long gap between pulses, and that ambiguity is the exact thing I keep failing to detect cleanly. If you've cracked distinguishing blocked-on-human from busy-thinking at the hook level, that's the hard part, and I'd love to know how you're calling it.
To be honest, I don't leave my desk and just approve everything one by one. I usually have 3 terminals up at any given time. I know it's a sedentary life, but even before my business, I sat at a desk at work for most of the day (sans 15 min breaks), so I'm just used to it.
Pushary
@rdychkstudios
Honest answer deserves an honest one back: for your setup, you might not need what I'm building, and I'd rather say that than pretend otherwise. Three terminals, never leaving the desk, approving one by one, that's the synchronous workflow done deliberately, and if you're genuinely present the whole time, the "agent stalled while you were away" problem just doesn't exist for you. You can't miss an approval you're sitting right on top of. The pain this whole thread is about is the gap between agent and human, and you've closed it by never opening it.
The one thing I'd gently separate, though: being at your desk and being the bottleneck aren't the same thing. Even glued to the chair, three agents finishing at once still means two are idle-waiting while you clear the first, and "approve everything one by one" means you're personally clearing trivia, can-I-create-this-file, that an agent could've done unattended if you'd told it the rules once. So the question for you isn't "do you leave your desk," it's "how much of your day is spent rubber-stamping stuff that didn't actually need you." If it's a lot, you could reclaim that attention without standing up, just by gating only the risky calls and letting the safe ones clear themselves. That's less about notifications and more about not being a captcha for your own agents.
No judgment on the desk life, by the way, plenty of people do their best work parked in one spot, and "I'm used to it" is a perfectly good reason. Genuine question: when you approve one by one across three terminals, does it ever feel like the approving itself is the work, like you're context-switching between three agents fast enough that you're busy but not actually thinking? Because that specific flavor of busy, present and occupied but not doing anything only you could do, is the thing I'd want to free you from, and I'm curious if you feel it or if the rhythm actually works for you.
@aadilghani Oh, I'm not saying there haven't been times where auto-approve hasn't been my go to. Especially if I have a meeting I have to go to. But, you are right. There are times where I am the bottleneck. But oddly enough, I find it kind of satisfying reading what my agents tell me before they make changes. It makes me feel present throughout the process.
I think what some developers (and nothing against them) could be missing is context. Sometimes, they just don't know what was done. I have definitely missed security issues during development, even when I was manually approving changes. That scares me as my app is a full production app. But I do tend to do security and testing before any submission, so I guess at that point, it's redundant.
To answer your question, I don't really mind. Keeps me in the loop, and teaches me what I might have to do in the future as a developer if/when I have to manually code to fix something if I had to. God knows there have been many a time where claude just didn't understand what I wanted and I had to go in myself and tinker around on my own. It works for, at least for now. But my process has changed so much, especially from manually coding to this new engineering manager role that I'm sure that I'll find a new way again. Let's just say, it keeps me from taking extensive breaks, and even taking full on naps when I should be working.
Pushary
My current setup as a solo ML engineer building in health AI:
- Claude Code for the heavy lifting, but I keep a tmux session with a simple tail -f on a log file I write to at each agent step. Old school but zero latency.
- For longer unattended runs I use a Python watchdog that sends me an iMessage via AppleScript when a run completes or hits an error. Free, instant, no third-party dependency.
- The bigger discipline shift: I scope agent tasks much tighter than I used to. A 10-minute focused run I can keep a half-eye on beats an hour-long run I completely context-switch away from.
The approval problem you describe is the hard one. I’m curious whether you found people want to approve in real-time or batch review decisions after the fact — seems like it would depend heavily on how reversible the actions are.
Pushary
@sabber_ahamed
Direct answer to your question first, because you also handed me the variable that resolves it: it splits on reversibility, exactly as you guessed, but not only that. Two axes, not one. Reversibility decides whether real-time approval is even necessary, and blocking decides whether batch review is even possible. Real-time-versus-batch is the cell those two axes land you in.
Irreversible and blocking, deploy to prod, dropping a table, anything that gates the run and can't be undone, must be real-time, because batch review of an irreversible action is just reading the autopsy. Reversible and non-blocking, the agent did something undoable and kept going, batch is fine and real-time would be pure interruption tax, you review after, revert the few that were wrong. The interesting cell is irreversible but the agent's willing to wait, which is where async approval earns its keep: not batch, because you can't let it slide, but not desk-bound real-time either, the agent parks and you approve from your phone whenever you surface. So the honest answer to "real-time or batch" is "depends where the action sits on reversibility and blocking, and a good tool routes each action to the right one instead of forcing all decisions into one mode." Most tools pick one mode globally, which is why they feel wrong half the time.
For your domain specifically, health AI, I'd weight it harder toward real-time on a bigger slice than a typical web app, because reversibility there isn't only technical. A code change can be git-revertible while the thing it touched, a data transformation on protected health information, a model that influenced something, isn't cleanly undoable in the way that matters. "I can revert the commit" and "I can undo the consequence" diverge fast in health, so I'd treat more of your actions as effectively irreversible than the diff alone suggests. That's not a notification preference, it's a domain risk floor.
On your setup, the tail -f plus AppleScript-iMessage combo is the good kind of old-school, zero latency, no dependency, and it does the one thing that matters, push not poll. The ceiling is just that it's send-only, the iMessage tells you done-or-error but you can't reply "yes, proceed" and have the run act on it, so it's awareness, not control. Fine until the approval you need to give is the thing blocking the run, then send-only leaves you walking back to the terminal anyway.
But the line I actually want to underline is your discipline shift, because it's the most undervalued thing in this whole thread: a 10-minute run you half-watch beats an hour run you abandon. That's not a workaround, it's the real insight, and it inverts the usual framing. Everyone treats long autonomous runs as the goal and notifications as the patch for losing track of them. You've noticed that tighter scope reduces the need for the notification in the first place, because the blind window is short enough that nothing rots in it. Prevention over alerting. The corollary, which is maybe the actual punchline: better tooling shouldn't be used to enable longer unattended runs, it should let you keep your tight-scope discipline without paying the attention tax for it. The win isn't "now I can safely walk away for an hour," it's "I get my half-eye back for the ten minutes."
Question back, since you've clearly tuned this for a high-stakes domain: when you scope to 10-minute runs, what's your actual stopping criterion, time, or a natural checkpoint like "after it writes the transform but before it runs it on real data"? Because if it's the latter, you're not really time-boxing, you're placing approval gates at the irreversibility boundaries by hand, which is exactly the thing I think should be declarable up front, and I'm curious whether you'd trust a tool to hold those gates or whether in health you specifically want to place every one yourself.
Solo founder running Claude Code all day — I feel this exactly. My setup:
Terminal visible on a second monitor, but I still miss the "waiting for approval" moments constantly
The 30-min-ago-finished problem is real, especially when I'm context-switching between building and other work
Honestly haven't solved it cleanly. What kills me most is the silent "waiting for approval" — the agent's just sitting there and I have no idea. A push the moment it needs input (vs. just when it's done) would be the killer feature for me.
Checking out Pushary — this is exactly the gap.
Pushary
@burak_emre_taser
You said the killer-feature line yourself, so let me just confirm you're right and then sharpen why, because the reason it's the killer feature and not just a feature is the part worth internalizing.
Done and waiting are not two flavors of the same alert, they're opposite economics. "Done" is a finish, the work is safe, you find out late and you shrug, the cost of the delay is basically zero because nothing's deteriorating. "Waiting for approval" is a live stall, the agent is frozen and the clock is running, and crucially the cost grows with every minute you don't know. That's why the silent wait kills you specifically and the late finish merely annoys you, one is a static fact and the other is a bill that's still accruing. So a tool that only pings on done has solved the cheap half and left the expensive half exactly as broken as the second monitor leaves it.
Which is the thing about your second monitor: it doesn't actually help with the failure you named, and it's worth seeing why so you don't keep trusting it. A monitor shows you activity. But waiting-for-approval is the absence of activity, the terminal just sits there, and a quiet terminal looks identical whether the agent is thinking, blocked, or done. You can't see a silence, even when it's six inches away in your peripheral vision. The monitor is great for watching things move and useless for noticing things stop, and stopping is your whole problem. That's why you miss the waiting moments "constantly" despite having the screen right there, it's not inattention, it's that the signal you need isn't visible by looking.
The fix is the agent declaring "I'm blocked, I need input" as an event the instant it stops, so a silence gets converted into a push instead of waiting for you to surface from context-switching and discover it. That's the half the second monitor can't do and the half that's worth your money.
Go try it, and since you're the exact target user, solo, Claude Code all day, context-switching between building and everything else a solo founder also has to be, I'd genuinely want your read on one thing: when the push fires for "needs input," do you want to answer it from the phone and keep moving, or do you actually prefer being pulled back to the terminal because you want the full context before you say yes? Solo founders split hard on this, some want to clear the approval in two seconds and stay in their other work, some don't trust a yes they gave from a lock screen. Which one are you, because it changes what "solved cleanly" even means for you.
@aadilghani Tried Pushary after this thread — the "waiting for approval" push is the part I actually needed. Second monitor never solved it for me because a stalled terminal looks the same as a working one, you can't notice a silence.
I'm solo too, building a few SaaS products in Claude Code all day (VS Code + MD prompt files), so I context-switch constantly between building and the hundred other things. That gap between "agent stopped" and "I noticed" is exactly where my time leaks.
One thing I'm curious about from your side — when the approval push fires, are most people answering from their phone and moving on, or going back to the terminal? Changes a lot about how the flow should feel.
Pushary
@burak_emre_taser
Real answer from what I'm seeing: it splits cleanly by the weight of the decision, not by the person, and that turned out to be the thing I had backwards at first. I expected people to have a fixed preference, "I'm a phone person" or "I'm a terminal person." They don't. The same person answers from the phone for the cheap calls and walks back to the terminal for the heavy ones, and which mode they pick is set entirely by how much they trust their own judgment without the surrounding context in front of them.
The cheap ones clear from the phone every time, "can I install this package," "overwrite this file," "yes, proceed", because the decision is fully contained in the question, the context wouldn't change your answer, so the lock screen is plenty and walking to the desk would be pure waste. The heavy ones pull people back to the terminal, "I'm about to refactor this auth flow," anything where you'd want to see the surrounding code before committing, because the question alone isn't enough and answering blind from your phone would just be rubber-stamping with extra steps. So it's not phone-versus-terminal as a personality, it's the decision telling you which one it needs.
Which means the design conclusion is the interesting part, and your instinct that it "changes a lot about how the flow should feel" is exactly right: the push can't be one-size. It has to carry enough context that the cheap decisions are genuinely answerable from the phone, the diff, the command, the risk flag right there, so you're not forced back to the terminal for something trivial just because the notification was too thin to decide on. But it also has to make the heavy ones honest, it should be obvious from the push when this is a "you really want to look at this properly" decision versus a quick yes, so it nudges you to the terminal instead of tricking you into a lock-screen rubber-stamp on something that deserved real eyes. The payload's job is to make the phone sufficient for the small stuff and to flag clearly when the phone isn't enough.
So the flow that feels right isn't "answer everything on phone" or "everything pulls you back," it's the push being rich enough to resolve the trivial in two seconds and self-aware enough to say "this one's worth the walk." Get that calibration right and people stay in their other work for the ninety percent that's trivial and only break focus for the ten percent that earns it, which for a solo founder context-switching all day is the entire game.
For you specifically, since you're solo across a few SaaS products in Claude Code, genuine question back: do your approval moments skew mostly trivial, the routine package-and-file stuff that's pure phone, or do you hit the heavy refactor-and-architecture decisions often enough that you'd want the push to actively tell you "go look at this in the editor"? Because if you're mostly trivial, the win is just never breaking focus, and if you hit heavy ones a lot, the more valuable feature is the push being good at flagging which is which, and I want to know which one to make sharper for your kind of use.
@aadilghani bit of both for me but the heavy ones hurt more — when it's a big refactor i don't trust a yes from the lock screen, i wanna see the surrounding code first. so honestly the flag telling me "this one's worth opening the editor" would be the part i'd use most.
also — i'm building MadeDay, productized design + frontend dev for founders. planning a PH launch soon. cool to connect with someone solving the same daily mess.
I relate to this a lot.
For coding agents, the biggest issue for me is not knowing whether the agent is still working, waiting for approval, or stuck in a loop.
A simple status layer would help a lot: running, waiting for input, completed, failed, plus what files changed. Without that, you end up babysitting the agent instead of delegating to it.
Pushary
@prashant_patil14
Your closing line is the whole thesis in one sentence: without a status layer you end up babysitting instead of delegating, and those are opposites, not points on a spectrum. Delegation means handing off and trusting you'll be told if something needs you. Babysitting means you can't hand off because you can't trust the silence, so you stay glued to it. The status layer is literally the thing that converts one into the other, it's what makes "walk away and trust" possible, and without it the agent's autonomy is fake, because the human is still pinned to the chair.
The three-state confusion you named is the sharpest part, and it's worth seeing why those three are genuinely hard to tell apart: working, waiting-for-approval, and stuck-in-a-loop can all present as the same thing from outside, an agent that isn't done and isn't obviously crashed. Working and waiting look identical because both are just an absence of completion. And a loop is the sneakiest, because it looks like the most productive state of all, it's busy, it's emitting, it's clearly doing something, it's just doing the same nothing over and over. So your status set isn't only useful, it's naming the exact distinctions that are invisible by default, which is why a real status layer has to come from the agent declaring its state, not from you squinting at the terminal trying to infer it.
The one I'd flag as needing a different detection method than the others: stuck-in-a-loop. Running, waiting, completed, failed are states the agent can announce. A loop is one the agent usually doesn't know it's in, that's what makes it a loop, so it won't declare it. You catch that one externally, by watching for activity that costs tokens and time without the state actually advancing, motion without progress. So your status layer is really two mechanisms wearing one interface: declared states for the things the agent knows, and a measured signal for the loop it doesn't.
That's exactly the layer I'm building, your five fields plus what-changed, so genuine question: of running / waiting / completed / failed, which transition do you most want pushed to you versus just visible in a view you can glance at? My read is waiting-for-input is the one that has to actively interrupt you because it's burning time silently, while completed and failed you might be fine seeing in a list when you look. But you've clearly thought about the state set, so I'm curious whether you'd want all of them pushed or just the one that's actually costing you while you're away.
@aadilghani Exactly ! waiting for input is the one I'd want pushed immediately because that's where time is silently wasted.
Completed and failed can probably sit in a dashboard or summary unless it's a critical task. But if an agent is blocked and needs a human decision, that should interrupt me right away.
Loop detection is also important, but I agree it needs to be measured externally rather than trusted from the agent itself.
Pushary
@prashant_patil14
You've just sorted the four states by interrupt-priority better than most frameworks do, and the underlying rule you're using is worth making explicit because it generalizes: push when the cost of not-knowing is still growing, dashboard when it's already settled. Waiting-for-input gets pushed because the meter is running, every minute you don't know costs you. Completed and failed can sit in a summary because they're terminal, the cost is fixed the moment they happen, finding out later doesn't make it worse. That's the actual principle, not "important versus unimportant," it's "is the clock still running on this." Failed feels urgent, but a failed run is just stopped, it's not bleeding, so it can wait for your glance. Waiting is the only one actively accruing.
Your "unless it's critical" caveat is the one refinement that rule needs, and it's the right one: the push-versus-dashboard line isn't fixed per state, it bends with stakes. A completed run on a throwaway task is dashboard. A completed run on the thing blocking your release is a push, because there's something downstream waiting on the news. So the cleanest model is two inputs, not one, urgency-of-knowing and stakes-of-the-task, and the same state routes differently depending on both. Most tools hardcode "completed = notify" and end up either spamming you with trivial done-pings or staying silent on the one finish you needed. Letting the task's criticality move the line is what keeps the channel honest.
And the fact that you immediately granted the loop point, external measurement not self-report, tells me you've actually thought about the mechanism and not just the wishlist. That's the distinction that trips people up: they list "detect loops" alongside "show me when it's done" as if they're the same kind of feature, when one is a state the agent hands you and the other is something you have to infer from the outside because the agent is, by definition, blind to it. Keeping those mentally separate is what stops you from building loop detection on top of agent self-report and then wondering why it never fires.
So we've landed in the same place, and it's a good place: waiting interrupts, terminal states settle into a view unless stakes pull them up, loops get measured. Genuine last question, since you've reasoned this through cleanly, how would you want the system to learn a task is critical, do you tell it up front when you kick the agent off ("this one's important, push everything"), or would you rather it infer criticality from signals like which files or which project? Declared is accurate but it's friction every time you start a run, inferred is zero-effort but wrong until it learns, and I keep hitting that same fork everywhere in this design, curious which side you'd actually tolerate living on.
@aadilghani I’d prefer declaring criticality up front, but with simple levels instead of too much configuration.
Something like: normal, important, release-blocking.
Inference can help later, but for agent workflows I’d rather be explicit at the start than have the system guess wrong. The friction is acceptable if it prevents notification noise and missed critical updates.
I just keep an eye on everything. When I use claude browser extension I actually get a clear push note that the work has been done, which is quite handy.
Pushary
@fbajo
"I just keep an eye on everything" is the honest baseline, and the Claude extension push you mentioned is a real improvement on it, so worth being precise about what it does and doesn't close. The push on "work done" solves the finish case, you stop having to keep an eye out for completion, which is genuinely handy and a step up from pure watching. But notice it's still done-only, and done is the easy half. The case that actually leaks your time is the one no done-ping fires for: the agent stopping partway to ask you something. That's not a finish, so the completion notification stays silent, and you're back to keeping an eye on it to catch the pause.
So the extension didn't replace "keep an eye on everything," it shrank it, you can stop watching for done, but you still have to watch for blocked, because nothing tells you about that one. And blocked is the expensive state, because while done-late just means you find out late, blocked-silent means the agent is frozen and idle the whole time you didn't know. The done-ping covers the cheap case and leaves the costly one to your eyeballs.
The other ceiling, quietly: the extension pings you for the extension. The moment you've got Claude Code in a terminal or Cursor running alongside, that one push doesn't know about them, so "keep an eye on everything" creeps back in as soon as everything is more than one tool. Single-tool, single-state notification is a real help and also exactly where it stops scaling.
Question, since the done-push is already working for you: does the Claude extension ping you when it's waiting on your input mid-task, or only when it's fully finished? Because if it's finish-only, that blocked-but-not-done gap is the precise thing still costing you the eye-keeping, and I'm curious whether you've noticed the silent waits or whether your tasks just don't pause much.
@aadilghani Honestly I'm an SWE and SRE, I like going into everything my agent does. I seldom launch multiple agents cause in my opinion that slows me down in the long term as I have to reverse engineer "my own" code. I review about everything, not every single line but the gist. I still find that agents are not capable to properly name things, and make poor long term architectural decisions that are specific to your domain, use-case and current architecture. This most likely has to do with the nature of LLMs that are mostly regurgitating "similar" scenarios they ingested earlier.
This will all improve of course, but until then, I don't really need to be notified as I'm on top
Pushary
@fbajo
Then you're not the user, and I'd rather say that plainly than try to talk an SRE into a notification he doesn't need. Your workflow is internally consistent: one agent, review the gist of everything, stay on top, never lose the thread, so there's no awareness gap for a notification to fill. The whole product assumes you've stepped away. You haven't, on purpose. Nothing to solve.
And your reason for staying single-agent is the sharp part, because it's not a limitation, it's a considered tradeoff most people don't reason through: parallel agents trade present-speed for future-cost, and the future-cost is reverse-engineering your own code. That's the real bill nobody puts on the invoice. Running six agents feels fast right up until you're an archaeologist on a codebase you nominally authored, reconstructing why six parallel sessions made six local decisions that don't cohere. You're choosing comprehension over throughput, and for someone who'll carry the on-call pager for this code, that's the correct optimization. The person who has to debug it at 3am should be the person who understood it at write-time.
Your naming-and-architecture point is the most durable critique of agents in this whole thread, and I think you've got the mechanism right. Naming and long-term architectural fit are exactly where "regurgitate the nearest similar thing I've seen" fails, because good naming and good architecture are domain-specific and context-specific, they depend on your use case, your existing structure, the conventions this particular codebase already committed to. There's no nearest-neighbor in the training data for "the right name given the seven other things in your module." The model is pattern-matching to the average codebase and you need the decision that fits your codebase, and those diverge precisely on the judgment calls that compound, a slightly-wrong name or a slightly-wrong boundary doesn't fail a test, it just quietly accrues into architecture you'll fight later. That's not a notification problem, that's a "the agent can't hold your system's whole shape in its head and care about its future" problem, and you're right that it's the current ceiling.
Where I'd gently disagree is "this will improve, until then I'm on top" smuggling in that it's purely a model-capability wait. Some of it is, the naming and architecture will get better. But the on-top-ness you're describing isn't something better models retire, it's something you'd want to keep even when the agent is good, because the value of an SRE reviewing the architecture isn't catching the agent's mistakes, it's that you're the one who'll operate it. Even a perfect agent makes locally-reasonable choices without owning the consequences, and ownership is the thing review gives you that no model improvement transfers. So I don't think you ever fully graduate into needing the notification, I think your review discipline is the right permanent posture for code you're accountable for, and the tooling should make that review cheaper, not replace it with a ping that says "trust me, it's done."
Genuine question, since you're the rare person optimizing explicitly against parallelism: is there any version of multi-agent you'd accept, like parallel agents on genuinely independent surfaces where the reverse-engineering cost doesn't compound, separate services, isolated modules, things that don't have to cohere into one architecture you hold in your head? Or is it that even independent parallel work fragments your mental model enough that one-at-a-time is just strictly better for how you operate? I ask because "parallelism is fine when the pieces don't have to fit together, and poison when they do" is a hypothesis I keep circling, and you're exactly the person whose answer would confirm or kill it.
The "switch to something else" loop is the part nobody designs for. Most agent UIs assume you're sitting and waiting, but the whole reason you have an agent is so you don't have to. Then 20 minutes later you have no idea where it stopped, what it touched, or whether the thing it claims to have done actually got done.
For me the signal that matters most isn't done vs blocked, it's intent drift. The agent starts on task A, hits a missing dependency, "decides" to refactor a config file to fix it, then proceeds to task B as if nothing happened. Three commits later you realize half the work was something you never asked for. A status notification doesn't catch that. Only reading the actual log does.
Curious what others do, do you treat the agent's chain of decisions as something to audit, or just check the final diff?
Pushary
@elias_motionfy
You've named a failure that's genuinely different in kind from the rest of this thread, and it's worth being precise about why, because most of what people call "monitoring" is structurally blind to it. Done-vs-blocked, status, even the final diff, all of those describe end states. Intent drift isn't an end state, it's a path problem. The agent can drift and still arrive at a clean-looking diff, because the unrequested config refactor compiles, passes, and sits there looking intentional. The diff shows you what the codebase is now, not the sequence of decisions that got there, and drift is entirely a property of the sequence. So checking the final diff can't catch it by construction, not because the diff is incomplete, but because drift is invisible in any single snapshot. You can only see it in the derivative, the chain of choices over time, which is why you correctly say only reading the log catches it.
The opening observation is the sharper frame, though: agent UIs assume you're sitting and waiting, which contradicts the entire reason the agent exists. That's the original sin. The chat interface was designed for synchronous conversation, you say a thing, it says a thing, you're both present. Then we handed that same interface a job that's supposed to run while you're absent, and the absence is the whole point. So the interface is optimized for exactly the mode you're not in. Drift is what happens in the gap between "I'm present and would've said no to that refactor" and "I'm absent so the agent's small wrong turn compounds three commits deep before I'm back." The synchronous UI would've caught the drift instantly, you'd have seen it decide to touch the config and said "wait, why." The async reality is what lets it metastasize, and no tool built on the sit-and-watch assumption addresses that, because it assumes the catch happens live.
To your actual question, audit the chain or check the diff: the honest answer is most people check the diff, because auditing the chain is expensive, and that's precisely the gap drift exploits. Reading the full decision log is slower than just doing the task yourself, so nobody does it, so drift survives. But I don't think the answer is "audit every chain," because that's unaffordable and just rebuilds the babysitting. The answer is to make drift cheap to detect without reading the whole log, and the way you do that is by catching it at the decision point rather than in the post-mortem. The moment the agent goes from "task A" to "I'll refactor this config to fix a missing dependency," that's a scope expansion, and a scope expansion is detectable as an event, the agent is about to do a class of thing it wasn't asked to do. You don't need to read three commits of log if the agent is required to flag "I'm about to do something outside the original task scope" the instant it decides to. Drift caught at commit three needs a forensic log read. Drift caught at the decision needs one notification.
Which reframes drift as a special case of the approval problem, and a particularly important one: the dangerous approvals aren't only "this action is risky," they're "this action is outside what you asked for." Scope is its own risk axis, independent of how destructive the action is. A perfectly safe config edit that you never requested is a drift event even though the edit itself is harmless, because the problem isn't the edit's danger, it's that the agent silently expanded its mandate. So the signal that catches drift is the agent declaring intent before it acts, here's what I'm about to do and here's whether it's still inside the original scope, so you can veto the unrequested refactor before it becomes three commits of work you have to unwind. That's the thing a status notification can't do and an intent notification can, and it's exactly why "assumptions and intent" keep coming up in this thread as the high-value, hard-to-capture fields, they're the leading indicators, and drift is the failure that proves leading indicators matter more than end-state reporting.
Genuine question back, because your example is specific enough that you've clearly been burned by this concretely: when the agent drifts like that, is it usually drift you'd have approved if it had asked, the missing dependency genuinely needed fixing and the config refactor was reasonable, just unannounced, or is it drift you'd have stopped, where the agent's "fix" was the wrong call and you'd have wanted to solve the dependency differently? Because those need different responses. If it's mostly reasonable-but-unannounced, the fix is a lightweight "FYI I expanded scope" that you skim. If it's often the-wrong-call, the fix is a hard stop that blocks on your approval before it proceeds, and which one you actually hit determines whether drift detection should interrupt you or just narrate itself into the trail for later. I keep needing to know whether drift is usually the agent being helpfully resourceful or quietly wrong, because the answer changes whether you gate it or just log it.
@aadilghani Honestly mostly the first category, the agent's expansion is usually defensible. The dependency really was missing, the refactor really would fix it, the next task really did need that config touched. If I'd been sitting there I'd probably have nodded and said go ahead. Maybe 70/30 split toward reasonable-but-unannounced versus wrong call.
But here's why I still think hard-stop makes more sense than narrate-and-skim, even at 70/30: the cost asymmetry is brutal. A skip-able FYI that I actually skim adds maybe 30 seconds of friction per run. A "wrong call" drift that I miss because I trusted the FYI pattern costs me an hour of git surgery and sometimes a half-day of finding the second-order bugs that the wrong fix introduced. The expected value math hits me right at the moment I'm least equipped to do the math, I'm doing something else, I'm context-switched out, the notification arrives and gets a 1-second glance.
The narration-only model assumes I'll skim attentively. In practice I skim at the level of "did anything red come up." Scope expansion doesn't show up red because the agent thinks it's helping. So the failure mode of FYI is "I miss the 30%," and the failure mode of hard-stop is "I'm interrupted on 70% of runs I'd have approved anyway." Right now I'd rather pay the interruption tax than the wrong-call tax, because I can amortize interruptions across a workday and I can't amortize an afternoon of cleanup.
Where I think you're more right than my current setup: at some point the interruption rate has to come down or nobody will keep the agent on. The honest answer is probably gating by risk class, config edits and any file outside the original task path hard-stop, dependency installs and dev-server restarts FYI-only. That mapping I haven't built yet because I haven't been burned often enough to bother. Which is probably exactly the trap your thread is about.
Pushary
@elias_motionfy
Your EV math is correct and it's the part I'd been hand-waving, so let me not do that. The asymmetry is the whole argument: a skimmed FYI costs 30 seconds, a missed wrong-call costs an afternoon plus the second-order bugs, and crucially the costs land on different sides of a multiplier you can't control, because the moment you're least equipped to evaluate the notification is the moment it arrives, you're context-switched out, it gets a one-second glance. So the expected cost of FYI isn't "30% × cleanup," it's "30% × cleanup × P(I actually catch it in a one-second glance)," and that last term is small precisely when it matters. Narrate-and-skim doesn't just risk the miss, it systematically degrades your catch-rate at the exact instant the stakes are highest. Hard-stop sidesteps the whole product by not relying on your attention being available, which is the one thing you can't guarantee when you've delegated specifically so your attention could be elsewhere.
The deeper thing your message exposes, and it's the sharpest point in the thread, is why scope expansion is uniquely undetectable by skimming: it doesn't show up red because the agent believes it's helping. Your skim heuristic is "did anything red come up," and drift is green by construction, the agent isn't erroring, it's confidently doing a reasonable-looking thing you didn't ask for. So the failure mode isn't that you skim lazily, it's that the signal you skim for and the signal drift emits are orthogonal. Red catches failures. Drift is a success the agent is proud of. No amount of attentive skimming fixes a category mismatch between what you're scanning for and what the thing actually looks like. That's why narration can't work for this specific failure even in principle, not just in practice, you'd have to skim for "is this in scope," which is a different and much more expensive read than "is this red."
And the 70/30 cuts the opposite way from how it first looks. A naive read says "70% reasonable, so mostly FYI." But the reasonable 70% is exactly what trains the trust that makes you miss the 30%. If drift were usually wrong, you'd stay alert to it. Because it's usually fine, you learn the FYI pattern means "probably nothing," and that learned complacency is what guarantees the one-second glance on the run that needed three minutes. The high reasonable-rate is not an argument for FYI, it's the mechanism that makes FYI fail. You can't have a notification that's right 70% of the time and expect humans to attend to it at 100% intensity, the base rate destroys the vigilance. Hard-stop is immune to this because it doesn't ask you to stay vigilant, it just refuses to proceed.
Your last paragraph is the real conclusion and you got there yourself: gate by risk class, and the right axis is exactly the one you named, files outside the original task path. That's the cleanest drift signal there is, because it's mechanical, not semantic. You don't need to judge whether the expansion is reasonable, you just detect that the agent touched a file the task didn't name, and that's computable without understanding intent at all. Config edits and any out-of-path file hard-stop, dependency installs and dev-server restarts FYI, because those are in-path expected side effects of the work you asked for. That mapping turns "70% of runs interrupted" into "only the runs where the agent left the lane interrupted," which collapses the interruption tax to roughly your actual drift rate instead of your whole run count. The interruption rate problem you flagged, nobody keeps the agent on if it stops 70% of the time, is solved not by softening the stop but by narrowing what triggers it. Hard-stop on a tight trigger beats soft-stop on a broad one.
And then the sentence that's the entire point of this thread, which you wrote yourself: you haven't built the risk-class mapping because you haven't been burned often enough to bother. That's the trap exactly, the mapping is cheap to build and you'll keep not building it until an afternoon of git surgery makes it retroactively obvious you should have, and the burn that finally motivates it is more expensive than all the prevention would have cost. The thing standing between you and the fix isn't difficulty, it's that the pain is intermittent enough to stay just under the threshold of action. Which is precisely why it's worth externalizing into a tool, not because you couldn't build it, you obviously could, but because a tool ships with the out-of-path-hard-stop default already on, so you're protected before the burn instead of after it. The whole value is being handed the lesson you haven't been forced to learn yet.
So genuine question, since you've basically specced the risk-class engine: when you say "outside the original task path," how do you imagine the path getting defined, do you state it when you kick off the run ("this task touches these files/dirs, stop if you leave"), or should the agent infer the expected path from the task description and the stop fires when it deviates from its own stated plan? Declared path is precise and airtight but it's friction on every run and you'll resent it on the small tasks. Inferred path is zero-friction but now you're trusting the agent to correctly predict its own scope, and an agent that under-scopes its plan would drift right past a stop that's keyed to its own underestimate. I genuinely don't know which is right, because declared makes you do work upfront to prevent work later, and inferred risks the detector inheriting the same blindness as the thing it's detecting. You've thought about this more concretely than anyone in the thread, so where would you put the path definition?
@aadilghani Declared. Inferred loses.
The inference model relies on the agent correctly predicting what its own scope should be, which is exactly the prediction that fails whenever drift happens. An agent that under-scopes its plan and then drifts past its own stated scope has the same blind spot for both, so the detector inherits the disease. It's like asking someone to grade their own exam, the errors they'd miss on the exam are the errors they'll miss on the grading.
Declared has friction but it's diagnostic friction. The moment you write out "this task touches these files/dirs, stop if you leave," you're forced to think about what the task actually is, and that pre-work catches the underspecified tasks that would produce ambiguous drift anyway. If declaring the path is annoying, that's a signal the task wasn't well-specified. If declaring the path is trivial, you've paid five seconds to buy airtight enforcement. Either way you learn something.
The friction argument against declared cuts the other way once you've been burned once. After the afternoon of git surgery, "state the paths at the start" stops feeling like friction and starts feeling like the seatbelt you wish you'd been wearing. Cheap when you don't need it, priceless when you do. Inferred has no equivalent upside, the only argument for it is convenience, and convenience is what got us into this in the first place.
There's a hybrid I'd tolerate: declared for anything you'd label a "real task" (feature work, refactors, anything with a ticket), inferred for one-off exploratory prompts where declared would be genuinely overkill. But the moment the exploratory prompt starts producing commits, promote it to declared. The signal that something has moved from "I'm poking around" to "I'm shipping" is a natural gate, once the agent's output is going anywhere permanent, the seatbelt goes on.
Which is really just a longer way of saying declared, but with a boundary that lets you not-declare the truly disposable stuff. Anything real gets a path.
I don't think the problem is the agents anymore, it's the lack of observability around them.
Around Turgo workflows, we've noticed that once you have multiple agents running, you need a control layer that surfaces status, approvals, failures, and dependencies in one place. Otherwise, context switching becomes the biggest productivity killer.
Feels like this is evolving into an "AgentOps" problem rather than an AI problem.
Pushary
@jahnavi_thota
"AgentOps rather than an AI problem" is the right name, and the reframe underneath it is the important part: the constraint moved. When the models were the bottleneck, every problem looked like an AI problem, make it smarter, make it hallucinate less. The models got good enough that the bottleneck slid downstream to everything around them, and now the limiting factor isn't the agent's capability, it's your ability to observe, coordinate, and trust a fleet of them. That's not an AI problem, it's an operations problem, and it rhymes hard with the history you're implicitly invoking, we went from "can the server run the code" to DevOps and observability the moment we had more servers than one person could watch. Agents are hitting that exact inflection. The word AgentOps is doing real work, not just branding, because it correctly says the discipline you need is operational, not model-level.
The item in your list that's the tell you've actually run this at scale is "dependencies," because the other three, status, approvals, failures, are per-agent properties, and dependencies is the one that's between agents. Anyone who's run a single agent knows they need status and failures. You only discover you need dependency-awareness once agents start producing work that other agents or other steps consume, and then a silent failure or a stall in one isn't a local problem, it's a cascade, agent B is happily waiting on an output agent A died producing, and neither of them knows. Single-agent observability is a dashboard. Multi-agent observability is a dependency graph with state on it, and that's a categorically harder thing, because the failures that matter most aren't in any single agent, they're in the edges between them. The fact that Turgo surfaced dependencies as a first-class need means you hit the cascade problem, which is the real threshold between "I have notifications" and "I have AgentOps."
Where I'd add one thing to the observability framing, and it's the distinction that keeps coming up in this thread: observability in the classic sense is pull, a place you look, and the whole productivity-killer you named, context switching, isn't solved by having a place to look, it's solved by not having to look. A control layer that surfaces everything in one place is necessary but it inherits the dashboard trap, if staying informed requires me to go check the control layer, I've just consolidated four context-switches into one, not eliminated them. The version that actually kills the context-switching tax is push on the state-changes that need a human and silent on everything else, so the control layer is the thing you consult when you choose to, but it reaches out to you for approvals and cascade-failures rather than waiting to be observed. Observability that you have to observe is still a tax. Observability that observes for you and taps you is the unlock. AgentOps has to be push-first or it's just a nicer control room you're still chained to.
Genuine question, since Turgo's clearly operating at the multi-agent-with-dependencies altitude most people in this thread haven't reached: when a dependency breaks, agent A fails and agent B is downstream waiting on it, how are you handling the propagation, does B get notified/halted automatically when A fails, or does B stall silently until someone notices the whole chain stopped? Because that's the exact place I think AgentOps gets genuinely hard and diverges from single-agent notification, a failure has to travel the dependency graph to everyone affected, not just alert the one agent that broke, and I'm curious whether you're doing active propagation or whether it's still surfaced as independent per-agent status that a human has to mentally reassemble into "oh, B is stuck because A died." The reassembly-by-human is the part I'd most want to automate away, and it's the part I haven't seen anyone solve cleanly.
That is a key problem and issue. At this point, most people don't seem to care so long as they get a result, particularly on long projects. It's hard to keep track of the ongoing thoughts.
Pushary
@frank_parsolano
Right, and that “don’t care so long as they get a result” attitude is exactly what quietly costs people on long projects. It works until the result is subtly wrong and you have no idea which of the agent’s hundred decisions caused it, because you stopped tracking the thoughts halfway through.
That’s the gap I’m building Pushary for: keeping a lightweight trail of what the agent did and where it got stuck, so coming back is a ten-second scan instead of trying to reconstruct its thinking from scratch.
Curious, on your long projects, is it more that you lose track of what it did, or why it did it? Those are slightly different problems and I keep going back and forth on which one hurts people more.
This is such a relatable problem!
Right now, I’m just brute-forcing it: because I run multiple agents at the same time, I usually have to stay actively at my desk and keep an eye on all of them manually. It's definitely not the most efficient way to work.
It would be incredibly smart to have a centralized notification system, especially just to get pinged whenever an agent is blocked, needs approval, or gets stuck on an error. Building a reliable way to handle those "waiting for user" states without having to constantly babysit the terminals would save a ton of time.
I’d definitely be interested to see what you are building for the push notifications/approval flows!
Pushary
@patrik_pyoria
"Brute-forcing it by staying at my desk to watch them all" is the honest baseline, and the draining part isn't the watching, it's that it pins you in place. Running multiple agents is supposed to buy freedom, and instead it chains you to the chair as a human monitoring system. You automated the work and kept the supervision manual, so the net freedom is smaller than it should be.
And you've already spotted the fix in your second paragraph: the three states worth a ping are blocked, needs-approval, and stuck-on-error, and nothing else. That restraint is the whole thing. Ping on every step and it's noise you'll learn to ignore. Ping only on "waiting for user," and every alert means your attention is actually required, so you can walk away and trust the silence.
That's exactly what Pushary is, a centralized ping for those "waiting for user" states across Claude Code, Cursor, and Codex, so you stop babysitting terminals and the agents come to you instead. The one that's genuinely hard is the stuck-on-error case, because a clean error announces itself but an agent quietly frozen mid-task looks identical to one that's thinking, so real detection is the actual work under the simple-sounding feature.
Since you're living the brute-force version, genuine question: which state costs you most right now, the silent finish, the approval wait, or the error you didn't catch? That tells me which one to make loudest. And happy to have you try it, pushary.com, you're exactly who it's built for.