Skip to content

flume is designed, not built. Its design book holds the design whole.

How it works

A launch names a repository, a kind, a brief, a name and a base. flume makes a place for it, runs the kind’s stages there with a fresh agent each, follows the work until it lands, and then tidies the place. flume runs on one host and launches there.

Field What it names
repository the repository the work changes
kind the list of stages the work runs through: fix, change, question, or a kind the repository or the launch declares
brief what the work is, as the caller wrote it; every stage that asks for it gets it whole
name the work’s name, which names its branch and its place
base the branch the place is cut from and the only one its work lands on: the repository’s shared branch unless the launch names another

A launch may also carry its agents’ settings, the stages that wait on the caller’s word, and a mark the caller finds its places by.

Five callers launch:

Caller Launches
You /launch <brief> in any Claude Code session, or the herdr plugin’s key
millpond an item’s send, as a fix or a change
headwater its fix key, as a fix with the release’s brief
sounding a question, as the place and session of a sounding
crew each unit, chore or fix of a team, as a place of a kind crew carries in the launch, every stage after the first waiting on crew’s word

flume makes a worktree of the repository at <repository>/places/<kind>--<name>, on a branch of its own, <prefix>/<name>, cut from the base’s current revision. The prefix is the kind’s: its own name, unless the kind names another. The repository’s own declaration of what a worktree needs makes it ready, so flume runs whatever the repository names and assumes no tool of its own. Every stage of the work runs in that one place, and the place lasts until the work lands or is dropped.

Three kinds, each a track of stages that end on their deliverablesThree tracks side by side. A fix, on fix/bump-mise from headwater’s fix key: code waits on a new commit, then submit waits on the landing, and the place is tidied. A change, on change/csv-export from millpond’s send: construct waits on the OpenSpec change written; code waits on every task ticked, and its six tasks tick one by one; verify waits on its report; submit waits on the landing, with the change archived; the place is tidied. A question, on sounding/parquet: sounding’s session works, waits on you once, works again, and ends when sounding conclude writes conclusion.md. Each stage starts a fresh agent and lights the next only once its deliverable exists. A repository or a launch may declare kinds of its own in the same form. fix fix/bump-mise launched here by headwater’s fix key code not started agent 1 · working waits on a new commit committed: bump mise submit not started agent 2 · working waits on the landing landed on main then flume tidies it tidied: place and branch change change/csv-export launched here by millpond’s send construct not started agent 1 · working waits on the OpenSpec change the change, written code not started agent 2 · working waits on every task ticked 6 of 6 tasks ticked verify not started agent 3 · working waits on its report report: 0 to fix submit not started agent 4 · working waits on the landing landed, the change archived then flume tidies it tidied: place and branch question sounding/parquet launched here by sounding sounding’s session not started working waiting on you working waits on its conclusion conclusion.md written ends on sounding conclude flume makes the place and runs the session. sounding keeps the question, its rounds and the conclusion you decide. ended on sounding conclude A repository or a launch may declare kinds of its own: each stage names its prompt and its deliverable.
Three kinds, each a track of stages that end on their deliverablesThree tracks side by side. A fix, on fix/bump-mise from headwater’s fix key: code waits on a new commit, then submit waits on the landing, and the place is tidied. A change, on change/csv-export from millpond’s send: construct waits on the OpenSpec change written; code waits on every task ticked, and its six tasks tick one by one; verify waits on its report; submit waits on the landing, with the change archived; the place is tidied. A question, on sounding/parquet: sounding’s session works, waits on you once, works again, and ends when sounding conclude writes conclusion.md. Each stage starts a fresh agent and lights the next only once its deliverable exists. A repository or a launch may declare kinds of its own in the same form. fix fix/bump-mise launched here by headwater’s fix key code not started agent 1 · working waits on a new commit committed: bump mise submit not started agent 2 · working waits on the landing landed on main then flume tidies it tidied: place and branch change change/csv-export launched here by millpond’s send construct not started agent 1 · working waits on the OpenSpec change the change, written code not started agent 2 · working waits on every task ticked 6 of 6 tasks ticked verify not started agent 3 · working waits on its report report: 0 to fix submit not started agent 4 · working waits on the landing landed, the change archived then flume tidies it tidied: place and branch question sounding/parquet launched here by sounding sounding’s session not started working waiting on you working waits on its conclusion conclusion.md written ends on sounding conclude flume makes the place and runs the session; sounding keeps the question and the conclusion you decide. ended on sounding conclude A repository or a launch may declare its own kinds, each stage with its prompt and its deliverable.
Each stage waits on its deliverable, and the next starts only once it exists. A change's tasks tick one by one, each submit stage waits on the landing, and a question waits on you once, through sounding, and ends on sounding conclude.

