← All posts

The tmux Window Title Lied to Me

I nudged a Claude agent to redo work it had already shipped, because I trusted a label instead of reading what the agent actually said.

  • agents
  • tmux
  • orchestration
  • claude-code
  • coordination

On May 29 I was sweeping through a grid of terminal panes, each one running a Claude coding agent, trying to figure out which ones were idle so I could hand them work. One pane’s window title read Debug QUIC error. So I nudged that agent — “hey, pick this up” — and it dutifully started spinning up on a network bug it had actually fixed and shipped days earlier.

Here’s the plain version for anyone who isn’t knee-deep in terminals: I run a bunch of AI coding assistants side by side, each in its own little window, and one of them acts as a coordinator handing tasks to the others. tmux is just the tool that tiles all those windows on one screen — think of it like a wall of security-camera feeds, one per agent. Each feed has a little label at the top. I trusted the label. The label was months stale.

That’s the whole mistake, and it’s dumber than it sounds. A tmux window title gets set once, usually when the session starts, and then nobody touches it again. It’s decorative. It is the sticky note somebody slapped on a door in January that still says “Meeting in progress” in July. The agent behind that door had long since finished, cleaned up, and moved on — but the note never changed, so I knocked and interrupted work that didn’t exist.

What saved me was luck dressed up as engineering. I’d built a two-way address contract between agents — before an agent accepts a nudge, both sides confirm what the task actually is — and that handshake caught the mismatch. But it still cost the poor agent a full turn-cycle: it read my nudge, loaded context, went “wait, I already did this,” and had to unwind. On a fleet where every turn burns real budget against the rate limits, that’s not free.

The fix was to stop reading labels and start reading output. An agent’s last 30-40 lines tell you everything a title pretends to: its recap of what it thinks it’s doing, its end-of-turn verdict on where the last turn left things, and its visible checklist from the task tool. Those get emitted fresh on every turn. The title doesn’t.

How I triage idle-vs-working from the pane, not the title give me the detail

Instead of trusting tmux list-windows names, I grab the live tail of each pane and pattern-match on what the agent actually emitted:

tmux capture-pane -t "$pane" -p -S -40 | tail -n 40

Then classify against the recap/verdict, not the label:

  • shipped / awaiting directiondone, don’t nudge
  • running <x> / an unchecked task-tool item mid-flight → working, leave alone
  • want me to <x>?idle-on-an-ask, answer the ask
  • blank / clean prompt → safe to nudge

The rule: the signal has to be something the agent regenerates every turn. A window title, a name field, a static dashboard badge — anything set once and forgotten — is a lie waiting to happen.

The general lesson travels past tmux: never infer “has work to do” from a field that isn’t updated on every action. Names, titles, and badges are where state goes to get stale. If you’re building triage on top of any fleet — agents, jobs, workers — read the thing they most recently said, not the thing someone once labeled them. State is a verb, not a nameplate.