# BUREAU // a multi-agent shepherd for Claude Code

Open-source shepherd for Claude Code + Linear. Bootstrap with one slash command. Local. In tmux. No SaaS.

---

## Dossier

*[ FILE #001 · DOSSIER ]*

Linear ticket in. Merged PR out. You mostly watch.

- Local. In tmux. No backend.

- Spec-driven. Loud on failure. Stops on red CI.

- MIT. One slash command to install.

[v0.7.5 · MIT · No dependencies you do not already run]

[CLONE // OPEN FILE](https://github.com/KaiaK808/bureau?utm_source=bureaupage)

## 3AM. A DRAWER GLOWS.

*[ FIELD REPORT · 03:00 ]*

No human triages the ticket. The bureau does. Spec-kit writes the spec. Agents implement. QA writes the missing tests. Code review flags the security bug I would have shipped. Merge when CI is green. I mostly watch.

Operations are not support for the product. They are the product.

Four merged PRs while I sleep is a good night. A private Rust CLI, a few months in.

Below: how it works, what it refuses to do, and how you install it on your own repo in the next twenty minutes.

*Representative session: a tmux session running six bureau agents in parallel — spec, spec-review, implement, qa, code-review and merge — with the merge pane and status bar in hot pink.*

*[ REPRESENTATIVE SESSION · six agents, one ticket in flight ]*

## SEVEN STAGES. ONE STATE MACHINE. LINEAR IS THE MEMORY.

*[ FILE #002 · PIPELINE ]*

Every ticket walks a fixed path through Linear states. Each stage is a bash script running Claude in a dedicated tmux window. State lives in Linear comments and git branches, nowhere else.

### SPEC

- **Input state:** Triage

- **Agent:** spec

- **Output artifact:** spec.md · plan.md · tasks.md

- **Next state:** Spec Review

### SPEC REVIEW

- **Input state:** Spec Review

- **Agent:** spec-review

- **Output artifact:** spec-digest comment

- **Next state:** Build

### DESIGN (opt-in)

- **Input state:** Design

- **Agent:** ux

- **Output artifact:** design notes

- **Next state:** Copy / Build

### COPY (opt-in)

- **Input state:** Copy

- **Agent:** copy

- **Output artifact:** microcopy

- **Next state:** Build

### BUILD

- **Input state:** Build

- **Agent:** implement

- **Output artifact:** feature branch · commits

- **Next state:** QA / Review

### QA (opt-in)

- **Input state:** QA

- **Agent:** qa

- **Output artifact:** missing tests · green suite

- **Next state:** Build Review

### BUILD REVIEW

- **Input state:** Build Review

- **Agent:** code-review

- **Output artifact:** review verdict · needs-human?

- **Next state:** Merge

### MERGE (opt-in)

- **Input state:** Merge

- **Agent:** merge

- **Output artifact:** squash-merge into main

- **Next state:** Done

*Dashed stages are opt-in — toggled per repo in .bureau.json.*

### TWO OPERATING MODES

#### CONTINUOUS

```sh
./scripts/start-bureau-v2.sh
```

Launches the whole tmux mesh. Queue-loops poll Linear every 30 min. Cron-friendly.

#### ON-DEMAND

```sh
./scripts/shepherd.sh --no-tmux EXP-123
```

Runs one ticket end-to-end, sequentially, in the current shell. For when you want to watch.

## SIX RULES THE MAINTAINER REFUSES TO BEND.

*[ FILE #003 · INVARIANTS ]*

These are the invariants in CLAUDE.md. They exist because the pipeline runs in cron, which means every bug it can silently swallow, it will.

### Rule 01 — CLAUDE NEVER TOUCHES LINEAR

Claude never does Linear CRUD. Every state move goes through the helpers in bureau-config.sh.

**Why:** Headless Claude cannot refresh OAuth tokens, so the model is never handed the keys.

### Rule 02 — BRANCHES RESOLVE VIA MARKER COMMENTS

The pipeline finds a ticket's branch through a marker comment, not Linear's branchName field.

**Why:** Linear's branchName does not match speckit's 001-* convention.

### Rule 03 — PRECONDITIONS BEFORE STATE MUTATIONS

Every stage checks its preconditions before it moves state. EXIT traps re-route crashed issues back to Triage.

**Why:** A stage that dies after moving state strands the ticket in a place nothing picks up.

### Rule 04 — EXIT CODES ARE A PROTOCOL

Each stage exits on a documented code. Telegram alerts throttle by (issue, class) per hour.

**Why:** An unthrottled cron loop turns one stuck ticket into a hundred alerts by morning.

### Rule 05 — WORKTREES RESET BETWEEN PICKS

clean -fdx and reset --hard after every stage. No state leaks from one ticket into the next.

**Why:** State bleeding between two tickets is the worst kind of bug to reproduce.

### Rule 06 — THE MERGE GATE IS STRICT

CI-green and base-current are checked independently of GitHub's async mergeStateStatus.

**Why:** Four PRs merged with red CI is what wrote this rule.

> “Main goes red and nobody notices until a developer pulls.”
>
> — the incident that wrote rule #06.

## ~80% FEWER TOKENS PER TICK. THREE FLAGS. INDEPENDENT.

*[ FILE #004 · TOKEN LEDGER ]*

### /goal

Haiku evaluates goal completion after every turn. Bash is not counting commits, so there is no stuck-detector puzzle to solve.

### caveman

Terse prompt discipline that keeps the model out of essay mode.

### Headroom

Context compression. Long sessions do not blow the window.

- **default:** 100%

- **/goal + caveman + Headroom:** ~20%

Each flag is a single JSON edit in .bureau.json. Independent, flippable, one command to roll back. The ~80% figure came from real pipeline ticks against the private Rust CLI over about ten weeks. Your mileage depends on ticket complexity.

## THE BUREAU STOPS ON THINGS IT SHOULDN’T FINISH.

*[ FIELD REPORT · THE INTENTIONAL FLAW ]*

Every ticket has a needs-human label the pipeline is allowed to apply. When code review requests architectural changes, when QA cannot fix the test itself, when the merge gate refuses three times in a row — the ticket parks and a Telegram alert fires. This is not failure. It is the design.

### Bureau pipeline alert

- **Issue:** EXP-491
- **Pipeline:** code-review
- **Exit:** 13
- **Reason:** needs-human

> “That’s how I know when to open my laptop.”

## THE BUREAU IS NOT:

*[ FILE #005 · SCOPE ]*

- A hosted SaaS. No cloud backend. No sign-up. All local, or your own CI.
- A Copilot replacement. No inline completions. This is batch autonomous work, not interactive pairing.
- For greenfield. It needs a repo, a Linear workspace, and enough acceptance-criteria discipline that specs are writable.
- Multi-repo out of the box. One .bureau.json per repo. Parallel pipelines on the same Linear project race.
- A replacement for branch protection. It complements branch protection. It never substitutes for required reviews or status checks.
- A test framework. It runs your tests and writes new ones where coverage is missing. It provides no test infrastructure.
- Lock-in. JSON config, bash scripts, Linear API, GitHub API. Fork it, migrate off it — the config is text.

## THREE COMMANDS TO YOUR FIRST PIPELINE TICK.

*[ FILE #006 · INSTALL ]*

Requires: git · tmux · jq · curl · Claude Code CLI · Linear account · GitHub CLI.

### 01

```sh
git clone https://github.com/KaiaK808/bureau.git ~/.claude/skills/bureau-init
```

*terminal · installs the skill (once per machine)*

### 02

```sh
/mcp
```

*in Claude Code · then authenticate linear-server (once per machine)*

### 03

```sh
cd path/to/your/repo
```

*then run /bureau-init in Claude Code — the 8-phase interactive walk-through in your repo*

### Then, to run continuously

```sh
./scripts/start-bureau-v2.sh
```

*starts the tmux mesh*

```sh
tmux attach -t bureau-v2-$(basename "$PWD")
```

*attach to watch it work*

### TYPICAL FIRST MERGE

- spec-only smoke test — 10–15 min
- end-to-end (spec → PR → merge) — 30–60 min
- varies with ticket complexity

## THE PROOF, SUCH AS IT IS.

*[ FILE #007 · WHAT WE’VE SHIPPED ]*

### RUN AGAINST

- brainhuggers-cli — a private Rust CLI (internal Claude Code fork)

### PERIOD

- April → June 2026 · ~10 weeks of continuous cron

### AGENTS RUNNING

- spec · spec-review · ux · copy · implement · qa · code-review · merge

### OUTCOMES

- 96 PRs merged autonomously
- ~15 needs-human parks (~1 in 7 tickets)
- 0 silent merges into red main

### PUBLIC SINCE

- 2026-07-03

*Counts from the merged-PR history on brainhuggers-cli · April → June 2026.*

Bureau shipped as open source last week. No one else has run it in production yet. You might be the first. That is what the SECURITY.md, the OPERATOR-CHEATSHEET, and the needs-human contract exist for.

## BUREAU IS BUILT BY KAI EBERT AT BRAINHUGGERS.

*[ FILE #008 · CLOSE ]*

20 years shipping code inside agencies (Fork, JvM, Valtech). First open-source repo.

Bureau is one piece of a larger studio bet: the operations are not support for the product. They are the product.

Feedback welcome. Especially on the merge gate and the /goal loop.

- [GitHub](https://github.com/KaiaK808/bureau?utm_source=bureaupage)
- [LinkedIn](https://www.linkedin.com/in/kaiebert/)
- [Email](mailto:hello@brainhuggers.com)

*Delegation, aber ernst gemeint.*
