Release 1.0.0 — one leader, one host, complete
CI / contract (push) Successful in 1m13s
CI / build (push) Successful in 1m36s

Bump bridged to 1.0.0 and add the release notes: the single-leader,
single-host scope is closed — gateway, lifecycle, two-way delivery,
pluggable peers, auth/authz/audit, supervision, CI. Cross-host
federation (CB-308) is the next major line.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ZGgxLQ2VpwZhEYoru8rkf
This commit is contained in:
2026-08-10 20:58:06 +07:00
parent 84081b2bd8
commit 8a549d8610
2 changed files with 120 additions and 1 deletions
+1 -1
View File
@@ -6,7 +6,7 @@
<groupId>dev.ltms</groupId>
<artifactId>bridged</artifactId>
<version>0.1.0-SNAPSHOT</version>
<version>1.0.0</version>
<packaging>jar</packaging>
<name>bridged</name>
+119
View File
@@ -0,0 +1,119 @@
# v1.0.0 — One leader, one host, complete
This is the first release of **`bridged`**.
`bridged` lets one main Claude Code session (the **leader**, on your Pro/Max subscription)
run a team of **workers** — extra Claude Code sessions on a cheaper or local model, and
non-Claude agents too. The leader's own session is never touched: it stays on subscription,
with a clean environment.
**This release finishes a full scope — it does not stop halfway.** The scope is *one leader
on one machine*, running many workers. Everything that setup needs is now built, tested, and
used daily: who-is-who, the subscription line, messages in both directions, worker start and
stop, security, and monitoring. Nothing on the single-machine path is left as a known gap.
This is also how the code is shaped: `PrimaryRegistry` holds exactly **one** leader. Running
across many machines is the next big step (see *What comes next* below) — not a missing piece
of this one.
## One gateway for all messages
- **Everyone talks through the same door.** The leader and every worker connect to the same
MCP server and use only its tools: `bridge_whoami` · `bridge_profiles` · `bridge_spawn` ·
`bridge_list` · `bridge_status` · `bridge_send` · `bridge_reply` · `bridge_ask` ·
`bridge_poll` · `bridge_ack` · `bridge_stop`.
- **You are who your connection says you are.** The bridge finds out who is calling from the
connection itself, never from a name the caller sends. So a worker cannot pretend to be
someone else, and `bridge_whoami` tells each agent its own role — no guessing.
- **The subscription line cannot be crossed.** Only a spawned worker gets
`ANTHROPIC_BASE_URL`; the leader never does. Each worker profile has a list of allowed
model hosts, checked before anything starts.
- **Messages wait for the right moment.** The bridge sends one message per turn, only when
the other side is ready — no hammering a busy agent.
## Worker lifecycle
- **Start → work → stop.** Each worker gets its own git worktree (its own copy of the repo)
with the same setup as the leader — `CLAUDE.md`, skills, hooks — so it commits on its own
branch and opens its own PR. Ready-made playbooks ship in the repo:
`.claude/skills/implementer` and `.claude/skills/reviewer`.
- **Fast failure, not a silent hang.** Starting a worker waits until it is really connected.
If it never connects, you get a clear error (`PeerUnreachableException`) instead of a stuck
send.
- **Workers don't live forever.** Idle workers are cleaned up (`idle_ttl`), long sessions have
a turn limit (`context_cap`), shutdown drains work first, and workers left behind by an old
daemon are found and removed at startup.
- **Predictable placement.** Each worker gets its own tab in a shared worker space, in the
same order every time.
## No reply gets lost
MCP only lets the client call the server, so the bridge could push to a worker but the leader
had to ask for its replies. That gap is now closed on a single machine:
- **Replies are kept, never dropped.** If a reply arrives and nobody is waiting, the bridge
holds it until the leader picks it up.
- **Replies can survive a restart.** With a broker (LavinMQ or RabbitMQ) set up, held replies
live on the broker, so a daemon restart does not lose them — they come back, and repeats are
filtered out by `msgId`. No `broker:` in the config → replies are held in memory instead.
- **The leader gets a tap on the shoulder.** When a reply lands, the bridge nudges the
leader's own pane — only when the leader is free, and only a few times. If the leader is on
another machine, this quietly falls back to pick-up mode; the reply still waits.
- **Workers can ask questions.** With `bridge_ask`, a worker can pause mid-task, ask the
leader something, and continue the *same* task with the answer.
## More than one kind of worker
Workers are started through a small plug-in interface (`PeerLauncher`). Two plug-ins ship:
one for Claude Code and one for **opencode** (tested live against opencode 1.18.5). The
opencode one proves the interface is neutral — it uses nothing Claude-specific. Each worker
only sees the tools its own launcher gives it.
## Security & operations
- **Auth.** Default is `loopback-trust`: only same-machine callers are trusted. Or set a
bearer `token`. Unknown callers count as `ANONYMOUS` — nobody is trusted by accident. If
the config would expose the daemon to the network without a token, it **refuses to start**.
Workers never need the token, so turning auth on cannot lock them out.
- **Rules + audit log.** The role rules are checked on both doors (REST and MCP). A worker
may only act as itself. The audit log is JSON and never contains message text.
- **Monitoring.** `/healthz` for liveness, `/metrics` for Prometheus — no extra libraries.
- **Runs as a service.** launchd (macOS) and systemd (Linux) files are included. If herdr
isn't up yet at boot, the daemon waits up to 30 seconds and then runs in a reduced mode
instead of crash-looping.
- **CI.** Every push builds and tests on the Gitea runner, including the broker test against
a real broker. Only the live-herdr test stays local (`-Pcontract`).
## What you need
Java 25 · Maven · **herdr 0.8.0 (protocol 19)** · optionally LavinMQ or RabbitMQ for
restart-proof replies · macOS (launchd) or Linux (systemd). For TLS, put a reverse proxy in
front — the daemon does not do TLS itself, by design.
## Tested
`mvn clean install` is green at `84081b2`: **399 tests**, coverage **75.6%** of instructions /
**64.5%** of branches. Live end-to-end runs under `e2e/`: a worker asking the leader a
question, one leader running several workers at once on a bug hunt, and a 30-turn
back-and-forth conversation. The bridge is used on itself — worker-run code reviews have led
to real committed fixes in this repo.
## What comes next
The single-machine story is done. The next big step stretches the same rules across machines:
- **Many machines (CB-308).** A leader on machine A with workers on machines B and C — built
on this release's broker layer, with one gateway per machine. The design is written
(`docs/CB-308-Multi-Host-Federation.md`); the open question is trust between machines.
- **Many leaders.** Today the bridge holds exactly one leader. The next idea is a small
council — for example one Claude and one Codex — that can discuss a problem together,
compare answers, and agree on a decision before the work is handed to workers. This needs
leader-to-leader messages and a simple way to settle disagreement, neither of which exists
yet.
- **Third-party launcher plug-ins.** Loading launcher plug-ins from outside the project needs
a trust model first, because a launcher runs with daemon rights and can hand secrets to
workers.
One thing we chose **not** to build, so it isn't read as a gap: the originally planned heavy
message envelope (CB-201). Connection identity already routes every reply to the right place,
so only a small `QUESTION` message kind and a `turn_id` were added.