{
  "markdown": "![Octopus Blackboard](docs/diagrams/banner.png)\n\n# Octopus Blackboard\n\n**A shared memory and coordination layer for AI coding agents.**\n\n> Agents do not need another boss. They need a shared blackboard.\n\n[简体中文](./README.zh-CN.md)\n\n> **Part of [Octopus Core](https://github.com/octoryn) — the open infrastructure stack for governed AI.** One job per repo, along the agent lifecycle: [Scout](https://github.com/octoryn/octopus-scout) · [Observe](https://github.com/octoryn/octopus-observe) · [Experience](https://github.com/octoryn/octopus-experience) · [Blackboard](https://github.com/octoryn/octopus-blackboard) · [Workstate](https://github.com/octoryn/octopus-workstate) · [Runtime](https://github.com/octoryn/octopus-runtime) · [Replay](https://github.com/octoryn/octopus-replay) — with [Inspect](https://github.com/octoryn/octopus-inspect) governing every stage. The whole stack rides one root primitive — [Evidence](https://github.com/octoryn/octopus-evidence), the canonical, tamper-evident atom that is the root category everything is built on.\n>\n> **This repo — Blackboard · Coordinate:** Shared cognition for coding agents.\n\n![How it works: agents connect over MCP to a shared blackboard that records and exposes but never orchestrates, producing a conflict-aware kanban, AI attribution, a CI review gate, and a tamper-evident audit trail](docs/diagrams/value-flow.png)\n\n---\n\nClaude Code, Codex, Gemini CLI, Cursor, and your local agents all work on the\nsame repo — but they are blind to each other. One refactors auth while another\nrewrites the same file. Context is scattered across CLIs. Nobody can replay what\nhappened.\n\nOctopus Blackboard is **not an orchestrator.** It does not schedule agents,\ntrigger them, or decide anything on their behalf. It is a passive, local-first\nshared memory that answers six questions:\n\n```text\nWho is working on what      →  agents, tasks, claims\nWhat changed                →  files_changed\nWhat was decided            →  decisions\nWhat evidence exists        →  evidence\nWhat risks are open         →  risks\nWhat was left for whom       →  messages, handoffs\n```\n\nEvery agent only needs to be able to **read the board, write the board,\nleave messages, and attach evidence.** That's the whole contract.\n\n## Why\n\n![Without a shared board, agents work blind — duplicate edits, no attribution, unseen conflicts. With Octopus Blackboard they share memory and produce a conflict-aware kanban, attribution, a review gate, and an audit trail](docs/diagrams/before-after.png)\n\nEnterprises are not primarily afraid that agents aren't smart enough. They are\nafraid that:\n\n- Multiple AI tools edit the same code simultaneously\n- Context is scattered across different CLIs\n- There is no shared memory, no audit, no handoff\n- There is no conflict awareness and no way to replay\n\nThe blackboard cuts straight through this. Every write appends a\n**tamper-evident, hash-chained entry** to an append-only `timeline`, so the\nentire history is auditable and replayable — and any after-the-fact edit to an\nearlier entry breaks verification.\n\n## Get Started in 2 Minutes\n\nBlackboard is the easiest way into the Octopus stack — pure coordination memory\nthat works today with just Claude Code and Cursor, no orchestrator required.\nOne command sets everything up:\n\n```bash\nnpx octopus-blackboard quickstart\n```\n\nThat single command: creates the local board (`.octoboard/`) if it isn't there,\n**auto-detects your MCP client** (`.claude/` → Claude Code, `.cursor/` → Cursor,\n… otherwise a generic snippet), prints the exact **paste-ready config** for it,\nand proves the board works with one write + one read.\n\nThen just:\n\n1. **Paste** the printed config block into the file it names.\n2. **Reload** your MCP client (restart it, or reopen the project).\n3. **You're done.** Ask your agent to call `board_status`, then\n   `board_note \"hello\"` — that's your first board action, on a shared,\n   tamper-evident timeline.\n\nRe-running `quickstart` is always safe: it never clobbers an existing board or\nits history. New to the idea of adopting a coordination layer *first*? See\n[**Why adopt Blackboard first**](docs/entry-point.md).\n\n## Install\n\n```bash\nnpm install\nnpm run build      # compiles to dist/\n```\n\nRequires Node ≥ 22. The board is a single SQLite file under `.octoboard/`,\ndiscovered by walking up from your working directory (like `.git`).\n\n## See it in action\n\n[`examples/two-agents.sh`](./examples/two-agents.sh) plays out the flagship\nscenario — Claude Code and Codex sharing one board on the same repo: a claim\nconflict, a live same-file collision, a decision, attribution, a handoff that\nlands in the other agent's inbox, an AI review, the human-approval CI gate\n(blocked → passes), the accountability scorecard, blame→narrative, and a\nverified hash chain with session signatures. Run it in an empty directory:\n\n```bash\nbash examples/two-agents.sh          # needs `octoboard` on PATH\n```\n\n## CLI\n\n```bash\noctoboard init                                   # create .octoboard/ here\noctoboard status                                 # who's on the board, right now\n\noctoboard note \"Codex is refactoring auth middleware\"\noctoboard claim trust-layer-policy-schema        # claim work; warns on conflict\noctoboard message claude \"Review policy edge cases before merge\"\noctoboard decision \"Use hash-chain audit log\" --why \"tamper-evidence\"\noctoboard risk \"Migration may break audit replay\" --severity high\noctoboard file src/auth.ts --change modified --task trust-layer-policy-schema\noctoboard handoff claude \"Tests pass except policy replay\" --task trust-layer-policy-schema\n\noctoboard timeline                               # the full hash-chained history\noctoboard verify                                 # confirm the chain is intact\n```\n\nIdentity is set with `--as <agent>` or the `OCTOBOARD_AGENT` environment\nvariable. Point at a specific board with `--board <dir>` or `OCTOBOARD_DIR`.\n\n### Conflict awareness\n\nThe board never blocks — it *surfaces*. If two agents claim the same key, or\ntouch the same task's files, both writes are recorded and the second agent is\nwarned:\n\n```text\n⚠ CONFLICT: \"trust-layer-policy-schema\" is also held by codex. Both claims recorded.\n```\n\n## AI attribution & shared development memory\n\nGit records who *pushed* a commit. It does not record which AI agent produced\nthe code, in which session, on which machine, whether another AI reviewed it, or\nwhether a human approved it. As AI-native development becomes common,\naccountability must move beyond Git authorship.\n\nThe blackboard adds an attribution layer **on top of** Git — it never rewrites\nhistory. Git stays the source of code; the blackboard becomes the source of\nattribution.\n\n### Sessions\n\nA session is one continuous execution of an agent, and the unit attribution\nhangs off. Starting one makes every subsequent write attribute to it (the active\nsession is remembered across CLI invocations, per agent):\n\n```bash\nexport OCTOBOARD_AGENT=claude OCTOBOARD_PROVIDER=anthropic \\\n       OCTOBOARD_MODEL=claude-opus-4-8 OCTOBOARD_CLI=claude-code\n\nblackboard session start --label \"auth work\"   # captures machine, branch, repo\nblackboard claim policy-engine\nblackboard file src/policy.ts --change modified\n# ... make a git commit ...\nblackboard link HEAD                            # attribute the commit's files\nblackboard session stop\n```\n\nIdentity is fully provider-independent — `--provider`, `--model`, `--cli`, or\nthe matching `OCTOBOARD_*` env vars. Any AI CLI (local or cloud) can register\nitself with no assumptions about a specific vendor.\n\n### Linking commits\n\n`blackboard link <rev>` reads the files a commit touched (via Git) and records\none attribution per file for the active session. Optionally it writes an\nadditive `git notes` entry under `refs/notes/blackboard`:\n\n```bash\nblackboard link HEAD --note\nblackboard attribute <sha> --file src/x.ts --actor human --name Ran  # manual\n```\n\n### Reviews\n\n```bash\nblackboard review HEAD --by ai   --name codex --outcome approved --note \"tests pass\"\nblackboard review HEAD --by human --name Ran   --outcome approved\n```\n\n### Querying the shared memory\n\n```bash\nblackboard who src/auth.ts             # git authors + AI sessions that touched it\nblackboard who src/auth.ts --line 42   # which session introduced this line\nblackboard explain HEAD                # attribution + reviews + related decisions\nblackboard commits claude-code         # which commits came from an AI / CLI\nblackboard unreviewed                  # AI commits never reviewed by a human\nblackboard joint claude codex          # files modified by BOTH agents\nblackboard timeline --session <id>     # per-session HH:MM timeline\n```\n\nExample `explain`:\n\n```text\ncommit 5fa3095…  Human Dev <a@b.c>  add auth\n  produced by:\n    ai claude [claude-opus-4-8] — src/auth.ts\n  reviews:\n    human Ran: approved\n  git note: blackboard: produced by claude-code (claude-opus-4-8), session 75b2b7e7…\n```\n\nEvery attribution, review, session, and decision is also recorded in the\nhash-chained `timeline`, so the full accountability history is tamper-evident\nand replayable. `blackboard` and `octoboard` are the same command.\n\n## Governance & accountability chain\n\n![The accountability chain: agent does work → attribute the commit → export/import → CI gate blocks unreviewed AI → human approves → merge, all recorded on the tamper-evident timeline](docs/diagrams/governance-chain.png)\n\nThe point of attribution is to *enforce* something. The chain from work to a\nmerge gate:\n\n```text\nagent work → commit attribution → export/import → CI check → human-review gate\n```\n\n### CI gate (`check`)\n\nTurn queries into an enforceable gate. Read-only — it reports pass/fail and\nexits non-zero; the CI system decides what to do. The blackboard never blocks.\n\n```bash\n# In CI, on a PR branch — fail the build if any AI commit isn't human-APPROVED\n# (a rejected / changes-requested review does not clear the gate):\nblackboard check --range origin/main..HEAD --require-human-review\necho $?   # 0 = pass, 1 = violations\n\nblackboard check --verify-chain --require-attribution --range origin/main..HEAD\nblackboard check            # default gate: verify chain + require human review\n```\n\n### Portability (`export` / `import` / `trailers`)\n\nAttribution is local-first; these make it survive `git push` into a team board\nor CI:\n\n```bash\nblackboard export --range origin/main..HEAD --out attribution.json  # on the dev machine\nblackboard import attribution.json                                   # on the team board / CI\nblackboard trailers HEAD                                             # trailer lines for a commit message\n```\n\n`import` is idempotent (keyed by row id). The bundle carries attributions,\nreviews, sessions, and related decisions.\n\n### Subscribe (`watch`)\n\nComplete the read/write/**subscribe**/message contract. Passive: it polls and\nreports; it never pushes work.\n\n```bash\nblackboard watch --for claude     # only messages/handoffs/conflicts addressed to me\nblackboard watch                  # the full stream\nblackboard watch --once           # one-shot poll (for scripts)\n```\n\n### Signed sessions (`sign` / `verify`)\n\nMinimal identity (v0): each session gets an Ed25519 keypair (private key stays\nlocal under `.octoboard/keys/`, gitignored). Signing the timeline head lets\n`verify` distinguish **trusted** state from merely asserted:\n\n```bash\nblackboard sign        # sign the current head with the active session key\nblackboard verify      # chain integrity + which sessions have signed, trusted/stale\n```\n\nA session auto-signs its head on `session stop`. A signature over a head becomes\n**stale** the moment any earlier history is altered — so tampering is visible\neven though the signature itself stays cryptographically valid. This is not yet\na full PKI (no key distribution or revocation).\n\n## Ingesting CLI transcripts\n\nPopulate the board from a CLI's session transcript instead of calling the API\nby hand — file edits, decisions, and notes flow onto the active session:\n\n```bash\nblackboard ingest ~/.claude/transcript.jsonl --format claude-code\nblackboard ingest session.jsonl --format codex        # also: gemini, grok\nblackboard ingest events.json    --format generic --dry-run\n```\n\n`claude-code`/`codex`/`gemini`/`grok` use a conservative tool-use JSONL\nheuristic (it finds file edits from `file_path`/`notebook_path` and\npatch/write tool calls). `generic` reads a normalized schema — the stable\nintegration path for **any** CLI:\n\n```json\n{ \"events\": [\n  { \"type\": \"file\", \"path\": \"src/auth.ts\", \"change\": \"modified\" },\n  { \"type\": \"decision\", \"title\": \"use ed25519\", \"rationale\": \"small keys\" },\n  { \"type\": \"note\", \"text\": \"left policy edge cases for review\" }\n] }\n```\n\n## Team backend\n\nBoards stay local-first; sync shares the portable attribution records (never a\nboard's private hash chain) into a team store — a shared file or Postgres.\n\n```bash\nblackboard sync push --target /shared/team.json          # file (shared drive)\nblackboard sync pull --target postgres://host/blackboard # team database (needs `pg`)\n```\n\n`export` signs the bundle with your active session key; `import` verifies it and\n`import --require-signed` refuses unsigned or tampered bundles — so imported\nattribution has origin authenticity, not just id-dedup.\n\nTamper-evidence goes further than the in-DB chain if you anchor the head\nexternally:\n\n```bash\nblackboard anchor --git-note              # record seq:hash on the commit (or --out file)\nblackboard verify --against git-note      # prove history wasn't truncated/altered\n```\n\nLiveness and compliance:\n\n```bash\nblackboard session heartbeat        # mark your session alive (active vs stale)\n# `blackboard file ...` now warns if another LIVE session is editing the same file\n\nblackboard prune --before 2026-01-01T00:00:00Z   # retention: drop old messages/\n                                                 # evidence/file-changes (timeline kept)\nblackboard redact 42 --reason PII                # hide a timeline entry's content\n```\n\n`prune` never touches the append-only timeline (the audit trail). `redact`\nblanks the content across every read path — the timeline overlay *and* the\nunderlying source row (a message body, evidence note, etc.) so `inbox`/`status`/\nthe dashboard can't leak it — while keeping the hash chain valid. It is not\ncryptographic erasure: the original summary stays in the timeline row so the\nchain still verifies, so don't store secrets you must be able to destroy. For\ntamper-evidence against an attacker with database write access, anchor the head\nhash externally (a commit, a log, a second machine) — `verify` shows an\n`unanchored` warning when it can't confirm the tail.\n\n## Tasks & kanban\n\nTasks are kanban cards — number, content, owner (which agent / CLI), project,\nblast radius, risk, and live progress. **\"Notifying an agent\" is passive:**\nassigning a task drops a \"please look at task #N\" message in that agent's inbox;\nthe agent reads it and decides to act — the board never launches anyone.\n\n![The read-only blackboard serve dashboard, a live kanban of tasks](docs/kanban.png)\n\n*The live `blackboard serve` dashboard — read-only, auto-refreshing. Each card\nshows the task number, progress bar, assignees, active-agent count (⚡), project,\nand a risk-coloured border.*\n\n```bash\nblackboard task add auth-mw --title \"Refactor auth middleware\" \\\n  --project octopus-api --impact \"src/auth.ts, src/db.ts\" --risk high\nblackboard assign 1 claude       # → drops \"please look at task #1 …\" in claude's inbox\nblackboard progress 1 40         # → moves #1 to in-progress, 40%\nblackboard tasks                 # kanban view, grouped by status\nblackboard task show 1           # full card: owner, project, impact, risk, files\n```\n\nThe read-only `serve` dashboard renders these as a live kanban (columns by\nstatus; each card shows number, title, a progress bar, assignees, active-agent\ncount, project, and a risk-coloured left border). Agents drive it via the MCP\ntools `board_task_define`, `board_assign`, `board_progress`, `board_tasks` — an\nagent calls `board_progress` as it works so the bar moves in real time.\n\n## Visibility\n\n```bash\nblackboard report          # scorecard: review coverage %, AI/human ratio, per-agent\nblackboard blame src/auth.ts 42   # trace a line → the session that wrote it, and its\n                                  # other work, decisions, and handoffs (blame → narrative)\nblackboard serve           # read-only local web dashboard (http://localhost:4319)\n```\n\nThe dashboard is dependency-free (`node:http`), strictly read-only (non-GET is\nrefused), and auto-refreshes: live timeline, sessions, conflict/attribution\nstate, and the accountability scorecard.\n\n## MCP server — connect any CLI\n\nThe blackboard speaks standard MCP over stdio, so **any** MCP-capable client\n(Claude Code, Cursor, Codex, Gemini CLI, VS Code, Windsurf, …) can read and\nwrite the board. Generate the exact config for your client in one step:\n\n```bash\nblackboard mcp-config cursor        # → ~/.cursor/mcp.json block\nblackboard mcp-config claude-code   # → project .mcp.json block\nblackboard mcp-config codex         # → ~/.codex/config.toml (TOML)\nblackboard mcp-config gemini        # → ~/.gemini/settings.json block\nblackboard mcp-config vscode        # → .vscode/mcp.json (servers block)\nblackboard mcp-config               # → generic mcpServers JSON (any client)\n```\n\nEach prints where to paste it and the ready-to-use snippet, e.g.:\n\n```json\n{\n  \"mcpServers\": {\n    \"blackboard\": {\n      \"command\": \"npx\",\n      \"args\": [\"-y\", \"octopus-blackboard-mcp\"],\n      \"env\": { \"OCTOBOARD_AGENT\": \"cursor\" }\n    }\n  }\n}\n```\n\nThe agent identity defaults to the client name (so Cursor writes as `cursor`,\nCodex as `codex`); override with `--agent`. The board is auto-discovered from\n`.octoboard/` in the working directory, or pin it with `--dir`. Two CLIs\npointed at the same `.octoboard/` now share one board — that's the whole point.\n\nTools exposed — coordination: `board_status`, `board_timeline`, `board_note`,\n`board_claim`, `board_task_define`, `board_task`, `board_tasks`, `board_assign`,\n`board_progress`, `board_message`, `board_inbox`, `board_handoffs`,\n`board_decision`, `board_evidence`, `board_file_changed`, `board_risk`,\n`board_handoff`, `board_heartbeat`, `board_since`; attribution: `session_start`,\n`session_stop`, `board_link`, `board_attribute`, `board_review`, `board_who`,\n`board_explain`, `board_blame`, `board_unreviewed`, `board_report`; governance &\nportability: `board_check`, `board_export`, `board_import`, `board_trailers`,\n`board_sign`, `board_trust`, `board_prune`, `board_redact`, `board_ingest`. Each\naccepts an optional `agent` argument to override the acting identity per call.\n\nThe recommended pattern: an agent calls `board_status` **before** starting work\nto see what everyone else is doing, and writes as it goes.\n\n## Data model\n\n| Layer | Tables | Purpose |\n|---|---|---|\n| **Who is present** | `agents`, `sessions` | provider-independent identity, session context |\n| **What's happening** | `tasks`, `messages`, `handoffs` | coordination — claim, message, hand off |\n| **Who produced what** | `attributions`, `reviews` | AI/human attribution & review, keyed by commit |\n| **Settled facts** | `decisions`, `evidence`, `files_changed`, `risks`, `timeline` | auditable shared memory |\n\n`timeline` is the append-only hash chain every other write also records into, so\nthe board and its audit log can never diverge.\n\n## Architecture\n\n```text\nbetter-sqlite3 (local-first, default)\n  + MCP server   (read / write board)\n  + CLI          (octoboard ...)\n  + hash-chain audit log (the timeline)\n  + optional Postgres sync   (portable attribution records)\n  + optional git / file watcher (planned)\n```\n\n## Status\n\nPublic beta (v0.3). Working today: local SQLite board, CLI (`octoboard` /\n`blackboard`), MCP server, a verifiable hash-chained timeline, first-class\nsessions, provider-independent AI/human attribution keyed to Git commits,\nreviews, the query layer (`who`, `explain`, `commits`, `unreviewed`, `joint`),\nthe read-only `serve` dashboard, signed import/export bundles, retention,\nredaction, quickstart, and MCP registry metadata/publishing workflow. Git\nintegration is read-only plus additive `git notes` — history is never rewritten.\nTeam sync supports a shared JSON file and a Postgres target for portable\nattribution records; the board's private hash chain remains local by design.\nChange subscriptions and deeper Octopus cross-repo bridges are still roadmap\nwork.\n\n## License\n\nApache-2.0 © Octoryn. See [LICENSE](./LICENSE).\n",
  "bytes": 20561,
  "sha": "19ad99e482eb029f8d8a46a70667ab55079a3dc12ae70a7d69939bd1fb82a033",
  "repo_slug": "octoryn/octopus-blackboard",
  "fonte": "repo",
  "truncated": false,
  "api": "https://agentalog.com/api/listings/mcp_io_github_octoryn_octopus_blackboard_2f096bea/readme"
}