How I maintain my open source projects with Claude agents
A technical deep dive: a conductor session paces Claude agents under written rules, and I get one question at a time. How it works, how to build yours.
I maintain about ten repositories on my spare time, and each one has an issue tracker that grows faster than my evenings:
- my tools: dtgraph (GitHub), Component Anatomy (GitHub), Transtyle (GitHub), Bootstrap Tokens (GitHub), Bootstrap test bench (GitHub);
- Open {re}Source (GitHub);
- this site;
- and Bootstrap itself (GitHub).
Since Saturday 3 October 2026, a set of Claude agents does most of the work on them. I call the whole thing the orchestrator. One Claude Code session in it, the conductor, plans and paces. Background agents, each on the model tier its task needs, do the work in each repository under written rules. A small command-line tool with a SQLite file holds the state they share. And I get one question at a time.
In short
Claude agents now do most of the work on my repositories, and they’re organized around one limit: my review time. One Claude Code session, the conductor, plans and paces. Background agents on four model tiers do the work under written rules. A small command-line tool over SQLite holds the state, and I get one question at a time. On Bootstrap, every open item is analyzed and a fix is prepared when one is needed, in a repository shared with Mark Otto, but nothing is posted without a maintainer.
How to read it: the first three sections give the idea. From budget pacing to safety, it’s the machinery, for anyone who wants to build one; How to replicate it is the short version. Step two is the Bootstrap story.
013 to 5 October 2026
Writing code isn’t the bottleneck, reviewing it is#
When I rebranded everything I publish, Claude opened about 80 pull requests in eight days. The writing was never the slow part. I was. Every pull request is a review, every question is a context switch, and I do both between two Bootstrap reviews or from my phone in the subway.
So the whole setup is designed around one constraint:
My attention is the scarce resource, not the tokens and not the code.
Every rule below exists to protect it:
- agents never wait on me in a way that blocks other work;
- what waits on me is capped per repository;
- what reaches me is one decision, explained well enough to answer without opening anything;
- what only I can do by hand is in one separate list.
Tokens come second: a weekly budget that’s paced, not burned on day one.
Protecting my attention also means not spending it on relaying. Once agents write the code, the easy role left for the human is the one Niklas Gruhn calls a meat proxy. The proxy pastes an issue into Claude, its answer into a comment, a reviewer’s feedback back into Claude, the next diff into GitHub, and adds nothing of their own on the way. It’s the question every software factory raises: what’s left for the human? I want as little of that relaying as possible. Carrying things between Claude and GitHub is the agents’ job. What reaches me should be what only a maintainer can add.
The shape: a conductor, agents, and one small database#
The conductor is a Claude Code session opened in a private repository. Its CLAUDE.md is the conductor’s protocol: plan, dispatch, pace the budget, bring me questions. It never writes code itself. It’s the only session I talk to, from my laptop or, with Remote Control, from my phone.
The agents are Claude Code subagents started in the background, one per task. Each one is a Markdown file in .claude/agents/. The front matter sets its model and effort. A few lines of instructions all say the same thing: read the worker protocol first and follow it.
---
name: engineer
description: Senior engineering tier (Opus). Features, non-trivial bugs, substantial PR reviews.
model: opus
effort: high
---
You are the engineer tier, handling substantial engineering. Understand the codebase
conventions before changing anything, keep diffs focused, and write the review/PR text
a maintainer would respect.
Read docs/worker-protocol.md first and follow it exactly. The task id is in your dispatch prompt.
The worker protocol (docs/worker-protocol.md, about 460 lines) is the contract every agent follows: how to load a task, where to work, what it may write on GitHub, how to describe a pull request, how to ask a question, and how to end a run. It’s the most important file in the repository, and the one I edit the most.
orc is the state. One Python file, about 3,200 lines, standard library only, over one SQLite file. Everyone goes through it: the conductor to plan, the agents to report, and me through slash commands in the conductor. Nothing lives in a chat transcript. If the conductor’s session ends, a new one reads the database and carries on.
What orc stores#
There are six tables. Most of the logic is in how they’re read:
| Table | What it holds |
|---|---|
tasks |
one per GitHub issue or pull request worth tracking, or per job added by hand: its repository, kind (review, my-pr, backlog-issue, task…), status (new, ready, running, blocked, needs_user, prepared, done, dropped), priority, tier, goal (“what done means”), branch and worktree, and what it waits on |
events |
an append-only log per task: every dispatch, every progress note, every state change |
questions |
the decisions waiting on me, with their context, options, recommendation and answer |
usage |
snapshots of my Claude plan’s usage meters, for pacing |
meta, ease |
the last sync time, overrides, and ratings that let /todo suggest the easiest issue to pick up |
SQLite in WAL mode, with a 30-second lock timeout, is enough for four agents and a conductor writing at once.
How a task becomes work#
A task is dispatched with a one-line prompt:
Task <id>. Mode: prepare. Skills: deramond-brand, brand-diagram.
The agent runs orc show <id> for the goal, the history and any question I already answered, then orc policy <repo> for the rules of that repository. Then orc worktree <id> gives it a git worktree on its own branch, outside my own clone. Agents never touch my checkouts. I have local branches and work in progress everywhere, and a background agent switching my branch would be a disaster.
Every run ends with exactly one outcome:
orc done <id> "<one-line result>" # goal achieved
orc prepared <id> "<state>" # branch built locally, waits for review room
orc refined <id> "<what changed>" # issue sharpened, back to ready
orc block <id> "<why>" --waits-on owner/repo#N # waits for a PR, an issue, a release or a day
orc ask --task <id> -q "<one question>" -c "<context>" -o "<option>" -o "<option>" -r 1
That’s the whole interface between the agents and the rest of the system. An agent that ends without an outcome is retried, and moved up a tier after two attempts.
The loop#
The conductor works in ticks. One tick:
- Budget. Read the usage meters (
get_usage), record them withorc usage, askorc budgethow much work this moment can afford. - Sync, if the last one is older than two hours:
orc syncpulls review requests, my pull requests, issues assigned to me and, for repositories that opt in, the whole open backlog. New items arenewuntil a cheap scout triages them. - Plan.
orc next --jsonreturns what to dispatch now, each with its tier, model, effort, run mode and skills, within the free slots, the per-repository limits and the review limits. - Dispatch each one as a background agent, then
orc start <id>with the agent’s id. - On completion, read the last few events (
orc show <id> --events 5), not the agent’s whole transcript. The conductor’s context is shared by everything, so it stays lean. - Inbox. If I’m here, show me the top question.
- Chain: tick again while there’s dispatchable work.
In manual mode, each tick proposes the plan in full sentences and waits for my go. In autopilot, the conductor runs /loop /tick and paces itself. It wakes up on every agent completion, and otherwise every 5 minutes while I’m active (I answered a question, commented on or merged one of its pull requests, or wrote to it in the last 15 minutes) and every 25 minutes when I’m away. It never asks me anything in autopilot. Questions wait in the inbox, and one push notification goes out if a question blocks the most important work.
The conductor resends its whole context on every tick. Past 300,000 tokens, it stops dispatching, lets the running agents finish and asks for a fresh session. Nothing is lost: the state is in orc.

