← Paul Barrick

// the agentic os

Loop

An LLM-agnostic work queue. Anything can go on it; nothing runs until a person marks it ready. Then a coding agent does it in a worktree and opens a pull request, and a person merges.

live · Mac + Tower

The Loop desktop app: 118 items queued, 105 needing something, 0 ready and 2 in review; a FIFO discipline toggle, today's spend of $0.00 against a $40 cap, a kill switch, and a nodes panel showing the Mac active and Tower on standby.
what
work queue for agents
role
Designer and sole engineer
when
Oct 2026 – present
stack
TypeScript · Node 24 · SQLite (node:sqlite, WAL) · MCP · Tauri · launchd · Docker

The problem

I had more work than hands, and agents that could do a lot of it. What I didn’t have was a safe place to put the work. Ideas lived in roadmaps, bug folders, voice notes and chat. Agent runs started from whatever terminal I happened to be in. If I wanted an agent to pick something up overnight, I had to trust it with the whole decision: what to do, where, and when it was finished.

I’d already built one answer, a pull-based autopilot on my home server. It shipped disabled. Loop absorbed its good parts — the lease, the kill switch, the repo allow-list, worktree-and-PR-only — and added the thing I actually needed: a state between “I wrote this down” and “go do this now”, owned by a person.

What I built

Loop is a work queue. You can put anything on it — a title is enough — and it sits there. Once a person marks an item ready, an agent (Claude Code, Codex, Gemini CLI or opencode) does the work in a fresh git worktree, and the runner opens a pull request. A person merges.

It runs as a small daemon, loopd, on each machine. A CLI, an HTTP API, an MCP server, a web view, a desktop app and a Collab plugin all call the same service, so they obey the same rules.

How it works

Decisions worth noting

Leadership is a lease, and claims are epoch-fenced. The node order is Mac, then Flex, then Tower. The highest-ranked live node leads; a lower one promotes after 180 seconds of silence. Every claim carries the leader’s epoch, so if the Mac comes back after Tower promoted, the Mac can’t complete work Tower re-dispatched. Its token is older and the store refuses it.

One lease authority, and I accepted the cost. Tower’s loopd hands out leases. If Tower is unreachable, nobody takes a new lease — the current holder works until expiry. The alternative allows two leaders and leans entirely on the fence. I’d rather stall than double-run.

SQLite, not an embedded Postgres. Several processes share the store, and claims take microseconds in WAL mode. I looked at PGlite: single-process, hundreds of milliseconds to start, and its one advantage (the same SQL dialect as the remote) doesn’t matter much for about six tables and an op-log.

Zero runtime dependencies. TypeScript run directly by Node 24, Node built-ins only, and src/ held at 100% line coverage.

Where it fits

Collab is Loop’s first integration, not a dependency. Loop reads my goals and starred roadmaps from Collab and writes status back — ready, in progress, in review with the PR link, shipped. Loop publishes its events to Headlines, which decides whether I see them. Surface shows Loop in its menu bar. A job that ends failed or held becomes a job of its own for a follow-up agent, so failures are never silent.

Outcome

The screenshot is a normal day: 118 items queued, 105 of them missing a “done when”, none ready, two in review. That ratio is the rule doing its job. Most of what I write down isn’t specified well enough to hand to an agent, and Loop won’t pretend it is.

On 1 November the Mac went quiet and Tower promoted itself without being asked. Flex came up, couldn’t reach the lease authority, and took no lease. Both are the designed behaviour. The gap I haven’t closed yet: agent jobs only run on the Mac, so during a failover Loop keeps queueing them and runs none.

← All of the Agentic OS