Bermuda v3.0.0 released! Since v2.0.0: giving a flow run one reader, after a month of watching it park #3481
calicoagent
started this conversation in
Show and tell
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
Looking for feedbacks :)
I posted here on 2026-08-16 about moving scheduled agent sequences out of the agent's head and into a harness. Five weeks and a dozen releases later, most of what changed was not a feature I planned. It was the same failure showing up in three different places, so this is a write-up of that rather than a changelog.
I build and maintain Bermuda, so read this as the author's account, not a review.
The failure
Every step of a flow is a fresh agent that has read nothing but its own prompt. That is deliberate — it is what stops step four inheriting step one's confusion. The cost took a month to become obvious: nobody is holding the shape of the run. So when a step failed, the harness could only do the thing available from outside — stop and wait for a person, at exactly the moment nobody knows why it stopped.
Three answers came out of that, in order.
1. Give the steps somewhere to talk (v2.4.0)
A flow run opens a space of its own and its steps share a thread. The chain still hands the next step one published line; the thread is where everything else a step learned survives it — that the arm64 failure was in the C shim, that the migration had already run, that a fixture does not need rebuilding.
run:steps get$BERMUDA_THREADtoo, so a shell script can post. A finished flow closes its space; a parked one leaves it open for whoever has to look.2. Let a checker hand work back (v2.5.0)
A flow ending in an adversarial reviewer could previously only park. Most of what a reviewer catches is fixable by the step that produced it:
The edge points at the maker, not the checker —
retries: 2onverifyre-reads the same unchanged diff and rejects it twice. Taking the edge invalidates everyresult.jsonin the span, so the checker cannot be handed a verdict from an attempt that never happened, and the retried step's prompt names who rejected it and on which attempt. Only a real verdict loops; a step that died wrote no judgement, and rewriting code because the machine fell over never converges.It stops three ways:
max_loops, a verdict identical to the previous one (loop_stuck), andgotomust point strictly upstream. Spent loops live in the run directory, so nothing that resumes on a clock can quietly refill an exhausted budget.3. Give the run one reader (v2.9.x)
Every flow that runs agents now has an overwatch, declared or not. It is handed the flow as declared, every step's outcome and note, and the artifacts of whatever just went wrong, and answers one question — what should this run do now — as
retry,goto,parkorabort.Two guards matter more than the feature. A declared
on_failedge always wins — it is explicit and it is the author's, and an agent overruling the file is the failure this tool exists to prevent. Andskipis not in the default allow-list, because accepting a failed step and carrying on ends what a flow is for; a flow that wants it says so in the file, and the board prints+skipso the choice is visible without opening anything.The place it earns its keep is where an edge has run out. This loop is not converging and this loop was pointed at the wrong step look identical from inside the loop, and completely different from two steps up.
The records, and why there are four
They differ by time horizon, which is the only reason they are not one thing.
The forum (v2.6.0) is durable, searchable, addressed to nobody in particular — an agent that solves something posts it, an agent that hits the same wall next week finds it, and neither has to be running at the same time. Posting takes no account, search is FTS5-ranked, and there is a read-only web view on
127.0.0.1:8422.Memory (v2.7.0) is one fact per Markdown note in Obsidian's format with a
MEMORY.mdindex and[[wikilinks]]. Bermuda parses none of it — agents read and write with their own file tools.memory init --vaultwires it into a real vault by symlink and refuses, in every branch, to overwrite notes that already exist. Since v3 the whole vault is also semantically searchable, so an agent can ask it a question in its own words instead of grepping.Checklists are the newest: one Markdown checkbox page per piece of work, with
--blocked-on <who>separating "not done yet" from "cannot be done by me". A flow step'scheck:item is seeded before step one and ticked when the step reports ok.Smaller things
about, input, permission posture, ordered steps with the model each will really run on, last run. A flow that does not parse shows the parser's complaint instead of an empty panel.enteron a flow launches it, and a slipped double click that starts an agent spends money there is no undo for.Mhands the mouse back to the terminal for drag-select.Honest bit
v2.0.0 shipped with agent steps that could not run at all — no agent kind, and permission prompts left on, so they parked
blockedafter eight seconds with nobody in the pane to answer. Every unit test and the whole end-to-end suite usedrun:steps, which survive both bugs completely. The feature's headline case was the one path nothing exercised. Since then every release is checked by installing it from GitHub into a bare Ubuntu container and using it as a stranger — 69 checks, 0 failures on the current one.If you want to try it
A plain
go build, so a Go toolchain is the only prerequisite. For the CLI on your$PATH:Note the
/v3. The module path moved at v3.0.0 and every version before it is retracted, so an oldergo getwill not resolve — if you installed from the earlier post, that is why.https://github.com/bon5co/bermuda
Happy to answer questions about any of the above, including the parts that did not work.
All reactions