Priority you can explain#
orc ranks tasks with a deterministic score, so orc explain <id> can say why something is first. It adds up:
| Part | Points |
|---|---|
| the kind | a review requested from me 60, an issue assigned to me or a task added by hand 50, a pull request of mine 40, a backlog issue 20 |
| the repository’s weight, from its policy | 0 to 30 |
| label boosts, from the policy | regression +10 on Bootstrap, priority: high +30 in my branding repo |
| age | up to +20 for a review waiting on me, +5 for a backlog item with recent activity, −10 for a pull request of mine stale for six months |
| the rest | +10 for a follow-up in a chain, a manual boost from the conductor, +100 for a pin |
So a review requested from me on Bootstrap, labelled regression, starts at 85: 60 for the kind, 15 for the repository, 10 for the label. It climbs while it waits.
Following open pull requests costs no tokens#
Once an agent opens a pull request, its task blocks on it (--waits-on owner/repo#N). From then on, orc checks it on every listing with plain gh calls. No model runs until there is work to do.
Two rules here matter more than they look. Rebases go first, even past the free-slot count: a pull request that needs a rebase can’t be reviewed or merged, and it holds the review room, so it blocks the whole repository. And only my comments are instructions. The agents post as me, so orc tells its own comments from mine by the attribution line every one of them ends with. Anyone else’s comment becomes a question for me instead of a change.
Waits aren’t only pull requests. A task can wait on npm:<package>@<version>. I publish releases by hand and the publish shows in my to-do list. Once the registry has the version, the item clears itself and the task wakes up to propagate the release. Or on until:<date>, for a policy rule like “one new Open {re}Source article every two weeks at most”.
Budget pacing and four tiers#
I’m on Claude Max 20x, which has three meters: a weekly limit for all models, a 5-hour window, and a separate weekly bucket for Fable. The goal is to finish each week near 95% of the weekly limit and never hit the wall before the reset.
orc budget compares the weekly meter with where it should be at this point of the week (time elapsed × 95%) and picks a mode:
| Mode | When | Parallel agents | Highest tier | Minimum priority |
|---|---|---|---|---|
stop |
the weekly target is reached | 0 | worker | 90 |
conserve |
more than 10 points ahead of pace | 1 | engineer | 55 |
steady-low |
3 to 10 points ahead | 2 | engineer | 40 |
steady |
on pace | 3 | engineer | 0 |
push |
more than 5 points behind, or the last 24 hours with over 10% left | 4 | architect | 0 |
On top of that, the 5-hour window halves the number of agents above 70% and pauses everything above 90%, until its reset. The Fable bucket has its own pace: ahead of it, the architect tier is kept for tasks that clearly need it; empty, nothing goes above engineer. There’s also a burn mode, every slot filled and engineer work moved to Fable, but only I can switch it on (/autopilot-burn). Pacing alone never goes past push.
The four tiers are four subagent files:
| Tier | Model, effort | Used for |
|---|---|---|
| scout | Haiku, low | triage, CI status, summaries: anything read-only and mechanical |
| worker | Sonnet, medium | well-specified changes, rebases, CI fixes, docs, dependency bumps, small reviews |
| engineer | Opus, high | features, tricky bugs, reviews of non-trivial PRs, anything that needs judgment |
| architect | Fable, xhigh | cross-cutting work, long chains, a task that failed twice |
The routing rules:
- the tier comes from the task, then from the repository policy (per kind, or per label), then from the kind’s default;
- triage decides the tier of the work, not of the triage: a scout can never be assigned anything that writes code, content or a pull request (
orc setrefuses it); - rebases and closing steps always go to a worker; a red CI gets a worker twice, then an engineer, then a question for me;
- an agent that’s out of its depth stops early and hands the task up a tier: a cheap stop beats an expensive flail;
- the budget mode caps the tier last.
Per-repository policies#
A repository without a policy is synced, so I can see it, but never worked on. A policy is a Markdown file with a TOML front matter. An onboarding skill researches the repository first, then writes the policy with me, one question at a time. It’s never invented.
The front matter holds what the code reads. Here’s this site’s:
repo = "julien-deramond/deramond.dev"
enabled = true
default_branch = "main"
weight = 20 # 0–30 priority bonus relative to other repos
max_parallel = 1 # concurrent tasks in this repo
skills = ["accessibility", "seo", "web-design-guidelines", "deramond-brand", "brand-diagram"] # excerpt
watch = ["issues", "prs"] # the whole open backlog, not only what's assigned to me
[autonomy] # auto | ask | never (unlisted = never)
push_branch = "auto"
open_pr = "auto"
open_draft_pr = "auto"
mark_ready = "never"
comment = "ask"
label = "ask"
close = "ask"
merge = "never"
[commands]
install = "pnpm install --frozen-lockfile"
typecheck = "pnpm check"
build = "pnpm build"
The body holds what the agents read: context and rules in plain words. For this site: “text in my voice opens as a draft pull request, for me to rewrite, and is never marked ready”. This post is one of those.
Every GitHub action is auto (do it), ask (file a question and stop) or never. The spread across my repositories says a lot about trust:
- my Bootstrap test bench: almost everything is
auto. It exists to find bugs, its issues follow a fixed taxonomy, and its CI catches mistakes. - this site: pushes and pull requests are
auto; comments, labels and closing issues areask. - my other tools (dtgraph, Component Anatomy, Transtyle, Bootstrap Tokens): every write is
ask, except refining Transtyle’s own issues. They have users. - Bootstrap: every write is
never. More on that below. - merging:
never, in every single policy. I merge.
The policy also carries the repository’s commands and skills. It says how many agents may work on the repository at once, which labels to watch or skip, and whether code from outside contributors may be run (run_untrusted_pr_code, false everywhere).
Review limits#
This is the part that makes the whole thing livable. Each repository has a max_open_prs, one by default: the number of agent pull requests that may wait on my review there. There’s no global cap, so a pull request waiting in one repository never holds back another.
A full repository doesn’t stop the work. It changes what the work produces:
- prepare: the agent builds the branch exactly as for a pull request (commits, checks green, title, description and labels drafted) but doesn’t push. Up to three prepared branches per repository.
- ship: when room frees up, a prepared branch is rebased, checked again and pushed. Branches I already approved go first.
- refine: when enough branches are prepared, agents stop writing code and make issues ready instead. They read the code the issue touches, do the research, sharpen the scope and the acceptance criteria, fix the labels and split what’s too big.
Work on pull requests that are already open (CI fixes, rebases, my feedback) doesn’t count against the limit, and neither do no-PR tasks: audits and analyses whose output is issues, comments or drafts. Questions are never limited.
One question at a time#
Every decision that is mine goes through orc ask, and the protocol is strict about how it’s written, because I come to it cold, between two other things, remembering nothing about the task:
- the context is four to eight full sentences. They say what the item is about and why it exists, what the agent did, where things stand (checks, what wasn’t verified), and why it needs me rather than the agent;
- it cites the evidence: commits, the files that matter, screenshots, the draft holding the exact text I’d approve;
- one question, two to four options, a recommendation.
/inbox shows me the top one. orc gathers the evidence itself, with git and gh only: the issue or pull request body, the task’s commits and changed files with their GitHub links, the full text of its drafts, the screenshots. The conductor turns that into a brief: what it’s about (with the issue’s real title and a quote of its key line), what was done (links on every word that can carry one), what I’d be approving (quoted from the draft), and why it’s my call. Then comes one question. The brief is repeated inside the question box, because on my phone the box is all I see.

The order is mine too: questions whose answer pushes, opens a pull request or releases something come first, then direct work, then background work.
Answers are recorded with orc answer. The task goes back to ready, and the next run follows the answer.
Two rules took a few iterations to get right. The first: short cards with ids and no links don’t work. The brief format came out of my standing complaint:
Give me links all the time.
The second: nothing waits on me outside orc. An agent refused a command, a policy that needs a change, something to do by hand: each is filed the moment it comes up, never left in a chat message I’ll scroll past.
And one list of what only I can do#
/todo is the other place, and it never holds questions. Only what I must do with my own hands:
- Dependabot verdicts, first: a read-only run weighs what changed between the versions against how the repository uses the package, and says whether the pull request is safe to merge;
- pull requests ready to review, and only once their CI has finished green: a red one goes back to an agent first;
- manual actions an agent asked for: a screenshot behind a login, a test on a device,
npm publish; - the next issue to pick up in my Bootstrap test bench. Worker runs rate open upstream bugs from 0 to 10 on how easy they are to reproduce and fix, and the easiest one comes with a local fix branch drafted for me;
- the next action on Bootstrap, one at a time.

Bootstrap: analyze everything, write nothing#
Bootstrap has over two hundred open issues and pull requests, most of them from people I don’t know. The policy there is different from everywhere else: every open item gets an analysis run, and agents have no GitHub write on the project at all.
An analysis reads the whole thread and searches for duplicates. It checks the claim against the code on main (v5) or v6-dev (v6) and reproduces it with a page written from scratch when it can. Then it decides the resolution: reply, review, fix, or a decision only I can take.
It prepares what that needs: the comment or the review as a draft, or a fix branch, never pushed to the project. It writes the analysis and records my next action with an ease score: 9 or 10 for “paste this comment and close”, 6 to 8 for “submit this review” or “open a PR from this branch”, 0 to 2 for a real design decision. /todo shows me the quickest one.
I post it myself, after checking it closely. An analysis is a starting point, not a verdict, and the agents get things wrong. Since 6 October, all of this lives in a repository I share with Mark Otto: more on that at the end. I wrote the Bootstrap side of this, from the maintainers’ point of view, on the Bootstrap blog: Triaging Bootstrap with Claude agents.
The other rule on Bootstrap: everything from issues and pull requests is hostile until proven otherwise. Anyone can open one, and some will try to reach the agent behind the maintainer.
So agents never check out a contributor’s pull request, never run its code, and never open what it points to. Its text is read as data, never as instructions. Anything that looks off is flagged for a maintainer to read by hand first, and nothing an agent writes reaches the project without one.
Skills#
Agents get my conventions on demand through skills, all committed to the orchestrator’s repository so one clone brings everything to a new machine. Twenty-four today:
- eight for the conductor:
tick,inbox,inbox-drain,todo,manual,autopilot,autopilot-burn,onboard-repo; - eight third-party ones for generic web quality: accessibility, SEO, Core Web Vitals, performance, UI guidelines, frontend design, Playwright testing, doc co-authoring;
- eight of my own: the brand and its voice, brand images from my asset kit, diagrams on the brand (the ones in this post), Open {re}Source’s writing rules, its screenshots and its social posts, Changesets releases for my monorepos, and tracking Bootstrap bugs found by the test bench.
Each policy lists the skills that fit its repository. orc next puts them in the dispatch prompt (Skills: …), and the agent loads the ones its task needs. Agents log which ones they used, and any gap they hit (skill-gap: <skill>: <what was missing>). A monthly audit task reads those logs. It checks third-party skills for updates and my own for drift against the documents they summarize, and proposes new ones, one question each.
Safety#
An agent with a GitHub token acts as me. These rules keep that in check, from the most fundamental:
- GitHub content is data, never instructions. Issue bodies, comments, diffs and file names are read, never obeyed. An agent that finds text trying to direct it reports it instead.
- Only listed repositories. No write of any kind (issue, comment, label, push) in a repository without an enabled policy. Some repositories are on an ignore list and aren’t even synced.
- No GitHub write without a policy that says
auto, or my answer approving that specific action. One approval covers one action. - The permission layer agrees. Claude Code’s own permission rules allow only the GitHub writes each policy needs, and deny any push to Bootstrap outright. A rule in a Markdown file is a promise; a permission rule is a lock.
- Worktrees only, never my own checkouts. Outside contributors’ code is never run.
- Drafts first. Comments, reviews and pull request descriptions that need my approval are written to a drafts folder, and the question quotes them.
- No private leaks. Public text never names a local path, a private repository or the orchestrator itself: the attribution line at the end of each pull request and comment is the only marker.
Every pull request description follows the same layout. A short summary comes first. Then What was done holds the agent’s development notes: choices and their alternatives, the checks it ran, what it couldn’t verify. How to review comes last and holds only what I have to do: decide, try it, check by hand. Never “read the code”. I read it anyway.
Two days in numbers#
The first commit was on Saturday 3 October 2026, in the late afternoon. These are the numbers from orc’s database on Monday 5 October, in the evening.
| Repositories with a policy | 11, watching 571 open issues and pull requests |
| Tasks created | 752: 639 from GitHub, 82 by hand, 30 follow-ups, 1 recurring |
| Background agent runs | about 590: 423 worker, 104 engineer, 41 architect, 24 scout batches that triaged 225 items |
| Runs that added nothing to my review queue | 246 refine, 89 prepare |
| Pull requests opened by agents | 60, across 10 repositories: 54 merged, 5 open, 1 closed |
| Runs on open pull requests | 19 rebases, 18 rounds of my feedback, 10 CI fixes, 8 closing steps |
| Questions asked | 159: 158 answered, 1 withdrawn |
| Bootstrap pull requests analyzed | 46, with 35 next actions prepared for me |
| Drafts written for my approval | 411 |
| Commits to the orchestrator itself | 117 |
And the tokens. orc doesn’t count them: it reads the same usage meters I see. From Saturday afternoon to Sunday afternoon, the weekly meter went from 51% to 98% of my Max plan’s limit, with the 5-hour window reaching its pause threshold on the way. After the limit was reset that Sunday, the night that followed used another 39% of the weekly limit and 69% of the Fable bucket. Two days of this is most of a week’s allowance. Pacing exists for exactly that reason.
What worked, and what didn’t#
What worked:
- The state outside the chat. A conductor session can die, be rotated or be cleared, and nothing is lost. The same goes for any agent.
- Review limits. I never open GitHub to forty pull requests. One per repository waits on me; the rest is prepared, refined, or waiting its turn.
- One question with a brief. I answered 158 questions in two days without opening a single issue to remember what it was about.
- Writing the rules down. The protocol and the policies do more for quality than any prompt. When an agent does something wrong, the fix is a rule, committed, and every later agent follows it.
What didn’t, or not yet:
- Most rules came from mistakes. 117 commits in two days, and most of them fix a behavior I noticed. Questions were written as fragments of ids. Agents woke themselves up with their own comments. Branch names leaked the setup on GitHub. A hung
ghcall froze the conductor. A pull request was found twice and tracked by two tasks. It’s young, and it shows. - It’s expensive. Most of a week’s allowance in two days. Pacing keeps a week from ending on Tuesday, but a backlog this size is still more work than one plan pays for.
- Review is still the bottleneck. The agents prepare more than I can review. The difference is that it now waits in branches and sharpened issues, not in my head.
- Every agent reads a long protocol. Four hundred and sixty lines, at the start of every run. Skills moved a lot of it out. The rest is the price of consistency.
How to replicate it#
The repository behind all this stays private, so there’s no template to fork. Here are the pieces instead, in the order I’d build them again, starting small:
- A state store everyone writes through. A CLI over SQLite, with tasks, events and questions. Start with
add,show,ready,done,block,askandanswer. Make it deterministic and boring: the agents are the creative part, the state must not be. - A worker protocol. One file every agent reads first: load the task, work in a worktree, respect the policy, end with exactly one outcome. Write it before the first agent runs, then edit it every time an agent surprises you.
- One policy per repository, starting with everything on
askandmerge = "never". Loosen one action at a time, when you’ve seen the agents do it right. - Tiers as subagent files, each with its model and effort. Two are enough to start: a cheap one for triage, a capable one for the work.
- A conductor protocol in the
CLAUDE.mdof the repository the conductor runs in: the loop, the hard rules, how to talk to you. Run it in manual mode for a while: watching it propose each step teaches you what to write down. - Review limits before autopilot. Without them, the first autonomous night ends with more pull requests than you can read in a week.
- The inbox. Write the rule about how questions are written early. It’s the part you’ll use every day.
- Budget pacing last, once you know what a normal day costs.
Start small
Start with one repository you own and know well, on manual mode, with a scout and a worker.
The setup grows by rules, not by code. The code is about 3,200 lines of plumbing. The rules are what make it trustworthy.
026 and 7 October 2026
Step two: sharing the Bootstrap backlog with mdo#
Everything above is step one: a setup that works for me, alone. Its Bootstrap part had an obvious limit. Everything the agents prepared stayed with me: analyses in the orchestrator’s private state, drafts in its drafts folder, fix branches in worktrees on my laptop. It reached one person, through my /todo. But I don’t maintain Bootstrap alone. Mark Otto, mdo, its co-creator, looks at the same backlog, and he had none of it.
So on Tuesday 6 October, in the evening, the Bootstrap part moved to a place we both see: twbs/triage, a private repository in the Bootstrap organization. The next morning, it learned to prepare a fix for every issue that needs one, and to put competing fixes side by side. The method stayed the same. What changed is where it writes, for whom, and how much it prepares.
What changed#
- One folder per item. Every open issue and pull request has
issues/<n>/orprs/<n>/, with the analysis (analysis.mdfor an issue,review.mdfor a pull request), the exact text to post (answer.md), the description of each pull request to open from a fix (pr.md,pr-2.md,pr-3.md), andmeta.json: status, resolution, next action, ease, when it was analyzed, when the item last moved on GitHub, the open pull requests that address it, and its fix branches. - Fix branches are pushed there. A fix starts from twbs/bootstrap’s own
main(v5) orv6-dev(v6), in one or two commits that cherry-pick cleanly, and goes to twbs/triage asissue-<n>-<base>.orc triage-pushpushes only commits I authored, never a contributor’s, at most three, only to twbs/triage. It refuses a commit the same task already pushed under another branch name. A push to the project itself stays forbidden, in the policy and in the permission rules. - Publishing is one command.
orc triage-publishruns the repository’s own check on the folder (validmeta.json, the main file present, no hidden Unicode, no local path). Then it commits that folder alone and pushes it tomain, under a lock, because three analysis runs may publish at the same moment. - Sync keeps it current. Every
orc syncalso runs the repository’s sync script, with read-onlygh. It updates the list of open items, the open pull requests that close or mention each issue, and the “last sync” line of its README. An item whose GitHub activity is newer than its analysis is flagged, and the same activity wakes its task. The next run rewrites the folder from scratch, and git keeps the old version. - Mark’s items and mine are analyzed too. Until then, the policy skipped our own issues and pull requests: they were ours to handle. In a shared backlog, a review of his pull request is useful to me, and the other way round.
- Nothing there names my setup. twbs/triage has its own
CLAUDE.mdand README, written for a maintainer, or any agent, who has never heard of the orchestrator. They cover the steps of an analysis, the format of each file and the security rules. Commits readissues/37807: analysisorSync with twbs/bootstrap. No task id, no local path, noorc. - Bootstrap moved up. Keeping that backlog analyzed and in sync now comes right after the Dependabot reviews in
orc next, ahead of the orchestrator’s own work.
The move itself was a one-off export. A script read the existing analyses and drafts from orc’s state and wrote one folder per item. It stripped every reference to the setup (draft paths, task ids, local paths) and listed any line that still matched a pattern of the setup’s words for a last look. It also pushed the fix branches that held only my commits. 190 items went in, in two commits. Fifteen minutes later, the analysis runs wrote straight into the twbs/triage clone, and the script was deleted.
A fix for every issue that needs one#
Before the move, a fix branch was the exception: the analysis prepared one when the fix was obvious. For two maintainers deciding together, a written fix is worth more than a paragraph describing it. So the rule changed on Wednesday morning:
- Every issue whose resolution changes code or docs gets at least one fix branch: a confirmed bug, a docs fix, a plausible feature kept open for v6, a design decision between implementations. No branch for what won’t change anything: by design, duplicate, can’t reproduce, won’t fix, suspicious.
- Even when someone already opened a pull request. A contributor’s or a maintainer’s pull request doesn’t replace ours. It’s something to compare ours with. Ours is written from scratch on the upstream base, never from their code. If it ends up close to theirs, the analysis says so.
- One branch per direction, three at most. When there are several reasonable ways to fix it (a maintainer writing “we could do A or B” on the thread is two), each direction gets its own branch, its own commits and its own
pr-<n>.md. The analysis compares them, open pull requests included, in a Directions part, and recommends one. Directions aren’t invented to fill a quota: one clear fix is one branch. - A review can come with an alternative. When the review of a pull request concludes that another approach would be better, that approach is prepared too, as a
pr-<n>-<base>branch. - The check enforces it.
npm run checkrefuses a fixable issue without a branch, and an analysis written since that morning without itsfixable,directionandpr_filefields.
Issue 37807, container queries for the flexbox grid, shows what that gives. Mark has a draft pull request that goes much wider. The analysis wrote two branches on v6-dev, in two directions: columns driven by their container by default, as in v6’s CSS Grid, or the same behind an opt-in Sass option. Its folder, as it lands on GitHub:
issues/37807/
analysis.md what it is, where it stands, findings, directions, recommendation, next action
answer.md the status comment to post on the issue
pr.md container-driven columns by default, from issue-37807-v6-dev (recommended)
pr-2.md the same behind an opt-in Sass option, from issue-37807-v6-dev-2
meta.json status "action", ease 6, fixable, open PR 42784, two branches
A dashboard anyone can run#
On GitHub, the folders read like any Markdown. To go through two hundred of them, twbs/triage comes with a small dashboard: one Node server and one page, built on Bootstrap’s own CSS with the v6 color tokens on top, in light, dark or automatic mode. Run npm start and the whole backlog is in the browser, quickest first, grouped by ease, with filters by status and by fix: Open PR for items a pull request on twbs/bootstrap already addresses, Triage fix for items with a branch prepared here. j and k step through the list, / searches, and on a phone the list and the item are two screens.

An item opens on its next action, with a button that copies the drafted answer. For issue 37807, it says to post a status comment and keep the issue open, then which pull request to open from which branch, or to let Mark’s land.

Under it, Fixes puts every way to solve the item side by side. Our branches come with their direction, commit, pull request description and the commands to cherry-pick them into a twbs/bootstrap clone. The real pull requests each link to their own review.

The analyses quote hostile content, so the page that shows them must not run it. The server listens on localhost only and renders Markdown without raw HTML. It loads nothing from outside (its Content Security Policy blocks every other origin) and makes hidden Unicode characters visible. Any link that doesn’t point to github.com/twbs or getbootstrap.com becomes inert text.
Day to day#
- The agents work as before. A new item, or new activity on one, is found at the next sync and analyzed in the next tick. The folder is published and its fix branches are pushed. On Wednesday morning: 224 open items, 223 analyzed, 120 fix branches on 80 of them, 31 with competing directions, 26 already addressed by an open pull request.
- I still get one next action at a time in
/todo, the quickest first, now with links to the item’s files on twbs/triage. I act on GitHub myself, or tell the conductor “post it”. It postsanswer.mdas is, or fetches the fix branch from twbs/triage and pushes it where I say. Either way, my activity on the item wakes its task, and the folder is rewritten if anything is left. - Mark needs no agent and no orchestrator: a
git pull,npm start(after onenpm ci), or the folders on GitHub give him the same backlog, with the same drafts, branches and comparisons. What he answers or merges shows up at the next sync, like anyone’s activity.
Prepared, never automatic#
The agents do the reading, the checking, the drafting, and now the fixing, in as many directions as the issue deserves. If you use Bootstrap or contribute to it, though, here’s the part that matters: none of it reaches the project without a maintainer going through it precisely. That’s why it’s semi-manual on purpose.
The agents make mistakes. They don’t know Bootstrap’s history well: why a selector is written the way it is, what was tried and reverted years ago, what we’ve planned for v6. And they tend to add code rather than refactor. They add one more rule on top of the existing ones, where the best fix would rethink the component with all of Bootstrap’s specifics, and the web platform’s, in mind. Part of that isn’t on them. Much of that knowledge lives in our heads, in old threads and in decisions never written down, so it isn’t in their context either.
An analysis is where we start, not what we ship.
Maybe we’ll find a way to make them smarter, starting with giving them that missing context. Until then, every comment, review and merge on Bootstrap is a maintainer’s, by hand.
What comes next#
Today, all of this runs on Claude, and as far as I know only on Claude: the subagent files, the skills, the slash commands, the usage meters orc budget reads, the permission rules. The parts that matter most aren’t tied to it, though. orc is a Python file over SQLite, and the protocol and the policies are Markdown. At some point the setup has to become agent-agnostic, and OpenCode, an open source coding agent that works with many model providers, is one way to get there.
Agent-agnostic also means that not every step needs a frontier model. Two experiments are on my list. The first is local models. A scout’s work (triage, summaries, CI status, rating how easy an issue is) is mechanical enough to run on my own machine, for free, without touching the weekly meter.
The second is Jev, a model by TypeSafe AI built for decisions rather than text: given a state and the allowed answers, it returns a typed choice with a calibrated confidence. The setup is full of questions shaped like that. Which tier does a task need? Does an item look suspicious? Which status and ease does an analysis land on? Is something worth a notification on my phone? Today each one costs an agent run, or hides in the middle of one. A typed answer with a confidence would let the clear cases go fast and cheap, and send only the uncertain ones to a bigger model, or to me.
Meanwhile, Claude Code’s own Remote Control fits the way I use it now. The conductor runs on my laptop, and I drive it from my phone, one question at a time, wherever I am. So: let’s see what happens.

For a while, I’m staying on Claude anyway. I got six months of Claude Max 20x for free through Claude for Open Source, a program for open source maintainers. It’s the plan this whole setup runs on.
The agents read, check and draft while I’m at work, asleep or in the subway. What’s left for me is the part that needs a maintainer: deciding, not relaying.
You can’t create time. This comes close.
Now, back to the next Bootstrap action in my to-do list.