Cherry-picked website/, scripts/generate-llms-full.sh, and deploy-docs.yml from joyshmitz's PR. Fixed workflow to trigger on main branch instead of docs/docusaurus-site. Features: - Docusaurus documentation site with llms.txt support - Environment-variable driven config (defaults to steveyegge org) - Automated llms-full.txt generation from docs - GitHub Pages deployment workflow Co-authored-by: joyshmitz <joyshmitz@users.noreply.github.com> 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com> Executed-By: beads/crew/dave Rig: beads Role: crew
9.3 KiB
sidebar_position, title, description
| sidebar_position | title | description |
|---|---|---|
| 1 | Architecture Overview | Understanding Beads' three-layer data model |
Architecture Overview
This document explains how Beads' three-layer architecture works: Git, JSONL, and SQLite.
The Three Layers
Beads uses a layered architecture where each layer serves a specific purpose:
flowchart TD
subgraph GIT["🗂️ Layer 1: Git Repository"]
G[(".beads/*.jsonl<br/><i>Historical Source of Truth</i>")]
end
subgraph JSONL["📄 Layer 2: JSONL Files"]
J[("issues.jsonl<br/><i>Operational Source of Truth</i>")]
end
subgraph SQL["⚡ Layer 3: SQLite"]
D[("beads.db<br/><i>Fast Queries / Derived State</i>")]
end
G <-->|"bd sync"| J
J -->|"rebuild"| D
D -->|"append"| J
U((👤 User)) -->|"bd create<br/>bd update"| D
D -->|"bd list<br/>bd show"| U
style GIT fill:#2d5a27,stroke:#4a9c3e,color:#fff
style JSONL fill:#1a4a6e,stroke:#3a8ac4,color:#fff
style SQL fill:#6b3a6b,stroke:#a45ea4,color:#fff
:::info Historical vs Operational Truth Git is the historical source of truth—commits preserve the full history of your issues and can be recovered from any point in time.
JSONL is the operational source of truth—when recovering from database corruption, Beads rebuilds SQLite from JSONL files, not directly from Git commits.
This layered model enables recovery: if SQLite is corrupted but JSONL is intact, run bd sync --import-only to rebuild. If JSONL is corrupted, recover it from Git history first.
:::
Layer 1: Git Repository
Git is the historical source of truth. All issue data lives in the repository alongside your code, with full history preserved in commits.
Why Git?
- Issues travel with the code
- No external service dependency
- Full history via Git log (recover any point in time)
- Works offline
- Enables multi-machine and multi-agent workflows
Layer 2: JSONL Files
JSONL (JSON Lines) files store issue data in an append-only format. This is the operational source of truth—SQLite databases are rebuilt from JSONL.
Location: .beads/*.jsonl
Why JSONL?
- Human-readable and inspectable
- Git-mergeable (append-only reduces conflicts)
- Portable across systems
- Can be recovered from Git history
- Recovery source:
bd sync --import-onlyrebuilds SQLite from JSONL
Layer 3: SQLite Database
SQLite provides fast local queries without network latency. This is derived state—it can always be rebuilt from JSONL.
Location: .beads/beads.db
Why SQLite?
- Instant queries (no network)
- Complex filtering and sorting
- Derived from JSONL (always rebuildable)
- Safe to delete and rebuild:
rm .beads/beads.db* && bd sync --import-only
Data Flow
Write Path
User runs bd create
→ SQLite updated
→ JSONL appended
→ Git commit (on sync)
Read Path
User runs bd list
→ SQLite queried
→ Results returned immediately
Sync Path
User runs bd sync
→ Git pull
→ JSONL merged
→ SQLite rebuilt if needed
→ Git push
Sync Modes
Beads provides specialized sync modes for different recovery scenarios:
Standard Sync
bd sync
Normal bidirectional sync: pulls remote changes, merges JSONL, rebuilds SQLite if needed, pushes local changes.
Import-Only Mode
bd sync --import-only
Rebuilds the SQLite database from JSONL without pushing changes. Use this when:
- SQLite is corrupted or missing
- Recovering from a fresh clone
- Rebuilding after database migration issues
This is the safest recovery option when JSONL is intact.
Force Rebuild Mode
bd sync --force-rebuild
Forces complete SQLite rebuild from JSONL, discarding any SQLite-only state. Use with caution:
- More aggressive than
--import-only - May lose any uncommitted database state
- Recommended when standard sync fails repeatedly
Multi-Machine Sync Considerations
When working across multiple machines or clones:
-
Always sync before switching machines
bd sync # Push changes before leaving -
Pull before creating new issues
bd sync # Pull changes first on new machine bd create "New issue" -
Avoid parallel edits - If two machines create issues simultaneously without syncing, conflicts may occur
See Sync Failures Recovery for data loss prevention in multi-machine workflows (Pattern A5/C3).
The Daemon
The Beads daemon (bd daemon) handles background synchronization:
- Watches for file changes
- Triggers sync on changes
- Keeps SQLite in sync with JSONL
- Manages lock files
:::tip The daemon is optional but recommended for multi-agent workflows. :::
Running Without the Daemon
For CI/CD pipelines, containers, and single-use scenarios, run commands without spawning a daemon:
bd --no-daemon create "CI-generated issue"
bd --no-daemon sync
When to use --no-daemon:
- CI/CD pipelines (Jenkins, GitHub Actions)
- Docker containers
- Ephemeral environments
- Scripts that should not leave background processes
- Debugging daemon-related issues
Daemon in Multi-Clone Scenarios
:::warning Race Conditions in Multi-Clone Workflows When multiple git clones of the same repository run daemons simultaneously, race conditions can occur during push/pull operations. This is particularly common in:
- Multi-agent AI workflows (multiple Claude/GPT instances)
- Developer workstations with multiple checkouts
- Worktree-based development workflows
Prevention:
- Use
bd daemons killallbefore switching between clones - Ensure only one clone's daemon is active at a time
- Consider
--no-daemonmode for automated workflows :::
See Sync Failures Recovery for daemon race condition troubleshooting (Pattern B2).
Recovery Model
The three-layer architecture makes recovery straightforward because each layer can rebuild from the one above it:
- Lost SQLite? → Rebuild from JSONL:
bd sync --import-only - Lost JSONL? → Recover from Git history:
git checkout HEAD~1 -- .beads/issues.jsonl - Conflicts? → Git merge, then rebuild
Universal Recovery Sequence
The following sequence demonstrates how the architecture enables quick recovery. For detailed procedures, see Recovery Runbooks.
This sequence resolves the majority of reported issues:
bd daemons killall # Stop daemons (prevents race conditions)
git worktree prune # Clean orphaned worktrees
rm .beads/beads.db* # Remove potentially corrupted database
bd sync --import-only # Rebuild from JSONL source of truth
:::danger Never Use bd doctor --fix
Analysis of 54 GitHub issues revealed that bd doctor --fix frequently causes more damage than the original problem:
- Deletes "circular" dependencies that are actually valid parent-child relationships
- False positive detection removes legitimate issue links
- Recovery after
--fixis harder than recovery from the original issue
Safe alternatives:
bd doctor— Diagnostic only, no changes madebd blocked— Check which issues are blocked and whybd show <issue-id>— Inspect a specific issue's state
If bd doctor reports problems, investigate each one manually before taking any action.
:::
See Recovery for specific procedures and Database Corruption Recovery for bd doctor --fix recovery (Pattern D4).
Design Decisions
Why not just SQLite?
SQLite alone doesn't travel with Git or merge well across branches. Binary database files create merge conflicts that are nearly impossible to resolve.
Why not just JSONL?
JSONL is slow for complex queries. Scanning thousands of lines for filtering and sorting is inefficient. SQLite provides indexed lookups in milliseconds.
Why append-only JSONL?
Append-only format minimizes Git merge conflicts. When two branches add issues, Git can cleanly merge by concatenating the additions. Edit operations append new records rather than modifying existing lines.
Why not a server?
Beads is designed for offline-first, local-first development. No server means no downtime, no latency, no vendor lock-in, and full functionality on airplanes or in restricted networks.
Trade-offs
| Benefit | Trade-off |
|---|---|
| Works offline | No real-time collaboration |
| Git-native history | Requires Git knowledge |
| No server dependency | No web UI or mobile app |
| Local-first speed | Manual sync required |
| Append-only merging | JSONL files grow over time |
When NOT to use Beads
Beads is not suitable for:
- Large teams (10+) — Git-based sync doesn't scale well for high-frequency concurrent edits
- Non-developers — Requires Git and command-line familiarity
- Real-time collaboration — No live updates; requires explicit sync
- Cross-repository tracking — Issues are scoped to a single repository
- Rich media attachments — Designed for text-based issue tracking
For these use cases, consider GitHub Issues, Linear, or Jira.
Related Documentation
- Recovery Runbooks — Step-by-step procedures for common issues
- CLI Reference — Complete command documentation
- Getting Started — Installation and first steps