A kind is a list of stages, and each stage names its prompt and its deliverable:

Kind Stages
fix code, then a submission to sluice
change construct, which writes the OpenSpec change; code, which ticks its tasks; verify; then a submission to sluice
question sounding’s session, which ends on sounding conclude

A repository, or a launch itself, may declare kinds of its own in the same form. The question kind’s branch prefix is sounding/, so a question’s place is a sounding’s, on sounding/<name>. flume makes it and runs the session, and sounding keeps the question, its rounds and the conclusion you decide.

Each stage starts a new agent in a herdr pane, or as a command flume prints for you to run. The agent before it has ended, so no stage inherits another’s conversation, and each starts from its prompt and what the place holds.

The first sending is lost, and the transcript shows it: flume sends the prompt once more and finds it there. Later the pane goes quiet while the checks run; with no deliverable, the stage goes on until the change is committed.

Keys typed into a pane prove nothing about what the agent took. The agent’s transcript records every message it took, so flume reads that:

  1. flume starts the agent and waits until it takes input.
  2. It sends the stage’s prompt.
  3. It reads the transcript for the prompt as a message from the user.
  4. When the transcript lacks it, flume sends the prompt once more and reads again. When the second sending is missing too, flume reports that the stage never began.

Text left typed in a pane is never a stage’s state. A tell, your words to a place’s agent, reaches it the same way: as a prompt the transcript holds, or not at all. flume holds a tell while the agent works and sends it once the agent waits, and refuses it, with nothing typed, when no agent is live or the agent is asking a person a question. A tell never starts, ends or moves a stage.

A stage ends when its deliverable exists, or when its agent stops short and says what it needs. It never ends because its pane went quiet: an agent waiting on a long test run shows nothing in its pane, and its work is not done.

  • When the deliverable exists, flume waits until the agent is quiet, then ends it and starts the next stage, unless that stage waits on its caller’s word.
  • When the agent stops short, no next stage starts. The place waits for a retry or a drop, and the agent’s words reach whoever waits on the stage.

A deliverable takes one of five forms, and counts only when made since its stage started:

Kind Stage Its deliverable
fix code a new commit on the place’s branch
fix submit the landing on its base
change construct the change written, its planning complete, in a new commit
change code every task of the change ticked, in a new commit
change verify its report
change submit the landing, with the change archived
question sounding’s session its conclusion, as a report: conclusion.md
Tidying: flume removes only places it made, and keeps a branch that holds commits main lacksflume looks at three worktrees in turn. fix/bump-mise landed, and its commits are on main: flume removes the place and the branch. change/parquet was dropped holding two commits main lacks: flume removes the place and keeps the branch, and names it. A worktree called spike was made by hand: flume did not make it, and leaves it alone. landed ledger/places/fix--bump-mise main fix/bump-mise what does it hold that main lacks? its commits are on main git cherry main the worktree removed place removed branch removed dropped ledger/places/change--parquet main change/parquet what does it hold that main lacks? 2 commits main lacks git cherry main the worktree removed place removed branch kept, and named made by hand ledger/spike main spike did flume make it? flume did not make it the worktree left alone
Tidying: flume removes only places it made, and keeps a branch that holds commits main lacksflume looks at three worktrees in turn. fix/bump-mise landed, and its commits are on main: flume removes the place and the branch. change/parquet was dropped holding two commits main lacks: flume removes the place and keeps the branch, and names it. A worktree called spike was made by hand: flume did not make it, and leaves it alone. landed ledger/places/fix--bump-mise main fix/bump-mise what does it hold that main lacks? its commits are on main git cherry main the worktree removed place removed branch removed dropped ledger/places/change--parquet main change/parquet what does it hold that main lacks? 2 commits main lacks git cherry main the worktree removed place removed branch kept, and named made by hand ledger/spike main spike did flume make it? flume did not make it the worktree left alone
flume removes the landed fix's place and branch, removes the dropped change's place and keeps its branch, and leaves a worktree made by hand alone.

