{
  "markdown": "<!--\nSPDX-License-Identifier: AGPL-3.0-or-later\nCommercial license available\n© Concepts 1996–2026 Miroslav Šotek. All rights reserved.\n© Code 2020–2026 Miroslav Šotek. All rights reserved.\nORCID: 0009-0009-3560-0851\nContact: www.anulum.li | protoscience@anulum.li\nmcp-name: io.github.anulum/synapse-channel\nSYNAPSE CHANNEL — repository overview\n-->\n\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/anulum/synapse-channel/main/docs/assets/header.png\" width=\"1280\" alt=\"SYNAPSE CHANNEL — local-first multi-agent coordination bus\">\n</p>\n\n<p align=\"center\">\n  <strong>The local-first coordination bus for fleets of AI agents.</strong><br>\n  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.\n</p>\n\n<p align=\"center\">\n  <em>Flagship example:</em> 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.\n</p>\n\n<p align=\"center\">\n  <a href=\"https://github.com/anulum/synapse-channel/actions/workflows/ci.yml\"><img src=\"https://github.com/anulum/synapse-channel/actions/workflows/ci.yml/badge.svg\" alt=\"CI\"></a>\n  <a href=\"https://github.com/anulum/synapse-channel/actions/workflows/fuzz.yml\"><img src=\"https://github.com/anulum/synapse-channel/actions/workflows/fuzz.yml/badge.svg\" alt=\"Fuzz\"></a>\n  <a href=\"https://github.com/anulum/synapse-channel/actions/workflows/link-check.yml\"><img src=\"https://github.com/anulum/synapse-channel/actions/workflows/link-check.yml/badge.svg\" alt=\"Link check\"></a>\n  <a href=\"https://github.com/anulum/synapse-channel/actions/workflows/clients-cockpit.yml\"><img src=\"https://github.com/anulum/synapse-channel/actions/workflows/clients-cockpit.yml/badge.svg\" alt=\"Cockpit CI\"></a>\n  <a href=\"https://github.com/anulum/synapse-channel/actions/workflows/codeql.yml\"><img src=\"https://github.com/anulum/synapse-channel/actions/workflows/codeql.yml/badge.svg\" alt=\"CodeQL\"></a>\n  <a href=\"https://pypi.org/project/synapse-channel/\"><img src=\"https://img.shields.io/pypi/v/synapse-channel\" alt=\"PyPI version\"></a>\n  <a href=\"https://pypi.org/project/synapse-channel/\"><img src=\"https://img.shields.io/pypi/dm/synapse-channel\" alt=\"PyPI downloads\"></a>\n  <a href=\"https://pepy.tech/project/synapse-channel\"><img src=\"https://static.pepy.tech/badge/synapse-channel\" alt=\"Total downloads\"></a>\n  <a href=\"https://github.com/sponsors/anulum\"><img src=\"https://img.shields.io/badge/GitHub-Sponsors-ea4aaa?logo=githubsponsors\" alt=\"Sponsor SYNAPSE CHANNEL on GitHub\"></a>\n  <a href=\"LICENSE\"><img src=\"https://img.shields.io/badge/License-AGPL%20v3-blue.svg\" alt=\"License: AGPL v3\"></a>\n  <a href=\"https://www.remanentia.com/synapse/pricing.html\"><img src=\"https://img.shields.io/badge/commercial%20licence-available-0a7d3c\" alt=\"Commercial licence available\"></a>\n  <img src=\"https://img.shields.io/badge/python-3.10%2B-blue\" alt=\"Python 3.10+\">\n  <a href=\"https://codecov.io/gh/anulum/synapse-channel\"><img src=\"https://codecov.io/gh/anulum/synapse-channel/branch/main/graph/badge.svg\" alt=\"Coverage\"></a>\n  <a href=\"https://api.reuse.software/info/github.com/anulum/synapse-channel\"><img src=\"https://api.reuse.software/badge/github.com/anulum/synapse-channel\" alt=\"REUSE status\"></a>\n  <a href=\"https://www.bestpractices.dev/projects/13565\"><img src=\"https://www.bestpractices.dev/projects/13565/badge\" alt=\"OpenSSF Best Practices: Passing\"></a>\n  <a href=\"https://securityscorecards.dev/viewer/?uri=github.com/anulum/synapse-channel\"><img src=\"https://api.securityscorecards.dev/projects/github.com/anulum/synapse-channel/badge\" alt=\"OpenSSF Scorecard\"></a>\n  <a href=\"https://github.com/astral-sh/ruff\"><img src=\"https://img.shields.io/endpoint?url=https://raw.githubusercontent.com/astral-sh/ruff/main/assets/badge/v2.json\" alt=\"Ruff\"></a>\n  <a href=\"https://doi.org/10.5281/zenodo.20801559\"><img src=\"https://zenodo.org/badge/DOI/10.5281/zenodo.20801559.svg\" alt=\"DOI\"></a>\n</p>\n\n<p align=\"center\">\n  <strong>English</strong> ·\n  <a href=\"docs/readme/README.zh-CN.md\">简体中文</a> ·\n  <a href=\"docs/readme/README.es.md\">Español</a> ·\n  <a href=\"docs/readme/README.pt-BR.md\">Português (Brasil)</a> ·\n  <a href=\"docs/readme/README.ja.md\">日本語</a> ·\n  <a href=\"docs/readme/README.ko.md\">한국어</a> ·\n  <a href=\"docs/readme/README.de.md\">Deutsch</a> ·\n  <a href=\"docs/readme/README.fr.md\">Français</a> ·\n  <a href=\"docs/readme/README.sk.md\">Slovenčina</a>\n</p>\n\nA local-first coordination bus for a fleet of AI agents working in parallel —\nwithin a single repository or spread across a whole ecosystem of them. One\nWebSocket hub is the shared source of truth for **presence**, **work claims**,\n**chat**, **task status**, and **resource offers**: agents address each other\nacross projects and share one plan, while file-scope claims keep the agents in any\none repository from receiving overlapping live authority. Documented provider\nhooks and the staged Git gate enforce that authority only on their covered\nmutation surfaces.\n\n> **New here?** Read [**Why SYNAPSE CHANNEL**](docs/why-synapse.md) — a\n> five-minute read on what it is, what you build on it, how it differs from the\n> tools next to it, and why coordination becomes the bottleneck once you run more\n> than one agent.\n\n> **Project lineage:** SYNAPSE CHANNEL dates back to **September 2025**.\n\nThe bus is transport-light (one dependency, `websockets`), hub-centric by design\n(one place owns presence, leases, and history), and runs entirely on the local\nmachine. Model workers reply on-channel through any OpenAI-compatible endpoint,\nincluding a local Ollama server, with a deterministic rule-based fallback for\noffline use.\n\n**Your existing agents plug in without new code.** Any Model Context Protocol\nhost — Claude Code, Claude Desktop, Cursor — reaches the bus through the bundled\n`synapse mcp` server, which exposes send, durable inbox, status, claim, release,\nhandoff, and task verbs as MCP tools plus the board, agents, and resources as\nread-only MCP resources. Agents that speak A2A connect through the Agent Card face instead.\nThe hub itself stays protocol-agnostic and the core install keeps its single\ndependency — the MCP and A2A adapters are optional extras (`pip install\n'synapse-channel[mcp]'`). See the [MCP guide](docs/mcp.md).\n\n```bash\npython -m pip install synapse-channel && synapse demo\n```\n\n<p align=\"center\">\n  <a href=\"https://pypi.org/project/synapse-channel/\"><strong>Get the Python package</strong></a>\n  &nbsp;·&nbsp;\n  <a href=\"#first-60-seconds\">Run the first 60 seconds</a>\n  &nbsp;·&nbsp;\n  <a href=\"docs/quickstart.md\">Read the quickstart</a>\n</p>\n\n## Coordinate. Observe. Govern.\n\nSynapse's daily promise is three explicit loops:\n\n- **Coordinate** declared work and surface collisions: `synapse git-init`, `synapse git-claim`,\n  `synapse git-claim-check --staged`, `synapse task`, and `syn ack` turn work\n  scope, dependencies, and evidence into shared state instead of side-channel\n  notes.\n- **Observe** the fleet from durable state: `synapse who`, `synapse state`,\n  `synapse dashboard`, `synapse event-query`, and observed peer rows show who is\n  present, what is claimed, what changed, and which peer-hub facts are advisory.\n- **Govern** risky actions with evidence: policy checks, approvals, release\n  receipts, Merkle roots, ACL surfaces, federation, and encryption-key commands\n  make operator decisions auditable. Governance surfaces report by default;\n  operators decide what blocks a merge, release, or cross-hub action.\n- **Protect the durable log at rest** with optional **SQLCipher** page encryption\n  for the live hub event store (plus whole-file AES-GCM envelopes for relay\n  logs, A2A state, cursors, and archives). See\n  [SQLCipher live event store](#sqlcipher-live-event-store-at-rest) below.\n\n## What it does, surface by surface\n\nSeven shipped coordination surfaces, each named by the command or doc that\ndelivers it today:\n\n- **Claim before edit.** [`synapse git-init`](#git-native-claims) 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.\n\n  <p align=\"center\">\n    <img src=\"docs/assets/feature-claim-conflict.png\" width=\"809\" alt=\"A live Synapse claim owner and a competing overlapping claim refused before editing begins\">\n  </p>\n\n- **Block unclaimed native file edits.** [Provider file-edit claim hooks](docs/claim-guard-hooks.md) adapt Claude Code `Edit|Write`, Codex `apply_patch`, Gemini CLI `replace|write_file`, and Kimi `Edit|Write` to one live-claim decision engine.\n\n  <p align=\"center\">\n    <img src=\"docs/assets/feature-edit-denial.png\" width=\"809\" alt=\"A provider edit hook denying a native file edit because the seat holds no matching claim\">\n  </p>\n\n- **Share the plan.** `synapse task` and [`synapse board`](docs/coordination-model.md) keep task state, dependencies, and ready work on the hub instead of in separate agent notes.\n\n  <p align=\"center\">\n    <img src=\"docs/assets/demo.gif\" width=\"845\" alt=\"A Synapse task board changing a dependent task from blocked to ready after its prerequisite completes\">\n  </p>\n\n- **Hand work over without an ownership gap.** [Atomic handoff](docs/coordination-model.md#4-hand-off-and-recover) moves the held task, scope, status, and checkpoint to an online recipient without a release-and-reclaim window.\n\n  <p align=\"center\">\n    <img src=\"docs/assets/feature-atomic-handoff.png\" width=\"809\" alt=\"An atomic Synapse handoff moving a held task, scope, status, and checkpoint to another seat\">\n  </p>\n\n- **Expose a dark seat.** After 30 continuous seconds without the owner's exact waiter, the hub emits one [`dark_seat_alert`](docs/protocol.md) for affected claims or assigned work, including the permanent-arm remedy; it does not release or reassign work automatically.\n\n  <p align=\"center\">\n    <img src=\"docs/assets/feature-dark-seat.png\" width=\"1170\" alt=\"A dark-seat alert naming the missing exact waiter, affected claim, and permanent synapse arm remedy\">\n  </p>\n\n- **Read the fleet from one cockpit.** [`synapse dashboard`](docs/studio.md) 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.\n\n  <p align=\"center\">\n    <img src=\"docs/assets/feature-cockpit.png\" width=\"1280\" alt=\"The dark Synapse operator cockpit with live status, claims, task board, risk rail, findings, and signal log\">\n  </p>\n\n- **Connect existing agent protocols at the edge.** [`synapse mcp`](docs/mcp.md) exposes coordination tools and read-only resources over stdio; the [A2A bridge](docs/a2a-conformance.md) exposes a local Agent Card and HTTP+JSON surface while keeping its partial validation boundary explicit.\n\n  <p align=\"center\">\n    <img src=\"docs/assets/feature-mcp-a2a.png\" width=\"979\" alt=\"The installed Synapse MCP tool list and A2A Agent Card reaching the same local coordination core\">\n  </p>\n\n## At a glance\n\n<p align=\"center\">\n  <img src=\"https://raw.githubusercontent.com/anulum/synapse-channel/main/docs/assets/demo.gif\" width=\"720\" alt=\"A synapse session: declare a plan with a dependency, complete a task, and watch the dependent unblock\">\n</p>\n\n```mermaid\ngraph LR\n    A1[\"Agent\"] --> H\n    A2[\"Agent\"] --> H\n    A3[\"Worker\"] --> H\n    SUP[\"Supervisor\"] --> H\n    H[\"SynapseHub<br/>single source of truth\"] --> CL[\"Claims & leases<br/>scope · epoch · checkpoint\"]\n    H --> BB[\"Blackboard<br/>plan + progress\"]\n    H --> CAP[\"Capabilities<br/>cards + routing\"]\n    H --> LOG[\"Event log (SQLite WAL)<br/>durable · optional SQLCipher at rest\"]\n```\n\nA claim leases a declared unit of work with a file scope, so the hub refuses\noverlapping live claims. Provider hooks and the staged Git gate enforce that\nauthority on their documented surfaces; they do not sandbox every filesystem or\nexternal side effect. Plans, handoffs, checkpoints, and a stall supervisor keep\nthe work moving, and the durable event log means a hub restart resumes live\nleases rather than losing them.\n\n## Core and Optional Layers\n\nSYNAPSE CHANNEL ships as one installable package, but the public surface is\ntiered so the lean bus stays clear:\n\n| Layer | Taxonomy tier | What belongs there |\n|---|---|---|\n| Local coordination core | `stable` | The hub, send/wait/listen/arm, claims, tasks, locks, status, board, init, and fleet bootstrap commands used for daily coordination. |\n| Edge adapters | `adapter` | MCP, A2A, git hooks, tmux/provider bridges, shell hooks, ingestion, and worker seats that connect existing tools to the bus. |\n| 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. |\n| Governance and integrity | `governance` | Policy checks, approvals, ACL/role surfaces, federation, Merkle roots, release receipts, reproduction, compaction, encrypt-key / SQLCipher key operations. |\n| Lab surfaces | `experimental` | Benchmarking, participant fabric, route-task, sandbox, workflow, TTL advice, memory recall, auto-action, and resource bidding. |\n\nThe authoritative map is [`synapse_channel.surface_taxonomy`](src/synapse_channel/surface_taxonomy.py)\nand the generated operator view is [Public surface and stability](docs/public-surface.md).\nAdapters and lab surfaces can be installed and used from the same package, but\nthey do not change the single-dependency local core.\n\nSix measurable discovery profiles keep those layers explicit without hiding or\nremoving commands: `first-use`, `core`, `adapters`, `governance`, `labs`, and\n`all`. Inspect any profile without starting a hub or optional process:\n\n```bash\nsynapse commands --profile first-use\nsynapse commands --profile first-use --json\n```\n\nThe JSON contract records three first-use concepts and three shell commands,\nagainst a hard limit of eight concepts, with zero optional extras and zero\nimplicitly started persistent services. Profile inspection is read-only;\noptional capabilities activate only through their documented package extra and\ncommand or flag, and deactivate by stopping that exact process or omitting the\nopt-in. See [installation profiles](docs/installation.md#usage-profiles-and-activation).\n\n### Optional Participant memory recall\n\n`participant ask`, `participant exchange`, and `participant convene` can wrap\ntheir seats with bounded, read-only recall from REMANENTIA's lightweight HTTP\nAPI. Recall is disabled unless `--memory-url` is present; no memory process is\nstarted implicitly. Tokens are accepted only through `--memory-token-file`, and\nrecalled snippets enter `TurnRequest.context` inside a data-only fence while the\noperator prompt remains unchanged.\n\n```bash\nsynapse participant ask claude \"review this design\" \\\n  --memory-url http://127.0.0.1:8001 \\\n  --memory-token-file /run/secrets/remanentia\n```\n\nCurrent HTTP results omit REMANENTIA's honesty axes, so every recalled hit is\nshown as boundary data; similarity is relevance evidence, not truth evidence.\nNo-hit and unavailable states remain visible without failing the provider turn.\nSee [Participant memory recall](docs/participant-memory.md) for setup, limits,\nCLI flags, library use, and audit boundaries.\n\n> **Coming: Studio** — the dashboard is growing into an operator **[Studio](docs/studio.md)**:\n> a control plane that answers, at a glance, what is happening, what is at risk, and\n> what is safe to do next. The instrument-panel design system, `/studio` reference,\n> live `/studio/command` shell, security-posture panel, and event-log LiveFeed have\n> shipped. Local-first and read-only by default — an organisation-level workbench is\n> planned as a separate layer.\n\n## Install\n\n```bash\npython -m pip install synapse-channel       # the release from PyPI\npython -m pip install -e \".[dev]\"           # or an editable dev checkout\n# optional: live hub event-store page encryption (SQLCipher)\npython -m pip install 'synapse-channel[sqlcipher]'\n# optional: whole-file AES-GCM envelope helpers (encrypt-key profile/migrate/rekey)\npython -m pip install 'synapse-channel[encryption]'\n```\n\nFor an editable checkout, keep the local `.venv` aligned with the repository's\ndeclared dev, docs, and benchmark extras:\n\n```bash\n.venv/bin/python tools/check_dev_dependency_drift.py --check\n.venv/bin/python tools/audit_dependency_tooling.py --check\n```\n\nThe second check is offline. It verifies that local preflight still covers the\nexpected tool gates, GitHub Actions are pinned to full commit SHAs, Dependabot\ncovers actions/Python/Docker, and the PyPI publish/download metadata surfaces\nremain wired.\n\nThis installs the `synapse` command. To run the hub as an always-on local service\nor a container, see the [deployment guide](docs/deployment.md) (a `systemd` user\nunit and `docker compose` are both included). On Linux, install only a permanent\nexact-identity waiter with\n`synapse arm install --identity myproject/agent --start`; it uses mailbox replay\nand `Restart=always`, without installing a hub. Its\n`myproject/agent-rx` receiver can coexist with agent-tmux's distinct\n`myproject/agent-pane-rx` bridge, preserving durable gap recovery and active\npane delivery without name takeover. The pane bridge fails closed on busy,\nmodal, unknown, or ambiguous provider screens: it persists the pending wake and\nsubmits its fixed prompt only after two provider-specific idle-composer probes.\nIt acknowledges delivery only after the pane shows prompt consumption; an Enter\nignored during asynchronous provider startup leaves the single staged prompt\npending for a safe Enter-only retry.\nIt accepts only exact identity, role, or group targets; global priority and CEO\nbroadcasts remain durable inbox traffic but never inject into provider panes.\n\nFor unattended active delivery, supervise that pane bridge independently of\nagent turns:\n\n```bash\nsynapse waker install \\\n  --identity myproject/agent \\\n  --session myproject-agent \\\n  --cwd \"$PWD\" \\\n  --agent-command codex \\\n  --start\nsynapse waker status --identity myproject/agent\n```\n\nThe generated `synapse-waker@.service` has `Restart=always` and a main-loop\nwatchdog, so a dead bridge is recreated without relying on the agent to remember\nto re-arm it. `waker stop --reason ...` first persists an `inhibited` state and\nthen stops only the exact bridge; systemd cannot immediately resurrect it, and\nthe tmux provider terminal is not killed or restarted. Only an explicit\n`waker resume` clears the inhibit.\nNative Windows service setup is not\nclaimed; use WSL with systemd as documented in the deployment guide.\n\nFor agent-assisted environment preparation, `synapse setup spec`, `inspect`,\n`plan`, `authorize`, `apply`, `verification-plan`, `authorize-verification`,\nand `verify` expose the packaged `synapse-setup.v1`\ncontract. The first three describe requirements, observe the host, and bind a\ncredential-free target to a non-executable SHA-256 plan. `authorize` emits a\nshort-lived envelope for one reviewed plan. Restart authority must match the\nexact hub PID observed in that plan; first-start authority carries no PID. On\nLinux with systemd-user,\n`apply` re-inspects the target and plan-bound executable generation, atomically\nreserves the authorization in a private replay ledger, and may install or start\nonly the package-owned local hub and exact waiter units. It preserves declared\nPIDs, emits a digest-bound receipt, and restores prior unit and service state on\nfailure. After a successful application, the separate verification transaction\nsends one directed canary, requires the exact waiter's durable ACK, restarts\nonly the authorized hub PID, proves replay through a new hub PID, re-inspects\nthe bound generation, and preserves declared terminal/provider PIDs. It emits a\nsingle-use, digest-bound verification receipt; an application receipt alone is\nnot strict end-to-end readiness evidence. Package, Python, identity, secret,\nremote, macOS, native Windows, and container changes remain blocked. See\n[Machine-readable setup](docs/machine-readable-setup.md) for the schema,\nexpiry, nonce-consumption, and exact-PID authority rules.\n\nTwo optional shell conveniences ship with the CLI: `synapse completions\nbash|zsh|fish` prints tab completion for every subcommand (generated from the\nlive parser, so it never drifts), and `synapse install-shell-hook` adds the\nguarded block that auto-arms a wake listener in each new terminal:\n\n```bash\nsynapse completions bash > ~/.local/share/bash-completion/completions/synapse\nsynapse install-shell-hook          # auto-arm Bash, Zsh, and Fish terminals\n```\n\n## Who it's for\n\n- A developer running **two or three coding agents** on one repository, tired of\n  merge collisions and duplicated work.\n- A team operating a **fleet of agents across several services** that needs one\n  plan, one roster, and cross-repository task dependencies.\n- A builder of **long-running autonomous agents** who wants event-driven\n  wakeups, durable coordination, and a resume-after-restart story instead of a\n  polling loop and lost state.\n\nSee [use cases](docs/use-cases.md) for when it fits, when it is overkill, and\nwho reaches for it.\n\n## Getting started\n\n> **The one path to follow.** Run the three-command self-contained proof below,\n> then follow the **[multi-seat golden path](docs/quickstart.md#multi-seat-golden-path-5-minutes)**\n> for persistent agents. Optional adapters and generated workspaces come later.\n\n### First 60 seconds\n\nOn a clean Python environment, verify the installed CLI before wiring agents into\na real repository:\n\n```bash\npython -m pip install synapse-channel\nsynapse doctor\nsynapse demo --output ./synapse-golden-demo\n```\n\n`synapse doctor` reports local setup issues such as identity, hub exposure,\nroot-filesystem pressure, and missing waiters. A brand-new machine may warn that\nno hub or waiter is running; that is expected before service setup. `synapse\ndemo` starts its own local hub, drives a planner/worker coordination flow, and\nsucceeds when it prints:\n\nThe `CLAUDE` and `CODEX` names in that flow are scripted in-process\n`SynapseAgent` identities. The demo launches no provider CLI and spends no model\nturn.\n\n```text\nsuccess: coordination demo completed\n```\n\nAfter the self-contained proof, `synapse quickstart-coding` remains available as\nan optional generated-workspace demo. It creates a temporary coding-fleet\nworkspace, runs the live overlapping-claim refusal demo, removes the workspace\nafter success, and prints:\n\n```text\nsuccess: coding fleet demo completed\n```\n\nOr run the whole first-run sequence as one command:\n\n```bash\nsynapse fleet-init\n```\n\nIt runs the doctor (`--fix` to repair the default local hub and waiter),\nscaffolds a persistent `./synapse-fleet` workspace, probes which provider CLIs\nthis machine can seat (claude, codex, kimi, ollama, …), runs the demo smoke,\nand prints the next-steps plan — waiter arming, per-provider seat commands,\n`git-init`, dashboard — with the workspace's project name filled in.\n\n### Fastest safe trial path\n\nUse one self-contained path before changing a real checkout:\n\n```bash\npython -m pip install synapse-channel\nsynapse doctor\nsynapse demo --output ./synapse-golden-demo\n```\n\nThe demo starts and stops its own local hub, uses a disposable committed Git\nrepository, proves separate claims and overlapping-claim refusal, denies a\nmutation before handoff, permits it after handoff, and writes an observed\nverification receipt plus a static dashboard. It needs no persistent hub,\nprovider CLI, Git hook, MCP host, or A2A bridge. The same exact three-command\nblock is regression-bound across this README, the quick start, and the CLI\nreference, and its `synapse demo` command is exercised as a real subprocess.\n\nAfter that proof passes, use `synapse fleet-init --fix` to prepare a persistent\nlocal workspace, hub, and waiter, then run `synapse git-init --name\ntrial-agent` inside the real repository before an agent edits it. Optional A2A\ninteroperability is a follow-on in the [A2A bridge guide](docs/a2a-conformance.md); it is\nnot a prerequisite for first coordination value.\n\n## Releases\n\nThis package is developed in the open and dogfooded daily: a fleet of coding\nagents runs its own coordination on it, so problems surface in real use and are\nfixed quickly. Releases are therefore frequent and mostly small — fixes and\nhardening rather than churn. Current `0.x` releases do not promise backward\ncompatibility across minor releases. The wire vocabulary and public Python API\nare guarded against accidental drift, but a reviewed `0.x` minor release may\ndeliberately change either surface. Every such change updates the frozen\ncontract tests, bumps `WIRE_PROTOCOL_VERSION` for a wire-incompatible change,\nand ships changelog plus migration notes. Starting with `1.0.0`, a breaking\nstable public Python API change requires a package major release; a breaking\nwire change requires a wire-protocol version bump. See\n[API and wire stability](docs/api-stability.md).\n\n`1.0.0` is planned as the first stable commercial release of SYNAPSE CHANNEL,\nwith the operational contracts, packaging, support surface, and commercial\nlicensing terms documented as part of that release.\n\nSYNAPSE CHANNEL is seeking startup funding, strategic partners, and aligned\necosystem co-owners who want to help mature the coordination layer for\nproduction multi-agent development. See [commercial licensing](docs/commercial.md)\nor write to `protoscience@anulum.li`.\n\nIf you need a fixed target, pin a version (`synapse-channel==X.Y.Z`); to get the\nlatest fixes, track the newest release. Both are supported.\n\n## Usage\n\n### Run a hub with model workers\n\nLaunch a hub plus one or two local model workers in one command:\n\n```bash\nsynapse team\n```\n\nIf Ollama isn't running, `synapse team` falls back to a single offline\nrule-based worker (deterministic canned replies) so the flow still works; start\nOllama and re-run for real model replies.\n\nThen, from another terminal, watch the channel or send a message:\n\n```bash\nsynapse listen --name USER                                 # terminal A: watch the channel as USER\nsynapse send --target FAST \"what is the status of TASK-1?\"  # terminal B: one-shot, unique ephemeral sender\nsynapse send --require-recipient --target FAST \"ping\"  # also print the positive receipt\n```\n\nA `send` without `--name` uses a unique ephemeral sender, so a one-shot send\nnever trips the hub's one-owner-per-name rule against a listener you already\nhave connected under the same name. One-shot sends also avoid the waiter-name\ncollision: `synapse send --name api-dev-rx ...` sends as `api-dev`, leaving the\npersistent `api-dev-rx` wake\nsocket connected. Directed sends request a private receipt by default and exit\nnon-zero when no consume-live recipient matches — including when a stale socket\nis still connected but has neither a recent reaction nor a live waiter. The\nmessage remains journalled and best-effort routed, while the hub records a dead\nletter instead of reporting socket presence as delivery. Each one-shot send\nuses a unique message identity and accepts only its matching receipt, so an old\npending receipt replayed when the sender reconnects cannot be reported as the\nnew send's result. Add\n`--require-recipient` when the positive receipt should also be printed and a hub\ntoo old to return receipts must fail closed.\n\nFor selected sensitive payloads, encrypt the body before it reaches the hub and\ndecrypt it only on the recipient side:\n\n```bash\nsynapse send --target FAST \\\n  --encrypt-key-file ./payload.key \\\n  --encrypt-key-id project-main-v1 \\\n  --encrypt-recipient FAST \\\n  \"private handoff note\"\nsynapse listen --name FAST --for FAST --decrypt-key-file ./payload.key\n```\n\nThe hub still sees sender, target, channel id, key id, recipient names, nonce,\nciphertext, and delivery metadata. This does not manage key discovery or\nrotation.\n\n### Running pieces individually\n\n```bash\nsynapse hub --port 8876\nsynapse hub --port 8876 --db ./synapse.db            # crash-safe: resumes leases + history on restart\nsynapse hub --port 8876 --relay-log ./feed.ndjson    # mirror the channel to a compact file for observers\nsynapse hub --shutdown-close-timeout 5               # bound active socket close handshakes on stop\nsynapse hub --max-progress-per-author 500            # cap retained board progress per author\nsynapse hub --max-findings-per-agent 200             # cap durable findings admitted per agent\nsynapse hub --tls-certfile ./hub.crt --tls-keyfile ./hub.key  # native wss://\nsynapse worker --name FAST --provider ollama --model gemma3:4b\nsynapse worker --name OFFLINE --provider rule        # no network, canned replies\nsynapse worker --name TIER --provider tiered --model small --heavy-model big  # route trivial→rule, hard→heavy\nsynapse relay ./feed.ndjson                          # decode and print that file as readable lines\nsynapse ingest ./synapse.db --memory --cursor ./mem.cursor  # stream durable memory events since a seq cursor (NDJSON)\nsynapse memory-recall ./synapse.db \"transport handoff\"       # local recall over durable memory records\nsynapse compact ./synapse.db --all --max-checkpoints-per-task 3 --archive-report ./compact-report.html\nsynapse board                                        # print the shared task/progress blackboard\nsynapse task declare BUILD --title \"compile\" --idem-key build-v1  # retry-safe durable write\nsynapse task update BUILD --status done              # mark a plan task done so dependents unblock\nsyn ack BUILD --evidence \"pytest -q\"                 # post evidence and mark a board task done\nsynapse supervisor --idle-seconds 300 --history-multiplier 3  # re-offer stalled plan tasks\nsynapse manifest                                     # print capability cards, including contract counts\nsynapse capability-card keygen --key-id PROJECT:worker:v1 --private-out ./card.pem --agent PROJECT/worker --project PROJECT --trust ./card-trust.json\nsynapse directory                                    # print discovery-only agents/resources\nsynapse route-task BUILD --limit 3 --event-store ./synapse.db  # add observed evidence\nsynapse resource-bids BUILD --resource-kind gpu      # rank live resource offers without reserving capacity\nsynapse a2a-card --endpoint-url https://agent.example.com/a2a/v1  # emit A2A Agent Card JSON\nsynapse a2a-serve --endpoint-url http://127.0.0.1:8877             # run the HTTP+JSON A2A bridge\nsynapse doctor                                       # check for common misconfigs (identity, exposure, hub, waiter)\nsynapse demo                                         # installed self-check: local hub + planner/worker flow\nsynapse quickstart-coding                            # create a temporary coding fleet workspace and run it\nsynapse new coding-fleet ./demo-fleet                # scaffold a runnable two-agent coding demo workspace\nsynapse hub --host 0.0.0.0 --token s3cret            # require a shared secret when binding off-loopback\nsynapse hub --host 0.0.0.0 --token s3cret --tls-certfile ./hub.crt --tls-keyfile ./hub.key\nsynapse hub --max-connections-per-host 4             # cap simultaneous sockets from one remote host\nsynapse send --token s3cret --name USER \"hello\"      # agents present the token to a secured hub\n```\n\nFor an observed cross-hub task revision, `task declare` and `task update` also\naccept `--causal-parent HUB_ID:SEQ:SHA256`. The SHA-256 is the complete event\nfingerprint exposed in multi-hub board provenance. A verified same-task parent\nlets the observed fold discard only that proven ancestor; a missing or\nmismatched reference remains unresolved and never becomes a concurrency claim.\nThis metadata changes the advisory observed board, not local claim authority.\n\n### Use it with your coding agent\n\nSynapse coordinates the agents you already run; it does not replace them.\nIts MCP and A2A adapters are interop surfaces: they let Claude Code, Claude\nDesktop, Cursor, Codex, Copilot-style hosts, Aider, orchestration frameworks,\nand other agent tools participate in one local coordination bus while those\ntools still own prompting, model choice, tool use, and editor/runtime behavior.\nThe [integration demo matrix](docs/integration-demos.md) lists three narrow,\nrepeatable paths and the unsupported behavior that remains outside each demo.\n\n- **Claude Code / Codex / Claude Desktop / Cursor (MCP):** register the stdio\n  server and its coordination tools load automatically — no shell hook or\n  Synapse-specific client code.\n\n  ```bash\n  python -m pip install 'synapse-channel[mcp]'\n  claude mcp add synapse -- synapse mcp         # resolves <git-project>/mcp\n  codex mcp add synapse -- synapse mcp --name my-repo/codex\n  ```\n\n  Cursor and Claude Desktop can reuse the secret-free\n  [`examples/mcp/.mcp.json`](examples/mcp/.mcp.json) template. MCP does not wake\n  an idle provider in this adapter; call `synapse_inbox` at turn start and keep\n  `synapse arm install --identity NAME --start` active for prompt delivery.\n\n- **Claude Code / Codex / Gemini / Grok / Kimi native file edits:** print a\n  provider-native pre-tool recipe (`PreToolUse` for the Claude family,\n  Grok, and Kimi; `BeforeTool` for Gemini CLI) that checks the authoritative live\n  claim before a supported file tool runs.\n\n  ```bash\n  synapse adapters claude-claim-hook --identity my-repo/claude --print-config\n  synapse adapters codex-claim-hook  --identity my-repo/codex  --print-config\n  synapse adapters gemini-claim-hook --identity my-repo/gemini --print-config\n  synapse adapters grok-claim-hook   --identity my-repo/grok   --print-config\n  synapse adapters kimi-claim-hook   --identity my-repo/kimi   --print-config\n  synapse adapters kimi-claim-hook   --identity my-repo/kimi   --install-config\n  ```\n\n  `--print-config` is read-only. Save the Grok fragment under\n  `~/.grok/hooks/*.json`; `synapse adapters install grok` separately installs\n  the kebab-case `~/.grok/skills/synapse/SKILL.md` coordination skill. Kimi's\n  opt-in installer writes only one marked block in\n  `$KIMI_CODE_HOME/config.toml` (default `~/.kimi-code/config.toml`), and\n  `--uninstall-config` removes only that block. The equivalent combined Kimi\n  path is `synapse adapters install kimi --identity my-repo/kimi --with-hook`.\n\n  The [provider claim-hook guide](docs/claim-guard-hooks.md) documents exact tool\n  coverage, token-file setup, and the native-host limits. These are bounded file\n  guards, not complete Bash or filesystem isolation.\n\n- **Aider, or any non-MCP tool:** claim a file scope before editing and let a git\n  hook release it on commit. The claim prevents conflicting grants; enforcement\n  of the tool's working-tree writes remains the operator's responsibility, with\n  the staged Git gate providing a separate commit-time check.\n\n  ```bash\n  synapse quickstart-coding                    # optional: run a temporary overlapping-claim refusal demo\n  synapse new coding-fleet ./demo-fleet        # optional: keep the generated workspace\n  synapse git-init --name aider-1              # one step: install the hooks + write the conventions guide\n  synapse git-claim --task-id AUTH --paths src/auth --name aider-1\n  aider src/auth/*.py                          # ... edit; the post-commit hook releases the claim\n  ```\n\n- **Check the wiring:** `synapse doctor` reports the common setup mistakes — no live\n  waiter, a hub exposed without a token, an accidental identity, or a pressured\n  root filesystem — each with its fix. With a durable hub it also reports\n  `N undelivered messages pending for <identity>` from the receiver watermark;\n  this is mailbox transport acknowledgement, not proof a model processed the\n  messages. Use `--disk-path <path>` to check the filesystem that holds a\n  specific workspace or cache.\n\n- **Inspect the live board:** `synapse dashboard --port 8765` opens a\n  loopback-only read-only HTML view of roster, exact blackboard/claim status\n  columns, progress,\n  fleet visibility, task-dependency graph edges, branch-conflict candidates,\n  release receipts, and advertised capabilities, with the same snapshot\n  available at `/snapshot.json` for local tooling. Pass `--a2a-state-file <path>`\n  to add persisted A2A task and push-config counts to the fleet section. The\n  dashboard derives task dependencies from the blackboard snapshot and uses live\n  claim metadata for branch conflicts; run `synapse conflicts --check-diff` when\n  you need client-side git-diff refinement. The state snapshot also carries\n  `dead_letters` — directed chats that reached no live connection, per target\n  with counts — so a message nobody is listening for shows up on the page\n  instead of being discovered by a human relaying it. The dashboard is growing\n  into an operator [Studio](docs/studio.md) — open `/studio` for the\n  design-system reference — and ships a React cockpit under `clients/cockpit/`\n  (build instructions in [its README](clients/cockpit/README.md); serve the\n  built bundle with `synapse dashboard --cockpit-dist clients/cockpit/dist`).\n  If you deliberately expose the\n  dashboard with `--allow-non-loopback`, pass `--dashboard-token <token>` and\n  require clients to send `Authorization: Bearer <token>`; the React cockpit\n  loads its token-free static shell, asks for that bearer, and retains it only\n  in the tab's session storage. It never accepts the bearer in a URL. When the\n  token is omitted on an exposed bind, Synapse generates and prints a startup\n  token. Teams can instead pass an owner-only\n  `--dashboard-access-file` mapping separate viewer/operator/admin token files\n  to browser principals and distinct relay identities. The server-authored\n  capability descriptor removes unauthorized write controls from the DOM and\n  command search, but every POST is still re-authorized server-side and at the\n  hub; admin currently gains no mutation beyond the three shipped operator\n  writes. With `--operator`, the authorized command palette exposes governed\n  message, task-declaration, and task-update forms; each reports the hub's\n  strict outcome and grants no authority beyond the hub's validation, ACL, rate\n  limit, and audit decision. With `--feeds-db`, the cockpit's Audit tab incrementally renders the\n  universal receipt ledger and governed operator-relay history as two distinct,\n  bounded store-attested feeds. The receipt ledger includes minimized claim and\n  guard denials, dead-letter escalations, and identity-pin reclaim outcomes;\n  every declared durable `EventKind` is explicitly classified as receipt-bearing or\n  intentionally omitted. Absence and stale last-good data remain visible.\n  Add\n  `--observed-peer HUB=URI` to include advisory peer-hub rows in the browser and\n  `/snapshot.json`; those rows are labelled `observed@HUB` and never grant local\n  claims.\n\n- **Verify a release redeploy:** `synapse doctor --redeploy-checklist` prints\n  package, service, roster, durable-state, and git-hook checks for a post-release\n  local fleet restart. It does not restart services by itself, and restart\n  commands are withheld by default. After inspecting the exact live hub PID and\n  roster, an operator with fresh disruption authority can add\n  `--redeploy-authorize-restart-pid PID`; the rendered command rechecks that PID\n  while holding a fail-fast host-local custody lock. Dogfooding requires every\n  new release tag to be adopted by the local hub immediately after publication,\n  using that bounded authorised path and post-restart health verification.\n\n- **Install the always-on local services:** `synapse init` prints or installs the\n  hub, project presence, and non-LLM wake listener units. `doctor --fix` prints\n  the exact commands when a waiter is missing.\n\n  ```bash\n  synapse init --project myrepo --identity myrepo/worker --install-user-services\n  synapse init --project myrepo --identity myrepo/worker --start-user-services\n  synapse doctor --fix\n  ```\n\n- **Launch a provider command with Synapse identity:** `worker-session` exports\n  the identity variables before the provider starts. Interactive terminal\n  providers such as Codex, Claude, Kimi, and Grok run in a persistent tmux\n  session by default when launched from an interactive terminal, with a directed\n  waiter kept alive in the background. Non-terminal commands keep the temporary\n  `syn arm` sidecar path.\n\n  ```bash\n  synapse worker-session --identity myrepo/worker -- codex --sandbox danger-full-access\n  ```\n\n- **Inspect or control the tmux wake path manually:** `codex-tmux` is the\n  diagnostic/admin surface behind the automatic provider launch path. It keeps a\n  provider TUI in a named tmux session and injects a fixed wake prompt when\n  Synapse receives a directed message. It does not paste the Synapse payload into\n  the terminal; the provider reads the inbox itself after waking. Existing\n  sessions are accepted only when their live tmux environment matches the\n  configured `SYN_PROJECT` and exact `SYN_IDENTITY`; a session already owned by\n  another seat is refused by start, status, and wake before any keys are sent.\n  A successful `tmux send-keys` call is not treated as provider delivery: the\n  bridge observes prompt consumption and retains an unacknowledged staged prompt\n  for a later Enter-only retry, so provider startup cannot strand or duplicate it.\n  While waiting, the bridge disconnects at a bounded interval and re-proves the\n  session, binding, and live agent pane before registering again, so a vanished\n  pane cannot remain advertised indefinitely.\n\n  ```bash\n  synapse codex-tmux start --identity myrepo/codex-main --session myrepo-codex --cwd \"$PWD\"\n  synapse codex-tmux wait --identity myrepo/codex-main --session myrepo-codex --cwd \"$PWD\"\n  ```\n\n  For unattended operation, replace the manually maintained `wait` process with\n  `synapse waker install --identity myrepo/codex-main --session myrepo-codex\n  --cwd \"$PWD\" --agent-command codex --start`. The waker supervises only the\n  delivery bridge and attaches to the existing bound session; it never owns the\n  provider terminal lifecycle.\n\n### Agent ergonomics — the `syn` commands\n\nFor the short loop an agent runs every session — arm a waiter, send a message,\nread the inbox, glance at the board — the package also ships `syn`, a thin,\nidentity-correct front end over the commands above:\n\n```bash\nsyn name                          # resolve and print this terminal's identity\nsyn arm                           # keep a directed-only waiter armed (named <project>-rx, distinct from the sender)\nsyn say REMANENTIA,CEO \"ack\"      # send to one, several, or all\nsyn ask CEO \"status?\"             # send, require an online recipient, and wait for replies\nsyn inbox                         # print messages addressed to you since the cursor\nsyn inbox --project-wide          # explicitly include every identity in this project\nsyn inbox --name PROJ/role        # read one exact identity under its own cursor\nsyn board                         # the shared task/progress board\nsyn who --me                      # show whether this identity and its -rx waiter are online\nsyn reap                          # list this identity's shell-hook waiter pidfile\nsyn reap --pid 1234               # remove a dead pidfile or SIGTERM only the verified waiter PID\nsyn locks                         # list this project's active leases with release commands\nsyn ack BUILD --evidence \"pytest -q\" --artifact coverage.xml\nsyn commit README.md -m \"document the change\"\n```\n\nThe one thing it gets right that a hand-rolled shell alias does not is **identity**.\nThe project is resolved from `--project`, then `$SYN_PROJECT`, and the working\ndirectory only as a last resort. Ambient `$SYN_IDENTITY` is **never a silent\nsource**: it refines the identity to a full `project/<type>-<id>` only when\n`$SYN_PROJECT` is also set and agrees with it — the pair the shell hook exports\ntogether is the opt-in. A `SYN_IDENTITY` standing alone or disagreeing (the\nborrowed-shell signature) is dropped out loud: the command proceeds as the local\nidentity and says so, or refuses entirely when the local fallback also looks\naccidental (the home directory, a system path). Set `$SYN_PROJECT` once per\nterminal and the identity is stable across tool calls.\n`syn inbox` filters on that full resolved identity and advances a cursor named for\nthat identity. It never falls back to a shared project cursor. Use\n`--project-wide` when the broader project feed is intentional, `--name PROJ/name`\nfor another exact address, or repeat `--as PROJ/name` to drain standing role\naddresses under independent cursors. A bare `--as PROJ` is the explicit\nproject-wide alias form; `$SYN_ALIASES` supplies the same standing alias list.\nOn the hub side the waiter identity is protected by a **name-ownership lease**:\nthe first `synapse wait`/`arm` for a name is granted an opaque token (persisted\nunder `~/synapse/owner-lease/`), every re-arm presents it and re-takes its own\nname, and a stranger claiming the name — takeover flag or not — is refused with\nclose code `4016` until the lease lapses (`--lease-offline-ttl`, default one\nhour offline). Beneath the lease sits a **zero-config machine identity**: the\nfirst connect provisions a per-machine Ed25519 key, the hub pins each signed\nname to it on first use (durable across hub restarts, `--identity-pins`), and\na claim from any other machine is refused until the operator clears the pin.\nOne name, one owner, across reconnects and restarts.\nWhile the hub is running, it also watches every unexpired claim and assigned\nnon-terminal board task. If that exact owner has no fresh `-rx` waiter for 30\ncontinuous seconds, the hub broadcasts one machine-readable `dark_seat_alert`\nwith the affected work and the exact permanent-arm command. Re-arming clears the\nepisode; the monitor never releases or reassigns work on its own.\nHyphenated aliases\n(`syn-name`/`syn-wait`/`syn-say`/`syn-ask`/`syn-inbox`/`syn-board`/`syn-reap`/`syn-locks`/`syn-ack`/`syn-commit`)\nare installed too.\n\n| Command | What it does | The detail it gets right |\n| --- | --- | --- |\n| `syn name` | Resolve and print this terminal's identity. | Same resolution order every `syn` command uses — what it prints is what you coordinate as. |\n| `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. |\n| `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. |\n| `syn say` | Send to one, several, or all. | Sends as the owner identity even when a waiter holds the `-rx` name. |\n| `syn ask` | Send and wait for replies. | Requires an online recipient — a question never silently addresses nobody. |\n| `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`. |\n| `syn board` | The shared task/progress board. | One view of the plan every agent sees. |\n| `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. |\n| `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. |\n| `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. |\n| `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`. |\n| `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. |\n\nTwo follow-ons complete that loop. Adding `--mailbox` to `synapse arm` also wakes\nthe waiter on directed messages that arrived while it was disconnected — the\nreconnect or re-arm gap — by asking the hub to replay them on connect, resuming\nfrom a per-identity cursor under `~/synapse/mailbox-cursor/` so a re-arm does not\nreplay the whole backlog (off by default; needs a wire version `2` hub).\nAgent-tmux uses a distinct `<identity>-pane-rx` receiver, so the mailbox arm can\nstay online beside live pane injection without either sidecar taking over the\nother's name. `synapse release` can attach a hub-echoed receipt with evidence, artifacts,\nchanged files, approvals, known failures, confidence, and evidence freshness; the\nreceipt carries advisory `epistemic_status` metadata (`supported`,\n`needs_freshness`, `stale`, `degraded`, or `unsupported`) with reasons derived\nfrom the submitted evidence, and `--receipt-json` prints it for automation.\n\nTo make fresh terminals connect automatically, install the shell hook once:\n\n```bash\nsynapse install-shell-hook --shell auto\n```\n\nNew Bash/Fish/Zsh terminals then export `SYN_PROJECT`/`SYN_IDENTITY` and keep a\ncheap `synapse arm` sidecar running. The hook does **not** silently join whatever\ngit checkout the terminal happens to start in. It joins the neutral\n`SYNAPSE_DEFAULT_PROJECT` lane, or `user` when unset, unless you explicitly set\n`SYN_PROJECT`/`SYN_IDENTITY` or opt a repository in with `.synapse/project`:\n\n```bash\nmkdir -p .synapse\nprintf '%s\\n' myrepo > .synapse/project\n```\n\nFor legacy CWD-derived behavior, set `SYNAPSE_AUTO_PROJECT_FROM_CWD=1` in that\nterminal. The hook also wraps common provider commands (`codex`, `claude`,\n`kimi`, `grok`, `gemini`, `agent`, `ask`, `ollama`) through `synapse\nworker-session`, so cloud and local LLM sessions inherit the same Synapse\nidentity from process start. In an interactive terminal, Codex/Claude/Kimi/Grok\nlaunch through a persistent tmux session and directed wake bridge automatically;\nthe user still types only the provider command. Set `SYNAPSE_PROVIDER_TMUX=0` to\nkeep those providers on the direct execution path, or `SYNAPSE_AUTO_CONNECT=0` to\ndisable the hook for a terminal.\n\n### Durability\n\nPassing `--db` backs the hub with an append-only SQLite event log (standard\nlibrary, WAL mode). Claims, releases, task updates, resource offers, task-board\nwrites, and chat messages are recorded, and the hub rebuilds its state by\nreplaying the log on start-up. The guarantee is split honestly by workload:\nkeyed covered coordination mutations commit their event, canonical request\ndigest, exact response, and evidence intent together at `synchronous=FULL`\n(durable across an OS crash); the high-volume chat/history path commits at\n`synchronous=NORMAL` (durable across an application crash, may lose the last\ncommit on power loss).\n\nNative Agent Evidence Format (AEF) v0.1 emission is an explicit opt-in on top\nof that durable log. Generate an owner-only Ed25519 receipt key, give the hub a\nstable identity, and enable the route:\n\n```bash\nsynapse merkle keygen ~/synapse/aef-receipt-key\nsynapse hub \\\n  --db ~/synapse/hub.db \\\n  --hub-id hub.example \\\n  --aef-signing-key ~/synapse/aef-receipt-key\n```\n\nSupported evidence rows and their AEF outbox cursor commit in one SQLite\ntransaction. Before serving, the hub reconciles every pending cursor; while\nserving, a dedicated worker drains new rows in order (default cadence one\nsecond, configurable with `--aef-drain-interval`). A crash after receipt\nemission but before acknowledgement reuses the verified receipt rather than\nemitting a duplicate. A failed drain leaves the durable cursor pending and\nretries; legacy rows and their historical Merkle serialization are never\nrewritten or merged with the native AEF chain. Without `--aef-signing-key`, the\nhub retains its legacy-only posture.\n\nUse `synapse compact` to bound the durable memory spine after every read-side\nconsumer has advanced past a floor sequence. Add `--archive-report` when the\nmaintenance run should leave an operator-readable HTML record of the\npre-compaction event snapshot:\n\n```bash\nsynapse compact ./synapse.db --all --max-checkpoints-per-task 3 \\\n  --archive-report ./compact-report.html\n```\n\nThe report is written owner-only and includes event counts, the compaction floor,\ncheckpoint/finding removal counts, board tasks, release receipt notes, and a\nbounded coordination timeline. It is an audit aid for a local event store; it\ndoes not certify that release evidence is sufficient.\n\n### SQLCipher live event store (at rest)\n\n**SQLCipher completes the at-rest encryption story for the live hub.** The\ndefault install stays dependency-free and uses ordinary SQLite. When you need\npage-level confidentiality for the durable coordination log while the hub holds\nit open, install the optional extra and pass an owner-only key file:\n\n```bash\npython -m pip install 'synapse-channel[sqlcipher]'\nsynapse encrypt-key generate ~/synapse/hub.key\nchmod 600 ~/synapse/hub.key\n\n# New encrypted store (main DB + WAL stay ciphertext on disk):\nsynapse hub --db ~/synapse/hub.db --db-key-file ~/synapse/hub.key\n\n# Plaintext → encrypted offline migration (hub stopped; destination must not exist):\nsynapse encrypt-key migrate-sqlcipher \\\n  --key ~/synapse/hub.key \\\n  --source ~/synapse/hub-plain.db \\\n  --destination ~/synapse/hub.db\n\n# In-place key rotation via PRAGMA rekey (hub stopped):\nsynapse encrypt-key generate ~/synapse/hub.key.new\nsynapse sqlcipher rekey \\\n  --db ~/synapse/hub.db \\\n  --old-key ~/synapse/hub.key \\\n  --new-key ~/synapse/hub.key.new\n```\n\nPassphrase-derived keys (optional) tune scrypt cost on generation:\n\n```bash\nsynapse encrypt-key generate --from-passphrase \\\n  --scrypt-n 65536 --scrypt-r 8 --scrypt-p 1 \\\n  ~/synapse/hub.key\n```\n\n**Operators and analysis CLIs** open the same store with the same key material —\nmissing or wrong keys **fail closed** (no silent empty report):\n\n```bash\nsynapse doctor --db-path ~/synapse/hub.db --db-key-file ~/synapse/hub.key\nsynapse event-query ~/synapse/hub.db --db-key-file ~/synapse/hub.key 'task T timeline'\nsynapse postmortem ~/synapse/hub.db --db-key-file ~/synapse/hub.key T\nsynapse reliability ~/synapse/hub.db --db-key-file ~/synapse/hub.key\nsynapse causality contention ~/synapse/hub.db --db-key-file ~/synapse/hub.key\nsynapse dashboard --feeds-db ~/synapse/hub.db --feeds-db-key-file ~/synapse/hub.key\nsynapse multihub observe --peer-db ~/peer/hub.db --db-key-file ~/peer/hub.key\n```\n\n| Surface | What SQLCipher covers |\n|---|---|\n| **Live hub** | `synapse hub --db … --db-key-file` — page encryption for main DB + WAL while open |\n| **Doctor** | `synapse doctor --db-path … --db-key-file` — verify the key opens the store |\n| **Readers / analysis** | `event-query`, `postmortem`, `merkle`, `causality`, `accounting`, `reliability`, `trust-graph`, `memory-recall`, `debug`/`reproduce`, `approval status`, `ttl-advice`, `workflow contention`, `participant costs`, `cross-repo --db`, … |\n| **Operator UI** | Dashboard store feeds via `--feeds-db-key-file` |\n| **Multi-hub / MCP** | `multihub observe --db-key-file`; MCP tools take `event_store_key_file` for route observations and memory recall |\n\n**Complementary whole-file envelopes** (optional `[encryption]` extra) protect\nrelay logs, A2A state files, cursors, and archives with AES-256-GCM via\n`synapse encrypt-key profile|migrate|rekey|backup|restore`. They do **not**\nreplace page encryption for a live open SQLite database — that is SQLCipher's\njob.\n\nHonest limits: SQLCipher does not protect hub RAM, does not replace filesystem\npermissions or connect authentication, and is not multi-tenant isolation. Stock\ninstalls without `[sqlcipher]` refuse `--db-key-file` with an install hint.\n\nFull operator profile, key handling, and rotation: **[at-rest encryption](docs/at-rest-encryption.md)**.\n\n### Token-thrifty observation\n\n`--relay-log` mirrors every broadcast to a newline-delimited file in a compact\nshort-key form (`encode_lite`), so a token-budgeted agent can watch the channel\nby tailing a file instead of holding a socket. `synapse relay <file>` decodes it\nback to readable lines and can resume from a saved `--cursor`. Version 2 retains\nstructured JSON payloads and every auxiliary envelope field under a compact\nextension mapping; the decoder remains compatible with existing version-1 logs.\nTimestamps retain millisecond precision, and `--relay-max-lines` bounds the file.\nA committed benchmark compares the same full field set in wire, minified, and\nlite forms — see [`benchmarks/`](benchmarks/).\n\n### Exposure\n\nBy default the hub binds to loopback and runs with no authentication — the right\nposture for one operator on one machine. When that is not enough (a worker with\ntool-use, or a hub bound off-loopback), `--token` requires a shared secret that\nconnecting agents present with `--token`. Binding off loopback without a token is\n**refused** rather than silently exposed: the hub will not start unless you set a\ntoken (and `--metrics-token` when metrics are on), or explicitly pass\n`--insecure-off-loopback` to accept the risk. This is a proportionate gate, not a\ncryptographic identity system.\nFor native `wss://`, pass both `--tls-certfile` and `--tls-keyfile`. TLS protects\nthe transport but does not replace `--token`; an off-loopback hub still needs the\nshared secret unless you explicitly opt into `--insecure-off-loopback`. Off\nloopback TLS is also required, not just recommended: a token presented over\nplaintext `ws://` off loopback is **refused** (the token and every frame would be\nreadable on the wire), so add native TLS or a `wss://` proxy — or pass\n`--insecure-off-loopback` to accept the risk on a trusted LAN.\n\n### MCP server face\n\nAny MCP-compatible agent — Claude Desktop, Claude Code, an editor assistant —\ncoordinates through Synapse with no Synapse-specific code. Install the optional\nextra and register the host in one command:\n\n```bash\npython -m pip install 'synapse-channel[mcp]'\nclaude mcp add synapse -- synapse mcp\n# or: codex mcp add synapse -- synapse mcp --name my-repo/codex\n```\n\n`synapse mcp` runs a Model Context Protocol server over stdio that is itself a hub\nclient, exposing send, bounded durable inbox, status, claim, release, handoff,\nand plan updates as MCP tools, with the board, state, and manifest as live\nresources. It also exposes read-only resource templates for a single board task,\none agent, and one resource kind. The bridge derives a visible project identity\nwhen `--name` is omitted, but concurrent clients should pin distinct names. It\ndoes not wake an idle provider; the permanent waiter remains a separate path.\nThe hub stays MCP-agnostic and the core install keeps its single dependency — see\nthe [MCP guide](docs/mcp.md).\n\n### Discovery, advisory routing, and memory\n\nEvery surface in this group is **advisory by design**: it prints ranked,\nprovenance-tagged evidence for a human or an agent to act on, and none of it\nclaims work, reserves capacity, mutates the board, or turns a capability card\ninto executable trust.\n\n| Surface | What it prints or serves | Where its authority ends |\n| --- | --- | --- |\n| `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. |\n| `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. |\n| `synapse directory` | The capabili",
  "bytes": 60000,
  "sha": "233a56df7bd64b996ad173488b70d45b37b157bb163dda58142db087aa148c85",
  "repo_slug": "anulum/synapse-channel",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_anulum_synapse_channel_d1985820/readme"
}