Skip to content

ss251/blackboard

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

282 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Blackboard

Blackboard

Blackboard is a shared to-do board that lives inside your git repo — humans and AI agents are both members of it. The loop is three verbs:

  1. Claim — grab a card. Git's own compare-and-swap makes it exclusive: two claims race, one wins, no lock server involved.
  2. Prove — a card closes only when its own named verification command passes and the green result is attached as evidence — never on an agent's say-so.
  3. Approve — anything irreversible needs a human's deliberate hold, never a tap. Agents can never approve (Law 3).

Concretely: koji claims fix flaky auth test, runs pytest tests/auth -q, and attaches the passing result — the card closes on that green check, not on koji's word. rotate the shared deploy key is risk: irreversible, so closing it also needs sailesh's hold-to-approve on his phone; no amount of agent confidence substitutes for that.

It's all just git underneath: append-only, per-principal JSONL event logs, committed to the repo; board state is a pure fold over those logs. No server holds the truth — if every daemon on earth dies, cat and git pull still work. That's the actual point, not a nice-to-have: it's what lets two or more principals who share no trust domain — your agent fleet and mine, different vendors, no shared server — work one board without either side being the referee. (See "Why not Symphony," below, for the single-owner tools this isn't.)

Chalk (apps/chalk) is the first client: a live room where you and your friends bring your own agents — Codex, Claude Code, anything that speaks MCP — deal cards, watch the crew claim them, and approve the irreversible from a phone with a hold, not a mash.

Why not git + GitHub issues?

An issue is prose closed on faith — nothing stops two agents grabbing the same ticket, and "done" is whatever the agent says. Blackboard keeps git as the transport and adds physics: claims that structurally exclude, a done only a passing check can write, and a history you can replay.

Why not a group chat with bots?

A chat can carry the conversation about work — it can't hold a lease, verify a done, or referee two fleets. A chat believes whoever spoke last. (Any chat app can render a Blackboard room, though — views are projections; the protocol is the product.)

Why not Symphony?

