Skip to main content
← Blog
AI AgentsHypemarc AI Team

How Do You Know an Agent Is Working? PTY Output Is Wrong in Both Directions

How Do You Know an Agent Is Working? PTY Output Is Wrong in Both Directions

A problem you never see with one agent

With a single agent you just watch the screen. The moment you run several at once, a program has to decide which ones are working — and almost everyone reaches for the same implementation first.

bytes came out of the PTY  → working
nothing for N seconds      → idle

Intuitive, and wrong. What makes it hard to spot is that it is wrong in both directions at once, so fixing one side makes the other worse.

Direction 1 — finished agents look busy

When an agent CLI finishes and sits at its prompt, it keeps repainting the cursor and spinner. Every repaint is PTY bytes.

Output-based detection promotes the agent back to "working" on each one. An idle agent stays busy forever.

The usual patch is a settle window — "only call it idle N seconds after the last output." That does not remove the misclassification, it delays it by N seconds. Spinners repaint more often than that.

Direction 2 — working agents look idle

This side is more dangerous.

An agent that is reasoning produces no PTY output at all. While the model generates a long response, while it waits on a tool result, the terminal is completely silent.

So any inactivity timeout will eventually mark a genuinely working agent as idle — and then the real damage starts. The orchestrator hands it more work, or reclaims it mid-task.

The rule — define turns by boundaries, not noise

A turn is defined by its start and end. It starts on submitted input and ends on an explicit completion report. Output is a hint, never the state.

Two details are easy to miss when implementing that.

Human input opens a turn too. If only programmatic submissions open turns, sessions where a person typed directly into the agent's terminal get stuck in idle forever. Open a turn on carriage return from any source. Individual keystrokes do not count — they may be mid-composition in an IME.

Emit the turn-start event when the input is accepted, not when it flushes. With queued or async write paths, a flush-time event arrives after the code that depends on that state has already read it.

A related bug — the self-destroying evidence pattern

While fixing liveness we hit a more general bug. It is worth naming because the shape recurs far beyond agents.

Our reclamation logic required an agent to be bound to a task ID to be eligible for cleanup. Our completion handler cleared that task ID as its first act.

The event that made an agent eligible for cleanup destroyed the evidence cleanup needed.

The outcome was inverted. Agents that finished cleanly became permanently unreclaimable, while only messily-dead ones got collected. The load average reached 44 on a 12-core machine with 11 zombie agents, while the cleanup tool reported "no reclaimable agents found."

When a cleanup gate depends on state X, check whether the normal, happy-path completion also clears X. If it does, preserve the evidence under a separate key at unbind time.

And the fix you should not reach for

Faced with this, one rule suggests itself — "no binding and idle for a long time → reclaim."

Do not. Agents that are still booting, and agents whose binding was never recorded, are indistinguishable from finished ones under that rule.

Absence of evidence is not evidence of completion. Report them as suspect, never reap them.

Summary

Common implementationWhat actually happens
PTY output = workingFinished agents stay busy on spinner repaints
Inactivity timeout = idleReasoning agents get reclaimed mid-task
Settle windowDelays the misclassification instead of removing it
Input submitted → completion reportedBoundaries define the state

Rather than implementing this detection yourself, it is faster to read state off a board. Marblo tracks ticket state explicitly through TODO → IN PROGRESS → REVIEW → DONE and shows which ticket each agent is bound to.

Everything here was measured while running a heterogeneous fleet of agent CLIs in production. The full write-up is public in the Fleet Operations knowledge pack — readable without an account.

More from the same fleet

MARBLO

Running it beats reading about it

Marblo is a desktop app for macOS and Windows. Connect the CLIs you already pay for, run a different model per ticket in parallel, and approve before anything merges. The free plan runs one project, so you can check it today.

How Do You Know an Agent Is Working? PTY Output Is Wrong in Both Directions - Hypemarc Blog | Hypemarc