Local-first multi-agent coordination for messages, leases, shared plans, status, and resources.
io.github.anulum/synapse-channel (MCP)
The MCP server “io.github.anulum/synapse-channel” provides local-first multi-agent coordination for messages, leases, shared plans, status, and resources. It is positioned as an orchestration/coordination component for agents, including A2A communication and parallel agent workflows.
🛠️ Key Features
Local-first multi-agent coordination
Message coordination
Leases management
Shared plans coordination
Status coordination
Resources coordination
🚀 Use Cases
Coordinating multiple agents in parallel
Agent-to-agent (A2A) communication
Federated or orchestrated multi-agent systems
Integration into developer tooling via MCP
⚡ Developer Benefits
Supports MCP (“mcp” topic) in a multi-agent context
Fits developer environments including VS Code extensions (topic: “vscode-extension”)
Communicates over WebSocket (topic: “websocket”)
⚠️ Limitations
No additional operational details (e.g., tool set, APIs, transport specifics beyond the stated topics) are provided in the available excerpt.
The local-first coordination bus for fleets of AI agents.
One WebSocket hub is the shared source of truth for presence, file-scope claims, a shared plan, task status, and capabilities — for agents working in one repository or across a whole ecosystem of them.
Flagship example: coordinate parallel AI coding agents through declared file scopes — the hub refuses a second overlapping live claim, while covered provider hooks and the staged Git gate enforce only their documented mutation boundaries.
A local-first coordination bus for a fleet of AI agents working in parallel —
within a single repository or spread across a whole ecosystem of them. One
WebSocket hub is the shared source of truth for presence, work claims,
chat, task status, and resource offers: agents address each other
across projects and share one plan, while file-scope claims keep the agents in any
one repository from receiving overlapping live authority. Documented provider
hooks and the staged Git gate enforce that authority only on their covered
mutation surfaces.
New here? Read Why SYNAPSE CHANNEL — a
five-minute read on what it is, what you build on it, how it differs from the
tools next to it, and why coordination becomes the bottleneck once you run more
than one agent.
Project lineage: SYNAPSE CHANNEL dates back to September 2025.
The bus is transport-light (websockets, plus typing-extensions on Python
3.10), hub-centric by design
(one place owns presence, leases, and history), and runs entirely on the local
machine. Model workers reply on-channel through any OpenAI-compatible endpoint,
including a local Ollama server, with a deterministic rule-based fallback for
offline use.
Your existing agents plug in without new code. Any Model Context Protocol
host — Claude Code, Claude Desktop, Cursor — reaches the bus through the bundled
synapse mcp server, which exposes send, durable inbox, status, claim, release,
handoff, and task verbs as MCP tools plus the board, agents, and resources as
read-only MCP resources. Agents that speak A2A connect through the Agent Card face instead.
The hub itself stays protocol-agnostic and the core install keeps its single
dependency — the MCP and A2A adapters are optional extras (pip install 'synapse-channel[mcp]'). See the MCP guide and the separately
qualified authenticated HTTP profile.
Coordinate declared work and surface collisions: synapse git-init, synapse git-claim,
synapse git-claim-check --staged, synapse task, and syn ack turn work
scope, dependencies, and evidence into shared state instead of side-channel
notes.
Observe the fleet from durable state: synapse who, synapse state,
synapse dashboard, synapse event-query, and observed peer rows show who is
present, what is claimed, what changed, and which peer-hub facts are advisory.
Govern risky actions with evidence: policy checks, approvals, release
receipts, Merkle roots, ACL surfaces, federation, and encryption-key commands
make operator decisions auditable. Governance surfaces report by default;
operators decide what blocks a merge, release, or cross-hub action.
Protect the durable log at rest with optional SQLCipher page encryption
for the live hub event store (plus whole-file AES-GCM envelopes for relay
logs, A2A state, cursors, and archives). See
SQLCipher live event store below.
What it does, surface by surface
Seven shipped coordination surfaces, each named by the command or doc that
delivers it today:
Claim before edit.synapse git-init installs claim-aware Git hooks; synapse git-claim records an exact worktree, branch, and path scope so an overlapping claim can be refused before files diverge.
Block unclaimed native file edits.Provider file-edit claim hooks adapt Claude Code Edit|Write, Codex apply_patch, Gemini CLI replace|write_file, and Kimi Edit|Write to one live-claim decision engine.
Share the plan.synapse task and synapse board keep task state, dependencies, and ready work on the hub instead of in separate agent notes.
Hand work over without an ownership gap.Atomic handoff moves the held task, scope, status, and checkpoint to an online recipient without a release-and-reclaim window.
Expose a dark seat. After 30 continuous seconds without the owner's exact waiter, the hub emits one dark_seat_alert for affected claims or assigned work, including the permanent-arm remedy; it does not release or reassign work automatically.
Read the fleet from one cockpit.synapse dashboard serves the local command centre, exact-status task columns, claims, conflicts, security posture, and an optional durable event feed; the read-only Studio projection adds no new hub authority.
Connect existing agent protocols at the edge.synapse mcp exposes coordination tools and read-only resources over stdio; the A2A bridge exposes a local Agent Card and HTTP+JSON surface while keeping its partial validation boundary explicit.
At a glance
graph LR
A1["Agent"] --> H
A2["Agent"] --> H
A3["Worker"] --> H
SUP["Supervisor"] --> H
H["SynapseHub<br/>single source of truth"] --> CL["Claims & leases<br/>scope · epoch · checkpoint"]
H --> BB["Blackboard<br/>plan + progress"]
H --> CAP["Capabilities<br/>cards + routing"]
H --> LOG["Event log (SQLite WAL)<br/>durable · optional SQLCipher at rest"]
A claim leases a declared unit of work with a file scope, so the hub refuses
overlapping live claims. Provider hooks and the staged Git gate enforce that
authority on their documented surfaces; they do not sandbox every filesystem or
external side effect. Plans, handoffs, checkpoints, and a stall supervisor keep
the work moving, and the durable event log means a hub restart resumes live
leases rather than losing them.
Core and Optional Layers
SYNAPSE CHANNEL ships as one installable package, but the public surface is
tiered so the lean bus stays clear:
Layer
Taxonomy tier
What belongs there
Local coordination core
stable
The hub, send/wait/listen/arm, claims, tasks, locks, status, board, init, and fleet bootstrap commands used for daily coordination.
Edge adapters
adapter
MCP, A2A, git hooks, tmux/provider bridges, shell hooks, ingestion, and worker seats that connect existing tools to the bus.
Operator analysis
analysis
Doctor, state, dashboard, causality, multihub, reliability, trust graph, directory, accounting, fleet scorecard export, manifests, and event queries. These do not mutate coordination state; explicit export modes can write to an operator-selected sink.
The authoritative map is synapse_channel.surface_taxonomy
and the generated operator view is Public surface and stability.
Adapters and lab surfaces can be installed and used from the same package, but
they do not change the single-dependency local core.
Six measurable discovery profiles keep those layers explicit without hiding or
removing commands: first-use, core, adapters, governance, labs, and
all. Inspect any profile without starting a hub or optional process:
The JSON contract records three first-use concepts and three shell commands,
against a hard limit of eight concepts, with zero optional extras and zero
implicitly started persistent services. Profile inspection is read-only;
optional capabilities activate only through their documented package extra and
command or flag, and deactivate by stopping that exact process or omitting the
opt-in. See installation profiles.
Optional Participant memory recall
participant ask, participant exchange, and participant convene can wrap
their seats with bounded, read-only recall from REMANENTIA's lightweight HTTP
API. Recall is disabled unless --memory-url is present; no memory process is
started implicitly. Tokens are accepted only through --memory-token-file, and
recalled snippets enter TurnRequest.context inside a data-only fence while the
operator prompt remains unchanged.
bash
synapse participant ask claude "review this design" \
--memory-url http://127.0.0.1:8001 \
--memory-token-file /run/secrets/remanentia
Current HTTP results omit REMANENTIA's honesty axes, so every recalled hit is
shown as boundary data; similarity is relevance evidence, not truth evidence.
No-hit and unavailable states remain visible without failing the provider turn.
See Participant memory recall for setup, limits,
CLI flags, library use, and audit boundaries.
Coming: Studio — the dashboard is growing into an operator Studio:
a control plane that answers, at a glance, what is happening, what is at risk, and
what is safe to do next. The instrument-panel design system, /studio reference,
live /studio/command shell, security-posture panel, and event-log LiveFeed have
shipped. Local-first and read-only by default — an organisation-level workbench is
planned as a separate layer.
Install
bash
python -m pip install synapse-channel # the release from PyPI
python -m pip install -e ".[dev]"# or an editable dev checkout# optional: live hub event-store page encryption (SQLCipher)
python -m pip install 'synapse-channel[sqlcipher]'# optional: whole-file AES-GCM envelope helpers (encrypt-key profile/migrate/rekey)
python -m pip install 'synapse-channel[encryption]'
For an editable checkout, keep the local .venv aligned with the repository's
declared dev, docs, and benchmark extras:
The second check is offline. It verifies that local preflight still covers the
expected tool gates, GitHub Actions are pinned to full commit SHAs, Dependabot
covers actions/Python/Docker, and the PyPI publish/download metadata surfaces
remain wired.
This installs the synapse command. To run the hub as an always-on local service
or a container, see the deployment guide (a systemd user
unit and docker compose are both included). On Linux, install only a permanent
exact-identity waiter with
synapse arm install --identity myproject/agent --start; it uses mailbox replay
and Restart=always, without installing a hub. Its
myproject/agent-rx receiver can coexist with agent-tmux's distinct
myproject/agent-pane-rx bridge, preserving durable gap recovery and active
pane delivery without name takeover. The pane bridge fails closed on busy,
modal, unknown, or ambiguous provider screens: it persists the pending wake and
submits its fixed prompt only after two provider-specific idle-composer probes.
It acknowledges delivery only after the pane shows prompt consumption; an Enter
ignored during asynchronous provider startup leaves the single staged prompt
pending for a safe Enter-only retry.
It accepts only exact identity, role, or group targets; global priority and CEO
broadcasts remain durable inbox traffic but never inject into provider panes.
For unattended active delivery, supervise that pane bridge independently of
agent turns:
The generated synapse-waker@.service has Restart=always and a main-loop
watchdog, so a dead bridge is recreated without relying on the agent to remember
to re-arm it. waker stop --reason ... first persists an inhibited state and
then stops only the exact bridge; systemd cannot immediately resurrect it, and
the tmux provider terminal is not killed or restarted. Only an explicit
waker resume clears the inhibit.
Native Windows service setup is not
claimed; use WSL with systemd as documented in the deployment guide.
For agent-assisted environment preparation, synapse setup spec, inspect,
plan, authorize, apply, verification-plan, authorize-verification,
and verify expose the packaged synapse-setup.v1
contract. The first three describe requirements, observe the host, and bind a
credential-free target to a non-executable SHA-256 plan. authorize emits a
short-lived envelope for one reviewed plan. Restart authority must match the
exact hub PID observed in that plan; first-start authority carries no PID. On
Linux with systemd-user,
apply re-inspects the target and plan-bound executable generation, atomically
reserves the authorization in a private replay ledger, and may install or start
only the package-owned local hub and exact waiter units. It preserves declared
PIDs, emits a digest-bound receipt, and restores prior unit and service state on
failure. After a successful application, the separate verification transaction
sends one directed canary, requires the exact waiter's durable ACK, restarts
only the authorized hub PID, proves replay through a new hub PID, re-inspects
the bound generation, and preserves declared terminal/provider PIDs. It emits a
single-use, digest-bound verification receipt; an application receipt alone is
not strict end-to-end readiness evidence. Package, Python, identity, secret,
remote, macOS, native Windows, and container changes remain blocked. See
Machine-readable setup for the schema,
expiry, nonce-consumption, and exact-PID authority rules.
Two optional shell conveniences ship with the CLI: synapse completions bash|zsh|fish prints tab completion for every subcommand (generated from the
live parser, so it never drifts), and synapse install-shell-hook adds the
guarded block that auto-arms a wake listener in each new terminal:
bash
synapse completions bash > ~/.local/share/bash-completion/completions/synapse
synapse install-shell-hook # auto-arm Bash, Zsh, and Fish terminals
Who it's for
A developer running two or three coding agents on one repository, tired of
merge collisions and duplicated work.
A team operating a fleet of agents across several services that needs one
plan, one roster, and cross-repository task dependencies.
A builder of long-running autonomous agents who wants event-driven
wakeups, durable coordination, and a resume-after-restart story instead of a
polling loop and lost state.
See use cases for when it fits, when it is overkill, and
who reaches for it.
Getting started
The one path to follow. Run the three-command self-contained proof below,
then follow the multi-seat golden path
for persistent agents. Optional adapters and generated workspaces come later.
First 60 seconds
On a clean Python environment, verify the installed CLI before wiring agents into
a real repository:
synapse doctor reports local setup issues such as identity, hub exposure,
root-filesystem pressure, and missing waiters. A brand-new machine may warn that
no hub or waiter is running; that is expected before service setup. synapse demo starts its own local hub, drives a planner/worker coordination flow, and
succeeds when it prints:
The CLAUDE and CODEX names in that flow are scripted in-process
SynapseAgent identities. The demo launches no provider CLI and spends no model
turn.
text
success: coordination demo completed
After the self-contained proof, synapse quickstart-coding remains available as
an optional generated-workspace demo. It creates a temporary coding-fleet
workspace, runs the live overlapping-claim refusal demo, removes the workspace
after success, and prints:
text
success: coding fleet demo completed
Or run the whole first-run sequence as one command:
bash
synapse fleet-init
It runs the doctor (--fix to repair the default local hub and waiter),
scaffolds a persistent ./synapse-fleet workspace, probes which provider CLIs
this machine can seat (claude, codex, kimi, ollama, …), runs the demo smoke,
and prints the next-steps plan — waiter arming, per-provider seat commands,
git-init, dashboard — with the workspace's project name filled in.
Fastest safe trial path
Use one self-contained path before changing a real checkout:
The demo starts and stops its own local hub, uses a disposable committed Git
repository, proves separate claims and overlapping-claim refusal, denies a
mutation before handoff, permits it after handoff, and writes an observed
verification receipt plus a static dashboard. It needs no persistent hub,
provider CLI, Git hook, MCP host, or A2A bridge. The same exact three-command
block is regression-bound across this README, the quick start, and the CLI
reference, and its synapse demo command is exercised as a real subprocess.
After that proof passes, use synapse fleet-init --fix to prepare a persistent
local workspace, hub, and waiter, then run synapse git-init --name trial-agent inside the real repository before an agent edits it. Optional A2A
interoperability is a follow-on in the A2A bridge guide; it is
not a prerequisite for first coordination value.
Releases
This package is developed in the open and dogfooded daily: a fleet of coding
agents runs its own coordination on it, so problems surface in real use and are
fixed quickly. Releases are therefore frequent and mostly small — fixes and
hardening rather than churn. Current 0.x releases do not promise backward
compatibility across minor releases. The wire vocabulary and public Python API
are guarded against accidental drift, but a reviewed 0.x minor release may
deliberately change either surface. Every such change updates the frozen
contract tests, bumps WIRE_PROTOCOL_VERSION for a wire-incompatible change,
and ships changelog plus migration notes. Starting with 1.0.0, a breaking
stable public Python API change requires a package major release; a breaking
wire change requires a wire-protocol version bump. See
API and wire stability.
1.0.0 is planned as the first stable commercial release of SYNAPSE CHANNEL,
with the operational contracts, packaging, support surface, and commercial
licensing terms documented as part of that release.
SYNAPSE CHANNEL is seeking startup funding, strategic partners, and aligned
ecosystem co-owners who want to help mature the coordination layer for
production multi-agent development. See commercial licensing
or write to protoscience@anulum.li.
If you need a fixed target, pin a version (synapse-channel==X.Y.Z); to get the
latest fixes, track the newest release. Both are supported.
Usage
Run a hub with model workers
Launch a hub plus one or two local model workers in one command:
bash
synapse team
If Ollama isn't running, synapse team falls back to a single offline
rule-based worker (deterministic canned replies) so the flow still works; start
Ollama and re-run for real model replies.
Then, from another terminal, watch the channel or send a message:
bash
synapse listen --name USER # terminal A: watch the channel as USER
synapse send --target FAST "what is the status of TASK-1?"# terminal B: one-shot, unique ephemeral sender
synapse send --require-recipient --target FAST "ping"# also print the positive receipt
A send without --name uses a unique ephemeral sender, so a one-shot send
never trips the hub's one-owner-per-name rule against a listener you already
have connected under the same name. One-shot sends also avoid the waiter-name
collision: synapse send --name api-dev-rx ... sends as api-dev, leaving the
persistent api-dev-rx wake
socket connected. Directed sends request a private receipt by default and exit
non-zero when no consume-live recipient matches — including when a stale socket
is still connected but has neither a recent reaction nor a live waiter. The
message remains journalled and best-effort routed, while the hub records a dead
letter instead of reporting socket presence as delivery. Each one-shot send
uses a unique message identity and accepts only its matching receipt, so an old
pending receipt replayed when the sender reconnects cannot be reported as the
new send's result. Add
--require-recipient to also print a positive receipt. A matching positive
receipt exits 0; an explicit negative receipt exits 1. A missing receipt,
including from an older hub, exits 3 and prints delivery unknown with the
message identity. --receipt-timeout bounds send and confirmation together
(default 2 seconds, finite, greater than 0, at most 300). Check the preserved hub
journal before retrying an unknown send: the recipient may already have received
it. The CLI never retransmits automatically. Broadcasts and channel sends without
--require-recipient report submission rather than confirmed delivery. No receipt
proves that a model read or acted on the message.
For selected sensitive payloads, encrypt the body before it reaches the hub and
decrypt it only on the recipient side:
bash
synapse send --target FAST \
--encrypt-key-file ./payload.key \
--encrypt-key-id project-main-v1 \
--encrypt-recipient FAST \
"private handoff note"
synapse listen --name FAST --for FAST --decrypt-key-file ./payload.key
The hub still sees sender, target, channel id, key id, recipient names, nonce,
ciphertext, and delivery metadata. This does not manage key discovery or
rotation.
Running pieces individually
bash
synapse hub --port 8876
synapse hub --port 8876 --db ./synapse.db # crash-safe: resumes leases + history on restart
synapse hub --port 8876 --relay-log ./feed.ndjson # mirror the channel to a compact file for observers
synapse hub --shutdown-close-timeout 5 # bound active socket close handshakes on stop
synapse hub --max-progress-per-author 500 # cap retained board progress per author
synapse hub --max-findings-per-agent 200 # cap durable findings admitted per agent
synapse hub --tls-certfile ./hub.crt --tls-keyfile ./hub.key # native wss://
synapse worker --name FAST --provider ollama --model gemma3:4b
synapse worker --name OFFLINE --provider rule # no network, canned replies
synapse worker --name TIER --provider tiered --model small --heavy-model big # route trivial→rule, hard→heavy
synapse relay ./feed.ndjson # decode and print that file as readable lines
synapse ingest ./synapse.db --memory --cursor ./mem.cursor # stream durable memory events since a seq cursor (NDJSON)
synapse memory-recall ./synapse.db "transport handoff"# local recall over durable memory records
synapse compact ./synapse.db --all --max-checkpoints-per-task 3 --archive-report ./compact-report.html
synapse board # print the shared task/progress blackboard
synapse task declare BUILD --title "compile" --idem-key build-v1 # retry-safe durable write
synapse task update BUILD --status done# mark a plan task done so dependents unblock
syn ack BUILD --evidence "pytest -q"# post evidence and mark a board task done
synapse supervisor --idle-seconds 300 --history-multiplier 3 # re-offer stalled plan tasks
synapse manifest # print capability cards, including contract counts
synapse capability-card keygen --key-id PROJECT:worker:v1 --private-out ./card.pem --agent PROJECT/worker --project PROJECT --trust ./card-trust.json
synapse directory # print discovery-only agents/resources
synapse route-task BUILD --limit 3 --event-store ./synapse.db # add observed evidence
synapse resource-bids BUILD --resource-kind gpu # rank live resource offers without reserving capacity
synapse a2a-card --endpoint-url https://agent.example.com/a2a/v1 # emit A2A Agent Card JSON
synapse a2a-serve --endpoint-url http://127.0.0.1:8877 # run the HTTP+JSON A2A bridge
synapse doctor # check for common misconfigs (identity, exposure, hub, waiter)
synapse demo # installed self-check: local hub + planner/worker flow
synapse quickstart-coding # create a temporary coding fleet workspace and run it
synapse new coding-fleet ./demo-fleet # scaffold a runnable two-agent coding demo workspace
synapse hub --host 0.0.0.0 --token s3cret # require a shared secret when binding off-loopback
synapse hub --host 0.0.0.0 --token s3cret --tls-certfile ./hub.crt --tls-keyfile ./hub.key
synapse hub --max-connections-per-host 4 # cap simultaneous sockets from one remote host
synapse send --token s3cret --name USER "hello"# agents present the token to a secured hub
Python embedders can configure a hub with HubConfig and use
SynapseHub.from_config(config). The explicit composition factory also supports
substituting complete collaborator families; see embedding a hub.
CLI hub queries and task writes return 0 only after a matching reply.
Missing replies return 1 with an unconfirmed-outcome diagnostic. A write may
already have committed: inspect synapse board and retain the same --idem-key
and unchanged request for any explicit retry. The CLI never retries a timed-out
write automatically. See query confirmation.
For an observed cross-hub task revision, task declare and task update also
accept --causal-parent HUB_ID:SEQ:SHA256. The SHA-256 is the complete event
fingerprint exposed in multi-hub board provenance. A verified same-task parent
lets the observed fold discard only that proven ancestor; a missing or
mismatched reference remains unresolved and never becomes a concurrency claim.
This metadata changes the advisory observed board, not local claim authority.
Malformed parent metadata is privately refused before a task write is committed.
Validation retains authored reasons; unexpected parser faults return fixed text.
The board stays unchanged, and a corrected request may reuse its retry key.
Use it with your coding agent
Synapse coordinates the agents you already run; it does not replace them.
Its MCP and A2A adapters are interop surfaces: they let Claude Code, Claude
Desktop, Cursor, Codex, Copilot-style hosts, Aider, orchestration frameworks,
and other agent tools participate in one local coordination bus while those
tools still own prompting, model choice, tool use, and editor/runtime behavior.
The integration demo matrix lists three narrow,
repeatable paths and the unsupported behavior that remains outside each demo.
Claude Code / Codex / Claude Desktop / Cursor (MCP): register the stdio
server and its coordination tools load automatically — no shell hook or
Synapse-specific client code.
Claude Code can instead use the optional, separately versioned
Synapse plugin, which packages this MCP face with
the existing claim-aware edit hook and reversible profile onboarding.
The vendor compatibility watch checks official
releases daily and records which host versions have actually been verified.
Vendor and provider discovery reviews bounded
public candidate feeds weekly before an integration is considered. Its host
intake rejects the reviewed Pages download lure and does not rank cron pushes
as code provenance.
The host integration catalog reports accepted
versions and provides one inspect/install/diagnose/uninstall entry point for
the host packages whose lifecycle has been verified.
The optional pi participant uses pinned pi 0.86.0 RPC. Its
separate extension checks live claims before supported file writes; the
default participant runs without tools.
Cursor and Claude Desktop can reuse the secret-free
examples/mcp/.mcp.json template. MCP does not wake
an idle provider in this adapter; call synapse_inbox at turn start and keep
synapse arm install --identity NAME --start active for prompt delivery.
Claude Code / Codex / Gemini / Grok / Kimi native file edits: print a
provider-native pre-tool recipe (PreToolUse for the Claude family,
Grok, and Kimi; BeforeTool for Gemini CLI) that checks the authoritative live
claim before a supported file tool runs.
--print-config is read-only. Save the Grok fragment under
~/.grok/hooks/*.json; synapse adapters install grok separately installs
the kebab-case ~/.grok/skills/synapse/SKILL.md coordination skill. Kimi's
opt-in installer writes only one marked block in
$KIMI_CODE_HOME/config.toml (default ~/.kimi-code/config.toml), and
--uninstall-config removes only that block. The equivalent combined Kimi
path is synapse adapters install kimi --identity my-repo/kimi --with-hook.
The provider claim-hook guide documents exact tool
coverage, token-file setup, and the native-host limits. These are bounded file
guards, not complete Bash or filesystem isolation.
Aider, or any non-MCP tool: claim a file scope before editing and let a git
hook release it on commit. The claim prevents conflicting grants; enforcement
of the tool's working-tree writes remains the operator's responsibility, with
the staged Git gate providing a separate commit-time check.
bash
synapse quickstart-coding # optional: run a temporary overlapping-claim refusal demo
synapse new coding-fleet ./demo-fleet # optional: keep the generated workspace
synapse git-init --name aider-1 # one step: install the hooks + write the conventions guide
synapse git-claim --task-id AUTH --paths src/auth --name aider-1
aider src/auth/*.py # ... edit; the post-commit hook releases the claim
Check the wiring:synapse doctor reports the common setup mistakes — no live
waiter, a hub exposed without a token, an accidental identity, or a pressured
root filesystem — each with its fix. With a durable hub it also reports
N undelivered messages pending for <identity> from the receiver watermark;
this is mailbox transport acknowledgement, not proof a model processed the
messages. Use --disk-path <path> to check the filesystem that holds a
specific workspace or cache.
Inspect the live board:synapse dashboard --port 8765 opens a
loopback-only read-only HTML view of roster, exact blackboard/claim status
columns, progress,
fleet visibility, task-dependency graph edges, branch-conflict candidates,
release receipts, and advertised capabilities, with the same snapshot
available at /snapshot.json for local tooling. Pass --a2a-state-file <path>
to add persisted A2A task and push-config counts to the fleet section. The
dashboard derives task dependencies from the blackboard snapshot and uses live
claim metadata for branch conflicts; run synapse conflicts --check-diff when
you need client-side git-diff refinement. The state snapshot also carries
dead_letters — directed chats that reached no live connection, per target
with counts — so a message nobody is listening for shows up on the page
instead of being discovered by a human relaying it. The dashboard is growing
into an operator Studio — open /studio for the
design-system reference — and ships a React cockpit under clients/cockpit/
(build instructions in its README; serve the
built bundle with synapse dashboard --cockpit-dist clients/cockpit/dist).
If you deliberately expose the
dashboard with --allow-non-loopback, pass --dashboard-token <token> and
require clients to send Authorization: Bearer <token>; the React cockpit
loads its token-free static shell, asks for that bearer, and retains it only
in the tab's session storage. It never accepts the bearer in a URL. When the
token is omitted on an exposed bind, Synapse generates and prints a startup
token. Teams can instead pass an owner-only
--dashboard-access-file mapping separate viewer/operator/admin token files
to browser principals and distinct relay identities. The server-authored
capability descriptor removes unauthorized write controls from the DOM and
command search, but every POST is still re-authorized server-side and at the
hub; admin currently gains no mutation beyond the three shipped operator
writes. With --operator, the authorized command palette exposes governed
message, task-declaration, and task-update forms; each reports the hub's
strict outcome and grants no authority beyond the hub's validation, ACL, rate
limit, and audit decision. With --feeds-db, the cockpit's Audit tab incrementally renders the
universal receipt ledger and governed operator-relay history as two distinct,
bounded store-attested feeds. The receipt ledger includes minimized claim and
guard denials, dead-letter escalations, identity-pin reclaim and identity-key
enrolment outcomes, with approval and application kept distinct;
every declared durable EventKind is explicitly classified as receipt-bearing or
intentionally omitted. Absence and stale last-good data remain visible.
Durable-feed storage and encoding failures return a fixed HTTP 503;
internal diagnostics stay in server logs, and a later request can recover
after the store is repaired. The live durable-feed channels use the same
failure detail. See the cockpit recovery guide.
Add
--observed-peer HUB=URI to include advisory peer-hub rows in the browser and
/snapshot.json; those rows are labelled observed@HUB and never grant local
claims.
Verify a release redeploy:synapse doctor --redeploy-checklist prints
package, service, roster, durable-state, and git-hook checks for a post-release
local fleet restart. It does not restart services by itself, and restart
commands are withheld by default. After inspecting the exact live hub PID and
roster, an operator with fresh disruption authority can add
--redeploy-authorize-restart-pid PID; the rendered command rechecks that PID
while holding a fail-fast host-local custody lock. Dogfooding requires every
new release tag to be adopted by the local hub immediately after publication,
using that bounded authorised path and post-restart health verification.
Install the always-on local services:synapse init prints or installs the
hub, project presence, and non-LLM wake listener units. doctor --fix prints
the exact commands when a waiter is missing.
Launch a provider command with Synapse identity:worker-session exports
the identity variables before the provider starts. Interactive terminal
providers such as Codex, Claude, Kimi, and Grok run in a persistent tmux
session by default when launched from an interactive terminal, with a directed
waiter kept alive in the background. Non-terminal commands keep the temporary
syn arm sidecar path.
Inspect or control the tmux wake path manually:codex-tmux is the
diagnostic/admin surface behind the automatic provider launch path. It keeps a
provider TUI in a named tmux session and injects a fixed wake prompt when
Synapse receives a directed message. It does not paste the Synapse payload into
the terminal; the provider reads the inbox itself after waking. Existing
sessions are accepted only when their live tmux environment matches the
configured SYN_PROJECT and exact SYN_IDENTITY; a session already owned by
another seat is refused by start, status, and wake before any keys are sent.
A successful tmux send-keys call is not treated as provider delivery: the
bridge observes prompt consumption and retains an unacknowledged staged prompt
for a later Enter-only retry, so provider startup cannot strand or duplicate it.
While waiting, the bridge disconnects at a bounded interval and re-proves the
session, binding, and live agent pane before registering again, so a vanished
pane cannot remain advertised indefinitely.
For unattended operation, replace the manually maintained wait process with
synapse waker install --identity myrepo/codex-main --session myrepo-codex --cwd "$PWD" --agent-command codex --start. The waker supervises only the
delivery bridge and attaches to the existing bound session; it never owns the
provider terminal lifecycle.
Agent ergonomics — the syn commands
For the short loop an agent runs every session — arm a waiter, send a message,
read the inbox, glance at the board — the package also ships syn, a thin,
identity-correct front end over the commands above:
bash
syn name # resolve and print this terminal's identity
syn arm # keep a directed-only waiter armed (named <project>-rx, distinct from the sender)
syn say REMANENTIA,CEO "ack"# send to one, several, or all
syn ask CEO "status?"# send, require an online recipient, and wait for replies
syn inbox # print messages addressed to you since the cursor
syn inbox --source hub --uri ws://127.0.0.1:8876 # read the connected hub journal
syn inbox --project-wide # explicitly include every identity in this project
syn inbox --name PROJ/role # read one exact identity under its own cursor
syn board # the shared task/progress board
syn who --me # show whether this identity and its -rx waiter are online
syn reap # list this identity's shell-hook waiter pidfile
syn reap --pid 1234 # remove a dead pidfile or SIGTERM only the verified waiter PID
syn locks # list this project's active leases with release commands
syn ack BUILD --evidence "pytest -q" --artifact coverage.xml
syn commit README.md -m "document the change"
The one thing it gets right that a hand-rolled shell alias does not is identity.
The project is resolved from --project, then $SYN_PROJECT, and the working
directory only as a last resort. Ambient $SYN_IDENTITY is never a silent
source: it refines the identity to a full project/<type>-<id> only when
$SYN_PROJECT is also set and agrees with it — the pair the shell hook exports
together is the opt-in. A SYN_IDENTITY standing alone or disagreeing (the
borrowed-shell signature) is dropped out loud: the command proceeds as the local
identity and says so, or refuses entirely when the local fallback also looks
accidental (the home directory, a system path). Set $SYN_PROJECT once per
terminal and the identity is stable across tool calls.
syn inbox filters on that full resolved identity and advances a cursor named for
that identity. It never falls back to a shared project cursor. Use
--project-wide when the broader project feed is intentional, --name PROJ/name
for another exact address, or repeat --as PROJ/name to drain standing role
addresses under independent cursors. A bare --as PROJ is the explicit
project-wide alias form; $SYN_ALIASES supplies the same standing alias list.
For a remote hub, select syn inbox --source hub --uri ENDPOINT or set
SYN_INBOX_SOURCE=hub for the CLI or MCP adapter. This reads authenticated
journal pages with independent endpoint and identity cursors instead of a
stale local feed. Repeat while has_more is true; an unavailable result
is not an empty inbox. Hub mode treats aliases as exact identities and
excludes channel-tagged chat. See remote inbox.
On the hub side the waiter identity is protected by a name-ownership lease:
the first synapse wait/arm for a name is granted an opaque token (persisted
under ~/synapse/owner-lease/), every re-arm presents it and re-takes its own
name, and a stranger claiming the name — takeover flag or not — is refused with
close code 4016 until the lease lapses (--lease-offline-ttl, default one
hour offline). Beneath the lease sits a zero-config machine identity: the
first connect provisions a per-machine Ed25519 key, the hub pins each signed
name to it on first use (durable across hub restarts, --identity-pins), and
a claim from any other machine is refused until the operator clears the pin.
One name, one owner, across reconnects and restarts.
While the hub is running, it also watches every unexpired claim and assigned
non-terminal board task. If that exact owner has no fresh -rx waiter for 30
continuous seconds, the hub broadcasts one machine-readable dark_seat_alert
with the affected work and the exact permanent-arm command. Re-arming clears the
episode; the monitor never releases or reassigns work on its own.
Hyphenated aliases
(syn-name/syn-wait/syn-say/syn-ask/syn-inbox/syn-board/syn-reap/syn-locks/syn-ack/syn-commit)
are installed too.
Command
What it does
The detail it gets right
syn name
Resolve and print this terminal's identity.
Same resolution order every syn command uses — what it prints is what you coordinate as.
syn arm
Keep a persistent directed-only waiter armed.
Connects as the -rx sidecar (never steals the sender name); announces exactly whose messages it wakes on; stays armed across many wakes.
syn-wait
The wake primitive: wait for one directed message, print it, exit.
Defaults to --max-wakes 1 so a harness that re-invokes on background-task exit is actually woken; self-healing reconnect means a hub restart re-arms transparently and only a real wake ends the wait.
syn say
Send to one, several, or all.
Sends as the owner identity even when a waiter holds the -rx name.
syn ask
Send and wait for replies.
Requires an online recipient — a question never silently addresses nobody.
syn inbox
Print messages addressed to you.
Defaults to the exact resolved identity and its own cursor, so another terminal's mail is neither displayed nor consumed; broader project scope requires --project-wide.
syn board
The shared task/progress board.
One view of the plan every agent sees.
syn who --me
Presence of this identity and its waiters.
Reports the identity separately from durable -rx and active -pane-rx sidecars, because receiver sockets are not agents.
syn locks
Active leases for the project.
Prints holder, scope, age, remaining TTL, checkpoint/git context, and the exact synapse release <task> --name <owner> command.
syn reap
Clean up shell-hook waiter sidecars.
Inspects only this identity's pidfile and refuses to signal a PID unless its live command line verifies as that exact waiter — it never pattern-kills.
syn ack TASK
Post evidence and close a board task.
Repeatable --evidence/--artifact land as an assessment note authored by the resolved identity; waits for hub confirmation before marking done.
syn commit
Lease-guarded, pathspec-scoped commit.
Holds the project git lease and stages/commits only the requested paths, so a co-agent's staged files stay out of your commit.
Two follow-ons complete that loop. Adding --mailbox to synapse arm also wakes
the waiter on directed messages that arrived while it was disconnected — the
reconnect or re-arm gap — by asking the hub to replay them on connect, resuming
from a per-identity cursor under ~/synapse/mailbox-cursor/ so a re-arm does not
replay the whole backlog (off by default; needs a wire version 2 hub).
Within each mailbox wake, repeated copies of the same durable hub/sequence
pair print once. Separate events with identical text still print separately;
legacy frames without a valid positive sequence remain visible. The waiter
joins its connection cleanup before persisting the surfaced cursor.
Agent-tmux uses a distinct <identity>-pane-rx receiver, so the mailbox arm can
stay online beside live pane injection without either sidecar taking over the
other's name. synapse release can attach a hub-echoed receipt with evidence, artifacts,
changed files, approvals, known failures, confidence, and evidence freshness; the
receipt carries advisory epistemic_status metadata (supported,
needs_freshness, stale, degraded, or unsupported) with reasons derived
from the submitted evidence, and --receipt-json prints it for automation.
A fresh manual release verifies exact-confirmation support before mutation.
An unsupported or unresponsive hub returns 1 with no release sent and keeps
the claim held; published hubs 0.48.0 and 0.99.27 require a matching hub upgrade.
Manual release bounds each send/reply exchange with --reply-timeout (30 seconds
by default). A missing acknowledgement returns 3 (outcome unknown), prints the
original operation key and SHA-256 fingerprint, and provides a --confirm-only
command that reads the exact durable result without another release. A valid
matching grant or durable confirmation returns 0; explicit refusal or invalid
local input returns 1. Lease absence and legacy replies cannot supply that
proof. See release recovery for journal and compatibility boundaries.
To make fresh terminals connect automatically, install the shell hook once:
bash
synapse install-shell-hook --shell auto
New Bash/Fish/Zsh terminals then export SYN_PROJECT/SYN_IDENTITY and keep a
cheap synapse arm sidecar running. The hook does not silently join whatever
git checkout the terminal happens to start in. It joins the neutral
SYNAPSE_DEFAULT_PROJECT lane, or user when unset, unless you explicitly set
SYN_PROJECT/SYN_IDENTITY or opt a repository in with .synapse/project:
For legacy CWD-derived behavior, set SYNAPSE_AUTO_PROJECT_FROM_CWD=1 in that
terminal. The hook also wraps common provider commands (codex, claude,
kimi, grok, gemini, agent, ask, ollama) through synapse worker-session, so cloud and local LLM sessions inherit the same Synapse
identity from process start. In an interactive terminal, Codex/Claude/Kimi/Grok
launch through a persistent tmux session and directed wake bridge automatically;
the user still types only the provider command. Set SYNAPSE_PROVIDER_TMUX=0 to
keep those providers on the direct execution path, or SYNAPSE_AUTO_CONNECT=0 to
disable the hook for a terminal.
Durability
Passing --db backs the hub with an append-only SQLite event log (standard
library, WAL mode). Claims, releases, task updates, resource offers, task-board
writes, and chat messages are recorded, and the hub rebuilds its state by
replaying the log on start-up. The guarantee is split honestly by workload:
keyed covered coordination mutations commit their event, canonical request
digest, exact response, and evidence intent together at synchronous=FULL
(durable across an OS crash); the high-volume chat/history path commits at
synchronous=NORMAL (durable across an application crash, may lose the last
commit on power loss).
If store initialization fails, SQLite and SQLCipher connections close before
the error reaches the caller, including interrupted initialization. Existing
event rows remain available for diagnosis; incompatible schemas still refuse
startup. This cleanup does not make schema migration atomic. See
failed database startup.
Native Agent Evidence Format (AEF) v0.1 emission is an explicit opt-in on top
of that durable log. Generate an owner-only Ed25519 receipt key, give the hub a
stable identity, and enable the route:
Supported evidence rows and their AEF outbox cursor commit in one SQLite
transaction. Before serving, the hub reconciles every pending cursor; while
serving, a dedicated worker drains new rows in order (default cadence one
second, configurable with --aef-drain-interval). A crash after receipt
emission but before acknowledgement reuses the verified receipt rather than
emitting a duplicate. A failed drain leaves the durable cursor pending and
retries; legacy rows and their historical Merkle serialization are never
rewritten or merged with the native AEF chain. Without --aef-signing-key, the
hub retains its legacy-only posture.
Use synapse compact to bound the durable memory spine after every read-side
consumer has advanced past a floor sequence. Add --archive-report when the
maintenance run should leave an operator-readable HTML record of the
pre-compaction event snapshot:
The report is written owner-only and includes event counts, the compaction floor,
checkpoint/finding removal counts, board tasks, release receipt notes, and a
bounded coordination timeline. It is an audit aid for a local event store; it
does not certify that release evidence is sufficient.
SQLCipher live event store (at rest)
SQLCipher completes the at-rest encryption story for the live hub. The
default install stays dependency-free and uses ordinary SQLite. When you need
page-level confidentiality for the durable coordination log while the hub holds
it open, install the optional extra and pass an owner-only key file:
multihub observe --db-key-file; MCP tools take event_store_key_file for route observations and memory recall
Complementary whole-file envelopes (optional [encryption] extra) protect
relay logs, A2A state files, cursors, and archives with AES-256-GCM via
synapse encrypt-key profile|migrate|rekey|backup|restore. They do not
replace page encryption for a live open SQLite database — that is SQLCipher's
job.
Honest limits: SQLCipher does not protect hub RAM, does not replace filesystem
permissions or connect authentication, and is not multi-tenant isolation. Stock
installs without [sqlcipher] refuse --db-key-file with an install hint.
--relay-log mirrors every broadcast to a newline-delimited file in a compact
short-key form (encode_lite), so a token-budgeted agent can watch the channel
by tailing a file instead of holding a socket. synapse relay <file> decodes it
back to readable lines and can resume from a saved --cursor. Version 2 retains
structured JSON payloads and every auxiliary envelope field under a compact
extension mapping; the decoder remains compatible with existing version-1 logs.
Timestamps retain millisecond precision, and --relay-max-lines bounds the file.
A committed benchmark compares the same full field set in wire, minified, and
lite forms — see benchmarks/.
Exposure
By default the hub binds to loopback and runs with no authentication — the right
posture for one operator on one machine. When that is not enough (a worker with
tool-use, or a hub bound off-loopback), --token requires a shared secret that
connecting agents present with --token. Binding off loopback without a token is
refused rather than silently exposed: the hub will not start unless you set a
token (and --metrics-token when metrics are on), or explicitly pass
--insecure-off-loopback to accept the risk. This is a proportionate gate, not a
cryptographic identity system.
For native wss://, pass both --tls-certfile and --tls-keyfile. TLS protects
the transport but does not replace --token; an off-loopback hub still needs the
shared secret unless you explicitly opt into --insecure-off-loopback. Off
loopback TLS is also required, not just recommended: a token presented over
plaintext ws:// off loopback is refused (the token and every frame would be
readable on the wire), so add native TLS or a wss:// proxy — or pass
--insecure-off-loopback to accept the risk on a trusted LAN.
MCP server face
Any MCP-compatible agent — Claude Desktop, Claude Code, an editor assistant —
coordinates through Synapse with no Synapse-specific code. Install the optional
extra and register the host in one command:
The default synapse mcp runs a Model Context Protocol server over stdio that is itself a hub
client, exposing send, bounded durable inbox, status, claim, release, handoff,
and plan updates as MCP tools, with the board, state, and manifest as live
resources. It also exposes read-only resource templates for a single board task,
one agent, and one resource kind. The bridge derives a visible project identity
when --name is omitted, but concurrent clients should pin distinct names. It
does not wake an idle provider; the permanent waiter remains a separate path.
Unexpected inbox and advisory storage failures return fixed diagnostics;
cursor-write failures retain the original cursor and allow a retry after recovery.
For a private remote client, synapse mcp --transport streamable-http uses
direct TLS, provisioned subject-to-seat grants and bounded project-scoped
actions. The HTTP guide documents the verified Inspector CLI
surface; this does not establish desktop or cloud application compatibility.
The hub stays MCP-agnostic and the core install keeps feature libraries optional — see
the MCP guide.
Discovery, advisory routing, and memory
Every surface in this group is advisory by design: it prints ranked,
provenance-tagged evidence for a human or an agent to act on, and none of it
claims work, reserves capacity, mutates the board, or turns a capability card
into executable trust.
Surface
What it prints or serves
Where its authority ends
synapse a2a-card
The live capability manifest projected as an A2A Agent Card JSON document, ready for a thin HTTP edge to serve as /.well-known/agent-card.json.
Discovery metadata only.
synapse a2a-conformance
The local support matrix against the A2A 1.0.0 operation model — supported, partial, unsupported, and external rows.
Visible from the installed package; not an external conformance claim.
synapse directory
The capability manifest joined with live resource offers into a discovery-only directory.
Routing hints and review evidence; no reservation, authorisation, or trust certification.
synapse route-task
Candidate agents for a board task, ranked by deterministic local signals; with --event-store it adds positive release-receipt notes as observed evidence, each tied to its source task and durable event sequence.
Does not claim work, mutate the board, reserve resources, or grade agents.
synapse resource-bids
Resource offers ranked with deterministic reasons: kind, capacity, task-class/skill matches, description and name overlap, metadata.
A marketplace-style view only; nothing is reserved or authorised.
synapse memory-recall
Provenance-preserving recall over durable findings, checkpoints, and handoffs: source sequence, event kind, task id, actor, matched tokens.
Reads only the local event store; no external embeddings, no service, no truth certification.
Capability cards can also carry declarative capability contracts: per-task-class
input_schema and output_schema mappings plus optional preconditions and
postconditions — discovery metadata for routing and review, not a grant of
executable trust.
They can now carry a domain-separated Ed25519 signature from a separate
card-signing key. synapse capability-card keygen|sign|verify manages the local
profile; worker --capability-card-key ... signs live advertisements and
hub --capability-card-trust ... verifies them. Every projection exposes an
explicit result, including valid, missing_signature, key/signature/expiry
failures, replay, downgrade, binding, digest, and history-capacity failures.
Verification remains advisory and unsigned cards remain compatible. History is
bounded and in memory by default; hub --capability-card-history-db FILE adds an
owner-only SQLite replay/downgrade floor across hub restarts and fails visibly as
history_unavailable when it cannot commit lifecycle state.
Official Go client
clients/go/synapse provides the official Go client for read-only ops and CI
tools. It fetches HTTP JSON surfaces such as synapse dashboard/snapshot.json
through DashboardSnapshot or GetJSON, with optional bearer authentication
for dashboard tokens on exposed HTTP surfaces.
It does not implement the WebSocket mutation protocol for claims, chat, board
writes, release receipts, or presence. See the Go client guide.
Official TypeScript/JavaScript client
clients/js provides the official typed WebSocket client, published to npm as
@anulum/synapse-channel. Unlike the read-only Go client it speaks the mutation
protocol — chat, claims, releases, board reads, presence, and receipts — and runs
unchanged in the browser and in Node 20+ with no runtime dependencies. See the
TypeScript/JavaScript client guide.
The opt-in scoped attachment API transfers small
project-local evidence through signed, bounded WebSocket frames. The Hub keeps
bytes in private local storage; hashes alone grant no access, and large
datasets or weights remain on owner-controlled artifact storage. A source can
separately permit an exact recipient hub, scope, digest and expiry through its
private peer read API;
each metadata or chunk request rechecks peer trust and the owner's current grant.
A2A HTTP bridge
synapse a2a-serve --endpoint-url ... runs the Agent2Agent edge directly — an
intentionally local-first HTTP+JSON bridge:
Serves the public Agent Card; forwards POST /message:send text/data/file
parts into SYNAPSE chat; supports immediate POST /message:stream
Server-Sent Events; exposes bridge-local task list/get/cancel and
push-notification configuration routes; exposes authenticated task-scoped,
credential-free push-delivery evidence; accepts JSON-RPC 2.0 on /rpc.
Operational bounds: Bearer auth plus request size/depth limits, durable task
state with --state-file, stale-task failure with --task-timeout, one
bounded subscription wait with --subscribe-timeout, plus a fixed bounded
three-attempt webhook retry schedule whose exhaustion dead-letters delivery
without rewriting the stored task transition.
Bearer custody: prefer owner-only --a2a-token-file PATH on serving and
outbound commands. Explicit --a2a-token remains a process-visible
compatibility override. Outbound clients refuse bearer-over-HTTP except to a
literal loopback IP unless --a2a-allow-insecure-http accepts the risk.
Task correlation travels in structured chat metadata (a2aTaskId,
a2aContextId) — the bridge never appends or trusts inline markers in chat
text, so user-authored message bodies stay data rather than task selectors.
Safety posture: owner-only state/temp files, unsafe caller ids and webhook
targets rejected (including delivery-time DNS or redirect targets that
resolve to local networks), bounded task/history/artifact/replay retention
with terminal-task GC, and subscription replay only from the current bridge
process.
Independent validation now includes an official a2a-sdk==1.1.0
discovery/send/get/list/cancel lifecycle and an official A2A TCK HTTP+JSON MUST
run (55 passed, 5 structured-response failures, 175 skipped). That is partial
interoperability evidence, not certification or full conformance: structured
artifact/direct Message scenarios, an outbound external-server pass, public
webhook and proxy/TLS receipts, durable replay, and operator deployment
sign-off remain open. Validation stays a track of reproducible
validation receipts — discovery, task
lifecycle, webhook, proxy/TLS, replay, and threat-model — rather than one
score. The installed support matrix is available with
synapse a2a-conformance and in the
A2A conformance matrix; exposed deployments should
also follow the A2A deployment threat model.
Git-native claims
A claim can be scoped to the git branch it happens on, resolved client-side:
bash
synapse git-init --name project/agent # persist exact identity/URI + install release hooks
synapse git-claim TASK-1 --paths src/auth.py # or: synapse git-claim --task-id TASK-1 ...
synapse git-claim-check --staged # fail unless this owner covers the staged index
synapse git-claim TASK-2 --diff-base main # optional [semantic] extra narrows safe edits to symbols
synapse git-hook install # (git-init already does this) auto-release on commit/merge
synapse conflicts --check-diff # predict cross-branch merge conflicts
Around those claims sits a family of security and governance profiles. Each
one is documented with an honest status — what runs today, and what each layer
explicitly does not claim:
Strict multi-seat production umbrella: composes --team-secure and --paranoid, then bounds per-agent (100/s), per-host (500/s), and per-host-connection (10) flood limits. Fails closed listing all missing material at once; a stricter operator limit is kept; one consolidated report.
Without --secure, fills disabled flood limits when the hub starts exposed (off-loopback bind, connect token, multi-seat intent, or bridge). Both flags default off; multi-seat is also inferred from trust-profile material. Operators running A2A/MCP against the hub should pass --bridge-exposed.
Runtime seat count and bridge process discovery are not automatic.
Machine-key trust-on-first-use pins when cryptography is installed; operator identity bundles; project namespaces; deny-by-default verb/target ACLs including mailbox and role-claim.
Automated credential lifecycle, read-surface ACLs, owner recovery, and full multi-tenant IAM.
Separate Ed25519 card keys and scoped trust bundles; strict canonical signing; expiry, revocation, binding, digest, and replay/downgrade diagnostics; optional owner-only SQLite history across hub restarts; projection through manifests, directories, dashboards, MCP resources, and Agent Cards.
Authorising tools; replacing per-message auth or signed events; sandboxing agents; managed key distribution; enforced admission.
synapse git-init records the exact identity and hub URI in local Git config,
optionally records a token-file path (never token content), installs only the
non-blocking post-commit/post-merge auto-release hooks, and writes a short
.synapse/git-claims.md guide. This repository separately wires
git-claim-check --staged into pre-commit: it reads the NUL-delimited Git index
itself and fails closed unless the configured owner has editable claims covering
every staged path on the same canonical worktree and branch. For semantic
claims it resolves HEAD versus the index and checks the exact tree-sitter
declarations touched; incomplete evidence widens to a whole-file requirement,
and parser failure denies. A Git serialization lock is not a path claim. An
empty staged index succeeds without a hub so
pre-commit run --all-files remains hermetic. synapse state shows each claim's
branch, while synapse conflicts flags agents about to edit the same files on
branches that merge into the same base.
--check-diff narrows directory or whole-worktree claims to files both branches
actually changed when both branch diffs are available.
With the optional semantic extra, --check-semantic further compares named
declarations on pinned revisions. Enclosing declarations overlap their members;
unavailable or ambiguous evidence retains a warning. A missing hub snapshot
returns an error. This committed-diff view neither reserves work nor proves
behavioural independence or a conflict-free merge. The hub stays
git-agnostic — it stores the branch as opaque metadata and never runs git or
reads a filesystem — so all git work is on the client. See the
git-native claims guide.
For a concise lease view while coordinating a session:
bash
syn locks # current project only
syn locks --all # every active lease
syn locks --owner api # one owner or project namespace
When a manual release is also the closeout record, attach the evidence directly:
When closeout evidence should be observed rather than hand-entered,
synapse verify-release runs declared commands, records exit codes and
stdout/stderr SHA-256 digests, hashes named artifacts, captures Git HEAD,
tree, and changed files, then writes receipt JSON for synapse release --receipt:
The resulting supported status remains advisory: it describes fresh submitted
evidence, not independent proof that the checks or artifacts are sufficient.
For safer task selection and release receipts, the local test ownership map
connects source files to likely owning tests using AST imports plus a
conservative filename fallback:
The command prints --paths ... arguments for synapse git-claim and can also
emit JSON for release tooling. It is a deterministic coordination aid; the
owning generator, such as python tools/capability_manifest.py --check, remains
the freshness check for the generated artefact itself.
For semantic task scopes, resolve modules, public symbols, API surfaces, tests,
generated artefacts, migrations, or source paths into ordinary claim paths:
For a symbol or API selector, the resolver prints a synthetic descendant such as
src/synapse_channel/core/receipts.py/.synapse-symbol/build_release_receipt;
likely owning tests and generated outputs remain whole-file companions. Module,
source, test, generated, and migration selectors also remain whole-file. The hub
uses its existing path ancestry rule: different functions can coexist, while a
class, whole-file, or parent-directory claim still conflicts with every symbol
below it.
For daily claims, synapse git-claim can resolve the same selectors directly:
The command resolves the current git root locally, expands the selector into
canonical claim paths, and writes receipt-ready selector evidence when requested.
To infer scopes from an actual tracked diff, install the optional local parser
bundle and claim from a base revision:
bash
pip install 'synapse-channel[semantic]'
python tools/semantic_diff_claims.py --base main --claim-args
synapse git-claim TASK-WORKER \
--diff-base main \
--diff-path src/synapse_channel/core/worker.py \
--semantic-evidence-json semantic-evidence.json
The client maps zero-context hunks on both old and new source sides to the
smallest named Python, JavaScript/JSX, TypeScript/TSX, Rust, Go, Java, C#, or Ruby declaration.
Renames claim both symbol names. Add/delete/rename statuses, module-level edits,
unsupported or invalid syntax, oversized sources, and every other incomplete
mapping widen to the whole file. Grammar wheels are installed with the extra;
there is no runtime download, new wire field, or hub-side Git access. The JSON is
planning evidence, not a correctness proof.
Semantic scopes are enforced end to end on the client. Precise provider edits
(Edit/replace/search_replace-style tools) may provisionally use a symbol
claim only when no competing owner holds another symbol in that physical source
and worktree. Whole-file writes and patch tools require whole-file claims. The
staged gate proves the exact index symbols before commit, while auto-release
repeats the committed diff and releases only the symbol actually changed.
Ambiguous or unavailable semantic evidence fails closed at the staged gate and
retains the claim at non-blocking post-commit release. Use isolated Git
worktrees for concurrent sibling-symbol edits.
Before merge or handoff, the import graph merge-risk radar compares changed
files with claimed paths, package-local Python import neighbours, CODEOWNERS,
and mapped test owners:
Use --base main --head HEAD instead of --changed to read a local branch diff,
or --claims-json claims.json to feed paths from an external claim snapshot.
The radar is an advisory local planning check; it predicts likely contention but
does not replace tests, review, or release receipt evidence.
For post-hoc coordination forensics, query the durable event log directly:
This temporal event-log query path is read-only. It reconstructs task timelines,
task state at a sequence or timestamp, path-touch windows, and historical
file-scope conflicts from the SQLite event store created by synapse hub --db.
The Datalog-like and Cypher-like examples are prototype aliases for the same
small query model, not a separate graph database or mutable policy engine.
Use synapse postmortem ./synapse.db TASK-1 when a task needs a replayable
postmortem for a handover or incident note. The report includes the durable task
timeline, owners, releases, assessment evidence, reconstructed path-overlap
conflicts, and candidate unanswered messages. Candidate unanswered messages mean
the log contains a directed chat mentioning the task id and no later matching
chat reply; it is an audit signal, not proof of intent.
Use synapse debug ./synapse.db --fork-at 142 to rewind a task in the log and
inspect a what-if. It reconstructs the exact claim state — owner, status, paths,
and the saved resume checkpoint — that the task held at that sequence, then prints
the resume manifest an agent would pick up from there (with --set FIELD=VALUE
overriding a resume field) next to the events that really followed. The hub runs
no task, so this is read-only inspection, not re-execution; it exits 1 when the
task held no live claim at that point.
Use synapse reproduce ./synapse.db TASK-1 to fingerprint a task's authoritative
history into a portable SHA-256 digest. Hub state is a pure fold of an append-only
log, so the same claim snapshots and releases replay to the same digest on every
machine; --expect DIGEST turns it into a gate that fails on any divergence, the
way a release receipt is verified.
Use synapse causality causes ./synapse.db 142 to trace coordination causality
over the log. It folds the durable events into a directed acyclic graph of three
recorded relations — a task's own lifecycle, a declared depends_on satisfied by
the dependency's completion, and a release that let a later, path-overlapping
claim proceed — and answers against an event sequence: causes for what preceded
it, effects for what it enabled, and counterfactual for the downstream events
that would lose their recorded cause without it. This is coordination causality
inferred from recorded scheduling semantics, not statistical causal discovery;
every edge is backed by a concrete event, and the counterfactual is a structural
what-if over the inferred graph. With --peer HUB=PATH the same queries trace
causality across federated hubs: the logs merge in the deterministic
multi-hub order, events are addressed as HUB:SEQ, and an edge whose endpoints
two different hubs authored is tagged federation — clock-ordered evidence,
since hubs share no sequence, and observe-only like the multi-hub read side;
--clock-skew HUB=SECONDS annotates offline federated reports with measured
local-minus-peer skew warnings, and --dot renders the federated answer as a
Graphviz digraph, one cluster per hub with federation edges coloured, so the
cross-hub topology is visible at a glance.
synapse causality otel projects the graph onto OpenTelemetry spans — one
trace per task, cross-task dependency/contention edges as span links, ids
deterministic — written as JSON (--out) or pushed as real OTLP over HTTP
(--endpoint, optional extra: pip install 'synapse-channel[otel]');
--service-name distinguishes hubs sharing one observability tenant,
--filter TASK_ID narrows the projection to named tasks without truncating
their cross-task links, an event recording the lifecycle failure terminal
projects span status ERROR, and --watch re-exports on a fixed cadence —
idempotent collector-side thanks to the deterministic ids. synapse causality health walks the same graph and flags orphaned claims (claimed, then
silence), declared dependencies that never completed, and unreleased claims
silent past a threshold — ages measured against the log's own final
timestamp, deterministic and replayable; exit 1 signals an anomaly.
Use synapse merkle root ./synapse.db to commit the durable log to a single
Merkle root — a 32-byte fingerprint of every event, so two operators or two
federated hubs holding the same log derive the same root and a mismatch proves
they differ. synapse merkle prove ./synapse.db 142 emits an O(log n)
inclusion proof for one event, and synapse merkle verify proof.json checks that
proof offline against a trusted root with no event store — the light-client
verification a follower runs. The tree follows RFC 6962 (Certificate
Transparency), so a leaf hash cannot be forged as an interior node. It commits
what the log contains — integrity and inclusion — complementing reproduce (a
per-task digest) with a log-wide, incrementally provable commitment.
A hub with a journal also persists that commitment as a hash-chained checkpoint
OUTSIDE the log — an owner-only <db>.checkpoint.db beside it — and verifies
the log against the newest link before serving: a tail-truncated or replaced
log is a hard AntiRollbackError at startup, not a quiet restart, and a
verified tip is anchored as the next chain link. While serving it anchors every
--checkpoint-interval seconds (default 60) and again at a clean stop, so writes
made after start are covered too; only the last interval before a crash is
unanchored. synapse merkle checkpoint ./synapse.db shows the newest link, and --verify re-checks the log against
it (exit 0 clean, 2 on detection). This is the local anti-rollback layer;
external witnessing stays owner-gated. An intentional rewrite such as
synapse compact trips the detector by design; the operator remedy is to
remove the checkpoint store and let the hub anchor a fresh chain.
Use synapse reliability ./synapse.db for evidence-only reliability memory. It
tracks stale claims, declared failed-check evidence, broken handoff candidates,
and merge-conflict frequency as audit signals, not scores. It does not rank
agents, assign trust grades, or replace review of the underlying event rows.
Use synapse accounting for opt-in model cost/token usage. Synapse never calls a
model provider and collects no telemetry, so usage exists only when you record
it: synapse accounting record posts a usage-kind progress note, and synapse accounting report ./synapse.db aggregates those notes into per-agent and
per-model totals, with optional --pricing for cost estimates and --budget for
budget evidence. Budgets are evidence, not an enforcement gate.
Use synapse fleet-scorecard ./synapse.db --out fleet-scorecard.json to compose
the existing causality spans, opt-in accounting, advisory claim contention, and
evidence-only reliability report into one atomic owner-only JSON bundle.
--trend bench-trend.db includes the full host-context-labelled benchmark
history. With the optional otel extra, replace --out with
--endpoint http://127.0.0.1:4318: the command pushes traces and current
scorecard gauges to the collector's standard HTTP signal paths. It does not
collect usage, rank agents, pre-empt claims, or pretend that current gauges
backfill historical benchmark timestamps.
Use synapse approval for human-in-the-loop approval gates on held tasks or
policy-gated releases. synapse approval request puts a subject in
awaiting_approval, synapse approval decide --approve|--reject records the
decision, and synapse approval status ./synapse.db replays the notes into the
current state per subject (the latest event wins, so a re-request re-opens the
gate). It is advisory evidence and an audit trail, not a hard runtime gate; an
approved subject can be cited in a release receipt via synapse release --approval.
Use synapse attention to project pending approvals,
failed delivery, recovery and optional private quota freshness into one
owner-local queue. synapse attention list distinguishes a quiet queue from
a missing observer; snooze and resolution affect only the alert, never the
underlying approval or delivery. The authenticated cockpit can read the same
queue when synapse dashboard --attention-store names its database. Generic
desktop summaries require an explicit --desktop opt-in.
The agent trust graph connects those reliability
signals, positive release receipts, handoff outcomes, and conflict history
into an inspectable evidence graph: synapse trust-graph ./synapse.db prints
typed evidence edges with event-log provenance, filtered by --agent,
--task, or a --since decay window, as text, JSON, or Graphviz DOT. It does
not rank agents, assign trust grades, authorize execution, replace code
review, or replace identity and ACL; the routing integration and the
owner-annotation workflow remain design targets.
The federated trust model has an opt-in runtime:
deny-by-default peer policy and lifecycle stores, signed-frame authorisation,
guarded multi-hub paths, and federation offer/fetch/import/list/rotate/revoke
bundle workflows. Operators still establish trust out-of-band by comparing
fingerprints; there is no automatic trust distribution, certificate authority,
or external federation certification, and the local-first default is unchanged.
The Agent Air Traffic Control architecture
names how the shipped parts compose into one control loop — separation (claims),
merge-risk radar (conflicts), evidence-gated completion (receipts, policy-check,
approval), post-incident replay (postmortem, reliability), and memory (the ingest
seam). It is an architecture, not a scheduler: only claims gate a mutation, and
everything else is read-only or advisory.
The shipped cross-agent adapter kits expose
synapse adapters to detect installed coding tools and write a thin claim-aware
adapter into each tool's native config. Kimi Code supports both its user-level
kimi skill (under $KIMI_CODE_HOME) and an explicit higher-priority
kimi-project skill; its native claim hook is a separate opt-in. Python-framework
shims remain a documented thin-client pattern. Adapters carry only "claim before
edit, release on commit, reach the hub" — Synapse stays persona-neutral and adds
no new coordination primitive.
The multi-hub sync (CRDT) research asks whether several
hubs could synchronise state while keeping claim safety and local-first. Its
honest core: an honest append-only event log with unique (hub_id, seq) identities
converges, but conflicting content for one identity fails closed before state or cursor
publication and quarantines the peer. Claims are mutual exclusion and not a CRDT — they are
routed by single-owner-per-namespace and fail closed on a partition. The shipped
surface is operator-managed peering: synapse multihub follow and
--observed-peer HUB=URI views observe peer logs as advisory observed@HUB
state; local claim authority remains local or explicitly routed to the owning
hub. Agents on two hubs can talk directly: with synapse hub --message-peer HUB_ID=URI a chat or delivery intent addressed to PROJECT/seat@HUB_ID is
forwarded over pinned mutual TLS to that peer. The peer must grant the target's
namespace. Chats are retried from a durable outbox until answered or expired,
and the peer deduplicates retries so a chat is queued there only once
(protocol).
Overlapping initial and retry attempts share one exchange per forward; other
chats remain independent. Terminal receipts are coalesced and stay pending for
an offline sender's next registration, including after restart.
A stopped durable watcher can record explicit recovery with
synapse multihub recover only after an operator accepts a new log generation or
checkpoint; reconnect alone never clears quarantine. Network observed-peer pulls also carry cursor lag and peer welcome-frame
clock skew, so operators can see when timestamp-ordered cross-hub evidence
depends on clocks outside their configured agreement.
The sandboxed tools and marketplace research
asks what it would take to run untrusted tool code safely — a capability-limited
WebAssembly sandbox (deny-by-default filesystem, network, and resources) — and
only then a marketplace built on signed capability cards, an explicit permission
manifest, and run receipts. No untrusted code runs without the sandbox, and no
executable marketplace ships before all the preconditions exist. The sandbox ships
behind the optional [wasm] extra, while signed capability cards, the permission
model, and bounded run receipts supply the other runtime prerequisites; the
WASM sandbox getting-started guide walks an
operator from a tool's source through validate, test, and run. The marketplace
distribution layer remains a boundary specification — local-first and deny-by-default
throughout.
The managed GitHub App design pins the boundary for
hosted cross-PR conflict prediction: the prediction itself reuses the existing
local-core conflict finder, while everything that makes it managed — webhooks,
GitHub auth, checks API, hosting — stays out of the local core. The independently
installable App skeleton verifies signed webhooks and writes neutral checks;
registration and hosting are separate gates. The local review-feedback
workflow preserves signed review evidence, requires
an independent hub decision and routes a notice to the exact author seat and
native session binding without automatic merge or model execution.
Use synapse ttl-advice ./synapse.db for read-only adaptive lease TTL advice.
It derives completed-task duration samples, active live-claim counts, and stale
claim counts from the event log, then prints an advisory default. It never
changes the hub default and explicit manual TTL values still win.
Coordination model
Claim before you work: an agent leases a task by id; a live lease blocks other
agents from