Issue Tracking with Beads (bd)
ESI.ts uses beads (bd) as its work tracker. Beads is a lightweight, git-native issue tracker with first-class dependency support — issues are "chained like beads", so you always know what is ready to work on and what is blocked by something else.
Issues live in a Dolt database under .beads/ (the binary DB is gitignored). A human-readable snapshot is exported to .beads/issues.jsonl, which is committed, so issues travel with the repo and show up in diffs and PRs.
Why beads here
- Dependencies, not just a list —
bd readyshows only unblocked work;bd blockedshows what is waiting and on what. - Epics with roll-up — parent/child hierarchies with completion percentages.
- Agent-friendly — Claude Code and Codex are wired to create, link, and query issues automatically (see Agent integration).
Install
# See https://github.com/gastownhall/beads for install options
bd version # verify the CLI is availableOne-time local setup
.beads/ (config, hooks, metadata) is committed, so cloning the repo is enough to read and query issues. Two things are intentionally local-only:
Agent integration — enables the SessionStart hook in the gitignored
.claude/settings.json:bashbd setup claude # or: bd setup codex, bd setup cursor, ...Sync remote — the remote is not tracked (so forks and alternate remotes work). Point it at your remote if you intend to sync:
bashbd config set sync.remote "git+https://github.com/<you>/ESI.ts.git"
Daily workflow
bd ready # what can I pick up right now?
bd show <id> # full detail of an issue
bd update <id> --claim # take ownership / mark in-progress
bd close <id> # mark complete
bd blocked # what is waiting, and on whatViewing issues
bd list # tree view with parent/child nesting
bd list --tree # explicit hierarchy
bd show <id> # single issue detail
bd dep tree <id> # dependency graph for an issue
bd stats # counts by status / priority
bd query "status:open priority:1" # filtered query languageYou can also just read .beads/issues.jsonl — one JSON object per issue, including labels, dependencies, and comments.
Creating issues
# Simple task
bd create "Fix pagination off-by-one in MarketClient" -t bug -p 1
# With a description
bd create "Add ETag support to X" -t feature -d "Detailed context here..."Types: bug | feature | task | chore | epic | decision. Priorities: 0–4 (P0 highest).
Epics and dependencies
# Create an epic, then attach children to it
EPIC=$(bd create "Improve OpenSSF Scorecard" -t epic -p 1 --silent)
bd create "Fix Token-Permissions" -t chore -p 1 --parent "$EPIC"
# Link a blocking dependency: <blocked> is blocked by <blocker>
bd link <blocked-id> <blocker-id> # default type: blocks
bd link <id-a> <id-b> --type related # non-blocking relationOnce a blocker is closed, the blocked issue automatically appears in bd ready.
Syncing issues
Beads stores issues in a Dolt DB and syncs via refs/dolt/data on your git remote; .beads/issues.jsonl is a passive export for humans and diffs, not the source of truth.
After changing issues, refresh the tracked snapshot before committing:
bashbd export -o .beads/issues.jsonl git add .beads/issues.jsonl(Or enable automatic export once:
bd config set export.auto true.)Cross-machine / team sync uses Dolt remotes, not the JSONL file. Set
sync.remotelocally first (see One-time local setup).
See the beads sync concepts for the full model and anti-patterns.
Agent integration
CLAUDE.md and AGENTS.md only point here and at bd prime; this section is the one copy of the agent rules. They are task-tracking guidance and never override repository, user or orchestrator instructions.
- Use
bdfor all durable task tracking, not markdown TODO lists; keep persistent project knowledge in Beads viabd remember. - Run
bd primewhen the Beads context is missing or stale. - Git policy (conservative, the default): do not commit, push or run
bd dolt pushunless explicitly asked. Only a repository that opts in to the team-maintainer profile lets agents close beads, run the quality gates, commit and push at session close, and a current "do not push" still wins.
Session completion
- File beads for any remaining follow-up work.
- If code changed, run the quality gates (tests, linters, build).
- Close finished beads and update in-progress ones.
- Sync by the active profile: by default report
git statusand the proposed commands and wait; with the team-maintainer opt-in rungit pull --rebase,bd dolt push,git push,git status. - Hand off: changes, validation, bead status, and any blocked sync or push with its exact command and error.
Gotchas
bd listreads the live Dolt DB, not the JSONL. If the two disagree, re-runbd export -o .beads/issues.jsonl..claude/settings.jsonis gitignored, so the SessionStart hook is per-contributor — runbd setup claudelocally to enable it.git config core.hooksPathpoints at.beads/hooksafterbd init; the existinglint-stagedpre-commit gate is preserved there.