flume tidies a place once its work lands or is dropped. It removes only places it made. Before it removes a branch, it compares the branch with its base: a branch that holds commits its base lacks stays, and flume names it, so dropping the work never loses a commit.

flume status --json gives each place:

  • its kind and its stage;
  • its agent’s state: working, waiting, asking a person, stopped, or unknown when flume cannot read it;
  • whether the stage’s deliverable exists;
  • its submission.

For a change, flume reads the OpenSpec change’s own files, so the status shows its tasks ticked as the agent ticks them. flume keeps only the live state of the places it runs. An item’s record is millpond’s.

  • The command line: flume launch, status, tell, stop, retry, drop, tidy, and prompt, which shows the prompt a stage would be sent and starts nothing. An agent runs flume needs to stop short.
  • The Claude Code plugin gives every session /launch <brief> and serves status over MCP.
  • The herdr plugin shows every place in flight in the sidebar, with its kind, its stage, its agent’s state and a change’s tasks ticked. Keys open a place’s pane, tell its agent, stop it and retry its stage. A sounding waiting on you shows as a row there too.
flume’s herdr plugin: every place in flight, a place’s pane and status, and the keysA herdr window. Its sidebar lists every place in flight with its kind, its stage and its agent’s state: change/csv-export in code, its tasks ticking from 3 of 6 to 6 of 6 before it moves on to verify; fix/bump-mise in sluice, which lands, is tidied and leaves the list; fix/flaky-test, whose code stage ended short; sounding/parquet, a question waiting on you; and fix/lint-config, working. Beside the selected place’s pane, its status gives the kind, the stage, the agent’s state, the deliverable and the submission. The tell key sends check fields with commas too to change/csv-export: flume holds it while the agent works and sends it once the agent waits, and it reaches the transcript. The open key shows fix/flaky-test, whose agent stopped short asking which CSV its test should read; the retry key starts the stage again with a fresh agent and the words use fixtures/small.csv. The open key shows fix/lint-config, whose agent rewrote the wrong files and waits; the stop key ends it, and the stage waits; the retry key starts it again with a fresh agent and the words one root eslint.config.js. herdr · flume’s plugin IN FLIGHT change/csv-export change · code · working change · verify · working change · verify · waiting change · verify · working 3/6 4/6 5/6 6/6 fix/bump-mise fix · submit · in sluice landed tidied: place and branch gone fix/flaky-test fix · code · ended short fix · code · agent 2 · working sounding/parquet question · waiting on you fix/lint-config fix · code · working fix · code · waiting fix · code · stopped fix · code · agent 2 · working change/csv-export fix/flaky-test fix/lint-config change/csv-export agent 2 · code · tasks.md read the ledger’s rows write rows as CSV quote fields with commas stream large ledgers add the export command test a round trip agent 3 · verify · a fresh agent prompt in its transcript checking the code against the change, task by task your tell, in its transcript checking fields with commas tell change/csv-export check fields with commas too held: the agent is working sent: the agent is waiting agent 1 · code · ended short stopped short, in its words: the test reads a CSV fixture that is not in the repository. Which one should it read? retry fix/flaky-test, with words use fixtures/small.csv agent 2 · code · a fresh agent prompt and your words, received reading fixtures/small.csv the test passes agent 1 · code · waiting rewrote .eslintrc in packages/api; 11 to go agent 1 · code stopped: agent 1 ended the stage waits for a retry retry fix/lint-config, with words one root eslint.config.js agent 2 · code · a fresh agent prompt and your words, received writing eslint.config.js removing 12 .eslintrc files flume status kind change stage code agent working deliverable tasks ticked, not all submission none yet kind change stage verify agent working deliverable no report yet submission none yet kind change stage verify agent waiting deliverable no report yet submission none yet kind change stage verify agent working deliverable no report yet submission none yet kind fix stage code, ended short agent waiting deliverable no commit yet submission none yet kind fix stage code, started 2 times agent working deliverable no commit yet submission none yet kind fix stage code agent waiting deliverable no commit yet submission none yet kind fix stage code, waits on a retry agent stopped deliverable no commit yet submission none yet kind fix stage code, started 2 times agent working deliverable no commit yet submission none yet KEYS open open tell tell stop stop retry retry a place’s pane, beside its status
flume’s herdr plugin: every place in flight, a place’s pane and status, and the keysA herdr window. Its sidebar lists every place in flight with its kind, its stage and its agent’s state: change/csv-export in code, its tasks ticking from 3 of 6 to 6 of 6 before it moves on to verify; fix/bump-mise in sluice, which lands, is tidied and leaves the list; fix/flaky-test, whose code stage ended short; sounding/parquet, a question waiting on you; and fix/lint-config, working. Beside the selected place’s pane, its status gives the kind, the stage, the agent’s state, the deliverable and the submission. The tell key sends check fields with commas too to change/csv-export: flume holds it while the agent works and sends it once the agent waits, and it reaches the transcript. The open key shows fix/flaky-test, whose agent stopped short asking which CSV its test should read; the retry key starts the stage again with a fresh agent and the words use fixtures/small.csv. The open key shows fix/lint-config, whose agent rewrote the wrong files and waits; the stop key ends it, and the stage waits; the retry key starts it again with a fresh agent and the words one root eslint.config.js. herdr · flume’s plugin IN FLIGHT change/csv-export change · code · working change · verify · working change · verify · waiting change · verify · working 3/6 4/6 5/6 6/6 fix/bump-mise fix · submit · in sluice landed tidied: place and branch gone fix/flaky-test fix · code · ended short fix · code · agent 2 · working sounding/parquet question · waiting on you fix/lint-config fix · code · working fix · code · waiting fix · code · stopped fix · code · agent 2 · working change/csv-export fix/flaky-test fix/lint-config change/csv-export agent 2 · code · tasks.md read the ledger’s rows write rows as CSV quote fields with commas stream large ledgers add the export command test a round trip agent 3 · verify · a fresh agent prompt in its transcript checking the code against the change, task by task your tell, in its transcript checking fields with commas tell change/csv-export check fields with commas too held: the agent is working sent: the agent is waiting agent 1 · code · ended short stopped short, in its words: the test reads a CSV fixture that is not in the repository. Which one should it read? retry fix/flaky-test, with words use fixtures/small.csv agent 2 · code · a fresh agent prompt and your words, received reading fixtures/small.csv the test passes agent 1 · code · waiting rewrote .eslintrc in packages/api; 11 to go agent 1 · code stopped: agent 1 ended the stage waits for a retry retry fix/lint-config, with words one root eslint.config.js agent 2 · code · a fresh agent prompt and your words, received writing eslint.config.js removing 12 .eslintrc files flume status kind change stage code agent working deliverable tasks ticked, not all submission none yet kind change stage verify agent working deliverable no report yet submission none yet kind change stage verify agent waiting deliverable no report yet submission none yet kind change stage verify agent working deliverable no report yet submission none yet kind fix stage code, ended short agent waiting deliverable no commit yet submission none yet kind fix stage code, started 2 times agent working deliverable no commit yet submission none yet kind fix stage code agent waiting deliverable no commit yet submission none yet kind fix stage code, waits on a retry agent stopped deliverable no commit yet submission none yet kind fix stage code, started 2 times agent working deliverable no commit yet submission none yet KEYS open open tell tell stop stop retry retry
A tell waits while its agent works and reaches it once the agent waits. retry starts a stage that ended short again, with your words and a fresh agent; stop ends an agent that went the wrong way, and its stage waits for a retry.