+++++
+++++

The Desk That Fills Itself

Last week I built the desk I said a manager needs: a board that hands tasks to a team of agents, runs an independent reviewer over every change, and only ever shows me a pull request that already passed its own checks. I ended that post with a list of things it couldn't do yet — honestly, because a tool you're still building has edges and pretending otherwise helps no one.

This is what I built in the week since. Not all of the list — some of it is still open, and I'll say which. But the shape of the work is worth naming up front, because it's the same move each time. The first post automated the one part of management I kept skipping: review. Everything here automates the parts I didn't even think to name — deciding what to work on, giving feedback, calling off a bad run, knowing what it all cost. A manager does more than approve. So now the desk does more than approve.

The board's closed loop with the new capabilities accented: the Scout proposes work into Queued; the spine runs Queued to Running to Review to Done; a running task can be cancelled to Done or auto-requeued once on timeout; a Review card can be sent back to Queued to update the same PR; and every finished task feeds a history/insights log of status, duration and cost.

The board decides what to work on

Here's the gap I hadn't admitted. The board picked up at "here's a task." I still had to have the task — notice the friction, phrase the work, hand it over. That's not the cheap part of managing. Deciding what the team should do is most of the job; the doing was always going to get automated first.

So I built a Scout. Every couple of hours it walks every repo under my code directory, brainstorms concrete improvements — infra, dev tooling, a missing feature, a bug, thin docs — and scores each one. Then it does the thing I care about: it proposes the single highest-ranked idea to me on Telegram, with two buttons. Tap ✅ and it becomes a task on the board. Tap ❌, or ignore it, and nothing runs.

The Scout flow: scan only the repos whose HEAD changed, score each idea on impact times confidence times ease, rank them in code rather than trusting the model, and propose the single top idea on Telegram — a check queues it as a task, a cross or silence drops it, and the ideas it ranked but didn't pitch go to a backlog for the next quiet run.

Two decisions in there matter more than the feature itself.

  • The ranking is computed in code, not trusted from the model. The agent scores every idea on impact, confidence, and ease; a plain function multiplies those into one number and sorts. I've watched enough models talk themselves into their own favorite idea to not let the thing that generated the ideas also pick the winner. Same instinct as the reviewer: don't let one context grade its own work.
  • It proposes; it doesn't queue. One idea, one tap, or it dies. An agent that silently fills your queue with its own suggestions is a machine for generating work you didn't ask for. The whole value of a manager deciding what to do evaporates if the deciding gets automated away too. So the model gets to suggest. I still get to choose.

The unglamorous half is what makes it survive contact with ~90 repos: it's incremental. It fingerprints every repo's HEAD and deep-scans only the ones that actually changed since last time, and it keeps the ideas it ranked but didn't pitch in a backlog — so a quiet run with nothing new to read still has a #2 and #3 to propose without paying to think again. A 2-hourly job that cold-re-read every repo would be both slow and expensive; this one mostly costs nothing.

Review can now say "not quite"

In the first version, a card in Review had exactly two ends: merge it, or reject it. That's a binary a real manager almost never uses. Most feedback isn't "ship it" or "throw it away" — it's "close, but the error handling's wrong, go again." The board had no word for that.

Now it does. A Review card can be sent back with a correction note, and it returns to the queue to be picked up again. Three things about how it goes back matter:

  • It updates the same pull request. The agent reopens the existing branch and pushes to it — the PR you were already looking at gets better, instead of a second PR appearing next to the first. Fewer things on the board, one thread per piece of work.
  • It resumes the original session. The agent that wrote the code the first time picks the task back up with its full memory of why it made the choices it made. You're not re-explaining the task to a stranger; you're giving feedback to the person who did the work. That's the whole difference between correcting a teammate and filing a new ticket.
  • It merges, not rebases. No force-push, one place to resolve a conflict, a fast-forward push to the same branch. For an automated flow, boring and robust beats clever.

You send it back from the board with a note, or straight from Telegram — the same channel I already use to hand out work is now the channel I use to push it back. The correction loop closed without me leaving the phone.

Two ways to stop a run going wrong

