name: beads-dependency-tracking description: Managing issue dependencies, viewing blocked work, and navigating dependency graphs triggers:
- add dependency
- show dependencies
- dependency tree
- blocked issues
- unblock
- bd dep
- bd blocked
Beads Dependency Tracking
First-class dependency management for issue tracking with visual graphs and blocking detection.
Overview
Beads treats dependencies as a core primitive, not an afterthought. The system supports:
- 4 dependency types: blocks, related, parent-child, discovered-from
- Bidirectional tracking: What blocks this issue, what this issue blocks
- Cycle detection: Prevents circular dependency chains
- Visual trees: ASCII and Mermaid.js graph outputs
- Blocking analysis: Find issues that can't proceed due to dependencies
Dependencies are the key to intelligent work prioritization and unblocking workflows.
Canonical Sources
Command Reference:
bd dep --help # Dependency management overview
bd dep add --help # Adding dependencies
bd dep remove --help # Removing dependencies
bd dep tree --help # Viewing dependency trees
bd dep cycles --help # Detecting cycles
bd blocked --help # Showing blocked issues
bd ready --help # Showing unblocked work
Dependency Types:
- blocks: This issue must be completed before the dependent can start
- related: Informational link, no blocking semantics
- parent-child: Hierarchical relationship (epics → tasks)
- discovered-from: Tracks issue discovery context (bugs found during work)
Patterns
Adding Dependencies
# Simple blocking dependency
bd dep add tmnl-abc tmnl-xyz
# Meaning: tmnl-abc is blocked by tmnl-xyz (xyz must complete first)
# Explicit type
bd dep add tmnl-abc tmnl-xyz --type blocks
# Related (non-blocking) dependency
bd dep add tmnl-abc tmnl-xyz --type related
# Parent-child relationship
bd dep add tmnl-child tmnl-parent --type parent-child
# Discovery context
bd dep add tmnl-bug tmnl-feature --type discovered-from
# Meaning: bug was discovered while working on feature
Adding Dependencies During Creation
# Inline dependency specification
bd create "Wire UI to backend" \
--type task \
--deps "blocks:tmnl-api,blocks:tmnl-ui,related:tmnl-docs"
# Multiple dependencies with different types
bd create "Fix integration bug" \
--type bug \
--deps "discovered-from:tmnl-feature,blocks:tmnl-infra"
Removing Dependencies
# Remove specific dependency
bd dep remove tmnl-abc tmnl-xyz
# Remove all dependencies of an issue
bd dep remove tmnl-abc --all # (if supported)
Viewing Dependency Trees
# Show what blocks this issue (dependencies, down direction)
bd dep tree tmnl-abc
bd dep tree tmnl-abc --direction down
# Show what this issue blocks (dependents, up direction)
bd dep tree tmnl-abc --direction up
# Show full bidirectional graph
bd dep tree tmnl-abc --direction both
# Filter by status (only open issues)
bd dep tree tmnl-abc --status open
# Limit depth
bd dep tree tmnl-abc --max-depth 3
# Mermaid.js output for visualization
bd dep tree tmnl-abc --format mermaid > graph.mmd
Finding Blocked Issues
# Show all blocked issues
bd blocked
# Filter blocked issues by priority
bd blocked | grep "\[P0\]"
# Show blocking dependencies for a specific issue
bd show tmnl-abc # Lists dependencies at bottom
Finding Ready Work
# Show unblocked issues (no open dependencies)
bd ready
# Filter ready work by priority
bd ready --priority 0 # P0 only
# Filter by assignee
bd ready --assignee val
# Show unassigned ready work
bd ready --unassigned
# Limit results
bd ready --limit 5
# Sort by priority (default), oldest, or hybrid
bd ready --sort priority
bd ready --sort oldest
bd ready --sort hybrid # Balances priority + age
Detecting Dependency Cycles
# Check for circular dependencies
bd dep cycles
# Example output if cycle detected:
# Cycle detected: tmnl-a → tmnl-b → tmnl-c → tmnl-a
Examples
Example 1: Feature Implementation Chain
# 1. Create foundation tasks
API_ID=$(bd create "Build API endpoint" --type task --priority P1 --json | jq -r '.id')
SCHEMA_ID=$(bd create "Design data schema" --type task --priority P1 --json | jq -r '.id')
UI_ID=$(bd create "Build UI component" --type task --priority P1 --json | jq -r '.id')
# 2. Add blocking dependencies
bd dep add $API_ID $SCHEMA_ID # API blocked by schema
bd dep add $UI_ID $API_ID # UI blocked by API
# 3. View dependency chain
bd dep tree $UI_ID
# Output:
# tmnl-ui: Build UI component
# └─ tmnl-api: Build API endpoint
# └─ tmnl-schema: Design data schema
# 4. Find what's ready to start
bd ready --limit 5
# Output shows tmnl-schema as unblocked, ready to work
Example 2: Unblocking Workflow
# 1. Check blocked work
bd blocked
# Output:
# [P0] tmnl-integration: Wire services together
# Blocked by 3 open dependencies: [tmnl-api, tmnl-db, tmnl-cache]
# 2. View dependency tree
bd dep tree tmnl-integration
# 3. Start work on blocking issues
bd update tmnl-api --status in_progress
# 4. Close completed blockers
bd close tmnl-api --reason "Endpoint implemented and tested"
# 5. Check if integration is now unblocked
bd show tmnl-integration # Shows remaining 2 blockers
bd blocked # No longer shows tmnl-integration when all blockers closed
Example 3: Epic Decomposition with Dependencies
# 1. Create epic
EPIC_ID=$(bd create "Search System v2" --from-template epic --priority P0 --json | jq -r '.id')
# 2. Create phases with parent relationship
PHASE1=$(bd create "Phase 1: Infrastructure" --type task --priority P0 --parent $EPIC_ID --json | jq -r '.id')
PHASE2=$(bd create "Phase 2: Indexing" --type task --priority P0 --parent $EPIC_ID --json | jq -r '.id')
PHASE3=$(bd create "Phase 3: UI" --type task --priority P1 --parent $EPIC_ID --json | jq -r '.id')
# 3. Add sequential blocking
bd dep add $PHASE2 $PHASE1 # Phase 2 blocked by Phase 1
bd dep add $PHASE3 $PHASE2 # Phase 3 blocked by Phase 2
# 4. Create subtasks for Phase 1
TASK1=$(bd create "Setup PostgreSQL FTS" --type task --priority P0 --json | jq -r '.id')
TASK2=$(bd create "Setup Redis cache" --type task --priority P0 --json | jq -r '.id')
bd dep add $PHASE1 $TASK1 # Phase 1 blocked by Task 1
bd dep add $PHASE1 $TASK2 # Phase 1 blocked by Task 2
# 5. View full dependency graph
bd dep tree $EPIC_ID --direction down
# Output shows waterfall structure:
# epic → phase1 → [task1, task2]
# → phase2 (blocked by phase1)
# → phase3 (blocked by phase2)
# 6. Find ready work
bd ready --limit 10
# Shows task1 and task2 as ready (no blockers)
Example 4: Bug Discovery Chain
# 1. During feature work, discover a bug
FEATURE_ID=$(bd show tmnl-feature-123 --json | jq -r '.id')
# 2. Create bug with discovery context
BUG_ID=$(bd create "Null pointer in auth handler" \
--type bug \
--priority P0 \
--deps "discovered-from:$FEATURE_ID" \
--json | jq -r '.id')
# 3. Bug blocks feature completion
bd dep add $FEATURE_ID $BUG_ID --type blocks
# 4. View feature's dependency tree
bd dep tree $FEATURE_ID
# Output:
# tmnl-feature-123: Implement user profile
# └─ tmnl-bug-456: Null pointer in auth handler
# └─ (discovered-from) tmnl-feature-123
# 5. Close bug, unblocking feature
bd close $BUG_ID --reason "Fixed NPE with null check"
bd ready --limit 5 # Now shows tmnl-feature-123 as ready
Example 5: Parallel Work Identification
# 1. Find all unblocked work
bd ready --limit 20 --sort priority
# 2. Filter to specific labels
bd ready --label backend --limit 10
# 3. Assign parallel work to team members
bd update tmnl-abc --assignee alice --status in_progress
bd update tmnl-xyz --assignee bob --status in_progress
bd update tmnl-def --assignee val --status in_progress
# 4. Check blocked work that will become ready soon
bd blocked | grep "\[P0\]"
# Shows high-priority blocked issues
# 5. View dependency trees for blocked work
bd dep tree tmnl-blocked-issue
# Identify which blockers to prioritize
Anti-Patterns
DON'T: Create circular dependencies
# WRONG - creates cycle
bd dep add tmnl-a tmnl-b # a blocked by b
bd dep add tmnl-b tmnl-c # b blocked by c
bd dep add tmnl-c tmnl-a # c blocked by a (CYCLE!)
# System will reject or warn. Fix by breaking cycle:
bd dep remove tmnl-c tmnl-a # Remove problematic link
DON'T: Start work on blocked issues
# WRONG - working on blocked issue
bd blocked | grep tmnl-abc
# Output: tmnl-abc has 3 open blockers
bd update tmnl-abc --status in_progress # BAD!
# CORRECT - work on unblocked issues
bd ready --limit 10
bd update tmnl-xyz --status in_progress # Good, no blockers
DON'T: Forget to remove dependencies when requirements change
# WRONG - leaving stale dependencies
# (Original plan: UI blocked by API)
bd dep add tmnl-ui tmnl-api
# (Plan changes: UI can use mock data, doesn't need real API)
# But dependency is still there, blocking UI work!
# CORRECT - remove stale dependency
bd dep remove tmnl-ui tmnl-api
bd ready # Now tmnl-ui shows as ready
DON'T: Use wrong dependency type
# WRONG - using "blocks" for informational links
bd dep add tmnl-ui tmnl-docs --type blocks
# (UI doesn't actually need docs to be complete)
# CORRECT - use "related" for informational links
bd dep add tmnl-ui tmnl-docs --type related
DON'T: Create deep dependency chains without reviewing
# WRONG - creating long chain without visualization
bd dep add tmnl-a tmnl-b
bd dep add tmnl-b tmnl-c
bd dep add tmnl-c tmnl-d
bd dep add tmnl-d tmnl-e
# (Creates 5-level waterfall, may be inefficient)
# CORRECT - visualize and refactor if needed
bd dep tree tmnl-a
# Review if some tasks can be parallelized
bd dep remove tmnl-c tmnl-d # Break chain if possible
DON'T: Ignore blocked issue warnings
# WRONG - closing issue with open dependents
bd close tmnl-api # (tmnl-ui depends on this)
# This orphans tmnl-ui's dependency, may cause confusion
# CORRECT - check reverse dependencies first
bd dep tree tmnl-api --direction up # See what depends on this
# If closing, update or remove dependents
bd dep remove tmnl-ui tmnl-api # If dependency no longer valid
bd close tmnl-api --reason "Obsolete, replaced by new endpoint"
Quick Reference Card
| Task | Command |
|---|---|
| Add blocking dependency | bd dep add [issue] [blocker] |
| Add related link | bd dep add [issue] [related] --type related |
| Remove dependency | bd dep remove [issue] [blocker] |
| View dependency tree | bd dep tree [issue] |
| View reverse tree (dependents) | bd dep tree [issue] --direction up |
| Show blocked issues | bd blocked |
| Show ready work | bd ready --limit 10 |
| Detect cycles | bd dep cycles |
| Mermaid graph | bd dep tree [issue] --format mermaid |
| Filter ready by priority | bd ready --priority 0 |
Dependency Types Reference
| Type | Semantics | Example |
|---|---|---|
| blocks | Hard blocker, dependent cannot start | API must exist before UI can call it |
| related | Soft link, informational only | UI relates to docs, but can proceed independently |
| parent-child | Hierarchical relationship | Epic contains multiple child tasks |
| discovered-from | Discovery context | Bug found while implementing feature |
Workflow Tips
- Start with
bd ready: Always check unblocked work before starting new tasks - Review
bd blocked: Identify bottlenecks and prioritize unblocking work - Use
bd dep tree: Visualize complex dependency chains before starting work - Check reverse dependencies: Before closing, verify what depends on the issue
- Detect cycles early: Run
bd dep cyclesafter adding complex dependency chains - Prefer parallel over sequential: Only use blocking deps when truly necessary
Integration Points
- Issue creation: Use
--depsflag (see beads-issue-management skill) - Session workflow:
bd readyandbd blockedinform daily work (see beads-session-workflow skill) - Git workflow: Dependencies preserved across
bd syncoperations - AI context: Dependency graphs help AI understand project structure