Labels provide flexible, multi-dimensional categorization for issues beyond the structured fields (status, priority, type). Use labels for cross-cutting concerns, technical metadata, and contextual tagging without schema changes.
When to use labels vs. structured fields:
-
Structured fields (status, priority, type) → Core workflow state
- Status: Where the issue is in the workflow (
open,in_progress,blocked,closed) - Priority: How urgent (0-4)
- Type: What kind of work (
bug,feature,task,epic,chore)
- Status: Where the issue is in the workflow (
-
Labels → Everything else
- Technical metadata (
backend,frontend,api,database) - Domain/scope (
auth,payments,search,analytics) - Effort estimates (
small,medium,large) - Quality gates (
needs-review,needs-tests,breaking-change) - Team/ownership (
team-infra,team-product) - Release tracking (
v1.0,v2.0,backport-candidate)
- Technical metadata (
# Add labels when creating issues
bd create "Fix auth bug" -t bug -p 1 -l auth,backend,urgent
# Add labels to existing issues
bd label add bd-42 security
bd label add bd-42 breaking-change
# List issue labels
bd label list bd-42
# Remove a label
bd label remove bd-42 urgent
# List all labels in use
bd label list-all
# Filter by labels (AND - must have ALL)
bd list --label backend,auth
# Filter by labels (OR - must have AT LEAST ONE)
bd list --label-any frontend,backend
# Combine filters
bd list --status open --priority 1 --label securityIdentify which part of the system:
backend
frontend
api
database
infrastructure
cli
ui
mobileExample:
bd create "Add GraphQL endpoint" -t feature -p 2 -l backend,api
bd create "Update login form" -t task -p 2 -l frontend,auth,uiGroup by business domain:
auth
payments
search
analytics
billing
notifications
reporting
adminExample:
bd list --label payments --status open # All open payment issues
bd list --label-any auth,security # Security-related workQuick effort indicators:
small # < 1 day
medium # 1-3 days
large # > 3 daysExample:
# Find small quick wins
bd ready --json | jq '.[] | select(.labels[] == "small")'Track what's needed before closing:
needs-review
needs-tests
needs-docs
breaking-changeExample:
bd label add bd-42 needs-review
bd list --label needs-review --status in_progressTrack release targeting:
v1.0
v2.0
backport-candidate
release-blockerExample:
bd list --label v1.0 --status open # What's left for v1.0?
bd label add bd-42 release-blockerIndicate ownership or interest:
team-infra
team-product
team-mobile
needs-triage
help-wantedExample:
bd list --assignee alice --label team-infra
bd create "Memory leak in cache" -t bug -p 1 -l team-infra,help-wantedProcess or workflow flags:
auto-generated # Created by automation
discovered-from # Found during other work (also a dep type)
technical-debt
good-first-issue
duplicate
wontfixExample:
bd create "TODO: Refactor parser" -t chore -p 3 -l technical-debt,auto-generatedAll specified labels must be present:
# Issues that are BOTH backend AND urgent
bd list --label backend,urgent
# Open bugs that need review AND tests
bd list --status open --type bug --label needs-review,needs-testsAt least one specified label must be present:
# Issues in frontend OR backend
bd list --label-any frontend,backend
# Security or auth related
bd list --label-any security,authMix both filters for complex queries:
# Backend issues that are EITHER urgent OR a blocker
bd list --label backend --label-any urgent,release-blocker
# Frontend work that needs BOTH review and tests, but in any component
bd list --label needs-review,needs-tests --label-any frontend,ui,mobile# Create untriaged issue
bd create "Crash on login" -t bug -p 1 -l needs-triage
# During triage, add context
bd label add bd-42 auth
bd label add bd-42 backend
bd label add bd-42 urgent
bd label remove bd-42 needs-triage
# Find untriaged issues
bd list --label needs-triage# Start work
bd update bd-42 --claim
# Mark quality requirements
bd label add bd-42 needs-tests
bd label add bd-42 needs-docs
# Before closing, verify
bd label list bd-42
# ... write tests and docs ...
bd label remove bd-42 needs-tests
bd label remove bd-42 needs-docs
# Close when gates satisfied
bd close bd-42# Tag issues for v1.0
bd label add bd-42 v1.0
bd label add bd-43 v1.0
bd label add bd-44 v1.0
# Track v1.0 progress
bd list --label v1.0 --status closed # Done
bd list --label v1.0 --status open # Remaining
bd stats # Overall progress
# Mark critical items
bd label add bd-45 v1.0
bd label add bd-45 release-blocker# Backend team picks up work
bd ready --json | jq '.[] | select(.labels[]? == "backend")'
# Frontend team finds small tasks
bd list --status open --label frontend,small
# Find help-wanted items for new contributors
bd list --label help-wanted,good-first-issue# Labels on a specific issue
bd label list bd-42
# All labels in database with usage counts
bd label list-all
# JSON output for scripting
bd label list-all --jsonOutput:
[
{"label": "auth", "count": 5},
{"label": "backend", "count": 12},
{"label": "frontend", "count": 8}
]Add labels in batch during creation:
bd create "Issue" -l label1,label2,label3Script to add label to multiple issues:
# Add "needs-review" to all in_progress issues
bd list --status in_progress --json | jq -r '.[].id' | while read id; do
bd label add "$id" needs-review
doneRemove label from multiple issues:
# Remove "urgent" from closed issues
bd list --status closed --label urgent --json | jq -r '.[].id' | while read id; do
bd label remove "$id" urgent
doneLabels are stored in the Dolt database and synced automatically with all issue data:
# Make changes
bd create "Fix bug" -l backend,urgent
bd label add bd-42 needs-review
# Changes are committed to Dolt history automatically
# Sync with remotes when ready:
bd dolt push
# After pulling changes:
bd dolt pull
bd list --label backend # Fresh data including labelsLabels are preserved when importing from markdown:
# Fix Authentication Bug
### Type
bug
### Priority
1
### Labels
auth, backend, urgent, needs-review
### Description
Users can't log in after recent deployment.bd create -f issue.md
# Creates issue with all four labelsDocument your team's label taxonomy:
# Add to project README or CONTRIBUTING.md
- Use lowercase, hyphen-separated (e.g., `good-first-issue`)
- Prefix team labels (e.g., `team-infra`, `team-product`)
- Use consistent size labels (`small`, `medium`, `large`)Labels are flexible, but too many can cause confusion. Prefer:
- 5-10 core technical labels (
backend,frontend,api, etc.) - 3-5 domain labels per project
- Standard process labels (
needs-review,needs-tests) - Release labels as needed
Periodically review:
bd label list-all
# Remove obsolete labels from issuesLabels are for categorization, not free-text search:
- ✅ Good:
backend,auth,urgent - ❌ Bad:
fix-the-login-bug,john-asked-for-this
Labels + dependencies = powerful organization:
# Epic with labeled subtasks
bd create "Auth system rewrite" -t epic -p 1 -l auth,v2.0
bd create "Implement JWT" -t task -p 1 -l auth,backend --deps parent-child:bd-42
bd create "Update login UI" -t task -p 1 -l auth,frontend --deps parent-child:bd-42
# Find all v2.0 auth work
bd list --label auth,v2.0Labels are especially useful for AI agents managing complex workflows:
# Auto-label discovered work
bd create "Found TODO in auth.go" -t task -p 2 -l auto-generated,technical-debt
# Filter for agent review
bd list --label needs-review --status in_progress --json
# Track automation metadata
bd label add bd-42 ai-generated
bd label add bd-42 needs-human-reviewExample agent workflow:
# Agent discovers issues during refactor
bd create "Extract validateToken function" -t chore -p 2 \
-l technical-debt,backend,auth,small \
--deps discovered-from:bd-10
# Agent marks work for review
bd update bd-42 --claim
# ... agent does work ...
bd label add bd-42 needs-review
bd label add bd-42 ai-generated
# Human reviews and approves
bd label remove bd-42 needs-review
bd label add bd-42 approved
bd close bd-42Labels can cache operational state for fast queries, enabling patterns where beads track both immutable history (events) and current state (labels).
Convention: <dimension>:<value>
Examples:
patrol:muted/patrol:active- patrol suppression statemode:degraded/mode:normal- operational modestatus:idle/status:working- worker statushealth:healthy/health:failing- component health
Implementation:
- Create an event bead (full context, immutable history)
- Update the role bead's labels (current state cache)
# Event: Full record of what happened and why
bd create "Muted patrol: user requested during debugging" -t event \
-l event-type:patrol-muted,actor:observer,reason:user-request
# State: Update the role bead's label to reflect current state
bd label remove beads/observer patrol:active
bd label add beads/observer patrol:mutedKey principle: Events are the source of truth. Labels are a cache for fast queries.
Fast queries without event scanning:
# Without labels-as-state: scan all events to find current patrol state
bd list --type event | grep "patrol" | tail -1 # Slow, fragile
# With labels-as-state: direct query
bd show beads/observer | grep "patrol:" # InstantHistory preserved:
# When was patrol muted? Why? Who did it?
bd list --label event-type:patrol-muted --type eventState recovery:
# If labels get corrupted, rebuild from events
bd list --type event --label event-type:patrol-muted | tail -1
# Then re-apply the label| Dimension | Values | Use Case |
|---|---|---|
patrol: |
active, muted |
Patrol cycle suppression |
mode: |
normal, degraded, maintenance |
Operational mode |
status: |
idle, working, blocked |
Worker activity |
health: |
healthy, warning, failing |
Component health |
lock: |
unlocked, locked |
Exclusive access control |
Always create an event before changing state labels:
# Function to transition state with audit trail
transition_state() {
local role="$1"
local dimension="$2"
local old_value="$3"
local new_value="$4"
local reason="$5"
# Record the transition
bd create "State change: $dimension $old_value → $new_value" -t event \
-l "event-type:state-change,dimension:$dimension,from:$old_value,to:$new_value"
# Update the cache
bd label remove "$role" "$dimension:$old_value"
bd label add "$role" "$dimension:$new_value"
}
# Usage
transition_state beads/observer patrol active muted "User debugging session"# Current state of a role
bd label list beads/observer | grep ":"
# All roles in a specific state
bd list --label patrol:muted
# Roles NOT in expected state
bd list --label-any mode:degraded,health:failing
# History of state changes
bd list --type event --label event-type:state-change- Use namespaced dimensions - Prefix with role type if ambiguous
- Keep value sets small - 2-4 values per dimension
- Document valid values - List allowed values in role docs
- Always create events first - Never update labels without history
- Treat labels as ephemeral - Rebuild from events if corrupted
The pattern suggests helper commands (see bd-7l67):
# Query current state
bd state beads/observer patrol # → "muted"
# Transition with automatic event creation
bd set-state beads/observer patrol=active --reason "Debugging complete"Until helpers exist, use the manual pattern above.
Track issues across multiple dimensions:
# Backend + auth + high priority
bd list --label backend,auth --priority 1
# Any frontend work that's small
bd list --label-any frontend,ui --label small
# Critical issues across all components
bd list --priority 0 --label-any backend,frontend,infrastructure# Label issues for sprint
for id in bd-42 bd-43 bd-44 bd-45; do
bd label add "$id" sprint-12
done
# Track sprint progress
bd list --label sprint-12 --status closed # Velocity
bd list --label sprint-12 --status open # Remaining
bd stats | grep "In Progress" # Current WIP# Mark debt
bd create "Refactor legacy parser" -t chore -p 3 -l technical-debt,large
# Find debt to tackle
bd list --label technical-debt --label small
bd list --label technical-debt --priority 1 # High-priority debt# Identify breaking changes
bd label add bd-42 breaking-change
bd label add bd-42 v2.0
# Find all breaking changes for next major release
bd list --label breaking-change,v2.0
# Ensure they're documented
bd list --label breaking-change --label needs-docsFor orchestration systems, labels can cache the current operational state of "role beads" (issues representing agents or system components). This enables fast state queries without scanning event history.
Use colon-separated labels with a dimension prefix and value suffix:
patrol:muted patrol:active
mode:degraded mode:normal
status:idle status:working
health:healthy health:failing
- Create an event bead with full context (immutable, audit trail)
- Update the role bead's labels to reflect current state (fast lookup)
# 1. Record the event (source of truth)
bd create "Muted patrol for agent-abc" -t event \
--parent agent-abc \
-d "Reason: investigating stuck worker. Expected duration: 30m"
# 2. Update the cached state label
bd label remove agent-abc patrol:active
bd label add agent-abc patrol:mutedEvents are source of truth. Labels are cache.
| Approach | Events Only | Labels as Cache |
|---|---|---|
| Query current state | Scan all events, find latest | bd list --label patrol:muted |
| Query state history | Natural (all events exist) | Query events |
| Audit trail | Complete | Complete (events still exist) |
| Performance | O(n) events | O(1) label lookup |
The pattern gives you both: complete history via events, fast queries via labels.
# Create a role bead for an agent
bd create "witness-alpha" -t role -l patrol:active,mode:normal,health:healthy
# Agent enters degraded mode
bd create "Degraded: high error rate" -t event --parent witness-alpha \
-d "Error rate exceeded 5%. Reducing poll frequency."
bd label remove witness-alpha mode:normal
bd label add witness-alpha mode:degraded
# Query current state
bd list --label mode:degraded --type role # All degraded roles
# Agent recovers
bd create "Recovered: error rate normal" -t event --parent witness-alpha
bd label remove witness-alpha mode:degraded
bd label add witness-alpha mode:normal| Dimension | Values | Use Case |
|---|---|---|
patrol |
active, muted, suspended |
Agent patrol cycles |
mode |
normal, degraded, maintenance |
Operational modes |
status |
idle, working, blocked |
Work state |
health |
healthy, warning, failing |
Health checks |
sync |
current, stale, syncing |
Sync state |
- Always create the event first - Labels are cache; events are truth
- Remove old value before adding new - Prevents dimension:value1 + dimension:value2 conflicts
- Use consistent dimension names - Establish team conventions early
- Keep dimensions orthogonal - patrol and mode are independent concerns
# Find all muted patrols
bd list --label patrol:muted
# Find healthy agents in normal mode
bd list --label health:healthy,mode:normal
# Find any non-healthy agents
bd list --label-any health:warning,health:failing
# Get state for a specific role
bd label list witness-alpha
# Output: patrol:active, mode:normal, health:healthyFor convenience, use these helpers:
# Query a specific dimension
bd state witness-alpha patrol
# Output: active
# List all state dimensions
bd state list witness-alpha
# Output:
# patrol: active
# mode: normal
# health: healthy
# Set state (creates event + updates label atomically)
bd set-state witness-alpha patrol=muted --reason "Investigating issue"The set-state command atomically:
- Creates an event bead with the reason (source of truth)
- Removes the old dimension label if present
- Adds the new dimension:value label (cache)
See CLI_REFERENCE.md for full command reference.
Labels require explicit fetching. The bd list command shows issues but not labels in human output (only in JSON).
# See labels in JSON
bd list --json | jq '.[] | {id, labels}'
# See labels for specific issue
bd show bd-42 --json | jq '.labels'
bd label list bd-42Check label names for exact matches (case-sensitive):
# These are different labels:
bd label add bd-42 Backend # Capital B
bd list --label backend # Won't match
# List all labels to see exact names
bd label list-allLabels are stored in the Dolt database. If labels seem out of sync:
# Pull from Dolt remote
bd dolt pull
# Or run doctor to diagnose
bd doctor- README.md - Main documentation
- AGENTS.md - AI agent integration guide
- ADVANCED.md - Advanced features and configuration