Delegation you can't interrupt isn't delegation, it's a launch. Two gaps here.

Cancel. An agent five minutes into the wrong approach used to be something I had to wait out. Now I text /cancel and it stops. The mechanic is more careful than it sounds — the bot and the agents are separate processes, so cancelling isn't a direct kill; it's a signal routed through the board that the right worker picks up and acts on, tearing down the whole process tree it spawned. A cancelled run goes straight to Done marked as mine to own, and is never quietly retried behind my back.

Auto-requeue. The flip side: a run that dies to a transient hang shouldn't cost me the task. Every runner has a timeout, and a task that blows through it gets requeued exactly once, tagged so a second timeout falls through to me instead of looping forever. The failure handling stopped being "hope it doesn't hang" and became a rule with a defined end.

Together they're the same principle from two directions: I can stop the work, and the work can recover itself — but only within limits I set, and the ambiguous cases always land back on my desk rather than disappearing.

Now I know what it cost

Once a team of agents is running unattended, the question stops being "did it work" and becomes "what did it cost, where's the time going, which repo eats the most." You can't manage what you don't measure, and I was flying blind.

So every finished task now writes one line to a run-history log — status, duration, the review gate's confidence score, and the dollar cost of the run. There's a CLI that summarizes it (success rate, average duration, total spend, broken down by repo and by agent), and a live Insights panel on the board that shows the same thing without leaving the page. Cost is the one I didn't have before and most wanted: generation got cheap, but cheap isn't free, and the only way to keep it honest is to watch the number. A per-run cost chip on each card keeps it in my face instead of in a bill at the end of the month.

The loop cleans up after itself

Small, and the kind of thing you only notice when it's missing. The merge-watcher used to do one job: when a PR merged, move its card to Done. It now handles the whole aftermath.

  • Reject a PR on GitHub and the watcher deletes the dead card instead of leaving it to rot in Review.
  • Either way it prunes the stale branch the run created, so my remote doesn't fill with atb/* heads.
  • On a merge it fast-forwards my local checkout, which matters more than it looks: the Scout decides what to work on by reading my local repos, so if my working copy lagged behind what already shipped, the Scout would keep proposing work that's already done. Keeping the local copy current is what stops the front of the board from arguing with the back of it.

None of this is a headline feature. All of it is the difference between a demo and a thing you leave running.

What's still on the list

Same honesty as last time. Some of the original gaps I closed; three I didn't, and there are new ones.

It still doesn't manage a project that outlasts one context window. Every task assumes it fits in a single agent run. The genuinely large jobs — break into steps, each in a fresh context seeded by the last — are still outside the board. This was the biggest thing I admitted last time and it's still the biggest thing open. The Scout decides what to do next; it doesn't yet decompose a what that's too big to do at once.

The review is still one reviewer, not a panel. A single fresh agent catches a lot, but correctness, security, and "just try to break it" are different reading postures, and one pass does one of them at a time. Fanning the gate into a few perspective-specialized reviewers is a clear upgrade I haven't built.

There's still no plan to argue with. The Scout picks the task and the board carries it to a merged PR, but the highest-leverage artifact — the plan you fight over before a line gets written — still doesn't exist as a lane. Sending a PR back is feedback after the fact; I'd rather also catch it before the fact.

And send-back is manual, not escalation. I can push a change back with a note, but the system still doesn't kick the genuinely ambiguous product call — "should it even behave this way" — up to me as a decision on its own. It flags; it doesn't yet know which questions were never the reviewer's to answer.

The desk does more than approve

Step back and the week's work is one idea. The first post took the part of management I was skipping — review — and made it a property of the system instead of a habit I had to remember. This one did the same to the rest of the job. Deciding what to work on. Giving feedback that isn't just yes or no. Stopping a bad run. Knowing the cost. Cleaning up the loop.

A good manager, I said last time, isn't the one who reviews everything — it's the one who built a team that's safe not to watch. A week in, I'd add one line to that. The team that's safe not to watch is also the team that knows what to do next without being told, takes a correction without starting over, and hands the hard calls back up to you. The desk stopped waiting for me to fill it. That was always the point.