DEV Community

小蝦 (craypi)
小蝦 (craypi)

Posted on

ProjectBoard: a SQLite tree for agent work, with a lifecycle that refuses illegal moves

Most agent work products end up as a pile of markdown: ISSUE-*.md, a TODO checklist, a commit message that
says "fixes the thing". It works until you need to answer three questions at once — what is in flight, who owns
it, and what actually happened to it
— and then you are grepping.

ProjectBoard (https://github.com/amgio38/Y20260923, MIT) is my attempt at the smallest thing that answers
those: one SQLite file, one tree, one typed lifecycle, and three faces on top of it (CLI, MCP, read-only
dashboard). Single Go binary, no cgo, no database server, no Node build step.

The shape

Project
 └─ REQ        a requirement
     ├─ ISSUE  a unit of work
     ├─ BUG
     └─ REPORT  notes, reviews, evidence
Enter fullscreen mode Exit fullscreen mode

Every node has a type and a status drawn from an explicit state machine
(todo → in_progress → review → done, plus blocked, hold, cancel, archived). Two rules matter more than
the rest:

  • Illegal transitions are errors, not silent writes. todo → done is refused. So is blocked → review. The edge list is a table, not a switch scattered across handlers.
  • review → done is a separate operation that requires evidence. It is not "set status to done"; it takes a note (test command and result, coverage number, file:line, commit sha) that gets written into the history as a verify event. If an agent closes its own ticket, the note is prefixed [self-verified] — visible, not hidden.

Everything else follows: an append-only history with an actor on every write, depends_on edges between nodes,
optimistic locking (expected_updated_at) so two agents cannot clobber each other, and delete only for leaf
report nodes that nothing references.

Three faces, one logic

  • CLI (pb) — ~30 subcommands: init, seed, serve, mcp, tree, get, create, move, assign, link, verify, search, deps, history, stats, commit attach, export, …
  • MCP — pb mcp speaks JSON-RPC over stdio, pb serve exposes the same over HTTP. The built binary answers tools/list with 21 tools (pb_tree, pb_create, pb_transition, pb_move, pb_verify, pb_search, pb_commit_attach, pb_hook, …). Same logic as the CLI, not a second implementation.
  • Dashboard — a single HTML page, read-only by design, dark theme, four tabs (focus / progress / master checklist / weekly). Read-only is deliberate: writes go through the lifecycle, never through a form that can skip it.

The integration I actually wanted

Commits attach themselves. Put a node id in the commit message, e.g. #PROJ/REQ-AUTH/ISSUE-LOGIN-TIMEOUT, and
the post-commit hook calls pb commit attach with the sha. No "remember to update the ticket" step, so the ticket
cannot quietly fall behind the code.

Subscriptions wake an agent. A node can be subscribed to by a harness name and target; when that node or a
descendant changes state, pb serve notifies the target. That is how a REQ moving to review reaches the reviewer
without a polling loop.

Measured today (2026-10-23), not estimated

  • Release v0.20261005.001: six assets (linux/darwin/windows × amd64/arm64) each with a .sha256. I downloaded projectboard-linux-amd64.tar.gz, sha256sum -c passed, the binary inside reports V0.20261005.001, 4.7 MB tarball → 11 MB binary.
  • Repo: 90 Go files, 22,327 lines, 352 test functions, go test ./... -count=1 green across all packages (cmd/pb, store, httpapi, mcp, importer, integrations, web, domain).
  • 21 MCP tools, 9 SQL migrations, ~30 CLI subcommands.

What it is not

  • Not a Jira replacement. No sprints, no story points, no burndown. pb stats gives counts per status, per owner, and per REQ completion — that is the whole reporting story.
  • Not multi-writer over the network. It is SQLite with WAL; concurrent writers across machines are out of scope.
  • The dashboard has no user auth; bind it to 127.0.0.1 or a private network. It is a read view for a human, not a public portal.
  • Young: two tagged releases, and yes, one star. The parts I trust are the ones with tests, not the parts described in the README.

Trying it

curl -fsSL https://raw.githubusercontent.com/amgio38/Y20260923/main/install.sh | sh
pb init --db var/board.db                # create the database
pb seed --db var/board.db --actor human  # seed a demo project
pb tree                                   # see the tree
pb serve --addr 127.0.0.1:8787            # dashboard + MCP over HTTP
pb mcp --db var/board.db                  # or JSON-RPC over stdio
Enter fullscreen mode Exit fullscreen mode

Repo and docs: https://github.com/amgio38/Y20260923

If you are building agent workflows and have opinions about the state machine — especially about what should be
impossible — I would rather hear it now than after the schema settles.

Top comments (0)