wiki: redraw diagrams — bridged as standalone daemon (SERVER/CLIENT faces + MCP)

Declutter every component diagram to show bridged as ONE standalone daemon
split into a SERVER (north) face — MCP server + REST/SSE + policy brain — and
a CLIENT (south) face — status-gated injector + herdr socket client. Claude
sessions are shown as herdr panes that mount the MCP server (call up) while the
client drives them down over the socket.

- 2-Message-Server: main architecture flowchart rebuilt (herd subgraph of
  panes + bridged subgraph with srv/cli); intro reframed; split-host node label
- 1-Architecture: components diagram — bridged subgraph with SERVER/CLIENT faces
- 6-Team: topology — bridged split into faces + role router; worker bridge_reply
- Home + README: overview flowchart — bridged subgraph with SERVER/CLIENT faces
All 16 mermaid blocks validated with mmdc.
Dai Ha
2026-07-11 15:52:17 +02:00
parent c70d213fcb
commit c71175e1c7
4 changed files with 85 additions and 61 deletions
+16 -10
@@ -33,11 +33,15 @@ flowchart TB
end
subgraph work["SECONDARY worker host — off-subscription"]
BD["bridged<br/>message server<br/>(not a claude process)"]
HERDR["herdr server<br/>panes · agent-status"]
WCC["claude (worker)<br/>ANTHROPIC_BASE_URL set"]
subgraph BD["bridged — standalone daemon (not a claude process)"]
SRV["SERVER face<br/>MCP server · REST/SSE · policy"]
CLI["CLIENT face<br/>herdr socket client"]
SRV --> CLI
end
HERDR["herdr<br/>panes · agent-status"]
WCC["worker pane · claude<br/>ANTHROPIC_BASE_URL set · MCP client"]
HOOK["Stop-hook<br/>long-poll client"]
BD -->|"Unix socket<br/>send_text · events.subscribe"| HERDR
CLI -->|"Unix socket<br/>send_text · events.subscribe"| HERDR
HERDR -->|"drives PTY"| WCC
WCC --- HOOK
end
@@ -45,23 +49,25 @@ flowchart TB
BROKER["Broker<br/>Redis Streams / NATS JetStream<br/>inbox-primary · inbox-worker"]
MODEL["ollama.ltms.dev /v1<br/>or GX10 vLLM<br/>(worker model)"]
OPUS -->|"MCP bridge_send → reply in tool result"| BD
WCC -.->|"MCP bridge_reply / bridge_ask"| BD
BD -.->|"SSE /events (status, for observers)"| OPUS
OPUS -->|"MCP bridge_send → reply in tool result"| SRV
WCC -.->|"MCP bridge_reply / bridge_ask"| SRV
SRV -.->|"SSE status (observers)"| OPUS
OPUS -.->|"write / long-poll (async)"| BROKER
HOOK -.->|"long-poll / write (async)"| BROKER
BD -.->|"bridge inbox ↔ session"| BROKER
SRV -.->|"bridge inbox ↔ session"| BROKER
WCC -->|"inference"| MODEL
classDef sub fill:#2b6cb0,stroke:#1a365d,color:#ffffff;
classDef pick fill:#2f855a,stroke:#22543d,color:#ffffff;
classDef warn fill:#b7791f,stroke:#7b341e,color:#ffffff;
class OPUS sub
class BD,HERDR,WCC pick
class SRV,CLI,HERDR,WCC pick
class BROKER warn
```
*Figure: solid arrows = the blocking request/response `bridged`/herdr channel; dotted = the optional async
*Figure: `bridged` is one **standalone daemon** split into a **SERVER face** (the MCP server
the Claude sessions mount, plus REST/SSE + policy) and a **CLIENT face** (the herdr socket
client). Solid arrows = the blocking MCP request/response channel; dotted = the optional async
broker. The primary's env stays clean; only the worker sets `ANTHROPIC_BASE_URL`, and
`bridged` — a plain daemon — enforces that boundary in code.*
+47 -39
@@ -139,58 +139,66 @@ bridge on either side is subscription-safe by construction (see
## Architecture
`bridged` is the hub. Its **south side** speaks herdr's Unix-socket JSON-RPC; its **north
side** speaks HTTP/SSE to synchronous clients and (optionally) a broker for async duplex.
herdr, `bridged`, the worker panes, and the model endpoint are colocated on the
off-subscription **worker host**; the primary reaches in over HTTP and/or the broker.
`bridged` is a **standalone daemon** — one component, two faces:
- a **SERVER (north face)** — an **MCP server** the Claude Code sessions mount, plus REST/SSE
for non-Claude clients, sitting over the session tracker, subscription guard, and reply
rendezvous (the policy brain); and
- a **CLIENT (south face)** — a herdr socket client that injects turns (status-gated) and
subscribes to agent-status.
The Claude sessions themselves live **as panes inside herdr**. Each pane reaches *up* to
`bridged`'s MCP server (to send/reply); `bridged`'s herdr client reaches *down* through
herdr's socket to drive those same panes and read their status. herdr, `bridged`, the panes,
and the model are colocated on one host (same-host scenario); a broker is optional for async
duplex.
```mermaid
flowchart TB
subgraph clients["NORTH — clients"]
OPUS["Primary Opus<br/>(Claude Code, env CLEAN)<br/>MCP client"]
BUS["External event bus<br/>(webhook / NATS / Redis)"]
HUMAN["Human / CLI / chat UI"]
subgraph herd["herdr — agent multiplexer (Claude sessions run here, same host)"]
PP["primary pane · Opus<br/>env CLEAN · MCP client"]
WP["worker pane(s) · claude<br/>ANTHROPIC_BASE_URL set · MCP client"]
end
subgraph server["bridged — message server (NOT a claude process)"]
API["North API<br/>MCP server · REST · SSE"]
SESS["Session manager<br/>spawn · health · recycle"]
INJ["Injector<br/>queue + status gate"]
COLL["Reply rendezvous<br/>bridge_reply | event | pane.read"]
GUARD["Subscription guard<br/>enforces the boundary"]
HCL["herdr socket client<br/>NDJSON, id-correlated + events"]
API --> SESS --> INJ --> HCL
HCL --> COLL --> API
SESS --> GUARD
HCL -->|"events.subscribe"| INJ
subgraph bridged["bridged — standalone daemon (NOT a claude process)"]
subgraph srv["SERVER — north face"]
MCP["MCP server<br/>bridge_send · reply · ask · status"]
REST["REST / SSE<br/>(non-Claude clients)"]
POL["policy brain<br/>session tracker · subscription guard<br/>· reply rendezvous"]
end
subgraph cli["CLIENT — south face"]
INJ["injector<br/>status-gated"]
HCL["herdr socket client<br/>send_text · events · pane.read"]
end
MCP --> POL
REST --> POL
POL --> INJ --> HCL
HCL -->|"events · replies"| POL
end
BROKER["Broker (optional)<br/>Redis Streams / NATS JetStream<br/>inbox-primary · inbox-worker"]
HERDR["herdr server<br/>workspaces · panes · agent-status"]
WCC["worker claude pane(s)<br/>ANTHROPIC_BASE_URL set<br/>MCP client"]
MODEL["ollama.ltms.dev /v1<br/>or GX10 vLLM"]
MODEL["ollama.ltms.dev / GX10 vLLM<br/>(worker model)"]
BROKER["Broker (optional)<br/>Redis / NATS — async duplex"]
OPUS -->|"MCP: bridge_send / poll / status"| API
BUS -.->|"async"| BROKER
HUMAN --> API
BROKER -.-> API
HCL -->|"Unix socket"| HERDR
HERDR -->|"drives PTY"| WCC
WCC -->|"inference"| MODEL
WCC -.->|"MCP: bridge_reply / bridge_ask"| API
PP -->|"MCP tools"| MCP
WP -->|"MCP tools"| MCP
HCL -->|"Unix socket · drive + status"| herd
WP -->|"inference"| MODEL
POL -.->|"async"| BROKER
classDef core fill:#2f855a,stroke:#22543d,color:#ffffff;
classDef ext fill:#2b6cb0,stroke:#1a365d,color:#ffffff;
classDef warn fill:#b7791f,stroke:#7b341e,color:#ffffff;
class API,SESS,INJ,COLL,GUARD,HCL core
class OPUS ext
class BROKER,HERDR,BUS warn
class MCP,REST,POL,INJ,HCL core
class PP ext
class MODEL,BROKER warn
```
*Figure: `bridged` translates a clean north-side message API into herdr socket calls, gating
every injection on live agent-status events. Only the worker panes carry
`ANTHROPIC_BASE_URL`; `bridged` itself is a plain daemon and may poll/subscribe freely
because it consumes no Anthropic quota.*
*Figure: `bridged` is one standalone daemon with a **SERVER** face (the MCP endpoint the
Claude panes mount, over the policy brain) and a **CLIENT** face (the herdr socket client).
The Claude sessions are herdr **panes**: they call *up* into the MCP server, while `bridged`'s
client drives them *down* through herdr's socket and gates every injection on live
agent-status. Only worker panes carry `ANTHROPIC_BASE_URL`; `bridged` holds no quota, so it
subscribes freely. (Split-host moves the primary out of herdr — see [Deployment model](#deployment-model).)*
### Components
@@ -471,7 +479,7 @@ flowchart LR
end
subgraph host["Worker host (off-subscription, near model)"]
direction TB
BD["bridged<br/>:8080 HTTP/SSE"]
BD["bridged<br/>:8080 MCP · REST/SSE"]
HS["herdr server"]
W2["worker claude pane(s)"]
BD -->|"Unix socket"| HS --> W2
+11 -5
@@ -30,8 +30,12 @@ alike. Scale each kind horizontally by adding panes.
```mermaid
flowchart TB
LEAD["lead — Opus<br/>(Claude Code, env CLEAN)"]
BD["bridged<br/>message server + router"]
LEAD["lead — Opus<br/>(Claude Code, env CLEAN)<br/>MCP client"]
subgraph BD["bridged — standalone daemon"]
SRV["SERVER face<br/>MCP · REST/SSE · role router"]
CLI["CLIENT face<br/>herdr socket"]
SRV --> CLI
end
HERDR["herdr<br/>panes · agent-status"]
WC1["w-claude-1<br/>Sonnet · CLEAN"]
WC2["w-claude-2<br/>Sonnet · CLEAN"]
@@ -40,9 +44,11 @@ flowchart TB
ANT["api.anthropic.com<br/>(Pro/Max)"]
OLL["ollama.ltms.dev<br/>(local model)"]
LEAD -->|"MCP bridge_send (target role)"| BD
BD -->|"Unix socket · send_text · events.subscribe"| HERDR
LEAD -->|"MCP bridge_send (target role)"| SRV
CLI -->|"Unix socket · send_text · events.subscribe"| HERDR
HERDR --> WC1 & WC2 & WL1 & WL2
WC1 -.->|"MCP bridge_reply"| SRV
WL1 -.->|"MCP bridge_reply"| SRV
WC1 --> ANT
WC2 --> ANT
WL1 --> OLL
@@ -52,7 +58,7 @@ flowchart TB
classDef core fill:#2f855a,stroke:#22543d,color:#ffffff;
classDef local fill:#6b46c1,stroke:#44337a,color:#ffffff;
class LEAD,WC1,WC2 ext
class BD,HERDR core
class SRV,CLI,HERDR core
class WL1,WL2 local
```
+11 -7
@@ -22,22 +22,26 @@ env-clean and calls `bridged`'s MCP tools.
```mermaid
flowchart LR
OPUS["Opus — primary<br/>(Claude Code, env CLEAN)"]
BD["bridged<br/>message server<br/>(not a claude process)"]
OPUS["Opus — primary<br/>(Claude Code, env CLEAN)<br/>MCP client"]
subgraph BD["bridged — standalone daemon (not a claude process)"]
SRV["SERVER face<br/>MCP · REST/SSE · policy"]
CLI["CLIENT face<br/>herdr socket"]
SRV --> CLI
end
HERDR["herdr<br/>panes · agent-status"]
W["worker claude<br/>ANTHROPIC_BASE_URL set"]
W["worker claude pane<br/>ANTHROPIC_BASE_URL set<br/>MCP client"]
M["ollama.ltms.dev<br/>(worker model)"]
OPUS -->|"MCP bridge_send (blocks)"| BD
W -.->|"MCP bridge_reply"| BD
BD -->|"Unix socket<br/>send_text · events.subscribe"| HERDR
OPUS -->|"MCP bridge_send (blocks)"| SRV
W -.->|"MCP bridge_reply"| SRV
CLI -->|"Unix socket<br/>send_text · events.subscribe"| HERDR
HERDR -->|"drives PTY"| W
W -->|"inference"| M
classDef ext fill:#2b6cb0,stroke:#1a365d,color:#ffffff;
classDef core fill:#2f855a,stroke:#22543d,color:#ffffff;
class OPUS ext
class BD,HERDR core
class SRV,CLI,HERDR core
```
- **Subscription boundary:** the *primary* never sets `ANTHROPIC_BASE_URL` (stays on