Borg
Borg is a shared memory for coding agents. It turns the corrections you give your agent, and your team's written knowledge, into short lessons, and brings each lesson back when a later session, yours or a teammate's, meets the same decision. It runs as hooks in Claude Code and Codex and as extensions in omp (oh-my-pi) and opencode, learns in one plain session with nothing else running, and shares lessons with a team peer to peer, with no server.
Why: an agent forgets a correction when its session ends, so you make the same correction next week, and each teammate makes it again.
- Lesson: what a correction becomes: a question the agent asks itself, the situations where it applies, and the consequence it prevents.
- Drone: one agent session wired to Borg.
- Collective: one memory for a set of repos: shared with a team, private, or off.
- Queen: the queue of decisions no lesson answers yet, asked of you one at a time.
Status: 0.5.0, the first release on crates.io. It removed the hive and playbooks: sessions now message each other instead. In daily use, with lessons syncing between engineers' machines over the mesh, across NATs. Tested on Linux and macOS. Read Evidence and limits before you rely on it.
- Quick start
- How it works in one session
- The team
- Talking to other sessions
- Monitoring
- Cost
- Privacy
- Evidence and limits
- Upgrade and uninstall
- Development
Quick start
|
This installs prebuilt, sha256-checked borg, borg-mesh and borg-web into ~/.local/bin (Linux
x86_64/arm64, macOS on Apple silicon) and runs borg setup. Setup asks which harnesses to wire, which
repos go to a private or team collective and which stay off, fetches the vector model (~490 MB, once),
optionally learns the 50 newest corrections from your past sessions, shows every change, writes nothing
until you confirm, and ends with borg doctor. A second run changes nothing. Then start your agent as
usual:
| Harness | After setup | Notes |
|---|---|---|
| Claude Code | claude |
Every feature. Hooks in ~/.claude/settings.json |
| omp 18.8.5, 18.10.4 | omp |
Live mode needs omp 18.4.4 or newer. adapters/omp |
| opencode 1.18.32, 1.19.0, 2.0.23, 2.0.29 | opencode |
adapters/opencode |
| Codex CLI 0.153.2 | codex, then /hooks once to trust borg's hooks |
Hooks in ~/.codex/hooks.json; borg doctor says when codex skips them. Borg's own model calls need claude, omp or opencode on PATH, or BORG_PREDICT_MODEL=codex:<model> and BORG_LEARN_MODEL=codex:<model>. adapters/codex |
Borg's model steps (learning, the checks) run headless through a logged-in CLI on PATH, the drone's
own harness first (Sonnet by default for claude). Without one, Borg still records episodes and delivers
by word matching, but learns nothing.
Other ways in. install.sh takes --version, --dir and --no-setup after sh -s --. From
crates.io: cargo install borg-ai --locked (plus borg-mesh for a team, borg-web for the page; Rust
1.91+; --no-default-features builds a lean borg without vectors). Setup flags answer its questions for
scripts:
By hand: write ~/.config/borg/collectives.json (Collectives; without
one every repo joins a team collective named default), then borg install all (a dry run) and
borg install all --apply, borg vectors --fetch, and optionally borg assimilate --apply --limit 50.
Intel Macs, the macOS C++ header workaround and source builds: Install.
Reference: How one session learns · Delivery and modes · Commands · Configuration · Team sync · Statistics and the page · Harnesses · Own relay · Evidence · Reports
How it works in one session
Everything in this section works in one plain interactive session, with no team.
flowchart LR
S["corrections, borg no,<br/>review → fix findings,<br/>team documents"] -->|"borg learn at session end"| L[("lessons")]
L -->|"at the prompt: free"| D["drone"]
L -->|"during the turn: live check"| D
L -->|"at the stop: graded call"| D
D --> O["outcomes: changed, ignored,<br/>corrected, vetoed, tested, regretted"]
O --> B["usefulness belief"]
B -->|"ranks and fades"| L
Learning. Borg records an episode when you push back ("no, use a channel") or reject a tool call
with a reason. At session end borg learn makes one model call per episode and writes or updates a
lesson. Team documents become lessons through borg assimilate --from-dir.
Sources of lessons
Delivery. Lessons arrive at three moments. At the prompt or a touched file, free, by word matching
(Claude Code; ratified constraints on every harness). During the turn, in live mode (the default): after
an edit a background check grades the work so far and its questions arrive with the next tool call. At
the stop, a free word gate skips most turns; otherwise one model call grades the eligible lessons, and a
grade 3 blocks the stop for one more round. The same call judges whether what was handed over earlier
changed the work. "mode": "hook" checks only at the stop. Delivery and modes
Outcomes and belief. Every delivery is logged with its probability, and what followed (changed,
ignored, corrected anyway, vetoed, regretted, tested) moves the lesson's usefulness belief. The
Knowledge tab of borg web shows it. Outcomes
Review → fix. A reviewer sub-agent finds a bug and a fix step fixes it before any commit. borg review-fix reads those runs from Claude Code, omp, opencode and Codex at 0 tokens, and each fixed finding
becomes a lesson for the moment of building. On by default. Review → fix
Regret. A later commit that fixes an earlier decision is linked to it (borg why shows both ends).
With BORG_REGRESS=learn the fix becomes a lesson for the decision point; links only, by default. A
regret also counts against the lessons asked before the decision. Decision → fix links
Green tests. When a lesson was asked and the session's own tests then went from red to green, or
passed after the drone changed its work on the point, the lesson gets a tested credit at 0 tokens.
Green tests
borg no <reason> (or a prompt starting "borg no") vetoes what the drone is doing: the
lessons it was shown lose credit, the reason becomes a lesson (learned like a correction), and an invariant in it is proposed as a
constraint you can ratify. Saying no
Memory. Use strengthens a lesson, disuse fades it: about 54 sessions without use make it dormant, never deleted. The clock counts sessions, not days. Memory
The queen holds decisions no lesson answers (open decisions from documents, proposed constraints).
The drone asks you one at a session's first prompt; borg queen lists them.
The queen
The team
Each repo belongs to one collective: team (synced to its members), private ("share": "local",
never leaves the machine) or off (Borg reads and writes nothing). A correction about the code becomes
a team lesson; one about how you like the agent to work goes to your private collective; a repo
convention is delivered only in its repo. Who hears a lesson
flowchart LR
subgraph A["your machine"]
SA["session"] --> TA[("team collective")]
SA --> PA[("private collective")]
end
subgraph B["teammate's machine"]
TB[("team collective")] --> SB["session"]
end
TA <-->|"borg mesh serve: signed lines, peer to peer, encrypted"| TB
Each machine runs borg mesh serve. Peers find each other by key over iroh, through NAT or a relay, and
reconcile append-only files by hash. Hooks only read and write local files, so nothing waits on the mesh.
What syncs and what stays is under Privacy. borg top is a live screen of the team's drones, like Unix top;
borg pause and borg resume hold or release any of them (Talking to other sessions). Set up: borg setup --team <name> or --join <ticket>, or
Team sync; for a company, Company collective.
Talking to other sessions
Sessions in one collective can message each other, whatever harness runs them and whichever member's machine they are on. A session or the engineer's terminal sends:
The recipient is a drone as borg top names it, a session id, local, collective (or all, the
same) or engineer. Local first: local reaches the sessions running on this machine, and a drone or
session id that matches one here names it. A colleague's session is reached by <session>@<node>, when
nothing here matches, or as the sender a reply answers; collective reaches every session of the
collective on every member's machine and may wake them, so it is for what concerns their work. The message is shown once, at the recipient's next prompt or tool call, marked as
peer data rather than the user's words, with the command that replies (borg tell <session> --re <id>).
Text is redacted and cut to 1,000 characters, and one sender may send a recipient one message per 10
minutes. Messages are kept 7 days. One to local stays on this machine; one to collective, to
<session>@<node> or a reply syncs to the team collective's members.
The engineer can also hold a session, or every one:
borg pause local holds this machine's sessions; borg pause collective (or all) every member's.
These are messages too, shown at the next prompt or tool call on every harness, and never rate limited.
From another member's machine they count only if that member has the admin or steer role. A pause
lapses after a day.
A session that is idle sees a message when it next runs, unless it listens. Inside a session:
The opt-in lasts until --off or the session's end.
When its turn ends, borg wakes it in the way its harness allows. On Claude Code the model starts
borg listen --wait in the background. The omp and opencode adapters keep a stream running. On codex a
detached waiter queues a turn with codex queue. The wake names who wrote and how many messages wait,
and the session's next prompt hook shows the messages themselves. Nothing wakes a session while the
engineer's own turn runs. borg top shows who listens in its WAKE column.
Commands
Monitoring
A live page on 127.0.0.1 with tabs for the Overview, Knowledge (every lesson, its belief and state),
Conscience (checks, questions and what they led to per channel), Learning (week by week: lessons per
source, the share of asked lessons that changed the work, repeated vetoes), Steering
(corrections, rejected tool calls, pauses and vetoes, the tool calls a pause refused), Messages (the last
7 days' conversation, sends and refusals), the Queen (open questions, the queen's attention score), Cost and Drones.
It reads the same files as borg top and needs no mesh. In the terminal: borg status (modes, stores, what is wired,
spend), borg doctor (what is broken), borg queen, borg top.
Statistics and the page
Cost
- Most turn ends cost 0 tokens in hook mode: the free gate skipped 78% of 1,117 real turn ends. Early delivery and grade-2 and grade-1 lessons never call a model; they are judged only inside a call a question pays for.
- A turn-end call costs about $0.07 (Sonnet, mean over 67 calls) and takes about 10 s. An extra round happens only for a grade-3 lesson.
- Live mode adds one call per burst of changes: about 8× borg's own spend in hook mode, while whole runs cost about the same (Why live is the default).
- Learning costs about $0.02 per correction (21 lessons from 10 sessions: $0.66).
assimilate --from-dirmakes one call per chunk and prints its cost. Messages,borg no, review → fix, regrets and green tests are found at 0 tokens; a veto's reason or a fixed finding is then learned like any correction. - There is no cost cap:
borg statusand the Cost tab show what each mode spent.
Privacy
Stays on your machine: everything from off repos and private collectives; raw episodes (your exact
corrections), transcripts, the shell output adapters hand to borg, source code, collectives.json,
per-session state.
Goes to team members, for team collectives only, each line signed and dropped on revocation:
lessons (with author emails and repo names); redacted reasoning excerpts of landed commits, each held by
two members; decision → fix links; presence for borg top (harness, email, repo, the redacted first line
of your latest prompt, touched paths); redacted messages between sessions, pauses, resumes and vetoes among them; the signed member list; daily usage counts per
engineer; outcomes with session, repo and regret hashed (BORG_SHARE_OUTCOMES=off keeps them local);
and ratified constraints (the invariant, its lesson and who ratified it, never the veto's words).
A mesh relay sees node ids, IP addresses and traffic volume, never content; run your own to keep even that in-house (Privacy on the mesh, Own relay). The model provider receives what each model step needs: the turn and the eligible lessons, or the episode being learned.
Redaction (redact in crates/borg/src/notes.rs) strips tokens, keys, passwords and .env values from
excerpts and presence. Lessons skip it: the model writes them as general questions, but read
lessons.jsonl before you share a collective that handled secrets.
Hooks fail open. A missing binary, a crash, an invalid config, an unreachable model or a locked index lets the agent continue untouched. A turn-end call that fails ends the turn without questions, a live check that fails asks nothing (the turn end then checks as in hook mode), and unlearned episodes wait for the next run. Time limits
Evidence and limits
Measured, against rules written before each paid run (mostly on the author's and a few colleagues' sessions, so the data is not here):
- lessons at the turn end, 15 real decisions in a sealed sandbox: 25% → 34% engineer points on all 15, +8.8 [−1.4, +22.2], not significant; 34% → 63% on the subgroup of 4 cases with a directly relevant lesson, +29.2 [+4.2, +68.8];
- a memory of 21 lessons from 10 sessions held 21 useful ones; accuracy tied with Hindsight on the same memory model;
- the system gate cut wrong-system deliveries from 83 to 0;
- live mode: not worse than hook (+0.38 criteria per task [0, +0.88], 8 pairs, p = 0.50, directional only: 2 pairs differ; 0 redo rounds).
On although its rule was not met: review → fix lessons, +6.3 points of later bugs avoided [−5.1, +17.9]; the pre-registered rule (an interval excluding 0) failed, and the engineer turned it on so that users who never configure get it.
Rule not met: team documents as lessons, n = 9: +1.7 [+0.8, +2.4] knowledge checks over a plain agent (comparison runs not concurrent), but against a hand-written skill +0.11 [−0.56, +0.78], short of the pre-registered lower bound of −0.5.
Not shown: that Borg helps strangers on public data (SWE-chat: no memory helped, Borg included);
decision → fix precision on real history (so BORG_REGRESS stays links); whether the regret credit
improves the belief (the check was inconclusive: no data yet); the weights of vetoes and green tests. omp,
opencode and Codex get no early delivery of ordinary lessons, and there a live check sees tool calls,
not prose.
Full table, the regret check and every known limit: Evidence and limits.
Upgrade and uninstall
Hooks call the binary by path, so a reinstall needs no rewiring. Codex trusts each hook's command and
timeout: after an upgrade that moves borg or changes a timeout, trust them again with /hooks
(borg doctor says so). Stores are append-only JSONL and need no migration. The mesh protocol is
now borg/mesh/13. A member built from 0.3.0 sources (borg/mesh/12) still syncs everything except messages; nothing syncs
with an older one, and borg doctor names that member and which side has to upgrade.
Uninstall leaves an edited adapter or skill file in place and reports it. Your data stays: delete
~/.local/share/borg and ~/.config/borg to remove it, and git update-ref -d refs/notes/borg in each
repo for the reasoning notes.
Development
| Path | What |
|---|---|
crates/borg |
The product (crate borg-ai, binary and library borg): CLI, hooks, learning, checks, memory, collectives, install, vectors. assets/ holds the skill and the TS adapters it compiles in |
crates/borg-mesh |
Peer sync, membership, presence, admission of pauses and vetoes from other machines (iroh); separate so the hook binary stays small |
crates/borg-trace |
Parses Claude Code and omp transcripts |
crates/borg-web |
borg web, the live page; dist/ is its built Leptos client (ui/), committed |
crates/borg-eval, crates/borg-search, eval/ |
Eval harness and benchmarks; not shipped, use local paths under ~/.local/share/borg/eval/ |
adapters/omp, adapters/opencode |
TypeScript adapters, compiled into borg (borg.ts links to crates/borg/assets/adapters/) |
adapters/codex |
How the Codex hooks are wired and what they miss |
adapters/conformance |
The harness conformance suite (Harnesses: one module per agent behind one trait) |
skills/borg |
The borg skill borg install copies into each harness (a link to crates/borg/assets/skills/borg) |
reports/ |
Measured results |
Contributing: CONTRIBUTING.md. Security reports: SECURITY.md. License: MIT OR Apache-2.0 (LICENSE-MIT, LICENSE-APACHE).