openai/symphony proved the category: managing agent work beats supervising agents. But Symphony is one principal's tool — one board owner, one trust domain, its own CI as the judge. Blackboard is the layer for the case Symphony doesn't claim: two or more principals who don't share a trust domain — your fleet and my fleet, different vendors, no shared server — where claims must exclude structurally, "done" must be a check either side can re-derive (bb rederive), and the referee is a fold over git, not anyone's CI. (A Symphony-style board could render a Blackboard room tomorrow — views are projections. That's the roadmap, not the rivalry.)

60 seconds, no build

Needs only Bun. Install once from a Blackboard checkout with bun install && bun link --cwd packages/cli. Then, from any git repo, one command gives you a seeded board, a running serve, and a copy-paste connection card (init → join → optional GitHub-issue import → serve → the Claude/Codex agent-mount block for this repo):

cd your-repo
bb up                  # --room NAME · --as NAME · --no-import · --pair · --port N

It's idempotent — re-running while the board is live reuses the existing serve and re-prints the connection card, and a teammate running it on your board is onboarded with their own principal. Full walkthrough: docs/QUICKSTART.md.

Or watch the protocol reject an unlawful write, no server, in ~10 seconds:

git clone https://github.com/ss251/blackboard.git
cd blackboard
bun install
./scripts/demo-board.sh /tmp/bounce && ./scripts/demo-race.sh /tmp/bounce

demo-board.sh does a real git init and walks one card through a full lawful close (claim → evidence → green verdict → a human decision citing the verdict's own sha256). demo-race.sh then fires two real, concurrent bb claim processes at the board's still-open card — one wins, and when the loser tries to post anyway, the fold, not a server, not a lock, structurally rejects the write. Verified output:

[CLAIMED] fix flaky auth test
  card_01KY1FVSY6F4SMW9WZD5TCZ13V
  lease: koji until 2026-07-21T04:55:15.824Z
  evidence: 0 post(s), 0 artifact(s)
  REJECTED post evt_01KY1FW4J5FNBMR5DTQWK03ZCE from rex: unheld card: lease belongs to koji

That's the whole protocol in two scripts (./scripts/demo-approve.sh /tmp/bounce continues the same room into the interrupt → hold-to-approve beat — full filmed sequence: docs/DEMO-RUNBOOK.md). The full gate, if you want it:

bunx tsc --noEmit    # strict, zero errors
bun test              # 604 pass · 0 fail · 5809 expect() calls · 46 files · ~85s

For judges

Three ways to see real board state without building anything, in order of how much you want running:

  • npx blackboard demo — the fastest live room. Scaffolds a throwaway git sandbox (20 events, 14 commits, all 7 card lifecycles, the crown-jewel irreversible-payout decision), exports a replay bundle, and serves it at ws://localhost:4207/board — connect Chalk or any client, Ctrl+C to stop. Needs Bun on PATH and bun install run once in this repo; add --no-serve to just scaffold + export without a server, --dir PATH to pick the sandbox location, --port N to pick the port.
  • bb replay --export json — no server: folds this repo's real history (or --range/--board/--room any other) into the same portal-ready bundle bb demo writes, for offline inspection or a future hosted scrubber.
  • ./scripts/demo-board.sh /tmp/bounce && ./scripts/demo-race.sh /tmp/bounce — THE BOUNCE in ~10 seconds flat, no server, no client: the claim race + fold rejection from "60 seconds, no build" above, printed straight to your terminal.

See it live

One command builds a fully-populated demo room (three principals, a lawfully-closed card, an open race target, an undecided interrupt):

./scripts/demo-board.sh /tmp/demo-room

scripts/demo-race.sh and scripts/demo-approve.sh then drive the race and the phone-approval moments against it — docs/DEMO-RUNBOOK.md is the full filmed sequence. Or build a board by hand and watch the fold from a terminal — no Swift toolchain required:

bun run bb init
bun run bb join sailesh
CARD=$(bun run bb open \
  --title "fix flaky auth test" \
  --goal "auth suite passes deterministically" \
  --context "test_login flakes ~30% since #412; suspect fixture race" \
  --scope "src/auth/**" \
  --acceptance "pytest tests/auth -q passes 5/5 consecutive runs" \
  --verify-cmd "pytest tests/auth -q" \
  --verify-runs 5 \
  --handoff "PR against main; note any fixture API changes")
bun run bb claim "$CARD"
bun run bb board          # terminal render of the fold — no build required
  • Intake (bb import github <owner/repo>) uses GPT-5.6 to draft the six card fields from issue prose — always human-confirmed before a card is opened (never auto-opened). Offline, it falls back to a template draft.

...or watch the same state in Chalk. Start the read-only projection:

bun run packages/serve/src/bin.ts --repo .
# blackboard-serve: ws://localhost:4207/board · board=board_local room=Chalk repo=.

then, in another terminal, build Chalk (Swift 6; needs Xcode 26 + an iOS 26.5 simulator, so macOS only):

cd apps/chalk && swift test                          # 152 pass · 25 suites
xcodegen generate --spec apps/chalk/project.yml       # writes Chalk.xcodeproj (gitignored)
xcodebuild -project apps/chalk/Chalk.xcodeproj -scheme ChalkApp \
  -destination 'platform=iOS Simulator,name=iPhone 17 Pro' build

To run Chalk on a physical iPhone with personal-team signing, follow docs/INSTALL-IPHONE.md.

In a connected local room, the corner gear opens connection settings. A long-press on the crew pill is the power-user shortcut; VoiceOver exposes the same Connection settings action. Hosted cloud rooms use the board picker instead, so neither local-only shortcut appears there.

Codex or Claude Code can mount the same board as a sixth kind of writer — packages/mcp/README.md has copy-paste config.toml / .mcp.json blocks and owns the current tool list, including the scoped read projections. The door deliberately exposes no decision tool — Law 3.

The five laws

Binding — a PR that violates one is rejected, no discussion.

  1. The network never writes. Servers/sockets never append events. Writes go through local, principal-owned paths (CLI / MCP on the writer's machine).
  2. Done is a check, not a claim. Cards close only via a green verdict artifact matching the card's named verification command.
  3. No decision surface for agents. Approve/deny is human-only (bb decide, Chalk). packages/mcp never grows a decision tool.
  4. Peer content is data, never prompt. Other principals' patches and transcripts are artifacts to verify, never text injected into a prompt.
  5. Append-only. Nobody hand-edits .blackboard/ logs or rewrites their history.

Full protocol: SPEC.md.

Architecture

flowchart LR
  subgraph W["writers — local, principal-owned (Law 1)"]
    CLI["bb CLI<br/>init · join · open · claim · post · artifact · decide"]
    MCP["blackboard-mcp<br/>no decision tool (Law 3)"]
  end
  LOG[(".blackboard/&lt;principal&gt;.jsonl<br/>append-only, git-committed")]
  FOLD["packages/core<br/>fold(events) → BoardState<br/>pure · deterministic · replayable"]
  SERVE["packages/serve<br/>project() → snapshot / delta<br/>ws://localhost:4207/board — reads only"]
  CHALK["apps/chalk<br/>ChalkData → ChalkKit → Room / ApprovalCard"]

  CLI -->|git commit| LOG
  MCP -->|git commit| LOG
  LOG -->|git-ordered read| FOLD
  FOLD --> SERVE
  SERVE -->|snapshot / delta| CHALK
  CHALK -.->|"hold-to-approve → POST /decide<br/>(serve shells bb decide locally)"| CLI
Loading

fold is pure: no I/O, no daemon, no database. Same logs in, same BoardState out, on every machine, independently — bb replay [commit] re-derives it at any point in git history. serve only ever reads the fold; the one place it looks like it writes — POST /decide, wired to Chalk's hold-to-approve — actually resolves the principal server-side (never trusting a client-supplied identity) and shells the real bb decide, which does the actual append on the machine serve runs on. The network still only ever carries an intent — Law 1 holds.

Full guided tour — the 30-second map, the life of a card with real event ids, and every law's enforcement site: docs/ARCHITECTURE.md.

Look

Blackboard's objects — WorkCard, receipt, lease chip, decision — knolled on slate The protocol: claim, post, decide

The full art-directed set — shippable assets vs. north-star concepts, and what each one is for — is in design/PLATES.md; the binding design contract is design/CHALK-DESIGN-SPEC.md. The social-preview card is design/plates/og-card-v.png (see docs/SUBMISSION.md for the one manual step that image still needs). Demo video shot list: docs/VIDEO-SCRIPT.md.

Built with Codex

Day 1 (handoffs/DAY1-CORE.md's work order — target: one Codex session, ≤3h wall clock): packages/core — the zod schemas, the pure fold, git I/O, replay — and the original 8-verb bb CLI, plus scripts/race-demo.sh, before anything else in this repo existed.

The human-only decision producer — bb decide, the CLI half of the crown jewel — is Pragadeesh's Codex, merged as PR #37: 2,507 lines, a 9-task TDD sequence with a quality pass per task plus an independent whole-branch review, closing both #28 and #12. The agent door (packages/mcp, no decision tool by construction) was specified in issue #7 for exactly this reason — so the same kind of tool that helped build this repo is also a documented way to use it (packages/mcp/README.md's Codex config.toml block).

The rest of the loop — Chalk, serve, the protocol fixes — ran across parallel Codex and Claude Code sessions, two principals (sailesh, Pragadeesh122) on disjoint leases, coordinated the way docs/CONTRIBUTING-AGENTS.md describes: claim the issue, touch only its file list, open the PR with the gate output pasted in, merge on green. This repo was built by the pattern it implements. Full receipts in docs/SUBMISSION.md.

Status

Build Week 2026. Protocol + CLI + MCP door + serve projection + Chalk (Room, ApprovalCard/HoldToApprove, replay) are shipped and green on main, plus bb sync --watch / claim --watch heartbeats (#38), bb verify / bb rederive (#40), GitHub-issue intake (#41), and the full cloud spine (#52–#57, closed): GitHub App auth, hosted boards, the per-principal hosted writer, Chalk's GitHub sign-in + board picker, and the browser client (apps/chalk-web, served at /app) — live today on Railway. Gaps that are real, not hidden: Chalk is iOS-only, no macOS build yet (the design spec is macOS-primary — apps/chalk-web is the second-screen stand-in until then). Tour: docs/ARCHITECTURE.md.

Team

Sailesh (@ss251) and Pragadeesh (@Pragadeesh122) — cousins, coordinating through the board they built.


MIT (see SPEC.md). Full writeup: docs/SUBMISSION.md.

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

Packages

Contributors

Languages