Beads daemon lifecycle management, log analysis, socket recovery, and background sync operations. Covers start/stop/status, troubleshooting, and integration with git workflow.
The Beads daemon (bd daemon) runs as a background process that watches for issue mutations and automatically syncs changes to/from JSONL files. This skill covers daemon lifecycle, log analysis, troubleshooting, and integration with git workflows.
Key Files:
.beads/config.yaml โ Daemon configuration.beads/daemon.log โ Runtime logs.beads/daemon.pid โ Process ID file.beads/daemon.sock โ Unix socket for IPC.beads/issues.jsonl โ Serialized issue stateWhen: Managing the background sync process.
# Start in background (default)
bd daemon --start
# Start in foreground (for debugging)
bd daemon --start --foreground
# Start with metrics endpoint
bd daemon --start --metrics
# Start with auto-commit on changes
bd daemon --start --auto-commit
# Start with auto-push (implies auto-commit)
bd daemon --start --auto-push
# Quick status check
bd daemon --status
# Health check (verifies socket responsiveness)
bd daemon --health
# Output examples:
# โ Daemon running (PID 12345)
# โ Daemon not running
# โ Daemon unresponsive (stale socket)
# Graceful stop
bd daemon --stop
# Force stop (if graceful fails)
kill -9 $(cat .beads/daemon.pid)
rm .beads/daemon.sock .beads/daemon.pid
# Stop then start
bd daemon --stop && bd daemon --start
# Or with flags preserved
bd daemon --stop && bd daemon --start --auto-commit
When: Customizing daemon behavior via .beads/config.yaml.
# .beads/config.yaml
# Auto-start daemon when bd commands run
auto-start-daemon: true
# Debounce time before flushing changes to JSONL
flush-debounce: "5s"
# Custom sync branch (for multi-repo setups)
sync-branch: "beads-sync"
# Multi-repo configuration
multi-repo:
enabled: false
repos:
- path: "../other-repo"
sync-branch: "beads-sync"
Need automatic sync?
โ
โโ Yes, always
โ โโ auto-start-daemon: true
โ
โโ Yes, with git integration
โ โโ --auto-commit or --auto-push flags
โ
โโ No, manual control
โ โโ auto-start-daemon: false
โ (use bd sync --from-main manually)
โ
โโ Cross-repo sync?
โโ multi-repo.enabled: true
(configure repos array)
When: Debugging sync issues or understanding daemon behavior.
# View recent logs
tail -50 .beads/daemon.log
# Follow logs in real-time
tail -f .beads/daemon.log
# Search for specific patterns
grep "Export triggered" .beads/daemon.log
| Pattern | Meaning | Action |
|---|---|---|
Mutation detected: create <id> |
New issue created | Normal operation |
Mutation detected: update <id> |
Issue modified | Normal operation |
Mutation detected: close <id> |
Issue closed | Normal operation |
Export triggered by mutation events |
Flush to JSONL starting | Normal operation |
Exported to JSONL |
JSONL file updated | Verify with cat .beads/issues.jsonl |
Import triggered by file change |
JSONL file changed externally | Git pull or manual edit |
Skipping auto-import: JSONL content unchanged |
No-op optimization | Normal (prevents loops) |
Socket error |
IPC failure | Check socket recovery |
Daemon already running |
Duplicate start attempt | Use --status first |
[2025-12-19 20:37:53] Mutation detected: create tmnl-ahym
[2025-12-19 20:37:55] Export triggered by mutation events
[2025-12-19 20:37:55] Starting export...
[2025-12-19 20:37:55] Exported to JSONL
[2025-12-19 20:37:56] Import triggered by file change
[2025-12-19 20:37:56] Skipping auto-import: JSONL content unchanged
Interpretation: Issue created โ daemon detected โ exported to JSONL โ detected own file change โ correctly skipped re-import.
When: Daemon appears stuck, commands hang, or status shows "unresponsive".
bd commands hang indefinitelybd daemon --status shows running but --health failsbd daemon --start says "already running" but no process found# Check if process actually exists
ps aux | grep "bd daemon"
# Check PID file
cat .beads/daemon.pid
ps -p $(cat .beads/daemon.pid)
# Test socket responsiveness
bd daemon --health
# Step 1: Try graceful stop
bd daemon --stop
# Step 2: If that fails, force cleanup
rm -f .beads/daemon.sock .beads/daemon.pid
# Step 3: Verify cleanup
ls -la .beads/daemon.*
# Should show no .sock or .pid files
# Step 4: Restart fresh
bd daemon --start
bd daemon --status
# Should show: โ Daemon running (PID <new-pid>)
--stop--foreground during development for clean Ctrl+C handlingbd daemon --status before assuming issuesWhen: Syncing beads changes across branches or with remote.
# Ensure daemon is running
bd daemon --status || bd daemon --start
# Pull latest beads from main
bd sync --from-main
# Sync beads changes to main
bd sync --from-main # Get any updates first
# Commit code changes
git add .
git commit -m "feat: implement feature X"
# Merge to main (local)
git checkout main
git merge feature-branch
git checkout feature-branch
# Start daemon with auto-commit
bd daemon --start --auto-commit
# Now every mutation triggers:
# 1. Export to JSONL
# 2. git add .beads/issues.jsonl
# 3. git commit -m "beads: sync <issue-id>"
# For CI pipelines or shared environments
bd daemon --start --auto-push
# Triggers on mutation:
# 1. Export to JSONL
# 2. git add + commit
# 3. git push
When: Monitoring daemon health in dashboards or scripts.
bd daemon --start --metrics
# Starts HTTP endpoint on localhost:9090/metrics (default)
# Prometheus format
beads_mutations_total{type="create"} 42
beads_mutations_total{type="update"} 156
beads_mutations_total{type="close"} 23
beads_exports_total 89
beads_imports_total 12
beads_daemon_uptime_seconds 3600
beads_last_export_timestamp 1703012400
beads_last_import_timestamp 1703012350
curl -s localhost:9090/metrics | grep beads_
# WRONG โ Leaves stale socket/pid
kill -9 $(cat .beads/daemon.pid)
# Commands will hang on stale socket
# CORRECT โ Graceful stop cleans up
bd daemon --stop
# WRONG โ Race conditions, duplicate exports
bd daemon --start # First
bd daemon --start # Second (should fail, but if socket stale...)
# CORRECT โ Check status first
bd daemon --status || bd daemon --start
# WRONG โ Manual JSONL edit without daemon awareness
echo '{"id":"test"}' >> .beads/issues.jsonl
# Daemon imports, exports, imports, exports...
# CORRECT โ Use bd commands
bd create --title="Test" --type=task
# Daemon handles export, skips self-import
# WRONG โ Switch branch without sync
git checkout main
# Beads state may be stale or conflict
# CORRECT โ Sync before/after switch
bd sync --from-main
git checkout main
git merge feature-branch
Daemon issues?
โ
โโ Commands hang
โ โโ Check: bd daemon --health
โ โโ Health OK? โ Issue is elsewhere
โ โโ Health fails? โ Socket recovery (Pattern 4)
โ
โโ Changes not syncing
โ โโ Check: tail .beads/daemon.log
โ โโ No recent entries? โ Daemon not running
โ โโ Errors in log? โ Address specific error
โ โโ "Skipping import"? โ Normal (no actual changes)
โ
โโ Duplicate exports
โ โโ Check: ps aux | grep "bd daemon"
โ โโ Multiple processes? โ Kill all, clean restart
โ โโ Single process? โ Check flush-debounce timing
โ
โโ Git conflicts on JSONL
โโ Stop daemon first
โโ Resolve conflict manually
โโ bd sync --from-main
โโ Restart daemon
bd daemon [flags]
FLAGS:
--start Start the daemon
--stop Stop the daemon
--status Show daemon status
--health Check daemon health (socket test)
--foreground Run in foreground (no detach)
--auto-commit Auto-commit JSONL changes
--auto-push Auto-push after commit (implies --auto-commit)
--interval <dur> Polling interval (default: 1s)
--local Local mode (no remote sync)
--metrics Enable metrics endpoint
EXAMPLES:
bd daemon --start # Background start
bd daemon --start --foreground # Foreground (Ctrl+C to stop)
bd daemon --stop # Graceful stop
bd daemon --status # Check if running
bd daemon --health # Verify responsiveness
bd daemon --start --auto-commit # Auto-commit on changes
| File | Purpose | When to Check |
|---|---|---|
.beads/config.yaml |
Configuration | Setup, changing behavior |
.beads/daemon.log |
Runtime logs | Debugging, verification |
.beads/daemon.pid |
Process ID | Status check, recovery |
.beads/daemon.sock |
Unix socket | Recovery (stale socket) |
.beads/issues.jsonl |
Serialized state | Conflict resolution |