← Back to Blog

The Loop Runs While I Sleep

ai claude-code agentic-engineering workflow kanban

A few months ago I wrote that I orchestrate Claude instead of prompting it. That was true, but I was still in the loop. I would brainstorm requirements, steer the design, kick off a spec loop, then come back to review the PR. The system did the volume, I did the judgment, and I was present for every handoff.

Now I am not in the loop. The loop is.

A person asleep at a cluttered desk late at night while the work waits on the page in front of them

What changed

The old shape was conversational. I prompt, Claude responds, I follow up on requirements, we brainstorm, I steer the design, then I track the implementation. Good work, but every feature needed me sitting at the keyboard to start it, nudge it, and catch it at the other end.

The new shape is a queue. I write what I want as a GitHub issue, label it, and walk away. Every ten minutes a loop wakes up, looks at the board, and decides whether there is work to do. If there is, it does it. I am building Swimiss, a swim school booking platform, almost entirely this way.

The interface is no longer the chat window. The interface is the board.

GitHub Issues are the kanban board

There is no separate project tool. The board is GitHub Issues, and the columns are labels.

kanban:todo      queued, waiting to be picked up
kanban:working   in progress, at most ONE issue at a time
kanban:done      PR opened, merge auto-closes the issue
kanban:blocked   needs a human, the loop skips it

A card moves left to right by swapping a label. To queue work I open an issue and tag it kanban:todo. That is the whole ritual. I can do it from my phone on the train.

A Swimiss issue on the GitHub mobile app, open with the kanban:todo label being added

This is the actual interface. I write the issue from the GitHub app on my phone, describe the goal, add kanban:todo, and that is it. No laptop, no terminal, no chat window. I control the whole pipeline from the board in my pocket, and the loop on my machine does the rest.

The ten minute tick

A small script, _loop_tick.sh, runs on a schedule. Every tick it answers one question, what should the loop do right now, and prints a single line of JSON.

TICK (every 10 minutes)

1. Is the working tree dirty?      -> {"action":"dirty"}  refuse to start
2. Is an issue already working?    -> {"action":"busy"}   do nothing
3. Any kanban:todo issues?         -> if none, {"action":"idle"}
4. Pick the OLDEST todo            -> lock it, {"action":"work"}

Each guard exists for a reason I learned the hard way.

Dirty tree means stop. If a mid flight agent left uncommitted changes to tracked files, the loop refuses to start new work. It will not pile a second feature on top of a half finished one. Untracked scratch files and the kanban directory itself do not count, a stray doc sitting in the tree should not jam the queue.

At most one issue is working. Before picking anything up, the loop checks whether an issue already holds kanban:working. If one does, the tick is a no op. This is the single most important rule. It means there is never more than one feature in flight, so PRs never stack and the main branch never turns into a pileup of half merged ideas.

Oldest todo wins. When the board is clear to proceed, the loop sorts open kanban:todo issues by creation time and takes the oldest. First in, first out. No prioritization logic, no cleverness, just a fair queue. If I want something done sooner I file it sooner.

Fresh main every time. Before locking the issue, the loop checks out main and fast forward pulls. Every feature starts from the latest shared state, so PRs are clean diffs against current main rather than against whatever happened to be checked out.

Then it does the one thing that actually moves the card.

gh issue edit N --remove-label kanban:todo --add-label kanban:working

todo becomes working in a single atomic edit. The issue is locked. The flow runs.

What runs after the lock

Once an issue is locked to kanban:working, the rest is the spec driven build loop I have written about before. A builder agent learns the codebase and writes tests first, implements until they pass, and opens a PR. A separate reviewer agent reads the PR diff and cannot touch the code. When the PR opens, the issue moves to kanban:done, and merging it auto closes the issue.

The card has crossed the whole board. todo, working, done. I never touched the keyboard.

Why a loop and not just a faster agent

The honest answer is throughput against my attention, not against the machine.

Claude was never the bottleneck. I was. Every feature needed me to start it, and I can only start one thing at a time, and only when I am awake and at my desk. The loop removes me from the critical path. I batch my thinking into a stack of well written issues during the hour I am sharp, then the queue drains over the next day whether I am asleep, in a meeting, or freediving.

The constraints are what make it safe to walk away. One issue at a time means no chaos. Refuse on a dirty tree means no half built features stacking up. Fresh main every time means clean PRs. Oldest first means fairness. None of these are clever. They are the boring rules that let an autonomous system run unattended without producing a mess I have to clean up later.

What my job is now

My job is the top of the funnel and the bottom. I write the issues, which is to say I do the thinking about what should exist and why. And I review and merge the PRs, which is the judgment about whether what got built is right.

Everything between those two ends, the picking up, the branching, the building, the testing, the PR, the loop owns. The board is the contract between us. I keep it full of good todos. It keeps moving them to done.

I used to prompt. Then I orchestrated. Now I run a loop and read the board.