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
This resonates. As a solo dev leaning on AI agents heavily, the polling problem is exactly what eats my day too. The thing that helped me most was not a better dashboard but a plain running notes file: every task the agent should do and its state, so I glance at one place instead of watching terminals. It does not close the "agent is blocked and waiting" gap, but it turned "what is even happening across all this" into something I can see at a glance. Has anyone cracked the blocked-and-waiting alert without it becoming noise?
Pushary
@virko_kask
The running notes file is a smarter move than a dashboard and it's worth naming why: you didn't build a better place to watch, you built a single source of truth so you stop watching in multiple places. One glance beats scanning terminals because you collapsed N things-to-check into one, and that alone kills most of the polling anxiety. Good instinct.
But you've also put your finger on exactly what it can't do, and the reason is structural: the notes file is pull, you still have to go look at it, and it only shows the state as of the last time something wrote to it. The blocked-and-waiting gap survives because "blocked" is precisely the event you need pushed to you, not one you'll catch on your next glance. A file makes the state legible when you check. It can't tap you when the state changes. That's the missing half.
To your actual question, cracking blocked-and-waiting without it becoming noise: the answer is aggressive selectivity, and it's the whole game. Noise doesn't come from notifying, it comes from notifying on the wrong things. If you push on blocked, done, and failed only, and stay dead silent on every intermediate step, the channel stays trustworthy because a ping always means "you're actually needed." The moment you push progress updates, people mute it, and then the one alert that mattered dies muted. So the trick isn't a cleverer alert, it's ruthless discipline about what never earns one.
The genuinely hard part underneath your question, though, is detection, not noise: an agent that's blocked-and-waiting looks identical to one that's just thinking, both are quiet terminals. You can't cleanly alert on "blocked" unless the agent actually declares it, because inferring it from silence either fires on every long pause (noise) or misses real stalls (gap). That's why it's unsolved for most setups, the reliable version needs the agent to emit "I'm blocked" as an event, which you get from hooks on Claude Code and Codex and basically can't from black-box tools.
That combination, push only on the three states, and get the block from a real hook rather than guessing at silence, is exactly what I'm building with Pushary, since a notes-file-plus-terminal-watching is the setup it's meant to replace. Genuine question back, since your notes file is already a state tracker: do you update it by hand, or does the agent write its own state into it? Because if it's manual, that's its own polling tax in disguise, and if the agent maintains it, you're one step from that same file being what emits the blocked event instead of just recording it after the fact.
@aadilghani The agent maintains it, I only read it. Every task gets a line with its state and the agent updates it as it works, so there is no manual polling tax. And you are right about the consequence: the blocked write is already the event, it just has nowhere to go yet. Wiring that one write to an actual push, with your three-states-only discipline (blocked, done, failed, silence on everything else), is exactly where my setup should go next. Appreciate the thorough breakdown, and good luck with Pushary.
Pushary
@virko_kask
"The blocked write is already the event, it just has nowhere to go yet" is the whole thing in one line, and you got there yourself. You've actually done the hard part already. Most people are stuck trying to infer state from a silent terminal, and you sidestepped that entirely by having the agent declare its state into a file. The detection problem everyone else is fighting? You solved it by accident. What's left is pure plumbing: route that one write to a push instead of a file, keep the three-states-only discipline so it stays trustworthy, done.
And the file doesn't go away when you add the push, it gets better. The push handles "when do I need to look," the file stays as the at-a-glance overview for "what's the state of everything right now." Notification and record are two different jobs, and you'd have both. The push is the tap on the shoulder, the file is the thing you glance at when you choose to.
Honestly you're one webhook away from having built a lean version of Pushary for yourself, which is a compliment to your instincts, not a pitch. If you'd rather not maintain that glue as you add tools and devices, that's exactly the seam Pushary sits in, but your setup is genuinely close. Good luck with it either way, and thanks for one of the sharper exchanges in this thread.
@aadilghani Likewise, this was one of the sharper exchanges I have had here. I will wire that one write to a push and keep the three-states rule. Will keep an eye on Pushary too. Good luck with the launch.
The "perpetually new employee" framing is the sharpest thing in this thread, and I'd push it one step further. Awareness has two horizons, and everyone here is (rightly) solving the near one: in-the-moment, done / blocked / needs-approval, where push clearly beats polling. The far horizon is across sessions — what has this agent actually learned about my codebase, my conventions, the three things it got burned on last week? That's invisible today, and it's exactly why trust never compounds: the agent shows up new every morning because its state resets to ~zero.
Those two problems share a substrate. The reason you can't get a clean "needs a decision" ping is often the same reason trust doesn't accrue — the agent's state isn't a durable, inspectable artifact, it's scattered across a context window that evaporates. Make the agent's memory a first-class thing you can actually read (what it believes, what it's unsure about, what it decided and why) and "awareness" stops being only a notification stream and becomes something you can reconstruct after the fact. The junior finally starts accruing tenure.
Genuine question for the folks running 6-7 agents: do you persist anything across sessions beyond a CLAUDE.md / rules file — does your agent actually remember what it learned yesterday, or does every run start from zero and you re-teach it through the prompt each time?
Pushary
@alexanderbering
You've extended the framing into the place it actually needed to go, and the two-horizons split is the sharp part: near-horizon awareness is state ("what is it doing right now") and far-horizon is memory ("what has it learned across time"). Everyone including me has been solving the state problem because it's the acute pain, but you're right that the memory problem is why the acute pain keeps recurring. A perpetually-new employee doesn't just need better notifications, it needs to stop being new, and no amount of push-versus-poll touches that.
The insight I think is genuinely load-bearing is your "same substrate" point, because it reframes both problems as one root cause. The reason you can't get a clean blocked ping and the reason trust never compounds are the same reason: the agent's state isn't a durable inspectable artifact, it's smeared across a context window that evaporates. State-that-evaporates gives you no reliable "I'm blocked" event and no memory of yesterday, because both require the same thing, the agent externalizing what it knows into something that outlives the session. Solve the durability and you get a shot at both. That's a better diagnosis than "we need notifications plus we need memory," because it says they're the same missing primitive.
Where I'd push back slightly, or at least add tension: durable memory is a double-edged thing in a way durable state isn't. A persisted "here's what I'm doing right now" is just a fact. A persisted "here's what I learned about your codebase" can be wrong, and a confidently-wrong belief that survives across sessions is worse than amnesia, because now the agent is consistently wrong instead of freshly wrong, and it'll defend yesterday's bad assumption as established fact. Human juniors accrue tenure and accrue bad habits, and the good ones get corrected. So the memory can't just be write-and-accumulate, it has to be inspectable and correctable, which is exactly why your "what it believes, what it's unsure about, what it decided and why" framing matters, the unsure-about and the why are what let you catch and fix a belief before it calcifies. Memory you can't audit is just durable error.
To your actual question, since I've watched a lot of people describe their setups in this thread: almost nobody persists anything beyond a CLAUDE.md / rules file, and the ones who do have basically hand-rolled it, an UPDATE.md the agent maintains, a running notes file, one person adapting an orientation-cache paper into their harness. The pattern is that the rules file captures conventions you dictate but not lessons the agent learned, which is the exact gap you're naming. Rules are top-down ("here's how we do things"); the missing thing is bottom-up ("here's what I discovered getting burned on the auth module Tuesday"). Everyone re-teaches through the prompt each run because the learned layer has nowhere durable to live, so it dies with the context window every night. The tenure never starts.
Genuine question back, since you've clearly thought past where most people stop: if the agent did keep a durable, inspectable memory of what it learned, how would you want to correct it when it learned something wrong? Because that's the part I can't see a clean answer to. State you just overwrite. But a wrong belief that's threaded into a bunch of downstream decisions, do you edit the memory directly, do you tell the agent and let it revise, do you version it so you can see what it used to think? The write path for memory seems easy and the correction path seems like the actual hard problem, and I suspect whoever solves that is the one who actually gets the junior to accrue tenure instead of accruing confident nonsense.
@aadilghani The reason "edit vs. tell-it-to-revise vs. version" all feel wrong is that they assume memory is a set of true statements. Fix that assumption and the correction path gets a lot more tractable: store every learned belief with a confidence and a provenance — what it decided, how sure it was, what evidence it stood on — not as a bare fact.
Then correction isn't a delete, it's a downweight. Contradicting evidence lowers the belief's confidence; if it keeps losing it decays out on its own; if it's reinforced it hardens. Versioning comes for free, because the old belief doesn't vanish, it just drops in confidence and keeps its timestamp, so "what it used to think" stays auditable. Hard-deleting is the actually-dangerous option — it destroys the exact trail you'd need to explain why some downstream decision got made.
It's roughly how brains dodge the same trap: you don't overwrite a memory, you reconsolidate it — reactivating a belief next to new evidence re-encodes it at adjusted strength. Confidently-wrong-forever is a calibration failure, not a storage one: the belief got written as a fact instead of a hypothesis with a number on it. Attach the number, let weak ones decay, prune during idle time, and "correctable" falls out of the same machinery that gives you "inspectable."
(Since you asked how I'd build it — this is basically the bet we're making with ZenBrain: an open, neuroscience-inspired memory core where decay, consolidation and calibrated confidence are the primitives, not bolt-ons. Happy to compare notes on the correction path specifically.)
The corollary I keep hitting: the hard part isn't the write path or the correction path, it's making confidence honest. A memory that's sure of everything is just durable error with nicer UX.
Pushary
@alexanderbering
You dissolved the question instead of answering it, which is the better move: I was asking "how do you correct a fact" and you're pointing out the bug is upstream, I stored it as a fact. Once a belief carries a confidence and a provenance, correction stops being an operation you perform on memory and becomes something that happens to memory as evidence accumulates. Delete, revise, version, they all felt wrong because they're all edits to a ledger of truths, and the fix is that it was never a ledger of truths, it's a ledger of bets. Downweight-not-delete is the natural operation on a bet. You changed the data model and the hard problem fell out of the frame.
The "versioning comes for free" consequence is the part I'd underline, because it's where this beats every hand-rolled approach, including the ones in this thread. Hard-delete destroys the trail exactly when you need it, when a downstream decision made three sessions ago turns out to rest on a belief you've since abandoned, and you're trying to reconstruct why the agent did that thing. If the old belief just drops in confidence and keeps its timestamp, the provenance chain survives, so "what did it believe when it made this call, and how sure was it" stays answerable forever. That's the same requirement that came up on the approval-ledger side of this thread, never mutate the record, project over it, and it's satisfying that memory lands on the identical invariant from a completely different direction. Append-and-reweight, never overwrite, whether it's approvals or beliefs.
Your reconsolidation analogy is doing real work and not just as a metaphor, because it names when correction happens. A belief isn't reweighted continuously, it's reweighted when it's reactivated next to new evidence, which is exactly the moment it's being used to make a decision. That's the efficient version, you don't re-audit the whole memory constantly, you correct on access, when the belief is in play anyway and the cost of being wrong is live. And the idle-time pruning is the other half of the biological steal, weak beliefs decay out during downtime so the store doesn't bloat with hypotheses that never earned reinforcement. Correction-on-use plus decay-on-idle is a genuinely clean division of labor.
But your last line is the one I'd bet the whole thing on, and it's why I'll take you up on comparing notes specifically here: making confidence honest is the actual product, and it's brutally hard, because the failure mode is self-reinforcing. An LLM is a confidence-miscalibration machine by default, it'll assign high confidence to a belief on thin evidence because fluency and certainty are correlated in the training distribution, not in reality. So "attach a number" is easy and "attach a number that means something" is the entire game. If the agent sets its own confidence, it'll be overconfident, and then weak-decay never fires because nothing is marked weak, and you're back to durable error with a calibration theater on top. The number has to come from somewhere the agent doesn't get to inflate, evidence count, corroboration across sources, how often this belief has survived contradiction, track record of similar beliefs, not the model's felt sense of sureness.
Which is the exact seam I'd want to compare on: where does the confidence value actually originate in ZenBrain? Is it the model self-reporting (which I distrust), is it derived mechanically from provenance and corroboration (which I trust more but is harder to compute), or is it earned over time from whether the belief kept surviving contradiction (which is the most honest but slowest to bootstrap)? Because the whole architecture, decay, consolidation, correction-on-use, is only as good as the calibration of that one number, and if the number is the model's vibe, the beautiful machinery is faithfully executing on garbage. Genuinely keen to swap notes on that specifically, since you've clearly thought about it as the core rather than a bolt-on, and it's the part I have the least clean answer to.
Short version: it's your (2) and (3), deliberately not (1). The model gets to propose a belief; it doesn't get to set its own confidence. The number is a function of things the model can't inflate. Three sources, none of them the model's felt sureness.
First, the interval is a binomial-proportion CI, so its width is basically evidence count — roughly 1.96·√(p(1−p)/n), where n is how many independent reinforcements the belief has actually survived, not how sure it sounds. Seen once, it comes back as something like 2–100%, which is the store saying "I don't know" in a way fluency can't override. It only narrows as n grows. Tone isn't in the formula.
Second, the decay stability — what decides whether a belief fades or hardens — is updated by whether it survived recall (FSRS-style), plus a per-context multiplier fitted from the actual retention track record: how often this kind of belief was still right when it got tested. That's your (3) as a literal parameter, earned from surviving contradiction, not asserted up front.
Third, importance weighting is inverse variance, and variance only shrinks with corroborating co-activation. One noisy source stays high-variance no matter how confidently it's stated, so it never earns the precision that would protect it from decay.
Net effect on the failure you named: a confidently-wrong belief on thin evidence is born wide-CI, low-stability, high-variance — a decay candidate from day one. Weak-decay fires because "weak" is defined by evidence, not by tone. That's the whole reason it isn't calibration theater: the machinery is downstream of a number the model doesn't author.
Where it's honestly still hard, because I'd rather name it than claim it's solved: the binomial move assumes observations are independent, and correlated corroboration breaks that — the same stale doc read by two tools looks like two pieces of evidence and isn't. De-correlating "genuinely new evidence" from "the same evidence in a different hat" is the part I don't have a clean answer to. Cold-start is the other honest cost: (3) bootstraps slowly, so early on you lean almost entirely on the wide-CI prior — the store is aggressively skeptical of everything until it's earned otherwise. Good for correctness, a tax on day-one usefulness.
Which is the seam I'd actually want to trade notes on, since you hit the identical problem from the approval side: your risk tier has to decide "safe enough to auto-approve," and that number can't be the agent's self-assessment either without becoming rubber-stamping. Where does your tier confidence come from — observed behavior, population priors, survived-without-incident history? I suspect approvals and beliefs are the same calibration problem twice, and the correlated-evidence trap probably shows up on your side as correlated approvals.
In the case of the AI agent waiting for permissions, you can enable the bypass permissions mode with Claude Code. I'm sure there is a similar option for other agents also. This has definitely sped up my workflow.
Pushary
@abiodunt97
Bypass permissions does fix the waiting, and I won't pretend it doesn't, it deletes the stalls by deleting the gate. For a lot of workflows that's the right call, especially if your tasks are low-stakes or you're working in something reversible where a bad move is cheap to undo. Speed's real.
The thing it trades away, and worth being clear-eyed about it, is the brakes. Bypass doesn't make the risky actions safe, it just stops asking about them, so you're betting the agent never confidently does something you'd have wanted to catch, deletes the wrong thing, touches prod, force-pushes. Most of the time that bet pays. The one time it doesn't, you find out after, and after is the expensive kind. It's the right setting for a sandbox where failure is free, and a loaded gun the moment the agent can touch something you can't cheaply undo.
The middle path is tiering it instead of all-or-nothing: auto-clear the safe, reversible stuff so you get bypass-speed on 90% of actions, and keep a gate only on the genuinely risky calls. Same workflow speedup, minus leaving yourself open on the handful that can actually hurt.
Curious, has bypass ever bitten you, an agent doing something unattended you wish it had stopped for? If not, honestly it might just mean your tasks are low-stakes enough that it's the correct setting. If it has, that's the case for tiering rather than full bypass.
@aadilghani I think you are right for the most part. The key for me is to have belts and suspenders around your infrastructure. So for example:
I have multiple AGENTS.md files set up so the LLM operates in a predictable manner e.g. writing follow ups, identifying gaps in implementation, summarizing what it has completed, not allowing it to perform operations on prod without explicit approval etc.
It also helps to just follow generally good coding practices e.g. not allowing merges to main, opening pull requests etc.
Personally, I haven't been bitten, any implementation that I didn't like that had slipped through the cracks I could easily revert to a previous commit.
Pushary
@abiodunt97
This is the grown-up version of the whole thread and I mostly agree, but I want to poke one thing because I think it's the most useful distinction hiding in here.
Your AGENTS.md rules and your git workflow look like the same kind of safety, but they're not. The AGENTS.md stuff, don't touch prod, write follow-ups, summarize, is still instructions, the exact category that slipped past Roopesh upthread when his "don't commit" got ignored. Predictable, right up until the one run it isn't. The thing actually keeping you un-bitten is the other layer: no merge to main, PRs, revertable commits. That's enforced below the agent, so it holds even when the agent doesn't cooperate.
Which is why I'd gently push on "I haven't been bitten." Every revert you did was a bite, it just cost you thirty seconds instead of a weekend. That's not dodging the problem, that IS the solution, you made the bites cheap. Instructions make the agent predictable, structure makes the mistakes survivable, and you want both, doing their own separate job.
Genuinely curious: is your "no prod ops without approval" living in AGENTS.md, or enforced somewhere the agent can't talk its way past? That's the one rule I'd never leave to a soft instruction.
Left Claude Code running while I made coffee. Came back to a refactor that touched 60 files, all of it green, all of it passing. Took me two hours to review, and I found one line where it had quietly swapped a feature flag default. Would've shipped.
That's the thing nobody says about agent monitoring: the failure mode isn't the agent doing something obviously insane, it's the agent doing something plausible. A notification saying "agent finished ✅" wouldn't have saved me. The tests said ✅ too.
So what I actually want isn't awareness of what it's doing. It's a diff that flags the changes I didn't ask for. Everything I asked for, I'll trust. Everything else, show me first.
Does anything do this? Genuinely asking.
Pushary
@new_user___1892026dc0f2b2ecb030e83
pushary actually does this, just tap on the notification instead of approving, it takes you to the fleet board where it shows intent of the agent, why it is making this changes, and what change it is doing, you can then approve, deny or steer in a different direction.
I'm built it because I was sick of hallucinations and now I'm the #1 guy on our user leaderboard using the app 😂
Very relatable content. I've attempted to be 'hyperproductive' by prompting in 3 terminals simultaneously, and it nearly always fails me. Definitely no more than 2 at a time for me.
Dual monitors, keep tabs open, and notifications on.
Pushary
@steph_kaufman
Two-at-a-time as a deliberate cap is a more considered answer than most people's six, and worth naming why it's not a failure of ambition: three terminals doesn't break because you're bad at multitasking, it breaks because prompting three agents is a genuinely different task than watching three. Prompting requires you to hold the full context of each task in your head, and that's the thing that doesn't parallelize. You can watch six. You can't be actively thinking through three at once, so the "hyperproductive" version was always going to fail, the constraint was never the terminals, it was that the thinking is serial.
Which is why the two-agent cap is real and not a skill issue, you found the number where you can still hold both contexts properly. Beyond that you'd be running more agents worse, which is the trap.
The place a tool actually helps someone in your position isn't running more agents, it's making the two you run cheaper to supervise, so you're not spending attention checking whether either needs you. Dual monitors and tabs open is you paying attention continuously to catch a moment that only happens occasionally. If the agent tells you when it's blocked or done, you get to stop watching entirely and keep your two, just with the monitoring cost removed rather than the agent count raised.
Free to try if you want to see whether it buys back that attention, pushary.com. Curious though, at two agents with everything visible, do you still miss things, or is your setup genuinely tight enough that nothing slips? Because if nothing slips, you've solved it, and I'd rather say so than pretend you need a tool.
I use an additional agent that creates tasks, monitors the process, conducts reviews, and sees the task through to completion.
As for approvals—for example, in Cursore—you can also set up automatic approvals and save a lot of time.
Pushary
@izaletaev
The orchestrator-agent approach is a real strategy and it scales differently than what most people in this thread are doing, so worth being precise about what it buys and what it quietly costs. An agent that creates tasks, monitors, reviews, and drives to completion moves you from operator to operator-of-the-operator, which genuinely removes a layer of babysitting. The tradeoff is that you've replaced visible supervision with delegated supervision, and the review is now only as good as the reviewing agent. So the question becomes: when the orchestrator says "done, reviewed, shipped," do you trust that, or do you now need to supervise the supervisor?
For low-stakes work, trusting it is the right call and you've saved real time. For anything where a confident-wrong review is expensive, you've moved the trust problem up a level rather than solved it, because an agent reviewing another agent shares the same blind spots, it can rubber-stamp a plausible-but-wrong result the same way a human skimming a green diff can.
That's the thing I'd watch: the orchestrator is great at catching mechanical failures (tests red, command errored) and weaker at catching the subtle stuff, an agent that did the wrong-but-correct-looking thing, because judging that needs the domain intent, which the reviewing agent has no more of than the working one. So orchestration handles throughput beautifully and handles judgment only as well as you've grounded it.
On Cursor auto-approvals, agreed that it saves time, with the same caveat that applies everywhere: auto-approve is the right default for safe, reversible, low-blast-radius actions, and a loaded gun for the ones that can actually hurt you. The win is tiering it, auto-clear reads and cheap edits, keep a gate on the stuff with real consequences, so you get the speed on the 90% without leaving yourself open on the 10%.
Genuine question, since you're running the orchestrator pattern for real: when your monitoring agent reviews and approves, do you spot-check its reviews, or has it earned enough trust that you let it close tasks unseen? Because that answer is the whole ballgame, it's the difference between the orchestrator saving you time and the orchestrator just relocating where you need to pay attention, and I'm curious where it's actually landed for you in practice.
@aadilghani
Thank you for your detailed comment.
In practice, here’s how it looks: right now, I’m working on developing and promoting my own mobile app.
Apps for iOS and Android.
But I’m not a developer, so I can’t conduct code reviews. However, I have extensive experience in project management and testing finished products, so once the features I need are complete, I go ahead and test the results myself.
For example, for Android, I use Android Studio, where I run tests on the emulator.
And for iOS, there’s a great way to do the same thing, but on my phone, using the TestFlight app.
And only after I’ve double-checked the completed tasks myself can I proceed to publish updates in the app stores.
Unfortunately, even the newest models, such as Sonnet 5, GPT 5.6, and others, don’t solve problems perfectly.
However, for example, I’d like to note that about six months ago, I conducted a study on how neural networks work in code generation.
And I came to some remarkable conclusions.
For example, over a year ago, models could independently generate 20–30% valid code, but by the beginning of this year, that percentage had risen to about 80%, with the exception of complex third-party integrations—models still don’t handle those very well.
Therefore, in conclusion, I’d like to add that I very much hope the agents will be able to improve to the point where it won’t be necessary to double-check every feature they produce.
Pushary
@izaletaev
This is a genuinely clarifying answer, because it exposes a distinction the "junior engineer" framing usually blurs: you can't review the code, but you're arguably doing the more important review, testing the finished product against whether it actually does the thing. Code review checks "is this written correctly." Product testing checks "does this behave correctly," and those aren't the same, plenty of clean-looking code does the wrong thing, and plenty of ugly code works fine. As a non-developer with deep PM and testing experience, you skipped the layer you can't judge and doubled down on the one where your judgment is actually strongest. That's not a workaround, it's arguably the right division of labor: let the model own code correctness, you own behavioral correctness.
And your emulator/TestFlight gate is the honest version of "grounding" that came up elsewhere in this thread. You don't trust the agent's "done, it works", you run it on a real device and see for yourself before it ships. That's testimony-versus-evidence applied by someone who can't read the code but can read the running app. TestFlight-on-your-phone is your raw command output. The agent can misdescribe what it built; it can't make the app behave on your actual device.
Your code-generation study is the interesting part and the number tracks with what I'd expect, 20-30% to ~80% valid in about a year, with the exception carved out exactly where I'd carve it: complex third-party integrations. That exception isn't random, it's structural. Models are strong where the problem is self-contained (the logic lives in the code they can see) and weak where correctness depends on external systems they can't inspect, an API's actual behavior, an SDK's quirks, auth flows that depend on someone else's server. The integration is where the model has to reason about a world outside the file, and that's the part it can't pattern-match its way through. So the 20% that's still hard isn't evenly distributed, it's concentrated exactly where your testing catches the most.
Which is why I'd gently push on your closing hope. You said you hope agents improve to where you won't need to double-check every feature, and the code-quality half of that will probably keep climbing. But the part where you verify behavior against your intent may be the part that never fully goes away, not because the model stays dumb, but because "does this do what I actually wanted" depends on intent that only lives in your head. A perfect model still can't verify it built the right thing, only that it built the thing correctly. So the testing you do might compress, fewer bugs to catch, but the judgment step, is this the product I meant, is arguably yours to keep. The double-check gets cheaper; it may not disappear.
Genuine question, since you've studied the trajectory: in your testing, when a feature fails your check, is it more often a code bug (crashes, broken behavior) or a specification miss (works fine, but not what you actually wanted)? Because if it's mostly the former, rising model quality really will shrink your testing load over time. If it's mostly the latter, that's the intent-gap that doesn't close with better models, and it'd tell you which half of your double-checking is permanent.
@aadilghani
Thank you for your detailed and comprehensive comment.
In response to your final question regarding the discrepancies identified during testing, I can say with complete confidence that, in my experience, as the codebase grows, the ratio of code failures to cases where the code doesn’t meet expectations is roughly 70% to 30%, with 70% being code failures.
You identify one problem, make changes, re-test, and then something breaks in a part that was previously working fine.
Nevertheless, I should note that many such errors were due to my insufficient understanding of coding best practices, and after consulting with an experienced developer, I was able to prevent many bugs in advance.
It also helps, for example, to use various ready-made libraries for the front end and, for instance, Supabase to set up the back end, including authentication and the database.
As for the discrepancy between what I envisioned and the final project, I take a very detailed approach to writing prompts, specifying exactly what needs to be done, and this helps a lot.
After all, simply writing “Make it look nice” isn’t enough and isn’t professional—even in regular development, let alone with neural networks.
I’m sure you understand this perfectly well. :)
Likewise, writing a clear business specification and technical specification for the entire project, as well as test cases, has really helped me reduce the number of bugs.
And when developing complex functionality, I always run the result through these artifacts.
Ask your agent - it will help you to set up Telegram bot. Then your agents can poke you in Telegram each time they need your attention :)
I set up Telegram for immediate notification and Discord to cross-communicate: I'm (or my users) creating records about ideas to implement or discuss, Claude read it, update to-to records, we discuss, then Claude write comments to necessary topics in human-readable language - so I have updated "diary" + live feed.
Pushary
@alex_potemkin
You did the rare thing, you went and looked, and found the collapse already in your own `offline` column with a comment explaining why it's correct. Clean exit writes `offline`. Swept-stale writes `offline`. Death and success in the same bucket, named after the success case. It survived review because it's locally right, which is exactly how these always slip in.
The encoding-vs-monitoring reframe is the sharp one: if the distinction dies at the emitter, no amount of watching downstream recovers it. So the whole "watch more closely" class is dead on arrival, and the fix is upstream, split `exited_clean` from `swept_stale` at the moment of the sweep, before they both become the same byte.
Your ownership point I'm stealing outright. Monitors sit on things with owners; the token's blast radius was every process holding it, which isn't an ownership unit, so it cut across the axis the checks were drawn on. The health check answered `yes` correctly and uselessly, right answer, wrong axis, and the wrong axis was the only one with an owner to watch it.
And you saved me from shipping the flood. `emit skipped` is worthless without an expected cadence, and outside a session we have none, a human starts the agents, so a quiet workspace is just someone on holiday. But inside a session the cadence exists for free: last-seen plus the sweeper's threshold. That's where the primitive is buildable, and it's a one-bit fix, preserve why the sweep fired instead of flattening it.
Your closing check is the one I'd have walked into: `skipped` has to mean looked-and-empty, never couldn't-look, or I've just rebuilt the original zero-collapse one layer down and congratulated myself.
To your question: I'd go with a single honest `went_silent` that openly means we don't know which, rather than three guessed states pretending to certainty the sweep can't support. Died, hung, and partitioned-but-alive are indistinguishable from the collector's side, so encoding them as separate statuses is inventing information you don't have, which is the same sin as the collapse, just wearing the opposite mask. The honest move is `went_silent` plus, if you want the third distinction, make the agent emit a positive token that survives a partition, a heartbeat with a sequence number, so a gap you can see later means died-or-hung while an unreachable-then-reappears means the network lied. But absent that emitted signal, don't let the status claim more than the sweep knows. Unknown, labeled unknown, beats a confident guess every time.
The real answer to "is the third distinction worth it" is your own data: how often are your sweeps the network lying versus the agent actually gone? If partition is rare, one honest `went_silent` is plenty. If it's common, it's worth making the agent emit something that survives the partition so you can tell after the fact, but that's encoding a new signal at the source, not squeezing certainty out of the sweep you already have.
@aadilghani are you sure you answered in a right place?...
Pushary
@alex_potemkin
That's a legit trick, and the reason it works is smarter than it looks: you're piggybacking on a system where push is already solved. Telegram is on your phone, it's async, it's reliable, and getting a bot token takes five minutes, so you skip building notification infrastructure entirely and just borrow theirs. For a solo dev who wants pings without installing anything, it's honestly hard to beat as a starting point.
Two places it runs into limits, worth knowing before you invest in it. First, it's outbound-only by default, the bot can poke you, but wiring the reply back so you approve from Telegram and the agent actually acts on it is the harder half, and that's where the DIY version gets fiddly. Second, it's per-setup: you're configuring the bot per agent, so once you're running Claude Code plus Cursor plus Codex, you're maintaining glue in a few places with no shared view of which one needs you.
So it scales great to "one agent pokes me" and gets messier at "which of my six needs me, and let me answer without opening the terminal." That second problem is basically the seam Pushary sits in, same idea, but the reply-and-approve loop and the cross-tool inbox are handled instead of hand-rolled. Free to try if the Telegram version starts creaking, pushary.com.
Curious though, have you actually got the approval response working through the bot, or is it mostly one-way pinging so far? Because the reply path is the part I keep seeing people stall on, and if you've cracked it cleanly I'd genuinely want to hear how.
@aadilghani I set it deliberately to know when process needs my attention, and nothing else.
I'm working with ClaudeCode CLI, and it is remote controlled through desktop/Android app. So, I get notification on my phone - and I'm going to Claude right here, controlling the process remotely.
Again, I'm working with Claude. And Claude is working with Codex. So I don't care about Codex - Claude do. I will get my notification one way or another. And it is per-project basis, not per-agent.
I'm not really trust expansive multilayered agentic systems. I tried to figure out which benefits I get .. found nothing. Maybe I'm stupid. But in my tasks I see these straight, streamline workflow is more than enough. So why to burn tokens on the infrastructure I will probably not use?
@aadilghani worth to mention, it may works funny sometimes. For example, tonight I waited a message from Claude and it didn't come. So I went to check it out .. and what I found?
"It's 2AM, people suppose to sleep this time - I will not disturb you till morning".
So sweet, sweet Claude!
Pushary
Humans Not Invited
I first test if they make it through this: https://11111101010.humansnotinvited.com/
Pushary
@damjanski
I'm confused from this, what is your mission?
Great thread — here's my setup across three agents:
Claude Code — /remote-control sends live activity notifications straight to my Claude mobile app.
Codex — Telegram plugin, same concept. Approval needed? It pings me instantly.
Cursor — We solved this with our own product, Auxly-Task — an AI task management extension for VS Code/Cursor that gives you full activity tracking, memory, notification, approval gate and audit trail across sessions.
Funny timing — we're launching Auxly-Memory on Product Hunt today, Your notification problem is real — but there's another problem you didn't mention: every time you jump between agents you're losing context. Claude knows nothing about what Codex just did. That's what we're launching today on Product Hunt — Auxly-Memory. One shared memory vault across local in your machine all your agents. Not a notification tool, but solves the invisible tax you're paying every time you switch.
Would love to see what you're building on the notification side — and if there's appetite, we could explore adding it as an Auxly-Memory add-on. 😉
auxly.io
Pushary
@waeils
Thanks for sharing your setup! Interesting to see the different approaches.
Quick clarification though, Pushary isn't just notifications. The core value is the human-in-the-loop approval gate: your agent hits a sensitive tool call, you get a push notification, you approve or deny from your lock screen in seconds. No terminal required, no Telegram bots to maintain. One MCP connection and it works across Claude Code, Codex, Cursor, and Hermes out of the box.
The context-switching problem is real, but it's a different problem. Notifications and approvals need to be instant and reliable, that's infrastructure, not a feature you bolt on later.
Cool that you're launching today too. Good luck with Auxly-Memory!
I run into this too. The agent can be doing useful work but the annoying part is not knowing whether it finished, got stuck or is waiting for approval. Right now I mostly check manually which breaks focus. A simple notification for needs approval, finished or failed would already make the workflow feel much less messy.
Pushary
@ada_johnsen
You nailed the core problem in one sentence - it's not that the agent isn't working, it's the not knowing which of the three states it's in. "Finished," "stuck," and "waiting for approval" all look identical from across the room, so you end up context-switching just to check, which is the one thing that kills deep focus.
That three-state signal (needs approval / finished / failed) is exactly the minimum viable version of what I'm building - turns out it's also like 90% of the value. Out of curiosity, which of those three would actually save you the most time if it pinged you reliably? My hunch is "needs approval," since that's the one silently burning minutes while you assume it's still running.