bd has two complementary configuration systems:
- Tool-level configuration (Viper): User preferences for tool behavior (flags, output format)
- Project-level configuration (
bd config): Integration data and project-specific settings
Tool preferences control how bd behaves globally or per-user. These are stored in config files or environment variables and managed by Viper.
Configuration precedence (highest to lowest):
- Command-line flags (
--json,--no-daemon, etc.) - Environment variables (
BD_JSON,BD_NO_DAEMON, etc.) - Config file (
~/.config/bd/config.yamlor.beads/config.yaml) - Defaults
Viper searches for config.yaml in these locations (in order):
.beads/config.yaml- Project-specific tool settings (version-controlled)~/.config/bd/config.yaml- User-specific tool settings~/.beads/config.yaml- Legacy user settings
Tool-level settings you can configure:
| Setting | Flag | Environment Variable | Default | Description |
|---|---|---|---|---|
json |
--json |
BD_JSON |
false |
Output in JSON format |
no-daemon |
--no-daemon |
BD_NO_DAEMON |
false |
Force direct mode, bypass daemon |
no-auto-flush |
--no-auto-flush |
BD_NO_AUTO_FLUSH |
false |
Disable auto JSONL export |
no-auto-import |
--no-auto-import |
BD_NO_AUTO_IMPORT |
false |
Disable auto JSONL import |
no-push |
--no-push |
BD_NO_PUSH |
false |
Skip pushing to remote in bd sync |
create.require-description |
- | BD_CREATE_REQUIRE_DESCRIPTION |
false |
Require description when creating issues |
validation.on-create |
- | BD_VALIDATION_ON_CREATE |
none |
Template validation on create: none, warn, error |
validation.on-sync |
- | BD_VALIDATION_ON_SYNC |
none |
Template validation before sync: none, warn, error |
git.author |
- | BD_GIT_AUTHOR |
(none) | Override commit author for beads commits |
git.no-gpg-sign |
- | BD_GIT_NO_GPG_SIGN |
false |
Disable GPG signing for beads commits |
directory.labels |
- | - | (none) | Map directories to labels for automatic filtering |
external_projects |
- | - | (none) | Map project names to paths for cross-project deps |
db |
--db |
BD_DB |
(auto-discover) | Database path |
actor |
--actor |
BD_ACTOR |
$USER |
Actor name for audit trail |
flush-debounce |
- | BEADS_FLUSH_DEBOUNCE |
5s |
Debounce time for auto-flush |
auto-start-daemon |
- | BEADS_AUTO_START_DAEMON |
true |
Auto-start daemon if not running |
daemon-log-max-size |
- | BEADS_DAEMON_LOG_MAX_SIZE |
50 |
Max daemon log size in MB before rotation |
daemon-log-max-backups |
- | BEADS_DAEMON_LOG_MAX_BACKUPS |
7 |
Max number of old log files to keep |
daemon-log-max-age |
- | BEADS_DAEMON_LOG_MAX_AGE |
30 |
Max days to keep old log files |
daemon-log-compress |
- | BEADS_DAEMON_LOG_COMPRESS |
true |
Compress rotated log files |
~/.config/bd/config.yaml:
# Default to JSON output for scripting
json: true
# Disable daemon for single-user workflows
no-daemon: true
# Custom debounce for auto-flush (default 5s)
flush-debounce: 10s
# Auto-start daemon (default true)
auto-start-daemon: true
# Daemon log rotation settings
daemon-log-max-size: 50 # MB per file (default 50)
daemon-log-max-backups: 7 # Number of old logs to keep (default 7)
daemon-log-max-age: 30 # Days to keep old logs (default 30)
daemon-log-compress: true # Compress rotated logs (default true).beads/config.yaml (project-specific):
# Project team prefers longer flush delay
flush-debounce: 15s
# Require descriptions on all issues (enforces context for future work)
create:
require-description: true
# Template validation settings (bd-t7jq)
# Validates that issues include required sections based on issue type
# Values: none (default), warn (print warning), error (block operation)
validation:
on-create: warn # Warn when creating issues missing sections
on-sync: none # No validation on sync (backwards compatible)
# Git commit signing options (GH#600)
# Useful when you have Touch ID commit signing that prompts for each commit
git:
author: "beads-bot <beads@example.com>" # Override commit author
no-gpg-sign: true # Disable GPG signing
# Directory-aware label scoping for monorepos (GH#541)
# When running bd ready/list from a matching directory, issues with
# that label are automatically shown (as if --label-any was passed)
directory:
labels:
packages/maverick: maverick
packages/agency: agency
packages/io: io
# Cross-project dependency resolution (bd-h807)
# Maps project names to paths for resolving external: blocked_by references
# Paths can be relative (from cwd) or absolute
external_projects:
beads: ../beads
gastown: /path/to/gastownTool settings (Viper) are user preferences:
- How should I see output? (
--json) - Should I use the daemon? (
--no-daemon) - How should the CLI behave?
Project config (bd config) is project data:
- What's our Jira URL?
- What are our Linear tokens?
- How do we map statuses?
This separation is correct: tool settings are user-specific, project config is team-shared.
Agents benefit from bd config's structured CLI interface over manual YAML editing.
Project configuration is:
- Per-project: Isolated to each
.beads/*.dbdatabase - Version-control-friendly: Stored in SQLite, queryable and scriptable
- Machine-readable: JSON output for automation
- Namespace-based: Organized by integration or purpose
bd config set <key> <value>
bd config set --json <key> <value> # JSON outputExamples:
bd config set jira.url "https://company.atlassian.net"
bd config set jira.project "PROJ"
bd config set jira.status_map.todo "open"bd config get <key>
bd config get --json <key> # JSON outputExamples:
bd config get jira.url
# Output: https://company.atlassian.net
bd config get --json jira.url
# Output: {"key":"jira.url","value":"https://company.atlassian.net"}bd config list
bd config list --json # JSON outputExample output:
Configuration:
compact_tier1_days = 90
compact_tier1_dep_levels = 2
jira.project = PROJ
jira.url = https://company.atlassian.net
JSON output:
{
"compact_tier1_days": "90",
"compact_tier1_dep_levels": "2",
"jira.project": "PROJ",
"jira.url": "https://company.atlassian.net"
}bd config unset <key>
bd config unset --json <key> # JSON outputExample:
bd config unset jira.urlConfiguration keys use dot-notation namespaces to organize settings:
compact_*- Compaction settings (see EXTENDING.md)issue_prefix- Issue ID prefix (managed bybd init)max_collision_prob- Maximum collision probability for adaptive hash IDs (default: 0.25)min_hash_length- Minimum hash ID length (default: 4)max_hash_length- Maximum hash ID length (default: 8)import.orphan_handling- How to handle hierarchical issues with missing parents during import (default:allow)export.error_policy- Error handling strategy for exports (default:strict)export.retry_attempts- Number of retry attempts for transient errors (default: 3)export.retry_backoff_ms- Initial backoff in milliseconds for retries (default: 100)export.skip_encoding_errors- Skip issues that fail JSON encoding (default: false)export.write_manifest- Write .manifest.json with export metadata (default: false)auto_export.error_policy- Override error policy for auto-exports (default:best-effort)sync.branch- Name of the dedicated sync branch for beads data (see docs/PROTECTED_BRANCHES.md)sync.require_confirmation_on_mass_delete- Require interactive confirmation before pushing when >50% of issues vanish during a merge AND more than 5 issues existed before (default:false)
Use these namespaces for external integrations:
jira.*- Jira integration settingslinear.*- Linear integration settingsgithub.*- GitHub integration settingscustom.*- Custom integration settings
# Configure adaptive ID lengths (see docs/ADAPTIVE_IDS.md)
# Default: 25% max collision probability
bd config set max_collision_prob "0.25"
# Start with 4-char IDs, scale up as database grows
bd config set min_hash_length "4"
bd config set max_hash_length "8"
# Stricter collision tolerance (1%)
bd config set max_collision_prob "0.01"
# Force minimum 5-char IDs for consistency
bd config set min_hash_length "5"See ADAPTIVE_IDS.md for detailed documentation.
Controls how export operations handle errors when fetching issue data (labels, comments, dependencies).
# Strict: Fail fast on any error (default for user-initiated exports)
bd config set export.error_policy "strict"
# Best-effort: Skip failed operations with warnings (good for auto-export)
bd config set export.error_policy "best-effort"
# Partial: Retry transient failures, skip persistent ones with manifest
bd config set export.error_policy "partial"
bd config set export.write_manifest "true"
# Required-core: Fail on core data (issues/deps), skip enrichments (labels/comments)
bd config set export.error_policy "required-core"
# Customize retry behavior
bd config set export.retry_attempts "5"
bd config set export.retry_backoff_ms "200"
# Skip individual issues that fail JSON encoding
bd config set export.skip_encoding_errors "true"
# Auto-export uses different policy (background operation)
bd config set auto_export.error_policy "best-effort"Policy details:
-
strict(default) - Fail immediately on any error. Ensures complete exports but may block on transient issues like database locks. Best for critical exports and migrations. -
best-effort- Skip failed batches with warnings. Continues export even if labels or comments fail to load. Best for auto-exports and background sync where availability matters more than completeness. -
partial- Retry transient failures (3x by default), then skip with manifest file. Creates.manifest.jsonalongside JSONL documenting what succeeded/failed. Best for large databases with occasional corruption. -
required-core- Fail on core data (issues, dependencies), skip enrichments (labels, comments) with warnings. Best when metadata is secondary to issue tracking.
When to use each mode:
- Use
strict(default) for production backups and critical exports - Use
best-effortfor auto-exports (default viaauto_export.error_policy) - Use
partialwhen you need visibility into export completeness - Use
required-corewhen labels/comments are optional
Context-specific behavior:
User-initiated exports (bd sync, manual export commands) use export.error_policy (default: strict).
Auto-exports (daemon background sync) use auto_export.error_policy (default: best-effort), falling back to export.error_policy if not set.
Example: Different policies for different contexts:
# Critical project: strict everywhere
bd config set export.error_policy "strict"
# Development project: strict user exports, permissive auto-exports
bd config set export.error_policy "strict"
bd config set auto_export.error_policy "best-effort"
# Large database with occasional corruption
bd config set export.error_policy "partial"
bd config set export.write_manifest "true"
bd config set export.retry_attempts "5"Controls how imports handle hierarchical child issues when their parent is missing from the database:
# Strictest: Fail import if parent is missing (safest, prevents orphans)
bd config set import.orphan_handling "strict"
# Auto-resurrect: Search JSONL history and recreate missing parents as tombstones
bd config set import.orphan_handling "resurrect"
# Skip: Skip orphaned issues with warning (partial import)
bd config set import.orphan_handling "skip"
# Allow: Import orphans without validation (default, most permissive)
bd config set import.orphan_handling "allow"Mode details:
strict- Import fails immediately if a child's parent is missing. Use when database integrity is critical.resurrect- Searches the full JSONL file for missing parents and recreates them as tombstones (Status=Closed, Priority=4). Preserves hierarchy with minimal data. Dependencies are also resurrected on best-effort basis.skip- Skips orphaned children with a warning. Partial import succeeds but some issues are excluded.allow- Imports orphans without parent validation. Most permissive, works around import bugs. This is the default because it ensures all data is imported even if hierarchy is temporarily broken.
Override per command:
# Override config for a single import
bd import -i issues.jsonl --orphan-handling strict
# Auto-import (sync) uses config value
bd sync # Respects import.orphan_handling settingWhen to use each mode:
- Use
allow(default) for daily imports and auto-sync - ensures no data loss - Use
resurrectwhen importing from another database that had parent deletions - Use
strictonly for controlled imports where you need to guarantee parent existence - Use
skiprarely - only when you want to selectively import a subset
Controls for the sync branch workflow (see docs/PROTECTED_BRANCHES.md):
# Configure sync branch (required for protected branch workflow)
bd config set sync.branch beads-sync
# Enable mass deletion protection (optional, default: false)
# When enabled, if >50% of issues vanish during a merge AND more than 5
# issues existed before the merge, bd sync will:
# 1. Show forensic info about vanished issues
# 2. Prompt for confirmation before pushing
bd config set sync.require_confirmation_on_mass_delete "true"When to enable sync.require_confirmation_on_mass_delete:
- Multi-user workflows where accidental mass deletions could propagate
- Critical projects where data loss prevention is paramount
- When you want manual review before pushing large changes
When to keep it disabled (default):
- Single-user workflows where you trust your local changes
- CI/CD pipelines that need non-interactive sync
- When you want hands-free automation
# Configure Jira connection
bd config set jira.url "https://company.atlassian.net"
bd config set jira.project "PROJ"
bd config set jira.api_token "YOUR_TOKEN"
# Map bd statuses to Jira statuses
bd config set jira.status_map.open "To Do"
bd config set jira.status_map.in_progress "In Progress"
bd config set jira.status_map.closed "Done"
# Map bd issue types to Jira issue types
bd config set jira.type_map.bug "Bug"
bd config set jira.type_map.feature "Story"
bd config set jira.type_map.task "Task"Linear integration provides bidirectional sync between bd and Linear via GraphQL API.
Required configuration:
# API Key (can also use LINEAR_API_KEY environment variable)
bd config set linear.api_key "lin_api_YOUR_API_KEY"
# Team ID (find in Linear team settings or URL)
bd config set linear.team_id "team-uuid-here"Getting your Linear credentials:
- API Key: Go to Linear → Settings → API → Personal API keys → Create key
- Team ID: Go to Linear → Settings → General → Team ID (or extract from URLs)
Priority mapping (Linear 0-4 → Beads 0-4):
Linear and Beads both use 0-4 priority scales, but with different semantics:
- Linear: 0=no priority, 1=urgent, 2=high, 3=medium, 4=low
- Beads: 0=critical, 1=high, 2=medium, 3=low, 4=backlog
Default mapping (configurable):
bd config set linear.priority_map.0 4 # No priority -> Backlog
bd config set linear.priority_map.1 0 # Urgent -> Critical
bd config set linear.priority_map.2 1 # High -> High
bd config set linear.priority_map.3 2 # Medium -> Medium
bd config set linear.priority_map.4 3 # Low -> LowState mapping (Linear state types → Beads statuses):
Map Linear workflow state types to Beads statuses:
bd config set linear.state_map.backlog open
bd config set linear.state_map.unstarted open
bd config set linear.state_map.started in_progress
bd config set linear.state_map.completed closed
bd config set linear.state_map.canceled closed
# For custom workflow states, use lowercase state name:
bd config set linear.state_map.in_review in_progress
bd config set linear.state_map.blocked blocked
bd config set linear.state_map.on_hold blockedLabel to issue type mapping:
Infer bd issue type from Linear labels:
bd config set linear.label_type_map.bug bug
bd config set linear.label_type_map.defect bug
bd config set linear.label_type_map.feature feature
bd config set linear.label_type_map.enhancement feature
bd config set linear.label_type_map.epic epic
bd config set linear.label_type_map.chore chore
bd config set linear.label_type_map.maintenance chore
bd config set linear.label_type_map.task taskRelation type mapping (Linear relations → Beads dependencies):
bd config set linear.relation_map.blocks blocks
bd config set linear.relation_map.blockedBy blocks
bd config set linear.relation_map.duplicate duplicates
bd config set linear.relation_map.related relatedSync commands:
# Bidirectional sync (pull then push, with conflict resolution)
bd linear sync
# Pull only (import from Linear)
bd linear sync --pull
# Push only (export to Linear)
bd linear sync --push
# Dry run (preview without changes)
bd linear sync --dry-run
# Conflict resolution options
bd linear sync --prefer-local # Local version wins on conflicts
bd linear sync --prefer-linear # Linear version wins on conflicts
# Default: newer timestamp wins
# Check sync status
bd linear statusAutomatic sync tracking:
The linear.last_sync config key is automatically updated after each sync, enabling incremental sync (only fetch issues updated since last sync).
# Configure GitHub connection
bd config set github.org "myorg"
bd config set github.repo "myrepo"
bd config set github.token "YOUR_TOKEN"
# Map bd labels to GitHub labels
bd config set github.label_map.bug "bug"
bd config set github.label_map.feature "enhancement"Configuration is designed for scripting. Use --json for machine-readable output:
#!/bin/bash
# Get Jira URL
JIRA_URL=$(bd config get --json jira.url | jq -r '.value')
# Get all config and extract multiple values
bd config list --json | jq -r '.["jira.project"]'Example Python script:
import json
import subprocess
def get_config(key):
result = subprocess.run(
["bd", "config", "get", "--json", key],
capture_output=True,
text=True
)
data = json.loads(result.stdout)
return data["value"]
def list_config():
result = subprocess.run(
["bd", "config", "list", "--json"],
capture_output=True,
text=True
)
return json.loads(result.stdout)
# Use in integration
jira_url = get_config("jira.url")
jira_project = get_config("jira.project")- Use namespaces: Prefix keys with integration name (e.g.,
jira.*,linear.*) - Hierarchical keys: Use dots for structure (e.g.,
jira.status_map.open) - Document your keys: Add comments in integration scripts
- Security: Store tokens in config, but add
.beads/*.dbto.gitignore(bd does this automatically) - Per-project: Configuration is project-specific, so each repo can have different settings
Some bd commands automatically use configuration:
bd admin compactusescompact_tier1_days,compact_tier1_dep_levels, etc.bd initsetsissue_prefix
External integration scripts can read configuration to sync with Jira, Linear, GitHub, etc.
- README.md - Main documentation
- EXTENDING.md - Database schema and compaction config