Beads Viewer (bv)

September 8, 2026 ยท View on GitHub

Release Go Version License Coverage

The elegant, keyboard-driven terminal interface for the Beads issue tracker.

Main split view
Main split view: fast list + rich details
Kanban board
Kanban board (`b`) for flow at a glance
Insights view
Insights panel: PageRank, critical path, cycles
Graph view
Graph view (`g`): navigate the dependency DAG

Installation

brew install dicklesworthstone/tap/bv

This method provides:

  • Automatic updates via brew upgrade
  • Dependency management
  • Easy uninstall via brew uninstall

Windows: Scoop

scoop bucket add dicklesworthstone https://github.com/Dicklesworthstone/scoop-bucket
scoop install dicklesworthstone/bv

Homebrew and Scoop select the version in their published manifests. To pin v0.24.1, use a verified release archive below. See the distribution checks for version and checksum details.

Alternative: Direct Download

Pick the archive for your platform from the latest release page. Archives are named bv_<version>_<os>_<arch>.tar.gz (.zip on Windows), for example bv_0.23.0_linux_amd64.tar.gz, bv_0.23.0_darwin_arm64.tar.gz, bv_0.23.0_windows_amd64.zip, so a downloaded file always says which release it came from. Every release also ships checksums.txt; verify before extracting:

sha256sum -c --ignore-missing checksums.txt

Releases up to v0.22.0 used unversioned names (bv_linux_amd64.tar.gz); bv --update and install.sh accept both forms.

Alternative: Install Script

Linux/macOS: Prefer Homebrew, Scoop, or a checksum-verified release archive above. If you do pipe the script, pin it to a commit you have read instead of the moving main branch:

# Pinned to a reviewed commit; read it first: https://github.com/Dicklesworthstone/beads_viewer/blob/03f92509bceb9da31540167c223c10f16c279767/install.sh
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/beads_viewer/03f92509bceb9da31540167c223c10f16c279767/install.sh" | bash

Warning: curl ... | bash runs whatever the URL serves at that moment. The pinned form above cannot change under you; the main form can. install.sh downloads the release archive for your platform, verifies it against the release checksums.txt, and refuses to install on a mismatch.

Windows (PowerShell):

# Pinned to a reviewed commit; read it first: https://github.com/Dicklesworthstone/beads_viewer/blob/3ca2176f11cc6106be452815e03fc4164b581761/install.ps1
irm "https://raw.githubusercontent.com/Dicklesworthstone/beads_viewer/3ca2176f11cc6106be452815e03fc4164b581761/install.ps1" | iex

Note: The pinned installer above downloads the Windows release zip, verifies it against the release checksums.txt with Get-FileHash, and refuses anything that does not verify; no Go toolchain is needed. Pass -Version v0.24.1 to pin a release or -InstallDir to choose the folder (default %LOCALAPPDATA%\Programs\bv). Scoop installs the archive selected by its manifest. For best display, use Windows Terminal with a Nerd Font.

For a source build, use install.ps1 from this checkout (requires Git and Go 1.25+):

.\install.ps1 -FromSource -Version v0.24.1

This source path builds a verified checkout of the requested tag with that tag's vendored dependencies, checks the executable's version and Git revision before installation, and retains diagnostics on failure. The pinned installer above uses the same verified source-build path. Selecting an older release tag does not include later, unreleased fixes from this checkout.


Generating the JSONL File (br and bd)

bv reads Beads JSONL exports from .beads/. Current br and Dolt-backed bd workspaces use .beads/issues.jsonl; older legacy workspaces may use .beads/beads.jsonl. bv auto-discovers the supported file names.

Rust (br) users โ€” run br sync --flush-only after Beads mutations so .beads/issues.jsonl is current.

Go (bd) users โ€” run:

bd export -o .beads/issues.jsonl

Once the file exists, bv works identically regardless of which tool produced it.


๐Ÿค– Agent Quickstart (Robot Mode)

โš ๏ธ Never run bare bv in an agent context โ€” it launches the interactive TUI. Always use --robot-*.

# 1) Start with triage (single-call mega-command)
bv --robot-triage

# 2) Minimal mode: just the top pick + claim command
bv --robot-next

# 3) TOON output: smaller only for wide tabular payloads (--robot-graph); larger
#    for nested ones such as --robot-triage. Check with --stats before adopting.
bv --robot-graph --format toon
bv --robot-triage --format toon --stats
export BV_OUTPUT_FORMAT=toon

# 4) Full robot help
bv --robot-help

Output conventions

  • stdout = JSON/TOON data only
  • stderr = diagnostics
  • exit 0 = success

TOON uses an external toon_rust encoder. Discovery honors TOON_TRU_BIN or TOON_BIN, then looks for tru or toon on PATH and the library's known fallback paths; candidates are validated as toon_rust. If none is available, bv warns on stderr and emits JSON. A successful fallback is not evidence that TOON encoding ran. Keep the format set to JSON when copying the jq examples below.

๐Ÿ’ก TL;DR

bv is a high-performance Terminal User Interface (TUI) for browsing and managing tasks in projects that use the Beads issue tracking system.

Why you'd care:

  • Local browsing: Browse thousands of issues without a network round trip. Response time depends on the graph, selected view, and host.
  • Focus: Stay in your terminal and use Vim-style keys (j/k) to navigate.
  • Intelligence: It visualizes your project as a dependency graph, automatically highlighting bottlenecks, cycles, and critical paths that traditional list-based trackers miss.
  • AI-Ready: It provides structured, pre-computed insights for AI coding agents, acting as a "brain" for your project's task management.

๐Ÿ“– The Core Experience

At its heart, bv is about viewing your work nicely.

โšก Fast, Fluid Browsing

Browse your issue backlog in the terminal using standard Vim keys (j/k). Startup and navigation time depend on the workload; measured limits are described under Performance.

  • Split-View Dashboard: On wider screens, see your list on the left and full details on the right.
  • Markdown Rendering: Issue descriptions, comments, and notes are beautifully rendered with syntax highlighting, headers, and lists.
  • Keyboard Filtering: Press o for Open, c for Closed, or r for Ready (unblocked) tasks.
  • Live Reload: Watches the active Beads JSONL file and refreshes lists, details, and insights automatically when the file changesโ€”no restart needed.

๐Ÿ”Ž Rich Context

Don't just read the title. bv gives you the full picture:

  • Comments & History: Scroll through the full conversation history of any task.
  • Metadata: Instantly see Assignees, Labels, Priority badges, and creation dates.
  • Search: Fuzzy list filtering (/) matches titles, IDs and displayed metadata. CLI keyword search (--search) also indexes descriptions and can combine text scores with graph metrics.
  • Dependency Details: The detail pane shows dependencies up to three edges from the selected issue. Each issue's dependencies appear once along a shortest path; other occurrences say (reference: shown elsewhere). Every relationship within that limit retains its type and target metadata. Cycle-closing edges carry a separate (cycle) marker.

๐ŸŽฏ Focused Workflows

  • Kanban Board: Press b to switch to a columnar view (Open, In Progress, Blocked, Closed) to visualize flow.
  • Visual Graph: Press g to explore the dependency tree visually.
  • Insights: Press i to see graph metrics and bottlenecks.
  • History View: Press h to see the timeline of changes, correlating git commits with bead modifications. On wider terminals, enjoy a responsive three-pane layout showing commits, affected beads, and details.
  • Ultra-Wide Mode: On large monitors, the list expands to show extra columns like sparklines and label tags.

๐Ÿ› ๏ธ Quick Actions

  • Export: Press x to export all issues to a timestamped Markdown file with Mermaid diagrams (E opens the tree view).
  • Graph Export (CLI): bv --robot-graph outputs the dependency graph as JSON, DOT (Graphviz), or Mermaid format. Use --graph-format=dot for rendering with Graphviz, or --graph-root=ID --graph-depth=3 to extract focused subgraphs.
  • Copy: Press C to copy the selected issue as formatted Markdown to your clipboard.
  • Edit: Press O to open the active Beads JSONL file in your preferred GUI editor.
  • Time-Travel: Press t to compare against any git revision, or T for quick HEAD~5 comparison. Combined with History view (h), you can navigate to any commit and see exactly what changed.

๐Ÿ”Œ Automation Hooks

Configure pre- and post-export hooks in .bv/hooks.yaml to run validations, notifications, or uploads. Hooks run automatically whenever that file exists; pass --no-hooks to skip them for one export. Defaults: pre-export hooks fail fast on errors (on_error: fail), post-export hooks log and continue (on_error: continue). A post-export hook declared on_error: fail makes the export exit 1 even though the bundle has already been written. Empty commands are ignored with a warning for safety. Hook env includes BV_EXPORT_PATH, BV_EXPORT_FORMAT, BV_ISSUE_COUNT, BV_TIMESTAMP, plus any custom env entries.

Security: hooks are shell commands defined by the project you are exporting, so treat .bv/hooks.yaml in an unfamiliar repository as untrusted code and review it before exporting (or pass --no-hooks). To limit blast radius, bv strips credential-bearing environment variables (names containing TOKEN, SECRET, PASSWORD, CREDENTIAL, API_KEY, ACCESS_KEY, PRIVATE_KEY, etc., plus SSH_AUTH_SOCK) from hook subprocesses. A hook that legitimately needs one must re-grant it explicitly, e.g. env: { GITHUB_TOKEN: "${GITHUB_TOKEN}" }.


๐Ÿค– Ready-made Blurb to Drop Into Your AGENTS.md or CLAUDE.md Files

The text below is exactly what bv --agents-add (and the TUI's AGENTS.md prompt) installs (pkg/agents/blurb.go, AgentBlurb); a docs parity test keeps this copy identical to it.

<!-- bv-agent-instructions-v5 -->

---

## Beads Workflow Integration

This project uses a Beads trackerโ€”either the Go `bd` CLI or the Rust `br` CLIโ€”for issue tracking, plus [beads_viewer](https://github.com/Dicklesworthstone/beads_viewer) (`bv`) for graph-aware triage. Issues are stored in `.beads/`. `bv` auto-discovers supported JSONL exports, including `.beads/issues.jsonl` and legacy `.beads/beads.jsonl`.

**Choose the tracker CLI from this repository's instructions and configuration.** Use `bd` commands in a Go Beads workspace and `br` commands in a beads_rust workspace. Do not run both trackers against the same workspace or infer the tracker solely from the JSONL filename.

### Using bv as an AI sidecar

bv is a graph-aware triage engine for Beads projects. Instead of parsing .beads/issues.jsonl / .beads/beads.jsonl directly or hallucinating graph traversal, use robot flags for deterministic, dependency-aware outputs with precomputed metrics (PageRank, betweenness, critical path, cycles, HITS, eigenvector, k-core).

**Scope boundary:** bv handles *what to work on* (triage, priority, planning). The selected tracker CLI (`bd` or `br`) handles creating, claiming, modifying, and closing beads.

**CRITICAL: Use ONLY --robot-* flags. Bare bv launches an interactive TUI that blocks your session.**

#### The Workflow: Start With Triage

**`bv --robot-triage` is your single entry point.** Its `triage` object contains:
- `quick_ref`: at-a-glance counts + top 3 picks
- `recommendations`: ranked actionable items with scores, reasons, unblock info
- `quick_wins`: low-effort high-impact items
- `blockers_to_clear`: items that unblock the most downstream work
- `project_health`: status/type/priority distributions, graph metrics
- `commands`: copy-paste shell commands for next steps

```bash
bv --robot-triage        # THE MEGA-COMMAND: start here
bv --robot-next          # Minimal: just the single top pick + claim command

# TOON output (--format toon): a compact tabular encoding. Measured on this
# repository it is 7% smaller than JSON for --robot-graph but 9-15% LARGER for
# nested payloads (--robot-triage, --robot-plan, --robot-insights,
# --robot-label-health); use --stats to see both sizes before adopting it.
bv --robot-graph --format toon
bv --robot-triage --format toon --stats
```

Recommendations can include blocked or assigned work; `triage.quick_ref.top_picks` reflects snapshot readiness. A suggested action records its original local ID, working directory, and tracker route. Use that route rather than a namespaced display ID or an unrelated current directory. Inspect current tracker state before execution: analysis does not reserve work or guarantee that a later claim succeeds.

#### Other bv Commands

| Command | Returns |
|---------|---------|
| `--robot-plan` | Parallel execution tracks with unblocks lists |
| `--robot-priority` | Priority misalignment detection with confidence |
| `--robot-insights` | Full metrics: PageRank, betweenness, HITS, eigenvector, critical path, cycles, k-core |
| `--robot-alerts` | Stale issues, blocking cascades, priority mismatches |
| `--robot-suggest` | Hygiene: duplicates, missing deps, label suggestions, cycle breaks |
| `--robot-diff --diff-since <ref>` | Changes since ref: new/closed/modified issues |
| `--robot-graph [--graph-format=json\|dot\|mermaid]` | Dependency graph export |

Every robot command emits one JSON object; with `--graph-format=dot` or `mermaid` the diagram text is the `graph` field (`bv --robot-graph --graph-format=dot | jq -r .graph`), not the whole output.

#### Scoping & Filtering

```bash
bv --robot-plan --label backend              # Scope to label's subgraph
bv --robot-insights --as-of HEAD~30          # Historical point-in-time
bv --recipe actionable --robot-plan          # Pre-filter: ready to work (no blockers)
bv --recipe high-impact --robot-triage       # Pre-filter: top PageRank scores
```

### Tracker Commands for Issue Management

Use exactly one command family, matching the tracker configured for the repository.

#### Rust beads_rust (`br`)

```bash
br ready --json                       # Show issues ready to work (no blockers)
br list --status=open --json          # All open issues
br show <id> --json                   # Full issue details with dependencies
br create --title="..." --type=task --priority=2 --json
br update <id> --status=in_progress --json
br close <id> --reason="Completed" --json
br close <id1> <id2> --reason="Completed" --json
br sync --flush-only                  # Export DB to JSONL after Beads mutations
```

#### Go Beads (`bd`)

```bash
bd ready --json                       # Show issues ready to work
bd show <id> --json                   # Full issue details
bd create "..." -t task -p 2 --json
bd update <id> --claim --json         # Atomically claim work
bd close <id> --json
bd dep add <issue> <depends-on>
bd export -o .beads/issues.jsonl        # Refresh the compatibility export read by bv
```

### Workflow Pattern

1. **Triage**: Run `bv --robot-triage` to find the highest-impact actionable work
2. **Verify**: Check the selected tracker's `show`/`ready` output before claiming
3. **Claim**: Use `br update <id> --status=in_progress --json` or `bd update <id> --claim --json`
4. **Work**: Implement the task
5. **Complete**: Use the selected tracker's `close` command
6. **Refresh for bv**: Run `br sync --flush-only` or the `bd export` command above so the JSONL export is current

### Key Concepts

- **Dependencies**: Issues can block other issues. `br ready --json` and `bd ready --json` show unblocked work.
- **Priority**: P0=critical, P1=high, P2=medium, P3=low, P4=backlog (use numbers 0-4, not words)
- **Types**: task, bug, feature, epic, chore, docs, question
- **Blocking**: Use `br dep add <issue> <depends-on>` or `bd dep add <issue> <depends-on>` to add dependencies

### Git Policy

Tracker commands do not grant permission to commit or push application code. Follow this repository's own git and tracker instructions before staging, committing, syncing, or pushing. If the repository says "commit only when asked," that rule overrides any generic workflow advice.

<!-- end-bv-agent-instructions -->

Version Tracking:

The blurb uses HTML comment markers for version tracking:

<!-- bv-agent-instructions-v5 -->
... content ...
<!-- end-bv-agent-instructions -->

When a new version of the blurb is released, bv can detect the outdated version and offer to update it.


๐Ÿ“ Architecture & Design

bv treats your project as a Directed Acyclic Graph (DAG), not just a list. This allows it to derive insights about what is truly important.

graph TD
    %% Soft Pastel Theme โ€” Refined
    classDef data fill:#e3f2fd,stroke:#90caf9,stroke-width:2px,color:#1565c0,rx:8
    classDef logic fill:#fff8e1,stroke:#ffcc80,stroke-width:2px,color:#e65100,rx:8
    classDef ui fill:#f3e5f5,stroke:#ce93d8,stroke-width:2px,color:#6a1b9a,rx:8
    classDef output fill:#e8f5e9,stroke:#a5d6a7,stroke-width:2px,color:#2e7d32,rx:8

    subgraph storage [" ๐Ÿ“‚ Data Layer "]
        A[".beads/issues.jsonl<br/>or legacy beads.jsonl<br/>JSONL Issue Store"]:::data
    end

    subgraph engine [" โš™๏ธ Analysis Engine "]
        B["Loader"]:::logic
        C["Graph Builder"]:::logic
        D["9 Metrics<br/>PageRank ยท Betweenness ยท HITS..."]:::logic
    end

    subgraph interface [" ๐Ÿ–ฅ๏ธ TUI Layer "]
        E["Bubble Tea Model"]:::ui
        F["List View"]:::ui
        G["Graph View"]:::ui
        G2["Tree View"]:::ui
        H["Insights Dashboard"]:::ui
    end

    subgraph outputs [" ๐Ÿ“ค Outputs "]
        I["--robot-insights<br/>JSON for AI Agents"]:::output
        J["--export-md<br/>Markdown Report"]:::output
    end

    A --> B
    B --> C
    C --> D
    D --> E
    D --> I
    D --> J
    E --> F
    E --> G
    E --> G2
    E --> H

    linkStyle 0,1,2 stroke:#90caf9,stroke-width:2px
    linkStyle 3,4,5 stroke:#ffcc80,stroke-width:2px
    linkStyle 6,7,8,9 stroke:#ce93d8,stroke-width:2px

Key Metrics & Algorithms

bv computes 9 graph-theoretic metrics to surface hidden project dynamics:

#MetricWhat It MeasuresKey Insight
1PageRankRecursive dependency importanceFoundational blockers
2BetweennessShortest-path trafficBottlenecks & bridges
3HITSHub/Authority dualityEpics vs. utilities
4Critical PathLongest dependent chain in task countsPrerequisites supporting long chains
5EigenvectorInfluence via neighborsStrategic dependencies
6DegreeDirect connection countsImmediate blockers/blocked
7DensityEdge-to-node ratioProject coupling health
8CyclesCircular dependenciesStructural errors
9Topo SortValid execution orderWork queue foundation

1. PageRank (Dependency Authority)

The Math: Originally designed to rank web pages by "importance" based on incoming links, PageRank models a "random surfer" walking the graph. In our dependency graph (u โ†’ v implies u depends on v), we treat dependencies as "votes" of importance.

PR(v)=1โˆ’dN+dโˆ‘uโˆˆM(v)PR(u)L(u)PR(v) = \frac{1-d}{N} + d \sum_{u \in M(v)} \frac{PR(u)}{L(u)}

The Intuition: If many tasks depend on Task A, or if a single very important Task B depends on Task A, then Task A implicitly becomes "heavy." A random walker following dependency links will frequently get stuck at Task A.

Pragmatic Meaning: Foundational Blocks. High PageRank tasks are the bedrock of your project. They are rarely "features" in the user-facing sense; they are often schemas, core libraries, or architectural decisions. Breaking them breaks the graph.

2. Betweenness Centrality (Bottlenecks)

The Math: Defined as the fraction of all shortest paths in the network that pass through a given node vv. CB(v)=โˆ‘sโ‰ vโ‰ tฯƒst(v)ฯƒstC_B(v) = \sum_{s \neq v \neq t} \frac{\sigma_{st}(v)}{\sigma_{st}}

The Intuition: Imagine information (or progress) flowing from every task to every other task along the most efficient route. "Bridge nodes" that connect otherwise isolated clusters (e.g., the Frontend cluster and the Backend cluster) will see a massive amount of traffic.

Pragmatic Meaning: Gatekeepers & Bottlenecks. A task with high Betweenness is a choke point. It might be an API contract that both the mobile app and the server team are waiting on. If this task is delayed, it doesn't just block one thread; it prevents entire sub-teams from synchronizing.

3. HITS (Hubs & Authorities)

The Math: An iterative algorithm that defines two scores for every node:

  • Authority: The sum of Hub scores of nodes pointing to it.
  • Hub: The sum of Authority scores of nodes it points to.

The Intuition: This models a "mutually reinforcing" relationship. Good libraries (Authorities) are used by many applications. Good applications (Hubs) use many good libraries.

Pragmatic Meaning: Epics vs. Infrastructure.

  • High Hub Score: These are your Epics or Product Features. They aggregate many dependencies to deliver value.
  • High Authority Score: These are your Utilities. They provide value to many consumers.

4. Critical Path (Longest Path in DAG)

The Math: In a DAG, bv measures unweighted chain depth in tasks. Edges point from a dependent to its prerequisite, so the score is: Impact(u)=1+maxโก({Impact(v)โˆฃvโ†’u}โˆช{0})Impact(u) = 1 + \max(\{Impact(v) \mid v \to u\} \cup \{0\}) The implementation evaluates this in topological order. This node-count metric does not use task durations or establish a minimum project completion time.

The Intuition: If you hold the graph by its "leaf" nodes (tasks with no dependencies) and let it dangle, the tasks at the very top that support the longest chains are carrying the most weight.

Pragmatic Meaning: Keystones. High scores identify prerequisites supporting long dependent chains. Inspect the separate Slack metric for structural scheduling flexibility; neither metric proves that a delay translates one-for-one into delivery time. Cyclic graphs can leave critical-path metrics unavailable, as reported by .status.Critical.

5. Eigenvector Centrality (Influential Neighbors)

The Math: Eigenvector centrality measures a node's influence by considering not just its connections, but the importance of those connections. A node with few but highly influential neighbors can score higher than a node with many unimportant neighbors. xi=1ฮปโˆ‘jโˆˆN(i)xjx_i = \frac{1}{\lambda} \sum_{j \in N(i)} x_j

Where ฮป\lambda is the largest eigenvalue of the adjacency matrix and N(i)N(i) are neighbors of node ii.

The Intuition: It's not just how many connections you have, but who you're connected to. Being depended on by a critical task makes you more important than being depended on by many trivial tasks.

Pragmatic Meaning: Strategic Dependencies. High Eigenvector tasks are connected to the "power players" in your graph. They may not have many direct dependents, but their dependents are themselves critical.

6. Degree Centrality (Direct Connections)

The Math: The simplest centrality measureโ€”just count the edges. CDin(v)=โˆฃ{u:uโ†’v}โˆฃC_D^{in}(v) = |\{u : u \to v\}|

CDout(v)=โˆฃ{u:vโ†’u}โˆฃC_D^{out}(v) = |\{u : v \to u\}|

The Intuition:

  • In-Degree: How many tasks depend on me? (I am a blocker)
  • Out-Degree: How many tasks do I depend on? (I am blocked)

Pragmatic Meaning: Immediate Impact.

  • High In-Degree: This task is a direct blocker for many others. Completing it immediately unblocks work.
  • High Out-Degree: This task has many prerequisites. It's likely to be blocked and should be scheduled later in the execution plan.

7. Graph Density (Interconnectedness)

The Math: Density measures how "connected" the graph is relative to its maximum possible connections. D=โˆฃEโˆฃโˆฃVโˆฃ(โˆฃVโˆฃโˆ’1)D = \frac{|E|}{|V|(|V|-1)}

Where โˆฃEโˆฃ|E| is the edge count and โˆฃVโˆฃ|V| is the node count. For a directed graph, the maximum edges is โˆฃVโˆฃ(โˆฃVโˆฃโˆ’1)|V|(|V|-1).

The Intuition: A density of 0.0 means no dependencies exist (isolated tasks). A density approaching 1.0 means everything depends on everything (pathological complexity).

Pragmatic Meaning: Project Health Indicator.

  • Low Density (< 0.05): Healthy. Tasks are relatively independent and can be parallelized.
  • Medium Density (0.05 - 0.15): Normal. Reasonable interconnection reflecting real-world dependencies.
  • High Density (> 0.15): Warning. Overly coupled project. Consider breaking into smaller modules.

8. Cycle Detection (Circular Dependencies)

The Math: A cycle in a directed graph is a path vโ‚ โ†’ vโ‚‚ โ†’ โ‹ฏ โ†’ vโ‚– โ†’ vโ‚ where the start and end nodes are identical. bv uses Tarjan's strongly connected components algorithm and extracts one representative cycle from each cyclic component. It analyzes blocking edges among non-closed, non-tombstoned issues, applies a storage cap, and reports truncation in .status.Cycles.reason. It does not enumerate every elementary cycle; breaking one reported cycle can leave others in the same component.

The Intuition: If A depends on B, and B depends on A, neither can ever be completed. This is a logical impossibility that must be resolved.

Pragmatic Meaning: Structural Errors. Cycles are bugs in your project plan, not just warnings. They indicate:

  • Misclassified dependencies (A doesn't really block B, or vice versa)
  • Missing intermediate tasks (A and B both depend on an unstated C)
  • Scope confusion (A and B should be merged into a single task)

9. Topological Sort (Execution Order)

The Math: A topological ordering of a DAG is a linear sequence of all vertices such that for every edge u โ†’ v, vertex u appears before v in the sequence. Only acyclic graphs have valid topological orderings.

The Intuition: If you must complete tasks in dependency order, topological sort gives you a valid order (there may be many).

Pragmatic Meaning: Work Queue. The topological order is the foundation of bv's execution planning. Combined with priority weights, it generates the "what to work on next" recommendations that power --robot-plan.


๐Ÿค– The Robot Protocol (AI Interface)

bv bridges the gap between raw data and AI agents. Agents struggle with graph algorithms; bv solves this by acting as a deterministic "sidecar" that offloads the cognitive burden of graph traversal.

sequenceDiagram
    %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8f5e9', 'primaryTextColor': '#2e7d32', 'primaryBorderColor': '#81c784', 'lineColor': '#90a4ae', 'secondaryColor': '#fff8e1', 'tertiaryColor': '#fce4ec'}}}%%

    participant User
    participant Agent as ๐Ÿค– AI Agent
    participant BV as โšก bv
    participant File as ๐Ÿ“„ Beads JSONL

    User->>Agent: "Fix the next blocked task"

    rect rgba(232, 245, 233, 0.4)
        Note over Agent, BV: Cognitive Offloading
        Agent->>BV: bv --robot-plan
        BV->>File: Read & Parse
        BV->>BV: PageRank + Topo Sort
        BV-->>Agent: { next: "TASK-123", unblocks: 5 }
    end

    rect rgba(255, 243, 224, 0.3)
        Note over Agent: Implementation Phase
        Agent->>Agent: Fix TASK-123
        Agent->>BV: bv --robot-insights
        BV-->>Agent: Updated graph metrics
    end

The "Cognitive Offloading" Strategy

The primary design goal of the Robot Protocol is Cognitive Offloading. Large Language Models (LLMs) are probabilistic engines; they are excellent at semantic reasoning (coding, writing) but notoriously unreliable at algorithmic graph traversal (finding cycles, computing shortest paths). The two-phase analyzer returns degree/topo/density first and computes the remaining metrics asynchronously with size-aware timeouts. Graph-stat caches are keyed by issue data and analysis configuration; readiness and ranking also depend on the selected scope and reference clock. Check each metric's status before interpreting its values.

If you feed an Agent raw Beads JSONL data, you are forcing the Agent to:

  1. Parse thousands of lines of JSON.
  2. Reconstruct the dependency graph in its context window.
  3. "Hallucinate" a path traversal or cycle check.

bv solves this by providing a deterministic graph engine sidecar.

Why bv vs. Raw Beads?

Using beads directly gives an agent data. Using bv --robot-insights gives an agent intelligence.

CapabilityRaw Beads (JSONL)bv Robot Mode
Query"List all issues.""List the top 5 bottlenecks blocking the release."
Context CostHigh (Linear with issue count).Low (Fixed summary struct).
Graph LogicAgent must infer/compute.Pre-computed (PageRank/Brandes).
SafetyAgent might miss a cycle.Cycles explicitly flagged.

Agent Usage Patterns

Agents typically use bv in three phases:

  1. Triage & Orientation: Before starting a session, the agent runs bv --robot-insights. It receives a lightweight JSON summary of the project's structural health. It immediately knows:

    • "I should not work on Task C yet because it depends on Task B, which is a Bottleneck."
    • "The graph has a cycle (A->B->A); I must fix this structural error before adding new features."
  2. Impact Analysis: When asked to "refactor the login module," the agent checks the PageRank and Impact Scores of the relevant beads. If the scores are high, the agent knows this is a high-risk change with many downstream dependents, prompting it to run more comprehensive tests.

  3. Execution Planning: Instead of guessing the order of operations, the agent uses bv's topological sort to generate a strictly linearized plan.

JSON Output Excerpt (--robot-insights): Field names are case-sensitive. This excerpt uses illustrative values and omits the source envelope and other metrics; bv --robot-schema describes the complete contract.

{
  "Bottlenecks": [
    { "ID": "CORE-123", "Value": 0.45 }
  ],
  "Keystones": [
    { "ID": "API-001", "Value": 12.0 }
  ],
  "Influencers": [
    { "ID": "AUTH-007", "Value": 0.82 }
  ],
  "Hubs": [
    { "ID": "EPIC-100", "Value": 0.67 }
  ],
  "Authorities": [
    { "ID": "UTIL-050", "Value": 0.91 }
  ],
  "Cycles": [
    ["TASK-A", "TASK-B", "TASK-A"]
  ],
  "ClusterDensity": 0.045,
  "full_stats": {
    "pagerank": { "CORE-123": 0.15 },
    "betweenness": { "CORE-123": 0.45 },
    "eigenvector": { "AUTH-007": 0.82 },
    "critical_path_score": { "API-001": 12.0 }
  },
  "status": {
    "PageRank": { "state": "computed" },
    "Cycles": { "state": "computed" }
  }
}
FieldMetricWhat It Contains
BottlenecksBetweennessTop nodes bridging graph clusters (ID/Value records)
KeystonesCritical PathTop nodes on longest dependency chains
InfluencersEigenvectorTop nodes connected to important neighbors
HubsHITS HubTop dependency aggregators (Epics)
AuthoritiesHITS AuthorityTop prerequisite providers (Utilities)
CyclesCycle DetectionStored representative cycles; inspect status.Cycles for skips, timeouts and truncation
ClusterDensityDensityOverall graph interconnectedness
full_statsMetric mapsPer-issue values, capped by BV_INSIGHTS_MAP_LIMIT (default 200)

๐ŸŽจ TUI Engineering & Craftsmanship

bv is built with the Bubble Tea framework. Its adaptive layout responds to terminal resize events, and its custom graph renderer supports ASCII and Unicode. A 60fps frame budget is a design target; actual interaction latency depends on the graph, view, terminal, and host.

flowchart LR
    classDef core fill:#fef3e2,stroke:#f5d0a9,stroke-width:2px,color:#8b5a2b
    classDef engine fill:#f0e6f6,stroke:#d4b8e0,stroke-width:2px,color:#5d3a6b
    classDef ui fill:#e6f3e6,stroke:#b8d9b8,stroke-width:2px,color:#2d5a2d
    classDef output fill:#e8f4f8,stroke:#b8d4e3,stroke-width:2px,color:#2c5f7c

    INPUT["โŒจ๏ธ Input<br/>Keys ยท Mouse ยท Resize"]:::core
    MODEL["๐Ÿซ– Model<br/>Issues ยท Stats ยท Focus"]:::core
    GRAPH["๐Ÿงฎ Graph Engine<br/>PageRank ยท HITS ยท Cycles"]:::engine
    VIEWS["๐Ÿ–ผ๏ธ Views<br/>List ยท Board ยท Graph ยท Tree ยท Insights"]:::ui
    LAYOUT["๐Ÿ“ Layout<br/>Mobile ยท Split ยท Wide"]:::ui
    TERM["๐Ÿ–ฅ๏ธ Terminal<br/>Rendered Output"]:::output

    INPUT -->|tea.Msg| MODEL
    GRAPH -->|metrics| MODEL
    MODEL -->|state| VIEWS
    VIEWS --> LAYOUT
    LAYOUT --> TERM

    linkStyle 0 stroke:#f5d0a9,stroke-width:2px
    linkStyle 1 stroke:#d4b8e0,stroke-width:2px
    linkStyle 2 stroke:#b8d9b8,stroke-width:2px
    linkStyle 3,4 stroke:#b8d4e3,stroke-width:2px

1. Adaptive Layout Engine

bv doesn't just dump text; it calculates geometry on every render cycle.

  • Dynamic Resizing: The View() function inspects the current terminal width (msg.Width) on every frame.
  • Breakpoint Logic:
    • < 100 cols: Mobile Mode. List takes 100% width.
    • > 100 cols: Split Mode. List takes 40%, Details take 60%; the assignee column appears.
    • > 120 cols: the Sparkline (graph score) column appears.
    • > 140 cols: Ultra-Wide. Label tags are added to each row.
  • Padding Awareness: The layout engine explicitly accounts for borders (2 chars) and padding (2 chars) to prevent "off-by-one" wrapping errors that plague many TUIs.

2. Viewport Virtualization

bv limits list rendering to visible rows, including when browsing 10,000 issues:

  • Windowing: We only render the slice of rows currently visible in the terminal window.
  • Pre-Computation: Expensive graph metrics are computed asynchronously at startup and when source snapshots change. Navigation reuses the completed results.
  • Detail Caching: The Markdown renderer is reused. It can retain the last exact render within a 512 KiB input/output budget; selecting a different issue renders its actual details. Virtualizing the list does not eliminate the cost of rendering long details or analyzing a large graph.

3. Visual Graph Engine (pkg/ui/graph.go)

We built a custom 2D ASCII/Unicode rendering engine from scratch to visualize the dependency graph.

  • Canvas Abstraction: A 2D grid of rune cells and style pointers allows us to draw "pixels" in the terminal.
  • Manhattan Routing: Edges are drawn using orthogonal lines with proper Unicode corner characters ( โ•ญ, โ”€, โ•ฎ, โ”‚, โ•ฐ, โ•ฏ) to minimize visual noise.
  • Topological Layering: Nodes are arranged in layers based on their "Impact Depth," ensuring that dependencies always flow downwards.

4. Thematic Consistency

We use Lipgloss to enforce a strict design system.

  • Semantic Colors: Colors are defined semantically (Theme.Blocked, Theme.Open) rather than hardcoded hex values. This allows bv to switch between "Dracula" (Dark) and "Light" modes seamlessly.
  • Status Indicators: We use Nerd Font glyphs (๐Ÿ›, โœจ, ๐Ÿ”ฅ) paired with color coding to convey status instantly without reading text.

๐Ÿ“ˆ Visual Data Encoding: Sparklines & Heatmaps

In dense information environments like the terminal, text is expensive. bv employs high-density data visualization techniques (pkg/ui/visuals.go) inspired by Edward Tufte to convey complex metrics in minimal space.

1. Unicode Sparklines

When viewing the list in Ultra-Wide mode, bv renders a "Graph Score" column using Unicode block characters ( , โ–‚, โ–ƒ, โ–„, โ–…, โ–†, โ–‡, โ–ˆ).

  • The Math: RenderSparkline(val, width) normalizes a float value (0.0 - 1.0) against the available character width. It calculates the precise block height for each character cell to create a continuous bar chart effect.
  • The Utility: This allows you to scan a list of 50 issues and instantly spot the "spikes" in complexity or centrality without reading a single number.

2. Semantic Heatmaps

We don't just use random colors. pkg/ui/visuals.go implements a perceptually uniform color ramp (GetHeatmapColor) that maps metric intensity to a gradient:

  • 0.0 - 0.2: Low (Gray/Dim)
  • 0.2 - 0.5: Mid (Blue/Cool)
  • 0.5 - 0.8: High (Purple/Warm)
  • 0.8 - 1.0: Peak (Pink/Hot) This visual encoding is applied to badges in the Insights Dashboard, allowing you to differentiate between "somewhat important" and "critically urgent" tasks at a glance.

๐Ÿ” Search Architecture

The TUI's / filter performs local fuzzy matching over a composite string for each list item. This differs from --search, which uses hashed keyword vectors over ID, title, description and labels, with optional graph-based ranking.

The "Flattened Vector" Index

IssueItem.FilterValue() constructs a string in this order: title, ID, status, issue type, assignee (if set), labels, and repository prefix (if set). Description text and priority are not included in this default list filter.

Fuzzy Subsequence Matching

When you press /, the search engine performs a fuzzy subsequence match against this composite vector.

  • Example: "fix log" matches "Fix login race condition" in that order.
  • Example: "bug steve" can match issue type bug followed by assignee steve.
  • Example: "open v1.0" can match status followed by a label. This is subsequence matching, not a typed status/label query; use the dedicated filters for exact field selection.

Performance Characteristics

  • Local work: The list's filter command builds target strings and fuzzy-match results in memory; it makes no database or network request.
  • Allocations: FilterValue() builds strings during filtering, and the matcher allocates its result data. This path is not allocation-free.
  • Ranking: The default filter sorts by fuzzy-match score. Stable ties retain input order; unequal scores can change the original priority or recipe order.

๐Ÿงœ Mermaid Integration: Diagrams in the Terminal?

A common question is: "How do you render complex diagrams in a text-only terminal?"

bv approaches this problem in two ways:

1. The Native Graph Visualizer (g)

For the interactive TUI, we built a specialized ASCII/Unicode Graph Engine (pkg/ui/graph.go) that replicates the core value of a Mermaid flowchart without requiring graphical protocol support (like Sixel).

  • Selected-node neighborhood: Boxes show the selected issue, its blockers, and its dependents. The node list sorts by project critical-path depth when available, then by ID. A โ—† marks nodes on one deterministic longest dependency chain within the displayed scope; cyclic displayed graphs have no computed critical chain. The metrics panel retains the project analysis values.
  • Expandable dependency paths: Press Space to reveal upstream and downstream edges beyond the immediate neighborhood. Paths retain their prerequisite-to-dependent direction, stop at filtered-out records, and handle cycles without recursive loops. Press Space again to collapse; expansion is remembered per selected node.
  • Scrollable canvas: H/L pan horizontally and J/K scroll vertically through graph content and metrics. The viewport clips terminal cells without splitting Unicode graphemes or ANSI styles. Lowercase h/j/k/l select nodes; Enter opens details. The footer shows the current scroll position.

2. The Export Engine (--export-md)

For external reporting, bv includes a robust Mermaid Generator (pkg/export/markdown.go).

  • Sanitization: It automatically escapes unsafe characters in issue titles to prevent syntax errors in the Mermaid parser.
  • Collision-Proof IDs: When sanitization would collide (e.g., symbol-only IDs), nodes get a stable hash suffix so edges never merge or disappear.
  • Class-Based Styling: Nodes are assigned CSS classes (classDef open, classDef blocked) based on their status, so the resulting diagram visually matches the TUI's color scheme when rendered on GitHub or GitLab.
  • Semantic Edges: Blockers are rendered with thick arrows (==>), while loose relations use dashed lines (-.->), encoding the severity of the link into the visual syntax.
graph TD
    %% Generated by bv โ€” Soft Pastel Theme
    classDef open fill:#c8e6c9,stroke:#81c784,stroke-width:2px,color:#2e7d32
    classDef blocked fill:#ffcdd2,stroke:#e57373,stroke-width:2px,color:#c62828
    classDef inProgress fill:#fff3e0,stroke:#ffb74d,stroke-width:2px,color:#ef6c00

    A["CORE-123<br/>Refactor Login"]:::open
    B["UI-456<br/>Login Page"]:::blocked
    C["API-789<br/>Auth Endpoint"]:::inProgress

    A --> B
    A --> C
    C -.-> B

    linkStyle 0 stroke:#81c784,stroke-width:2px
    linkStyle 1 stroke:#81c784,stroke-width:2px
    linkStyle 2 stroke:#e57373,stroke-width:1px,stroke-dasharray:5

๐Ÿ“ธ Graph Export (--robot-graph)

Export the dependency graph in multiple formats for visualization, documentation, or integration with other tools:

bv --robot-graph                              # JSON (default)
bv --robot-graph --graph-format=dot           # JSON envelope; DOT text in .graph
bv --robot-graph --graph-format=mermaid       # JSON envelope; Mermaid text in .graph

# Every robot command emits one JSON object (data_hash, generated_at, source_path, ...),
# so the DOT or Mermaid text is a field to extract, not the whole output:
bv --robot-graph --graph-format=dot | jq -r .graph > graph.dot
bv --robot-graph --graph-format=mermaid | jq -r .graph > graph.mmd

# Focused subgraph extraction
bv --robot-graph --graph-root=bv-123          # Subgraph from specific root
bv --robot-graph --graph-root=bv-123 --graph-depth=3  # Limited depth

Output Formats

FormatUse CaseRendering
jsonProgrammatic processing, custom visualizationParse with jq or code
dotHigh-quality static imagesbv --robot-graph --graph-format=dot | jq -r .graph | dot -Tpng -o graph.png
mermaidEmbed in Markdown, GitHub renderingjq -r .graph the envelope, then paste into docs

Subgraph Extraction

For large projects, extract focused views around specific issues:

  • --graph-root=ID: Start from a specific issue and include all its dependencies and dependents
  • --graph-depth=N: Limit traversal to N levels (0 = unlimited)

JSON Output Excerpt

Top-level nodes and edges are counts. Node and edge records live under adjacency; other envelope fields are omitted here. Edges run from the issue to its referenced dependency and retain the recorded dependency type. Empty output can omit adjacency.

{
  "format": "json",
  "data_hash": "abc123",
  "nodes": 2,
  "edges": 1,
  "adjacency": {
    "nodes": [
      { "id": "bv-123", "title": "Fix auth", "status": "open", "priority": 1 },
      { "id": "bv-124", "title": "Test auth", "status": "open", "priority": 2 }
    ],
    "edges": [
      { "from": "bv-124", "to": "bv-123", "type": "blocks" }
    ]
  }
}
bv --robot-graph | jq '{nodes, edges, ids: [.adjacency.nodes[]?.id]}'
bv --robot-graph | jq '.adjacency.edges[]? | {from, to, type}'

๐ŸŒŒ Interactive Graph Visualization (--export-graph)

For deep exploration of complex dependency structures, bv generates single-file HTML visualizations powered by a force-directed graph engine. Pan, zoom, filter, and drill into individual beads without a server. Scripts and styles are embedded, fonts use the system stack, and the standalone graph makes no external requests.

# Generate interactive HTML graph
bv --export-graph graph.html                    # Export to specific file
bv --export-graph                               # Auto-generate timestamped filename
bv --export-graph --graph-title "Q4 Sprint"     # Custom title
bv --export-graph graph.svg --graph-preset roomy  # Static SVG/PNG snapshot; presets: compact (default), roomy

Why Interactive Graph Visualization?

Traditional list-based views show tasks in isolation. The interactive graph reveals the hidden structure of your project:

  • Dependency Chains: See at a glance which tasks are blocking others, and trace critical paths through your backlog
  • Bottleneck Detection: Nodes sized by PageRank/betweenness instantly reveal which items have outsized impact
  • Cluster Discovery: Force-directed layout naturally groups related work, exposing team boundaries or feature clusters
  • Context Switching: Hover over any node to see full detailsโ€”description, design notes, acceptance criteriaโ€”without leaving the visualization

What's Included in the Export

Each export is a single HTML file (typically 1-2 MB depending on project size; the vendored graph library and all bead data are inlined):

ComponentDescription
Full Bead DataTitle, description, design, acceptance criteria, notes, labels, timestamps
Graph MetricsPageRank, betweenness, critical path score, slack, hub/authority scores
Triage AnalysisComplete triage recommendations with scores and reasons
Git CorrelationCommit history linked to each bead (when available)
Dependency MapFull blocked-by/blocks relationships with visual edges

Interface Overview

The visualization provides a rich, keyboard-driven interface:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ“Š Project Graph | [Search...] | Layout โ–พ | Filters โ–พ | ๐Ÿ”ฅ ๐Ÿ“‹ โญ โ˜€๏ธ โ“    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                      โ”‚                                                      โ”‚
โ”‚   Bead Details       โ”‚              Force-Directed Graph                    โ”‚
โ”‚   โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•    โ”‚                                                      โ”‚
โ”‚   ID: bv-xyz         โ”‚         โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—                                    โ”‚
โ”‚   Title: Feature X   โ”‚        /โ”‚\      โ”‚                                    โ”‚
โ”‚                      โ”‚       โ— โ— โ—     โ—โ”€โ”€โ”€โ—                                โ”‚
โ”‚   Description:       โ”‚         โ”‚           โ”‚                                โ”‚
โ”‚   [markdown...]      โ”‚         โ—โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ—                                โ”‚
โ”‚                      โ”‚                                                      โ”‚
โ”‚   Graph Metrics:     โ”‚              โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                    โ”‚
โ”‚   PageRank: 2.34%    โ”‚              โ”‚ Low โ–ฐโ–ฐโ–ฐโ–ฐ High   โ”‚  <- Heatmap Legend โ”‚
โ”‚   Betweenness: 0.12  โ”‚              โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                    โ”‚
โ”‚   Critical Path: 4.0 โ”‚         โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                              โ”‚
โ”‚                      โ”‚         โ”‚ Mini-map    โ”‚                              โ”‚
โ”‚   Blocked By: [...]  โ”‚         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                              โ”‚
โ”‚   Blocks: [...]      โ”‚                                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Visual Encoding

Nodes encode multiple dimensions of information simultaneously:

Visual PropertyMeaning
ColorStatus: ๐ŸŸข Open, ๐ŸŸ  In Progress, ๐Ÿ”ด Blocked, โšซ Closed
SizeConfigurable metric (PageRank, betweenness, critical path, in-degree)
ShapeType: โ— Feature, โ–ฒ Bug, โ–  Task, โ—† Epic
GlowGolden halo on hover shows connected subgraph (2-hop neighbors)
Edge ColorPink edges indicate critical path connections

Keyboard Shortcuts

The visualization is fully keyboard-driven:

KeyActionKeyAction
?Help overlayDDock/detach detail panel
FFit all in viewLToggle light/dark mode
RReset to defaultsHToggle heatmap coloring
SpaceFullscreenTTop nodes panel
EscClear/cancelGTriage panel
1-4Layout modesYRecently viewed
PPath finder mode

Features

Filtering & Search

  • Full-text search: Find beads by ID, title, or content with live preview
  • Status filter: Open, In Progress, Blocked, Closed
  • Type filter: Feature, Bug, Task, Epic
  • Priority filter: P0 (Critical) through P4 (Backlog)
  • Label filter: Dynamically populated from your data

Navigation

  • Path Finder: Press P, then click two nodes to find and highlight the shortest path between them
  • Recently Viewed: Press Y to see your navigation history and jump back to previous nodes
  • Mini-map: Overview in the corner shows your current viewport position

Panels

  • Docked Detail Panel: Left sidebar shows full bead information on hover (default)
  • Floating Mode: Press D to detach the panel for floating tooltip-style display
  • Triage Panel: Shows top recommendations with scores and reasoning
  • Top Nodes: Lists highest PageRank nodes for quick navigation

Customization

  • Layout Modes: Force-directed (default), DAG top-down, DAG left-right, Radial
  • Size Metric: Choose what determines node size (PageRank, betweenness, critical path, in-degree)
  • Light/Dark Mode: Full theme support with proper contrast
  • Preferences Saved: Theme and layout choices persist via localStorage

Use Cases

ScenarioHow the Graph Helps
Sprint PlanningIdentify which items unblock the most downstream work
Stakeholder UpdatesShare a single HTML fileโ€”no setup required to view
Architecture ReviewSpot unexpected dependencies between features
OnboardingNew team members can explore the codebase's work structure
RetrospectivesVisualize completed work and remaining blockers

Example Workflow

# 1. Generate the visualization
bv --export-graph sprint_review.html --graph-title "Sprint 42 Review"

# 2. Open in browser
open sprint_review.html    # macOS
xdg-open sprint_review.html  # Linux
start sprint_review.html   # Windows

# 3. Share with team
# One HTML file: just send it or host anywhere

Technical Notes

  • No Server Required: Everything runs client-side in the browser
  • Offline Capable: Works offline once opened and makes no network requests at all; Inter and JetBrains Mono are used when installed locally, otherwise the system UI and monospace fonts
  • Modern Browsers: Tested on Chrome, Firefox, Safari, Edge
  • Performance: Handles 500+ nodes smoothly with Canvas 2D rendering (force-graph)
  • File Size: Typically 1-2 MB depending on project size and content

๐Ÿ“„ The Status Report Engine

bv isn't just for personal browsing; it's a communication tool. The --export-md flag generates a Management-Ready Status Report that converts your repo state into a polished document suitable for stakeholders.

1. The "Hybrid Document" Architecture

The exporter (pkg/export/markdown.go) constructs a document that bridges human readability and visual data:

  • Summary at a Glance: Top-level statistics (Total, Open, Blocked, Closed) give immediate health context.
  • Embedded Graph: It injects the full dependency graph as a Mermaid diagram right into the document. On platforms like GitHub or GitLab, this renders as an interactive chart.
  • Anchor Navigation: A generated Table of Contents uses URL-friendly slugs (#core-123-refactor-login) to link directly to specific issue details, allowing readers to jump between the high-level graph and low-level specs.

2. Semantic Formatting

We don't just dump JSON values. The exporter applies specific formatting rules to ensure the report looks professional:

  • Metadata Tables: Key fields (Assignee, Priority, Status) are aligned in GFM (GitHub Flavored Markdown) tables with emoji indicators.
  • Conversation threading: Comments are rendered as blockquotes (>) with the author and the absolute date (YYYY-MM-DD), preserving the flow of discussion distinct from the technical spec.
  • Intelligent Sorting: The report doesn't list issues ID-sequentially. It applies the same priority logic as the TUI: Open Critical issues appear first, ensuring the reader focuses on what matters now.

โณ Time-Travel: Snapshot Diffing & Git History

One of bv's most powerful capabilities is Time-Travelโ€”the ability to compare your project's state across any two points in git history. This transforms bv from a "viewer" into a progress tracking and regression detection system.

The Snapshot Model

bv captures the complete state of your project at any moment:

graph LR
    %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8f5e9', 'primaryTextColor': '#2e7d32', 'primaryBorderColor': '#81c784', 'lineColor': '#90a4ae'}}}%%

    subgraph "Git History"
        A["HEAD~10<br/><small>10 commits ago</small>"]
        B["HEAD~5<br/><small>5 commits ago</small>"]
        C["HEAD<br/><small>Current</small>"]
    end

    subgraph "Snapshots"
        D["Snapshot A<br/><small>45 issues, 3 cycles</small>"]
        E["Snapshot B<br/><small>52 issues, 1 cycle</small>"]
        F["Snapshot C<br/><small>58 issues, 0 cycles</small>"]
    end

    A --> D
    B --> E
    C --> F
    D -.->|"diff"| E
    E -.->|"diff"| F

    style D fill:#ffcdd2,stroke:#e57373,stroke-width:2px
    style E fill:#fff3e0,stroke:#ffb74d,stroke-width:2px
    style F fill:#c8e6c9,stroke:#81c784,stroke-width:2px

What Gets Tracked

The SnapshotDiff captures every meaningful change:

CategoryTracked Changes
IssuesNew, Closed, Reopened, Removed, Modified
FieldsTitle, Status, Priority, Tags, Dependencies
GraphNew Cycles, Resolved Cycles
Metricsฮ” PageRank, ฮ” Betweenness, ฮ” Density

Git History Integration (pkg/loader/git.go)

The GitLoader enables loading issues from any git revision:

loader := NewGitLoader("/path/to/repo")

// Load from various references
current, _ := loader.LoadAt("HEAD")
lastWeek, _ := loader.LoadAt("HEAD~7")
release, _ := loader.LoadAt("v1.0.0")
byDate, _ := loader.LoadAt("main@{2024-01-15}")

Cache Architecture:

  • Revisions are resolved to commit SHAs for stable caching
  • Thread-safe sync.RWMutex protects concurrent access
  • 5-minute TTL prevents stale data while avoiding redundant git calls

Use Cases

  1. Sprint Retrospectives: "How many issues did we close this sprint?"
  2. Regression Detection: "Did we accidentally reintroduce a dependency cycle?"
  3. Trend Analysis: "Is our graph density increasing? Are we creating too many dependencies?"
  4. Release Notes: "Generate a diff of all changes between v1.0 and v2.0"

๐Ÿณ Recipe System: Declarative View Configuration

Instead of memorizing CLI flags or repeatedly setting filters, bv supports Recipesโ€”YAML-based view configurations that can be saved, shared, and version-controlled.

Recipe Structure

Recipes are loaded from four sources, later ones overriding earlier ones by name: the built-in defaults, ~/.config/bv/recipes.yaml (user, recipes: map), .bv/recipes.yaml (project, recipes: map), and one recipe per file under .beads/recipes/<name>.yaml. --robot-recipes reports each recipe's source.

# .bv/recipes.yaml
recipes:
  sprint-review:
    name: sprint-review
    description: "Issues touched in the current sprint"
    filters:
      status: [open, in_progress, closed]
      updated_after: "14d"           # Relative time: 14 days ago
      exclude_tags: [backlog, icebox]
    sort:
      field: updated
      direction: desc
      secondary:
        field: priority
        direction: asc
    view:
      columns: [id, title, status, priority, updated]
      show_metrics: true
      max_items: 50
    export:
      format: markdown
      include_graph: true

The TUI applies recipe filters, the complete sort chain, and max_items to its view while retaining the loaded issues for subsequent recipe changes. Custom presentation fields configure the existing list, details, and graph:

FieldBehavior
view.columnsOrdered columns: id, title, status, priority, created, updated, tags, blockers. Empty uses the ordinary adaptive row.
view.show_graphOpens the dependency graph when selecting the recipe. Later keyboard navigation is preserved across refreshes.
view.show_metricsShows PageRank, impact, and triage values in rows and issue details. Unavailable metrics display an em dash in rows and unavailable in details.
metricsSelects displayed metrics and enables metric display: pagerank, betweenness, impact, triage, hub, authority, eigenvector, kcore, slack.
view.group_byGroups the list by status, priority, or tag; none disables groups. Tag grouping uses the first alphabetically sorted label, or untagged.
view.collapsedStarts groups collapsed. Enter or Space on a group expands/collapses it; search still includes collapsed issues.
view.truncate_titleMaximum title display cells, including ellipsis; respects wide Unicode characters. Zero uses available width.

Grouping preserves recipe order within each group. A refresh keeps selected issue IDs and expanded groups; changing recipes resets recipe-owned grouping and display defaults. Narrow rows fit the available width, and full issue details remain accessible. Invalid columns, metrics, group names, and negative widths fail recipe validation.

Recipe exports

Export settings take effect only with an explicit output request:

bv --recipe sprint-review --export review.md
bv --recipe sprint-review --export review.json --export-format json
bv --recipe sprint-review --export review.csv --export-format csv --export-include-graph=false
bv --recipe sprint-review --export review.mmd --export-format mermaid

Explicit export flags override recipe defaults. Without either, the format is Markdown and graphs are included; CSV defaults to no graph. --export-md PATH explicitly selects Markdown. --export-include-graph=false disables a recipe graph, and --export-template= clears a recipe template. CSV with a graph, Mermaid without a graph, and custom templates for other formats are errors. Selecting a recipe for the TUI or robot analysis creates no export file.

Report bodies retain recipe membership, ordering, and max_items. Graphs also include recursively referenced dependency context, without adding those issue bodies to the report. JSON reports preserve source completeness and provenance alongside selected issues and their verified action routes. An explicit SOURCE_DATE_EPOCH fixes the generation time for reproducible reports. Pre-export hooks run before writing; post-export hooks run afterward, including their configured failure policy.

export.template and --export-template PATH read a Markdown template relative to the working directory. Templates receive .Title, .GeneratedAt, .Issues, and .Graph (Mermaid text when graphs are enabled). Each issue exposes .ID, .Title, .Status, .IssueType, .Priority, .Description, and .Labels. Issue text is escaped for literal Markdown/HTML display. Templates have no command, environment, filesystem, or issue-method access; missing fields and parse/render errors fail before writing. Template input is limited to 1 MiB and rendered output to 16 MiB.

Filter Capabilities

FilterTypeExamples
statusArray[open, closed, blocked, in_progress]
priorityArray[0, 1] (P0 and P1 only)
tagsArray[frontend, urgent]
exclude_tagsArray[wontfix, duplicate]
created_afterRelative/ISO"7d", "2w", "2024-01-01"
updated_beforeRelative/ISO"30d", "1m"
actionableBooleantrue = eligible status, elapsed deferral, and satisfied dependencies, including inherited parent gates; missing dependency records withhold readiness
has_blockersBooleantrue = unresolved dependency state, including missing records or inherited parent gates
id_prefixString"bv-" for project filtering
title_containsStringSubstring search

Built-in Recipes

bv ships with 11 pre-configured recipes:

RecipePurpose
defaultDefault view showing all open issues sorted by priority
actionableIssues ready to work on (no open blockers)
recentIssues updated in the last 7 days
blockedIssues waiting on dependencies
high-impactIssues with highest blocking impact (PageRank)
staleOpen issues not updated in 30+ days
triageIssues sorted by computed triage score (high impact + unblocking potential)
closedRecently closed issues
release-cutRecently closed items for changelog generation
quick-winsEasy items with no blockers - good for quick progress
bottlenecksHigh betweenness nodes - potential project bottlenecks

Using Recipes

# Interactive picker (press 'R' in TUI)
bv

# Direct recipe invocation
bv --recipe actionable
bv --recipe high-impact

# Project or user recipe, by name
bv --recipe sprint-review

๐ŸŽฏ Composite Impact Scoring

Traditional issue trackers sort by a single dimensionโ€”usually priority. bv computes a multi-factor Impact Score that blends graph-theoretic metrics with temporal and priority signals.

The Scoring Formula

Impact=0.22โ‹…PageRank+0.20โ‹…Betweenness+0.13โ‹…BlockerRatio+0.05โ‹…Staleness+0.10โ‹…PriorityBoost+0.10โ‹…TimeToImpact+0.10โ‹…Urgency+0.10โ‹…Risk\text{Impact} = 0.22 \cdot \text{PageRank} + 0.20 \cdot \text{Betweenness} + 0.13 \cdot \text{BlockerRatio} + 0.05 \cdot \text{Staleness} + 0.10 \cdot \text{PriorityBoost} + 0.10 \cdot \text{TimeToImpact} + 0.10 \cdot \text{Urgency} + 0.10 \cdot \text{Risk}

Each factor is normalized to 0-1 before weighting (the *_norm fields in the breakdown). The weights are the Weight* constants in pkg/analysis/priority.go.

Component Breakdown

ComponentWeightWhat It Measures
PageRank22%Recursive dependency importance
Betweenness20%Bottleneck/bridge position
BlockerRatio13%Direct dependents (In-Degree)
Staleness5%Days since last update (aging)
PriorityBoost10%Human-assigned priority
TimeToImpact10%Critical-path depth plus estimated time
Urgency10%Urgent labels and time decay
Risk10%Volatility and risk signals

Why These Weights?

  • 42% Graph Metrics: The structure of dependencies (PageRank plus betweenness) is the primary driver of true importance.
  • 13% Blocker Ratio: Direct dependents matter for immediate unblocking.
  • 30% Time, Urgency, Risk: Depth on the critical path, urgent labels, and volatility signals surface work that the pure structure would miss.
  • 10% Priority: Human judgment is valuable but can be outdated or politically biased.
  • 5% Staleness: Old issues deserve a nudge, but age alone should not dominate.

Feedback retunes the weights. --feedback-accept and --feedback-ignore record events in .beads/feedback.json; once at least MinFeedbackSamples (3) events exist, --robot-triage scores with the adjusted, renormalized weights and reports feedback.applied: true together with the effective weights. --feedback-reset restores the constants.

Score Output

{
  "issue_id": "CORE-123",
  "title": "Refactor auth module",
  "score": 0.847,
  "breakdown": {
    "pagerank": 0.20,
    "betweenness": 0.17,
    "blocker_ratio": 0.12,
    "staleness": 0.03,
    "priority_boost": 0.08,
    "time_to_impact": 0.09,
    "urgency": 0.08,
    "risk": 0.10
  }
}

Priority Recommendations

bv generates actionable recommendations when the computed impact score diverges significantly from the human-assigned priority:

โš ๏ธ CORE-123 has Impact Score 0.85 but Priority P3. Reason: High PageRank (foundational dependency) + High Betweenness (bottleneck) Recommendation: Consider escalating to P1.

Priority Hints Overlay

Press p in the list view to toggle Priority Hintsโ€”inline visual indicators showing which issues have misaligned priorities:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  OPEN     CORE-123 โฌ† Database schema migration       P3  ๐ŸŸข โ”‚
โ”‚  OPEN     UI-456     Login page styling              P2  ๐ŸŸข โ”‚
โ”‚  BLOCKED  API-789  โฌ‡ Legacy endpoint wrapper         P1  ๐Ÿ”ด โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
        โฌ† = Impact suggests higher priority (red arrow)
        โฌ‡ = Impact suggests lower priority (teal arrow)

This provides at-a-glance feedback on whether your priority assignments match the computed graph importance.


๐Ÿ›ค๏ธ Parallel Execution Planning

When you ask "What should I work on next?", bv doesn't just pick the highest-priority item. It generates a complete execution plan that respects dependencies and identifies opportunities for parallel work.

Track-Based Planning

The planner uses Union-Find to identify connected components in the dependency graph, grouping related issues into independent "tracks" that can be worked on concurrently.

graph TD
    %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8f5e9', 'lineColor': '#90a4ae'}}}%%

    subgraph track_a ["๐Ÿ…ฐ๏ธ Track A: Auth System"]
        A1["AUTH-001<br/>P1 ยท Unblocks 3"]:::actionable
        A2["AUTH-002"]:::blocked
        A3["AUTH-003"]:::blocked
    end

    subgraph track_b ["๐Ÿ…ฑ๏ธ Track B: UI Polish"]
        B1["UI-101<br/>P2 ยท Unblocks 1"]:::actionable
        B2["UI-102"]:::blocked
    end

    subgraph track_c ["๐Ÿ…ฒ Track C: Independent"]
        C1["DOCS-001<br/>P3 ยท Unblocks 0"]:::actionable
    end

    A1 --> A2
    A2 --> A3
    B1 --> B2

    classDef actionable fill:#c8e6c9,stroke:#81c784,stroke-width:2px,color:#2e7d32
    classDef blocked fill:#ffcdd2,stroke:#e57373,stroke-width:2px,color:#c62828

    linkStyle 0,1,2 stroke:#81c784,stroke-width:2px

Plan Output (--robot-plan)

{
  "tracks": [
    {
      "track_id": "track-A",
      "reason": "Independent work stream",
      "items": [
        { "id": "AUTH-001", "priority": 1, "unblocks": ["AUTH-002", "AUTH-003", "API-005"] }
      ]
    },
    {
      "track_id": "track-B",
      "reason": "Independent work stream",
      "items": [
        { "id": "UI-101", "priority": 2, "unblocks": ["UI-102"] }
      ]
    }
  ],
  "total_actionable": 3,
  "total_blocked": 5,
  "summary": {
    "highest_impact": "AUTH-001",
    "impact_reason": "Unblocks 3 tasks",
    "unblocks_count": 3
  }
}

The Algorithm

  1. Identify Actionable Issues: Require an actionable status, elapsed deferral, and satisfied dependencies in the full loaded source; retain candidate filters separately.
  2. Compute Unblocks: For each actionable issue, calculate what becomes unblocked if it's completed.
  3. Find Connected Components: Use Union-Find to group issues by their dependency relationships.
  4. Build Tracks: Create parallel tracks from each component, sorted by priority within each track.
  5. Compute Summary: Identify the single highest-impact issue (most downstream unblocks; ties broken by highest priority, then lowest ID).

Benefits for AI Agents

  • Deterministic: The same source, candidate scope, readiness policy and reference clock produce the same dependency plan. A deferral can expire between calls.
  • Parallelism-Aware: Tracks separate dependency components. They do not detect overlapping file edits or reserve work; coordinate claims and file access separately.
  • Impact-Ranked: The highest_impact field tells agents exactly where to start.

๐Ÿ”ฌ Insights Dashboard: Interactive Graph Analysis

The Insights Dashboard (i) transforms abstract graph metrics into an interactive exploration interface. Instead of just showing numbers, it lets you drill into why a bead scores high and what that means for your project.

The 6-Panel Layout

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿšง Bottlenecks     โ”‚  ๐Ÿ›๏ธ Keystones       โ”‚  ๐ŸŒ Influencers     โ”‚
โ”‚  Betweenness        โ”‚  Impact Depth       โ”‚  Eigenvector        โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚
โ”‚  โ–ธ 0.45 AUTH-001    โ”‚    12.0 CORE-123    โ”‚    0.82 API-007     โ”‚
โ”‚    0.38 API-005     โ”‚    10.0 DB-001      โ”‚    0.71 AUTH-001    โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ›ฐ๏ธ Hubs            โ”‚  ๐Ÿ“š Authorities     โ”‚  ๐Ÿ”„ Cycles          โ”‚
โ”‚  HITS Hub Score     โ”‚  HITS Auth Score    โ”‚  Circular Deps      โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚
โ”‚    0.67 EPIC-100    โ”‚    0.91 UTIL-050    โ”‚  โš  A โ†’ B โ†’ C โ†’ A    โ”‚
โ”‚    0.54 FEAT-200    โ”‚    0.78 LIB-010     โ”‚  โš  X โ†’ Y โ†’ X        โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Panel Descriptions

PanelMetricWhat It ShowsActionable Insight
๐Ÿšง BottlenecksBetweennessBeads on many shortest pathsPrioritize to unblock parallel work
๐Ÿ›๏ธ KeystonesImpact DepthDeep in dependency chainsComplete firstโ€”delays cascade
๐ŸŒ InfluencersEigenvectorConnected to important beadsReview carefully before changes
๐Ÿ›ฐ๏ธ HubsHITS HubAggregate many dependenciesTrack for milestone completion
๐Ÿ“š AuthoritiesHITS AuthorityDepended on by many hubsStabilize earlyโ€”breaking ripples
๐Ÿ”„ CyclesTarjan SCCCircular dependency loopsMust resolveโ€”logical impossibility

The Detail Panel: Calculation Proofs

When you select a bead, the right-side Detail Panel shows not just the score, but the proofโ€”the actual beads and values that contributed:

โ”€โ”€โ”€ CALCULATION PROOF โ”€โ”€โ”€
BW(v) = ฮฃ (ฯƒst(v) / ฯƒst) for all sโ‰ vโ‰ t

Betweenness Score: 0.452

Beads depending on this (5):
  โ†“ UI-Login: Implement login form
  โ†“ UI-Dashboard: User dashboard
  โ†“ API-Auth: Authentication endpoint
  ... +2 more

This depends on (2):
  โ†‘ DB-Schema: User table migration
  โ†‘ CORE-Config: Environment setup

This bead lies on many shortest paths between
other beads, making it a critical junction.

Dashboard Navigation

KeyAction
Tab / Shift+TabMove between panels
j / kNavigate within panel
EnterFocus selected bead in main view
eToggle explanations
iExit dashboard

๐Ÿ“‹ Kanban Board: Visual Workflow State

The Kanban Board (b) provides a columnar workflow view with intelligent swimlane grouping, visual dependency indicators, and rich card details. Empty columns automatically collapse to maximize screen real estate.

Swimlane Grouping Modes

Press s to cycle through three grouping modes:

ModeColumnsUse Case
Status (default)Open | In Progress | Blocked | ClosedWorkflow state tracking
PriorityP0 Critical | P1 High | P2 Medium | P3+ OtherUrgency-based triage
TypeBug | Feature | Task | EpicWork categorization

The current mode is shown in the status bar. Each mode uses distinct column colors for quick visual identification.

Visual Dependency Indicators

Card borders are color-coded to show dependency status at a glance:

โ”Œโ”€ ๐Ÿ”ด RED โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€ ๐ŸŸก YELLOW โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ BLOCKED                    โ”‚    โ”‚ HIGH-IMPACT                  โ”‚
โ”‚ This card has unresolved   โ”‚    โ”‚ This card blocks others.     โ”‚
โ”‚ dependencies. Work on      โ”‚    โ”‚ Completing it will unblock   โ”‚
โ”‚ blockers first.            โ”‚    โ”‚ downstream work.             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

โ”Œโ”€ ๐ŸŸข GREEN โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€ โฌœ DEFAULT โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ READY TO WORK              โ”‚    โ”‚ NORMAL                       โ”‚
โ”‚ Open issue with no         โ”‚    โ”‚ Standard priority, no        โ”‚
โ”‚ blockers. Pick this up!    โ”‚    โ”‚ blocking relationships.      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Search matches overlay with purple (current match) or blue (other matches) borders.

Rich 4-Line Card Format

Each card displays comprehensive metadata in a compact format:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ ๐Ÿ› P1 BUG-1234           3d       โ”‚  โ† Line 1: Type, Priority, ID, Age
โ”‚ Fix authentication timeout         โ”‚  โ† Line 2: Title (truncated)
โ”‚ ๐Ÿ‘คalice  โ›”3  โ†’2  ๐Ÿท๏ธ2             โ”‚  โ† Line 3: Assignee, Blockers, Blocks, Labels
โ”‚ auth, backend, critical            โ”‚  โ† Line 4: Label names
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
ElementMeaning
Type Icon๐Ÿ› Bug, โœจ Feature, ๐Ÿ“ Task, ๐ŸŽฏ Epic, ๐Ÿ”ง Chore
PriorityP0 (red), P1 (red), P2 (muted), P3+ (gray)
Age Color๐ŸŸข <7d (fresh), ๐ŸŸก 7-30d (aging), ๐Ÿ”ด >30d (stale)
โ›”NBlocked by N issues
โ†’NBlocks N downstream issues
๐Ÿท๏ธNHas N labels

Column Statistics

Each column header shows aggregate statistics:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  IN PROGRESS (5)  ๐Ÿ”ฅ2 โš ๏ธ1          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚          โ”‚   โ”‚
         โ”‚          โ”‚   โ””โ”€โ”€ โš ๏ธ Blocked items in this column
         โ”‚          โ””โ”€โ”€โ”€โ”€โ”€โ”€ ๐Ÿ”ฅ P0/P1 critical items
         โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ Total count

Inline Card Expansion

Press d to expand the selected card inline, showing:

  • Full issue description
  • All blocking dependencies (with titles)
  • All downstream dependents
  • Complete label list
  • Comments preview

Navigation (j/k) auto-collapses expanded cards for smooth browsing.

Detail Panel

Press Tab to open a side panel with the full issue detail view (on wide terminals). Scroll with Ctrl+J/Ctrl+K.

Board Navigation

KeyAction
Movement
h / lMove between columns
j / kMove within column
gg / GJump to top/bottom of column
0 / $First/last item in column
H / LJump to first/last column
1-4Jump directly to column 1-4
Ctrl+D / Ctrl+UPage down/up
Grouping & Display
sCycle swimlane mode (Status โ†’ Priority โ†’ Type)
eToggle empty column visibility
dExpand/collapse inline card detail
TabToggle side detail panel
Search
/Start search
n / NNext/previous search match
EscCancel search
Filtering
oFilter: Open only
cFilter: Closed only
rFilter: Ready (no blockers)
Actions
yCopy issue ID to clipboard
VPreview related cass sessions (if cass installed)
EnterFocus selected bead in detail view
bExit board view

๐Ÿ”„ List Sorting: Multi-Dimensional Organization

Press s to cycle through five distinct sort modes, giving you instant control over how issues are organized. The current sort mode is displayed in the status bar.

Sort Modes

ModeKey DisplayOrdering LogicUse Case
DefaultDefaultPriority (asc) โ†’ Created (desc)Standard priority-driven workflow
Created โ†‘Created โ†‘Creation date ascending (oldest first)Audit: find long-standing issues
Created โ†“Created โ†“Creation date descending (newest first)Review: see recently created work
PriorityPriorityPriority only (P0 โ†’ P4)Pure priority triage
UpdatedUpdatedLast update descending (newest first)Activity tracking: see active issues

Design Philosophy

The sort system uses a stable secondary sort to ensure deterministic ordering. When primary sort values are equal, issues fall back to ID ordering for consistency across sessions. This prevents the "shuffling list" problem where equal-priority items randomly reorder.

Status Bar Indicator

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ“‹ ISSUES                                    [Created โ†“]  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  OPEN   FEAT-789  Add dark mode toggle           P2  ๐ŸŸข   โ”‚
โ”‚  OPEN   BUG-456   Fix login race condition       P1  ๐ŸŸข   โ”‚
โ”‚  OPEN   TASK-123  Update documentation           P3  ๐ŸŸข   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

The [Created โ†“] badge instantly communicates the active sort mode without requiring you to remember which mode you're in.


๐ŸŒฒ Hierarchical Tree View: Parent-Child Visualization

Press E to open the Hierarchical Tree Viewโ€”a collapsible tree that visualizes parent-child relationships between issues. Unlike the Graph View which shows all dependency types, the Tree View focuses exclusively on structural hierarchy: which issues are "part of" other issues.

Why Parent-Child Matters

In complex projects, issues often have two distinct relationship types:

  • Blocking dependencies (blocks/blocked_by): Task B cannot start until Task A completes
  • Parent-child relationships (parent): Feature X contains Tasks A, B, and C as sub-work

The Tree View renders only parent-child relationships, creating a work breakdown structure (WBS) that answers questions like:

  • "What sub-tasks make up this epic?"
  • "Which feature does this bug belong to?"
  • "How is work decomposed across the project?"

Tree Layout

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐ŸŒฒ TREE VIEW                                           3 roots ยท 12 nodes  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                             โ”‚
โ”‚  โ–พ ๐ŸŽฏ P1 EPIC-100   Auth System Overhaul                        โ— open     โ”‚
โ”‚  โ”‚ โ”œโ”€ โ–ธ โœจ P1 FEAT-101   Implement OAuth2 flow                  โ— open     โ”‚
โ”‚  โ”‚ โ”‚   โ””โ”€ โ€ข ๐Ÿ“ P2 TASK-102   Add token refresh logic            โ—‹ closed   โ”‚
โ”‚  โ”‚ โ””โ”€ โ€ข ๐Ÿ› P0 BUG-103   Fix session timeout race               โš  blocked  โ”‚
โ”‚  โ”‚                                                                          โ”‚
โ”‚  โ–พ ๐ŸŽฏ P2 EPIC-200   UI Polish Sprint                            โ— open     โ”‚
โ”‚  โ”‚ โ”œโ”€ โ€ข โœจ P2 FEAT-201   Dark mode support                      โ— open     โ”‚
โ”‚  โ”‚ โ””โ”€ โ€ข โœจ P3 FEAT-202   Responsive layout                      โ— open     โ”‚
โ”‚  โ”‚                                                                          โ”‚
โ”‚  โ€ข ๐Ÿ“ P3 TASK-300   Update documentation                        โ— open     โ”‚
โ”‚                                                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Visual Encoding

ElementMeaning
โ–พ / โ–ธExpanded / Collapsed (has children)
โ€ขLeaf node (no children)
โ”œโ”€ / โ””โ”€Tree branch connectors
Type Icon๐ŸŽฏ Epic, โœจ Feature, ๐Ÿ› Bug, ๐Ÿ“ Task, ๐Ÿ”ง Chore
PriorityP0 (critical red), P1 (high), P2 (medium gray), P3+ (muted)
Status Dotโ— Open (green), โ— In Progress (yellow), โš  Blocked (red), โ—‹ Closed (gray)

Tree Building Algorithm

The tree construction uses a parent-child only filter with intelligent root detection:

  1. Filter Dependencies: Only DepParentChild type dependencies are considered; blocking and related dependencies are ignored
  2. Build Index: Create a parent โ†’ children mapping for efficient traversal
  3. Identify Roots: Issues with no parent (or whose parent doesn't exist in the dataset) become root nodes
  4. Recursive Build: Depth-first traversal with cycle detection prevents infinite loops
  5. Sort Children: Within each parent, children are sorted by: Priority (ascending) โ†’ Type (epic > feature > bug > task) โ†’ Creation Date (newest first)

Handling Edge Cases:

  • Orphan References: If an issue references a parent that doesn't exist, it becomes a root node (not silently dropped)
  • Cycles: Detected during traversal; cyclic nodes are rendered without recursing further
  • Deep Hierarchies: No depth limitโ€”the tree faithfully represents arbitrarily nested structures

Tree Navigation

KeyAction
Movement
j / k / โ†“ / โ†‘Move cursor down / up
g / GJump to first / last node
Ctrl+D / Ctrl+UPage down / up (half viewport)
Expand/Collapse
Enter / SpaceToggle expand/collapse on current node
l / โ†’Expand node, or move to first child if already expanded
h / โ†Collapse node, or jump to parent if already collapsed
oExpand all nodes in the tree
OCollapse all nodes in the tree
Integration
TabSync selection to detail panel (in split view)
E / EscExit tree view, return to list

Use Cases

ScenarioHow Tree View Helps
Sprint PlanningExpand epics to see all sub-work and estimate scope
Progress TrackingCollapse completed branches, focus on open work
OnboardingNew team members understand project structure at a glance
RefactoringSee which tasks fall under a feature before restructuring
Status MeetingsWalk through the hierarchy top-down for stakeholder updates

Tree vs. Graph View

AspectTree View (E)Graph View (g)
RelationshipsParent-child onlyBlocking dependencies
LayoutIndented hierarchySelected-node boxes and expandable dependency paths
FocusWork breakdown structureDependency flow
NavigationVim-style (j/k/h/l)hjkl selection, H/L panning, J/K scrolling, Space expansion
Best For"What's inside this epic?""What blocks this task?"

Both views complement each other: use Tree View to understand structure, Graph View to understand flow.


๐ŸŽฏ Actionable Plan View: Parallel Execution Tracks

Press a to open the Actionable Plan Viewโ€”a structured display of work items grouped into independent execution tracks. This view transforms abstract graph analysis into a concrete "what to work on next" interface.

Why Tracks Matter

Traditional priority lists show tasks in a single ordered queue. But in complex dependency graphs, some work streams are completely independentโ€”working on one doesn't affect another. The Actionable Plan View identifies these parallel tracks using Union-Find connected component analysis, letting multiple agents or team members work concurrently without stepping on each other.

Visual Layout

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐ŸŽฏ ACTIONABLE PLAN                                      3 tracks ยท 8 items  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                             โ”‚
โ”‚  โ”โ”โ” Track A: Auth System โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”  โ”‚
โ”‚                                                                             โ”‚
โ”‚  โ–ธ ๐ŸŽฏ P1 AUTH-001   Implement OAuth2 flow                    unblocks 3    โ”‚
โ”‚    โœจ P2 AUTH-002   Add token refresh                        unblocks 1    โ”‚
โ”‚                                                                             โ”‚
โ”‚  โ”โ”โ” Track B: UI Polish โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”  โ”‚
โ”‚                                                                             โ”‚
โ”‚    ๐Ÿ“ P2 UI-101     Dark mode toggle                         unblocks 2    โ”‚
โ”‚    ๐Ÿ“ P3 UI-102     Responsive layout                        unblocks 0    โ”‚
โ”‚                                                                             โ”‚
โ”‚  โ”โ”โ” Track C: Independent โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”โ”  โ”‚
โ”‚                                                                             โ”‚
โ”‚    ๐Ÿ“ P3 DOCS-001   Update API documentation                 unblocks 0    โ”‚
โ”‚                                                                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Highest Impact: AUTH-001 (unblocks 3)                                      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

What Makes an Item "Actionable"

An issue appears in the Actionable Plan when it is in the selected candidate scope, its status is open or in_progress, its deferral has elapsed, and its dependency gates are satisfied. Direct blockers and inherited parent gates are checked against the full loaded source. Closed or tombstoned predecessors satisfy a gate; a missing dependency record does not. Parked statuses such as blocked, deferred and draft are not ready merely because they have no edges.

Planning readiness includes ongoing or assigned work. A new claim additionally requires an open, unassigned, non-epic issue without open children or configured not-ready labels. --robot-next also requires complete source authority and a usable live tracker route before emitting a claim. These checks describe the snapshot; they do not reserve work or guarantee a later tracker mutation succeeds.

Unblock Analysis

Each item shows an unblocks countโ€”the number of other issues that would become actionable if this item were completed. High unblock counts indicate force multipliers: completing them unlocks a cascade of downstream work.

The Highest Impact summary identifies the plan item that unlocks the most additional ready work, with priority and ID tie-breaks. Use --robot-next and its typed action route when choosing a new claim.

KeyAction
j / kMove between items (across tracks)
EnterFocus selected item in detail view
a / EscExit actionable view

Use Cases

ScenarioHow Actionable View Helps
Solo DevelopmentAlways know the highest-impact next task
Team StandupEach person claims a different track
AI Agent DispatchAgents grab highest_impact deterministically
Sprint PlanningEstimate work by counting actionable items per track

๐Ÿ”€ Flow Matrix View: Cross-Label Dependency Analysis

Press f to open the Flow Matrix Viewโ€”an interactive dashboard visualizing how labels (domains/teams) depend on each other. This reveals cross-team bottlenecks that aren't visible in single-issue views.

Why Cross-Label Flow Matters

In large projects, work is often organized by labels: frontend, backend, api, auth, infra. Dependencies between issues create implicit dependencies between labels. The Flow Matrix exposes these patterns:

  • Which team is blocking others the most?
  • Which domain is waiting on the most external work?
  • Where are the cross-team coordination bottlenecks?

Visual Layout

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ”€ FLOW MATRIX                                             5 labels ยท 23 deps โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  LABELS                                   โ”‚  DETAIL                          โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€    โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€   โ”‚
โ”‚                                           โ”‚                                  โ”‚
โ”‚  โ–ธ ๐Ÿ”ด api      โ”โ”โ”โ”โ”โ”โ”โ”โ”โ” 0.72           โ”‚  Label: api                      โ”‚
โ”‚       outgoing: 8 โ†’ [auth, db, infra]    โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€          โ”‚
โ”‚       incoming: 3 โ† [frontend, mobile]   โ”‚                                  โ”‚
โ”‚                                           โ”‚  Bottleneck Score: 0.72         โ”‚
โ”‚    ๐ŸŸก auth     โ”โ”โ”โ”โ”โ”โ”โ”   0.58           โ”‚  (top 20% = critical)            โ”‚
โ”‚       outgoing: 4 โ†’ [db]                 โ”‚                                  โ”‚
โ”‚       incoming: 5 โ† [api, frontend]      โ”‚  Outgoing Dependencies:          โ”‚
โ”‚                                           โ”‚    โ†’ auth (3 issues)             โ”‚
โ”‚    ๐ŸŸข frontend โ”โ”โ”โ”โ”     0.31            โ”‚    โ†’ db (4 issues)               โ”‚
โ”‚       outgoing: 2 โ†’ [api]                โ”‚    โ†’ infra (1 issue)             โ”‚
โ”‚       incoming: 0                        โ”‚                                  โ”‚
โ”‚                                           โ”‚  Incoming Dependencies:          โ”‚
โ”‚    ๐ŸŸข db       โ”โ”โ”       0.22            โ”‚    โ† frontend (2 issues)         โ”‚
โ”‚       outgoing: 0                        โ”‚    โ† mobile (1 issue)            โ”‚
โ”‚       incoming: 7 โ† [api, auth]          โ”‚                                  โ”‚
โ”‚                                           โ”‚  Critical Path: YES              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Bottleneck Score

The bottleneck score (0.0โ€“1.0) measures how much a label blocks cross-domain work relative to the busiest label. It is computed in the TUI (pkg/ui/flow_matrix.go) and is not part of the --robot-label-flow payload, which reports bottleneck_labels instead:

Bottleneck=Outgoingย Cross-Labelย DepsmaxโกlabelsOutgoingย Cross-Labelย Deps\text{Bottleneck} = \frac{\text{Outgoing Cross-Label Deps}}{\max_{\text{labels}} \text{Outgoing Cross-Label Deps}}
ScoreColorMeaning
> 0.7๐Ÿ”ด HIGHCritical bottleneckโ€”prioritize unblocking
0.3 โ€“ 0.7๐ŸŸก MediumModerate blockingโ€”monitor closely
โ‰ค 0.3๐ŸŸข LowHealthy flowโ€”no coordination issues

Drilldown Mode

Press Enter on a label to drill down into the specific issues creating cross-label dependencies:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ”€ FLOW MATRIX > api โ†’ auth                                    3 issues    โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                             โ”‚
โ”‚    ๐Ÿ› P1 API-123   Auth endpoint returns 500         blocks AUTH-456       โ”‚
โ”‚    โœจ P2 API-456   Add OAuth scope validation        blocks AUTH-789       โ”‚
โ”‚    ๐Ÿ“ P2 API-789   Token refresh rate limiting       blocks AUTH-101       โ”‚
โ”‚                                                                             โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
KeyAction
j / kMove between labels
TabToggle focus between labels list and detail panel
EnterDrill down into cross-label issues
EscExit drilldown / Exit view
f / qExit flow matrix view

Robot Command

bv --robot-label-flow | jq '.flow.bottleneck_labels'

๐ŸŽช Attention View: Label Priority Ranking

Press ] (or F4) to open the Attention Viewโ€”a ranked table of labels by attention score, helping you identify which project areas need focus. It is a focused view with its own cursor: move with j/k, jump with g/G, and press Enter on a label to drill into that label's issues.

Attention Score Formula

The attention score (ComputeLabelAttentionScore in pkg/analysis/label_health.go) combines multiple signals to surface neglected or problematic areas:

Attention=PageRanksumร—(1+StaleOpen)ร—(1+BlockImpact)ClosedLast30Days+1\text{Attention} = \frac{\text{PageRank}_{\text{sum}} \times \left(1 + \frac{\text{Stale}}{\text{Open}}\right) \times (1 + \text{BlockImpact})}{\text{ClosedLast30Days} + 1}
ComponentWhat It Measures
PageRank (sum)Summed PageRank of the label's issues within the label subgraph
Staleness factor1 + stale / open (issues idle for 14+ days over open issues)
Block ImpactNumber of blocking edges from other issues onto this label's issues
VelocityIssues closed in the last 30 days, plus 1 to avoid division by zero

High attention scores indicate labels that are both important and neglectedโ€”they need intervention.

Visual Layout

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐ŸŽช ATTENTION VIEW                                                          โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚ Rank โ”‚ Label      โ”‚ Attention โ”‚ Reason                                      โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  1   โ”‚ api        โ”‚    2.45   โ”‚ blocked=5 stale=3 vel=0.8                   โ”‚
โ”‚  2   โ”‚ auth       โ”‚    1.89   โ”‚ blocked=2 stale=4 vel=1.2                   โ”‚
โ”‚  3   โ”‚ infra      โ”‚    1.23   โ”‚ blocked=1 stale=6 vel=0.5                   โ”‚
โ”‚  4   โ”‚ frontend   โ”‚    0.67   โ”‚ blocked=0 stale=1 vel=3.5                   โ”‚
โ”‚  5   โ”‚ docs       โ”‚    0.34   โ”‚ blocked=0 stale=2 vel=2.1                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Interpreting Results

  • High Attention + Low Velocity: Area is stuckโ€”investigate blockers
  • High Attention + High Stale: Work forgottenโ€”resurface and reprioritize
  • Low Attention + High Velocity: Healthy areaโ€”keep momentum
  • High Blocked Count: Dependencies creating bottleneck
KeyAction
j / k (โ†“ / โ†‘)Move the cursor
g / GJump to the first / last label
EnterDrill into the selected label's issues
1-9Filter the list to the label at that rank
] / Esc / qExit attention view

Robot Command

bv --robot-label-attention --attention-limit=10

๐Ÿ“š Shortcuts Sidebar: Persistent Keyboard Reference

Press ; (semicolon) or F2 to toggle the Shortcuts Sidebarโ€”a persistent panel showing context-aware keyboard shortcuts alongside your current view.

Why a Sidebar (Not Just Help)?

The ? help overlay shows shortcuts but blocks your view. The shortcuts sidebar stays visible while you work, perfect for:

  • Learning keyboard shortcuts without interrupting your flow
  • Quick reference during complex navigation
  • Teaching new users while pair programming

Context Awareness

The sidebar automatically filters shortcuts to show only those relevant to your current view. Sections come from the key registry (pkg/ui/keybindings.go) and are named Navigation, Views, Filters, Actions, Graph, Board, Insights, and History:

ContextShown Sections
List ViewNavigation, Views, Filters, Actions
Board ViewNavigation, Views, Board
Graph ViewNavigation, Views, Graph
InsightsNavigation, Views, Insights
HistoryNavigation, Views, History

? and ; live in Views and are listed in every context.

Visual Layout

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                                              โ”‚  โŒจ๏ธ SHORTCUTS         โ”‚
โ”‚                                              โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€  โ”‚
โ”‚               Main Content Area              โ”‚                      โ”‚
โ”‚                                              โ”‚  Navigation          โ”‚
โ”‚           (List, Board, Graph, etc.)         โ”‚  j/k    Move โ†“/โ†‘     โ”‚
โ”‚                                              โ”‚  G/gg   End/Start    โ”‚
โ”‚                                              โ”‚  ^d/^u  Page โ†“/โ†‘     โ”‚
โ”‚                                              โ”‚                      โ”‚
โ”‚                                              โ”‚  Views               โ”‚
โ”‚                                              โ”‚  b      Board        โ”‚
โ”‚                                              โ”‚  g      Graph        โ”‚
โ”‚                                              โ”‚  i      Insights     โ”‚
โ”‚                                              โ”‚                      โ”‚
โ”‚                                              โ”‚  ; to hide           โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
KeyAction
; or F2Toggle sidebar visibility
Ctrl+JScroll sidebar down (when visible)
Ctrl+KScroll sidebar up (when visible)

The sidebar occupies a fixed 34-character width on the right edge of the terminal.


๐ŸŽ“ Interactive Tutorial System

Press ` (backtick) to open the Interactive Tutorialโ€”a comprehensive multi-page walkthrough that teaches all bv features through rich, styled content.

Tutorial Architecture

The tutorial uses a component-based rendering system that produces beautiful terminal output:

ComponentPurposeExample
SectionStyled headers with underlines## Navigation
ParagraphFlowing text with proper wrappingExplanation text
KeyTableAligned key-description pairsj/k โ†’ Move up/down
TipHighlighted advice boxes๐Ÿ’ก TIP: Press g to jump...
WarningAlert boxes for important notesโš ๏ธ WARN: This action...
CodeSyntax-highlighted code blocksbv --robot-triage
BulletStyled bullet listsโ€ข First item
TreeHierarchical structure displayDirectory trees
StatusFlowVisual workflow diagramsOpen โ†’ In Progress โ†’ Closed
InfoBoxBordered information panelsFeature highlights

Tutorial Sections

The tutorial is 30 pages in 6 sections (pkg/ui/tutorial_content.go):

  1. Introduction (4 pages): Welcome, the Beads philosophy, who it is for, quick start
  2. Core Concepts (5 pages): Beads, dependencies and blocking, labels, priorities and status, the dependency graph
  3. Views (8 pages): Navigation fundamentals, list, detail, split, board, graph, insights, history
  4. Advanced (7 pages): Semantic and hybrid search, time travel, label analytics, export and deployment, workspace mode, recipes, AI agent integration
  5. Workflows (5 pages): New feature, bug triage, sprint planning, onboarding, stakeholder review
  6. Reference (1 page): Keyboard reference

Progress Tracking

The tutorial shows a page counter and progress bar as you read:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ“– TUTORIAL                                           Page 3/10 ยท 30% โ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                             โ”‚
โ”‚  ## List View Navigation                                                    โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€                                                  โ”‚
โ”‚                                                                             โ”‚
โ”‚  The list view is your home base. Navigate with vim-style keys:             โ”‚
โ”‚                                                                             โ”‚
โ”‚    j / k       Move down / up                                               โ”‚
โ”‚    g / G       Jump to top / bottom                                         โ”‚
โ”‚    Ctrl+D/U    Page down / up                                               โ”‚
โ”‚                                                                             โ”‚
โ”‚  โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ   โ”‚
โ”‚  โ”‚ ๐Ÿ’ก TIP  Press `/` to search, then type any part of an issue title   โ”‚   โ”‚
โ”‚  โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ   โ”‚
โ”‚                                                                             โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ† h previous โ”‚ l next โ†’ โ”‚ t TOC โ”‚ q close                                  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Progress persists across sessions: pages you have seen are recorded in the user config directory (pkg/ui/tutorial_progress.go) when the tutorial closes, and reopening it resumes on the page you left. Set BV_NO_SAVED_CONFIG=1 to keep it session-only.

Tutorial Navigation

KeyAction
h / l, โ† / โ†’, p / n, Shift+Tab / SpacePrevious / Next page
j / kScroll content up / down
Ctrl+D / Ctrl+UPage content down / up
tToggle Table of Contents
g / GFirst / Last page
1 - 9Jump to page
q / EscClose tutorial

Context-Sensitive Filtering

When you open the tutorial from a specific view (e.g., press ` while in Board view), the tutorial can filter to show only pages relevant to that context. This provides focused learning without overwhelming new users.

Quick Reference vs. Full Tutorial

bv provides two help levels:

FeatureKeyPurpose
Quick Reference?Compact keyboard shortcuts for current view
Full Tutorial`Multi-page walkthrough with examples
Shortcuts Sidebar;Persistent reference while working

From Quick Reference, press Space to jump directly into the full tutorial.


๐Ÿ“œ History View: Bead-to-Commit Correlation

Press h to open the History Viewโ€”an interactive timeline that correlates beads with their related git commits. This bridges the gap between "what work was planned" and "what code was actually written."

The Correlation Engine

The pkg/correlation package implements a multi-strategy correlation system that infers relationships between beads and commits using several techniques:

graph TD
    %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8f5e9', 'lineColor': '#90a4ae'}}}%%

    subgraph strategies ["๐Ÿ” Correlation Strategies"]
        E["Explicit Mentions<br/><small>Commit contains bead ID</small>"]
        T["Temporal Proximity<br/><small>Commit near bead events</small>"]
        C["Co-Commit Analysis<br/><small>Files changed together</small>"]
    end

    subgraph scorer ["๐Ÿ“Š Confidence Scorer"]
        S["Multi-Factor Scoring<br/><small>Weighted combination</small>"]
    end

    subgraph output ["๐Ÿ“ˆ Output"]
        H["BeadHistory<br/><small>Events + Commits + Milestones</small>"]
    end

    E --> S
    T --> S
    C --> S
    S --> H

    classDef strategy fill:#e3f2fd,stroke:#90caf9,stroke-width:2px,color:#1565c0
    classDef score fill:#fff8e1,stroke:#ffcc80,stroke-width:2px,color:#e65100
    classDef out fill:#e8f5e9,stroke:#a5d6a7,stroke-width:2px,color:#2e7d32

    class E,T,C strategy
    class S score
    class H out

Correlation Strategies

pkg/correlation/types.go defines three correlation methods, and the Correlator behind the History view and --robot-history runs all three over the same commit window: the co-commit strategy, the explicit-ID matcher (explicit.go, extended by --id-pattern), and the temporal correlator (temporal.go). When several strategies match the same (commit, bead) pair the highest-confidence one becomes method and every match is listed in methods; stats.method_distribution and stats.strategies report the per-strategy counts. Stored confirm/reject feedback is applied on top (see Correlation Feedback System).

MethodConfidence rangeHow It Works
co_committed0.85 โ€“ 0.99The commit changed source files and the beads JSONL for this bead in the same commit
explicit_id0.70 โ€“ 0.99Commit message contains the bead ID (custom ID shapes via --id-pattern)
temporal_author0.20 โ€“ 0.85Commit by the bead's assignee inside the bead's in-progress window

There is no path-matching strategy; label-to-path hints only nudge temporal scores inside temporal.go.

Confidence Scoring

Each correlation carries a confidence score (0.0โ€“1.0) inside its method's range (MethodRanges in pkg/correlation/scorer.go). --robot-explain-correlation breaks a score into additive signals: co-commit 50, explicit message match 40, timing 25 plus author match 15, file overlap 5 per file (capped at 15), and proximity 7 when the score sits near the top of its range. When more than one method matches the same commit, CombineConfidence takes the strongest signal and adds diminishing credit for the others.

History View Layout

The History View uses a responsive layout that adapts to terminal width (layoutBreakpointStandard and layoutBreakpointWide in pkg/ui/history.go):

WidthLayout
< 100Two panes: List + Detail
100-150Three panes: Beads + Commits + Detail
> 150Wide: adds the Timeline pane (bead mode)

Wide Terminal (3-pane) Layout:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ“œ HISTORY VIEW                                          [Bead Mode] [โ‰ฅ 0.5]   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  BEADS                โ”‚  TIMELINE         โ”‚  COMMIT DETAIL                      โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€    โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€    โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€          โ”‚
โ”‚ โ–ธ BV-123 (3 commits)  โ”‚    โ”ƒ              โ”‚  abc1234 - Fix auth race            โ”‚
โ”‚   ๐ŸŽฏ BV-456 (1)       โ”‚   โ”โ•‹โ” Jan 15      โ”‚  Author: alice@example.com          โ”‚
โ”‚   ๐Ÿ”— BV-789 (5)       โ”‚    โ”ƒ   โ–ชโ–ชโ–ช        โ”‚  Date:   2025-01-15 14:32           โ”‚
โ”‚   ๐Ÿ“ BV-100 (2)       โ”‚   โ”โ•‹โ” Jan 14      โ”‚  Confidence: 0.85 (explicit)        โ”‚
โ”‚                       โ”‚    โ”ƒ   โ–ช          โ”‚                                      โ”‚
โ”‚                       โ”‚   โ”โ•‹โ” Jan 13      โ”‚  Files changed:                      โ”‚
โ”‚                       โ”‚    โ”ƒ   โ–ชโ–ชโ–ชโ–ชโ–ช      โ”‚    M pkg/auth/session.go            โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Timeline Panel

On terminals wider than 150 columns (bead mode), the Timeline Panel appears automatically as a fourth pane, a visual density chart of project activity:

  • Vertical axis: Time (newest at top)
  • Horizontal bars: Activity density (commits per day)
  • Bar magnitude: โ–ช = 1-2, โ–ชโ–ช = 3-5, โ–ชโ–ชโ–ช = 6-10, โ–ชโ–ชโ–ชโ–ช = 11+
  • Highlights: Selected bead's commits are marked with โ”

The pane is on by default at 150 columns or wider; press t in the History view to toggle it for the session (it needs bead mode and at least 100 columns).

Causality Markers

Each bead-commit correlation shows its detection method as a visual marker:

MarkerMeaningConfidence
๐ŸŽฏ DirectCommit message explicitly mentions bead ID (explicit_id)0.70-0.99
๐Ÿ”— TemporalCommit by the assignee inside the bead's active window (temporal_author)0.20-0.85
๐Ÿ“ FileCommit changed code and the beads file together (co_committed)0.85-0.99

A pair matched by more than one strategy shows the highest-confidence marker; a confirmed pair (--robot-confirm-correlation) is pinned to confidence 1.0 and flagged confirmed.

View Modes

Press v to toggle between two view modes:

ModeShowsUse Case
Bead Mode (default)Beads grouped with their correlated commits"What commits relate to this task?"
Git ModeCommits chronologically with correlated beads"What tasks did this commit touch?"

File-Centric Drill-Down (f Key)

Press f to switch to File Modeโ€”a tree view of changed files grouped by directory:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ“ FILE MODE                                              [12 files]   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  โ–ผ pkg/auth/                                                            โ”‚
โ”‚      session.go       42 changes   BV-123, BV-456                       โ”‚
โ”‚      token.go         18 changes   BV-123                               โ”‚
โ”‚      middleware.go    8 changes    BV-789                               โ”‚
โ”‚  โ–ผ pkg/api/                                                             โ”‚
โ”‚      handler.go       25 changes   BV-100                               โ”‚
โ”‚      routes.go        12 changes   BV-100, BV-456                       โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Navigate to a file and press Enter to see all beads and commits that touched it.

History Navigation

KeyAction
Navigation
j / kMove in primary pane (beads or commits)
J / KMove in secondary pane (commits or detail)
TabCycle focus between panes
EnterExpand/collapse or drill into selection
gJump to the graph view for the selected bead
View Modes
vToggle Bead Mode โ†” Git Mode
fToggle File-centric drill-down
Filtering
cCycle confidence threshold (0.0 โ†’ 0.3 โ†’ 0.5 โ†’ 0.7)
/Search commits or beads
Actions
yCopy selected commit SHA to clipboard
oOpen commit in browser (GitHub/GitLab)
VPreview cass sessions for selected bead
h / EscReturn to list view

Robot Command: --robot-history

bv --robot-history                          # Full history report
bv --robot-history --bead-history BV-123    # Single bead focus
bv --robot-history --history-since '30 days ago'
bv --robot-history --min-confidence 0.7     # High-confidence only

Output Schema:

{
  "stats": {
    "total_beads": 58,
    "beads_with_commits": 42,
    "total_commits": 156,
    "avg_cycle_time_hours": 72.5,
    "method_distribution": {
      "explicit": 89,
      "temporal": 45,
      "cocommit": 22
    }
  },
  "histories": {
    "BV-123": {
      "events": [...],
      "commits": [...],
      "milestones": [...],
      "cycle_time_hours": 48.2
    }
  },
  "commit_index": {
    "abc1234": ["BV-123", "BV-456"]
  }
}

Beyond simple bead-to-commit correlation, bv provides deep analysis of how beads relate to each other through shared code changes. This helps identify hidden dependencies, find related work, and understand the true impact of changes.

Impact Network Graph

The Impact Network visualizes implicit relationships between beads based on:

graph LR
    %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e3f2fd', 'lineColor': '#90a4ae'}}}%%

    subgraph connections ["๐Ÿ”— Edge Types"]
        SC["Shared Commit<br/><small>Same commit touches both beads</small>"]
        SF["Shared File<br/><small>Both beads modify same files</small>"]
        DEP["Dependency<br/><small>Explicit blocker relationship</small>"]
    end

    classDef edge fill:#fff8e1,stroke:#ffcc80,stroke-width:2px
    class SC,SF,DEP edge
Edge TypeWeightMeaning
Shared CommitHighA single commit references both beads (strong coupling)
Shared FileMediumBoth beads touched the same source file
DependencyExplicitDirect blocking relationship from issue tracker

Network Clusters

bv automatically detects clusters of tightly-connected beads as the connected components of the network after dropping edges with weight below 2 (detectClusters in pkg/correlation/network.go):

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ”— IMPACT NETWORK                                        [3 clusters]  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                         โ”‚
โ”‚  โ”Œโ”€โ”€โ”€ Cluster 1: Auth Module โ”€โ”€โ”€โ”     โ”Œโ”€โ”€โ”€ Cluster 2: API Layer โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚  BV-123 โ†โ”€โ”€โ†’ BV-456          โ”‚     โ”‚  BV-789 โ†โ”€โ”€โ†’ BV-100        โ”‚   โ”‚
โ”‚  โ”‚    โ†•           โ†•              โ”‚     โ”‚    โ†•                        โ”‚   โ”‚
โ”‚  โ”‚  BV-321 โ†โ”€โ”€โ†’ BV-654          โ”‚โ”€โ”€โ”€โ”€โ†’โ”‚  BV-111                     โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜     โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                                                         โ”‚
โ”‚  Central bead: BV-123 (highest degree)                                 โ”‚
โ”‚  Internal connectivity: 0.85 (tightly coupled)                         โ”‚
โ”‚  External edges: 1 (to API layer cluster)                              โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

File-to-Bead Lookup

Find all beads that have touched a specific file using --robot-file-beads:

bv --robot-file-beads pkg/ui/board.go

Returns beads sorted by recency with commit details:

{
  "file_path": "pkg/ui/board.go",
  "total_beads": 21,
  "open_beads": [],
  "closed_beads": [
    {
      "bead_id": "bv-v67w",
      "title": "Board: Integration & Polish",
      "status": "closed",
      "commit_shas": ["abc123"],
      "last_touch": "2025-12-18T00:19:21-05:00",
      "total_changes": 17
    }
  ]
}

Use cases:

  • Code ownership: "Who has worked on this file recently?"
  • Impact analysis: "What work items are affected by this file?"
  • Bug investigation: "What changes might have introduced this regression?"

Orphan Commit Detection

Find commits that should be linked to beads but aren't using --robot-orphans:

bv --robot-orphans

Returns candidate commits with probable bead matches:

{
  "stats": {
    "total_commits": 500,
    "correlated_count": 242,
    "orphan_count": 258,
    "orphan_ratio": 0.516
  },
  "candidates": [
    {
      "sha": "abc1234",
      "message": "feat: add auth caching",
      "suspicion_score": 100,
      "probable_beads": [
        {
          "bead_id": "bv-xyz",
          "confidence": 65,
          "reasons": ["touches file pkg/auth/cache.go", "same author worked on bead nearby"]
        }
      ]
    }
  ]
}

Use cases:

  • Hygiene: Find commits that slipped through without proper linking
  • Audit: Ensure all code changes are tracked to work items
  • Correlation improvement: Train the system by confirming/rejecting suggestions

For any bead, bv can find related work across four dimensions:

Relation TypeHow DetectedExample
File OverlapBoth beads modify same source files"BV-123 and BV-456 both touch session.go"
Commit OverlapBoth beads referenced in same commit"BV-123 and BV-456 fixed in commit abc123"
Dependency ClusterBoth in same tightly-connected subgraph"BV-123 is in the Auth cluster with BV-456"
ConcurrentActive during the same time window"BV-123 and BV-456 both worked on last week"

Each relation includes a relevance score (0-100) indicating strength.

Robot Commands

# Get the full impact network (use "all" for complete graph)
bv --robot-impact-network all

# Get subnetwork focused on specific bead (default depth=2, max=3)
bv --robot-impact-network bv-123 --network-depth 2

# Find related work for a bead
bv --robot-related bv-123

# Include closed beads in related work results
bv --robot-related bv-123 --related-include-closed

# Tune related work thresholds
bv --robot-related bv-123 --related-min-relevance 30 --related-max-results 20

# Analyze causal chain for a bead (timeline, blockers, insights)
bv --robot-causality bv-123

# Find beads that touched a file
bv --robot-file-beads pkg/auth/session.go

# Find orphan commits (unlinked to beads)
bv --robot-orphans

Causal Chain Analysis

bv --robot-causality <id> reconstructs committed status and dependency changes, including changes to blockers outside the displayed issue scope. It measures observed waiting intervals and links changes that affect readiness. Events retain Git first-parent order, author timestamps and committer timestamps; chronological proximity alone does not establish a cause.

Add --as-of <ref> to use the source file and history available at that Git revision, with ongoing waits measured through its timestamp. Later descendants stay excluded even if their dates were backdated. --history-limit and --history-since restrict the retained window; a window that omits creation cannot establish the full lifecycle duration.

Event TypeDescription
createdBead first appeared in the retained source
claimedStatus changed to in_progress
blocked / unblockedExplicit blocked status or dependency constraints changed
closed / reopenedA committed lifecycle transition
changed / deletedOther target changes or removal from the source; removal is not completion
constraint_changeA relevant dependency record or unresolved gate changed
observationAn ongoing wait measured through the reference instant

Correlated code commits appear separately in chain.related_commits. The chain.links array records the evidence for dependency transitions and observed waits; an unrelated preceding commit does not become a causal link.

Measurements:

  • explicit_blocked_duration measures recorded blocked status; dependency_wait_duration measures unsatisfied dependency gates. Their union is blocked_duration, so overlapping blockers count once.
  • active_duration is nonblocked elapsed time. It does not measure execution effort, and estimated_without remains null because Git history does not establish a minimum completion time.
  • critical_path follows evidence-supported links and weights observed waiting. It is not a project schedule. Gap statistics describe retained transitions when their clocks are consistent.
  • coverage, limitations and the duration-known fields expose missing records, truncated history and contradictory clocks. Unknown measurements serialize as null, distinct from a measured zero. An open wait extends through the reference instant, bounded by any requested history cutoff.

Example excerpt: a ten-hour lifecycle with a dependency wait from 02:00 to 08:00. Duration fields use integer nanoseconds, not duration strings. Use bv --robot-schema --schema-command robot-causality for the complete schema.

{
  "chain": {
    "bead_id": "A",
    "status": "closed",
    "total_time": 36000000000000,
    "duration_known": true,
    "is_complete": true
  },
  "insights": {
    "coverage": "complete",
    "total_duration": 36000000000000,
    "blocked_duration": 21600000000000,
    "active_duration": 14400000000000,
    "blocked_percentage": 60,
    "explicit_blocked_duration": 0,
    "dependency_wait_duration": 21600000000000,
    "estimated_without": null
  }
}

Correlation Feedback System

Record decisions about specific commit/issue pairs:

# Explain why a correlation exists
bv --robot-explain-correlation abc1234:bv-xyz

# Confirm a correct correlation (boosts confidence)
bv --robot-confirm-correlation abc1234:bv-xyz

# Reject an incorrect correlation (removes it)
bv --robot-reject-correlation abc1234:bv-xyz

# View feedback statistics
bv --robot-correlation-stats

Feedback Stats Output:

{
  "total_feedback": 15,
  "confirmed": 12,
  "rejected": 3,
  "accuracy_rate": 0.80,
  "avg_confirm_conf": 0.85,
  "avg_reject_conf": 0.42
}

Stored feedback applies to the identified commit/issue pair: confirmation pins confidence to 1.0, rejection removes that pair from the report and derived index, and ignore leaves it unchanged. These decisions do not train patterns for unrelated pairs or establish calibrated accuracy.

Impact Network Output Schema:

{
  "generated_at": "2025-01-15T14:32:00Z",
  "data_hash": "abc123...",
  "stats": {
    "total_nodes": 58,
    "total_edges": 142,
    "cluster_count": 5,
    "avg_degree": 4.9,
    "density": 0.086,
    "isolated_nodes": 3
  },
  "clusters": [
    {
      "cluster_id": 1,
      "bead_ids": ["BV-123", "BV-456", "BV-321"],
      "label": "Auth Module",
      "internal_connectivity": 0.85,
      "central_bead": "BV-123",
      "shared_files": ["pkg/auth/session.go", "pkg/auth/token.go"]
    }
  ],
  "edges": [
    {"from_bead": "BV-123", "to_bead": "BV-456", "edge_type": "shared_commit", "weight": 5}
  ]
}

๐Ÿค– Cass Integration: AI Session Correlation (Optional)

bv optionally integrates with cass (Coding Agent Session Search), which indexes coding sessions from AI assistants. The TUI can look up and preview sessions for a selected bead. Availability and session matches do not establish live agent activity or add a fourth Git-history correlation strategy.

How It Works

graph LR
    %%{init: {'theme': 'base', 'themeVariables': { 'primaryColor': '#e8f5e9', 'lineColor': '#90a4ae'}}}%%

    CASS["๐Ÿค– cass<br/><small>Session Store</small>"]
    BV["โšก bv<br/><small>Issue Viewer</small>"]
    CORR["๐Ÿ”— Enhanced<br/>Correlation"]

    CASS --> BV
    BV --> CORR

    classDef tool fill:#e3f2fd,stroke:#90caf9,stroke-width:2px
    class CASS,BV,CORR tool

Graceful Degradation: If cass is not installed, bv works normallyโ€”no errors, broken UI, or loading states. Cass features simply become unavailable.

Detection & Status

bv automatically detects cass on startup:

StatusIndicatorMeaning
Healthy๐Ÿค– cass in the footercass is installed, indexed, and ready
Needs Indexโš  cass index in the footercass installed but needs cass index
Not Installed(none)cass not in PATH; V says so when pressed

The check runs once when the TUI starts (cass health, bounded to 2 seconds) and its result is reused when you press V, so a missing or unindexed cass costs one probe, not one per keypress.

Session Preview Modal (V Key)

Press V on any bead to open the Session Preview Modalโ€”a view of AI coding sessions that may have contributed to that issue. V acts on whatever the current view has selected: the list or detail item, the board card, the tree node, or the history row.

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿค– Related Coding Sessions for BV-123                                  โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚                                                                         โ”‚
โ”‚  โ–ธ Session 1 (claude-opus-4)                         Dec 15, 2:30 PM   โ”‚
โ”‚    "Implementing session refresh timeout handling..."                   โ”‚
โ”‚    Confidence: 0.92 (explicit mention)                                  โ”‚
โ”‚                                                                         โ”‚
โ”‚    Session 2 (claude-opus-4)                         Dec 14, 10:15 AM  โ”‚
โ”‚    "Refactoring token validation middleware..."                         โ”‚
โ”‚    Confidence: 0.67 (file overlap)                                      โ”‚
โ”‚                                                                         โ”‚
โ”‚    Session 3 (claude-opus-4)                         Dec 13, 4:45 PM   โ”‚
โ”‚    "Adding retry logic to auth service..."                              โ”‚
โ”‚    Confidence: 0.45 (temporal)                                          โ”‚
โ”‚                                                                         โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  j/k: Navigate   y: Copy search command   Enter: View full session      โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Session Correlation Methods:

MethodWeightMeaning
Explicit0.9-1.0Session mentions bead ID directly
File Overlap0.5-0.8Session touched files associated with bead
Temporal0.3-0.6Session occurred during bead's active lifecycle
Keyword0.2-0.5Session contains keywords from bead title/description

Status Bar Indicator

The footer carries two cass indicators: the health badge from the startup check (๐Ÿค– cass or โš  cass index) and, once a session lookup has run, a ๐Ÿ“ŽN count of correlated sessions for the selected bead. bv does not show per-model "active" agent activity; that information is not part of the cass integration.

StateDisplayMeaning
Active๐Ÿค– agent-nameSession in progress within last 15 minutes
Idle๐Ÿ’คNo recent sessions

Installing Cass

# Install cass (see https://github.com/Dicklesworthstone/coding_agent_session_search for full docs)
brew install dicklesworthstone/tap/cass   # macOS
# or
cargo install coding-agent-search          # From source (binary is `cass`)

# Index your coding sessions
cass index

# Verify integration
bv  # Look for ๐Ÿค– in status bar

Cass-Enhanced History View

When cass is available, the History View gains additional capabilities:

  • Session Timeline: V key shows sessions alongside commits
  • Agent Attribution: See which AI assistant contributed to changes
  • Enhanced Search: Search across both commits and sessions

๐Ÿ“… Sprint Dashboard: Burndown & Progress Tracking

The Sprint Dashboard (pkg/ui/sprint_view.go) shows sprint progress with burndown visualization, scope change tracking, and at-risk detection, driven by .beads/sprints.jsonl. Press P from the list or detail view to open it on the sprint active today (the status line says so when no sprints are defined); j/k step between sprints, and P, Esc, or q close it.

Dashboard Layout

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ“… Sprint: January 2025                                                โ”‚
โ”‚  โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€    โ”‚
โ”‚  Dates:     Jan 6 โ†’ Jan 20                                              โ”‚
โ”‚  Remaining: 5 days                                                      โ”‚
โ”‚                                                                         โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•    โ”‚
โ”‚                          PROGRESS                                       โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•    โ”‚
โ”‚                                                                         โ”‚
โ”‚  Total: 24 beads    Closed: 18 (75%)    Remaining: 6                    โ”‚
โ”‚  [โ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–ˆโ–‘โ–‘โ–‘โ–‘โ–‘โ–‘] 75%                                       โ”‚
โ”‚                                                                         โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•    โ”‚
โ”‚                          BURNDOWN                                       โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•    โ”‚
โ”‚                                                                         โ”‚
โ”‚  24 โ”ค ยท                                                                 โ”‚
โ”‚  20 โ”ค  ยทยทยทยทยท                                                            โ”‚
โ”‚  16 โ”ค       ยทยทยทยทโ–ธ                                                       โ”‚
โ”‚  12 โ”ค            โ•ฒ    (ideal)                                           โ”‚
โ”‚   8 โ”ค             โ•ฒ                                                     โ”‚
โ”‚   4 โ”ค              โ•ฒ                                                    โ”‚
โ”‚   0 โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€    โ”‚
โ”‚     Jan 6          Jan 13                Jan 20                         โ”‚
โ”‚                                                                         โ”‚
โ”‚  Legend: ยท = Actual    โ•ฒ = Ideal    โ–ธ = Today                           โ”‚
โ”‚                                                                         โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•    โ”‚
โ”‚                       SCOPE CHANGES                                     โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•    โ”‚
โ”‚                                                                         โ”‚
โ”‚  Jan 8:  +2 beads added (BV-456, BV-457)                                โ”‚
โ”‚  Jan 10: -1 bead removed (BV-100 moved to backlog)                      โ”‚
โ”‚                                                                         โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•    โ”‚
โ”‚                        AT-RISK ITEMS                                    โ”‚
โ”‚  โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•    โ”‚
โ”‚                                                                         โ”‚
โ”‚  โš  BV-789 - Auth refactor (3d stale)                                    โ”‚
โ”‚  โš  BV-234 - Token rotation (5d stale)                                   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Burndown Calculation

The burndown chart tracks completion velocity and records scope changes:

  1. Ideal Burn Rate: Total Beads / Sprint Duration
  2. Actual Burn Rate: Closed Beads / Days Elapsed
  3. Scope Events: Added/removed beads are listed with their dates

The ideal line is scope-aware: it starts from the scope the sprint began with, and at each scope-change date the remaining count moves by the added or removed beads and the line re-linearizes from that day's count to zero at the sprint end, so a mid-sprint addition shows as a slope change instead of a false "behind schedule" gap.

At-Risk Detection

At-risk detection (analysis.DetectAtRisk, shared by the dashboard and --robot-burndown's at_risk array) flags any open sprint bead that trips one or more of four signals: blocked_too_long (blocked for 2+ days), no_activity (no update for 4+ days), critical_blocked (a P0/P1 bead that is blocked at all), and blockers_not_closing (an open blocker that has itself been idle 4+ days). Each item reports its signals, the instant it has been at risk since, and a one-line detail; the dashboard lists up to five.

Robot Commands

bv --robot-sprint-list                # List all sprints
bv --robot-sprint-show sprint-1       # Details for specific sprint
bv --robot-burndown current           # Burndown for active sprint
bv --robot-burndown sprint-1          # Burndown for specific sprint

Burndown Output (BurndownOutput in cmd/bv/main.go):

{
  "sprint_id": "sprint-1",
  "sprint_name": "January 2025",
  "start_date": "2025-01-06T00:00:00Z",
  "end_date": "2025-01-20T00:00:00Z",
  "total_days": 14,
  "elapsed_days": 9,
  "remaining_days": 5,
  "total_issues": 24,
  "completed_issues": 18,
  "remaining_issues": 6,
  "ideal_burn_rate": 1.71,
  "actual_burn_rate": 2.0,
  "projected_complete": "2025-01-18T00:00:00Z",
  "on_track": true,
  "daily_points": [{"date": "2025-01-06T00:00:00Z", "remaining": 24, "completed": 0}],
  "ideal_line": [{"date": "2025-01-06T00:00:00Z", "remaining": 24, "completed": 0}],
  "scope_changes": [
    {"date": "2025-01-08T00:00:00Z", "issue_id": "BV-456", "issue_title": "Add OAuth scopes", "action": "added"}
  ]
}

๐Ÿท๏ธ Label Analytics: Domain-Centric Health Monitoring

Press [ (or F3) to open the Label Dashboardโ€”a table view showing health metrics for each label in your project. This enables domain-driven prioritization by surfacing which areas of your codebase need attention.

Label Dashboard Layout

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿท๏ธ LABEL HEALTH                                                        โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ฌโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  Label       โ”‚ Health โ”‚ Status โ”‚ Open   โ”‚ Blockedโ”‚ Stale  โ”‚ Velocity   โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ผโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  ๐Ÿ”ด api      โ”‚   32   โ”‚ CRIT   โ”‚   12   โ”‚   5    โ”‚   3    โ”‚   0.8/wk   โ”‚
โ”‚  ๐ŸŸก auth     โ”‚   58   โ”‚ WARN   โ”‚    8   โ”‚   2    โ”‚   1    โ”‚   2.1/wk   โ”‚
โ”‚  ๐ŸŸข ui       โ”‚   85   โ”‚ OK     โ”‚    4   โ”‚   0    โ”‚   0    โ”‚   4.2/wk   โ”‚
โ”‚  ๐ŸŸข docs     โ”‚   92   โ”‚ OK     โ”‚    2   โ”‚   0    โ”‚   0    โ”‚   1.5/wk   โ”‚
โ”‚  ๐ŸŸก infra    โ”‚   61   โ”‚ WARN   โ”‚    6   โ”‚   1    โ”‚   2    โ”‚   1.2/wk   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ดโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Health Score Calculation

The label health score is a 0-100 composite of four component scores, each on 0-100 (ComputeCompositeHealth in pkg/analysis/label_health.go):

Health=0.25โ‹…Velocity+0.25โ‹…Freshness+0.25โ‹…Flow+0.25โ‹…Criticality\text{Health} = 0.25 \cdot \text{Velocity} + 0.25 \cdot \text{Freshness} + 0.25 \cdot \text{Flow} + 0.25 \cdot \text{Criticality}
ComponentWeightMeaning
Velocity0.25Throughput of closed issues (recent closes score higher)
Freshness0.25Share of issues updated within the stale threshold (14 days)
Flow0.25100 - 5 x incoming cross-label dependencies (fewer external blockers score higher)
Criticality0.25Up to 50 points from the label's average PageRank relative to the project maximum, plus up to 50 from its highest betweenness

The weights and the 14-day stale threshold are the defaults in DefaultLabelHealthConfig(); the robot payload echoes them under analysis_config.

Health Levels

LevelScore RangeIndicatorAction
Critical0 โ€“ 39๐Ÿ”ดImmediate attention required
Warning40 โ€“ 69๐ŸŸกMonitor closely
Healthy70 โ€“ 100๐ŸŸขOn track

Robot Commands for Label Analysis

--robot-label-health: Per-label health metrics

bv --robot-label-health
bv --robot-label-health | jq '.results.labels[] | select(.health_level == "critical")'

--robot-label-flow: Cross-label dependency flow matrix

bv --robot-label-flow
bv --robot-label-flow | jq '.flow.bottleneck_labels'

--robot-label-attention: Attention-ranked labels for prioritization

bv --robot-label-attention --attention-limit=5

Label-Scoped Analysis

Use --label to scope any robot command to a specific label's subgraph:

bv --robot-insights --label api    # Graph metrics for api-labeled issues only
bv --robot-plan --label backend    # Execution plan for backend domain
bv --robot-priority --label auth   # Priority recommendations for auth work

This enables domain isolation: analyze and plan within a bounded context rather than the entire project graph.

Flow Matrix: Cross-Label Dependencies

The flow matrix reveals how labels depend on each other:

          โ†’ api  โ†’ auth  โ†’ ui   โ†’ docs
api         -      3       2      0
auth        1      -       0      1
ui          4      2       -      0
docs        0      0       0      -

Read as: "api has 3 issues that depend on auth issues." High values indicate coupling between domains; the bottleneck_labels field highlights labels that block the most cross-domain work.


๐ŸŒ Static Site Export: Shareable Dashboards

bv can generate self-contained static websites for sharing project status with stakeholders who don't have terminal access.

Interactive Wizard

bv --pages

Launches an interactive wizard that guides you through:

  1. Export: Generate the static bundle
  2. Preview: Local server at http://localhost:9000 (or next available port)
  3. Deploy: Push to GitHub Pages with automatic repository creation

Direct Export

bv --export-pages ./bv-pages                    # Export to directory
bv --export-pages ./bv-pages --pages-title "Sprint 42 Status"
bv --export-pages ./bv-pages --pages-include-closed=false   # Omit closed issues (default: true)
bv --export-pages ./bv-pages --pages-include-history=false  # Omit git history (default: true)
bv --export-pages ./bv-pages --watch-export                 # Re-export whenever the beads file changes
bv --export-pages ./bv-pages --no-hooks                     # Skip .bv/hooks.yaml hooks for this export

# Preview an existing bundle without regenerating
bv --preview-pages ./bv-pages                   # Serve at localhost:9000 (or next available port)

Optional: Hybrid Search WASM Scorer

For very large datasets, you can build an optional WASM scorer used by the static viewer. Setting BV_BUILD_HYBRID_WASM=1 makes --export-pages run wasm-pack from a source checkout (pkg/export/wasm_scorer) and write the result into the bundle's wasm/ directory, in the released binary as well as in development builds; it fails with a clear error when wasm-pack or the source tree is missing. The viewer only loads it once the export holds 5,000 or more issues (threshold in wasm_loader.js); smaller exports always use the JS scorer.

# Build once (requires wasm-pack)
./scripts/build_hybrid_wasm.sh

# Or build during export
BV_BUILD_HYBRID_WASM=1 bv --export-pages ./bv-pages

If the wasm/ assets are missing, the viewer automatically falls back to the JS scorer.

What Gets Generated

./bv-pages/
โ”œโ”€โ”€ index.html              # Main dashboard with Alpine.js + Tailwind
โ”œโ”€โ”€ beads.sqlite3           # Full SQLite database (3.3 MB for this repository's 611 issues)
โ”œโ”€โ”€ data/
โ”‚   โ”œโ”€โ”€ graph_layout.json   # Pre-computed positions + metrics (116 KB for 611 issues / 746 edges)
โ”‚   โ”œโ”€โ”€ meta.json           # Export metadata
โ”‚   โ”œโ”€โ”€ triage.json         # Triage recommendations
โ”‚   โ””โ”€โ”€ history.json        # Bead-commit correlation data
โ””โ”€โ”€ vendor/
    โ”œโ”€โ”€ d3.v7.min.js        # Visualization library
    โ”œโ”€โ”€ force-graph.min.js  # Graph rendering
    โ””โ”€โ”€ bv_graph.js         # WASM graph engine

Graph Visualization: Pre-computed Layout

The export uses a hybrid architecture so the graph can render before the database has loaded:

ComponentSizePurpose
graph_layout.json116 KB for 611 issues / 746 edgesPre-computed node positions + graph metrics
beads.sqlite33.3 MB for 611 issuesFull issue data for detail pane, search, tables

Sizes are measured, not estimated: tests/e2e/export_pages_test.go re-exports this repository on every e2e run and checks the bundle against tests/artifacts/perf/pages_load.json (whole bundle 9.7 MB, of which 5.6 MB is the vendored viewer libraries); the record is rewritten only when the test runs with BV_RECORD_PERF=1, and a bundle that grows by more than a quarter fails the run.

How it works:

  1. Browser loads the small graph_layout.json first
  2. Graph renders with pre-computed fx/fy fixed positions
  3. SQLite loads in parallel for search and detail functionality
  4. Force simulation is bypassedโ€”no jittering, no layout delay

Load-time figures are not measured in the repository yet; the sizes above are from this repository's own export.

Detail Pane

Click any node to open a 400px sliding detail pane:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚                              โ”‚ โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ          โ”‚
โ”‚                              โ”‚ โ”‚ BV-123: Auth refactor   โ”‚          โ”‚
โ”‚       [Interactive Graph]    โ”‚ โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚          โ”‚
โ”‚                              โ”‚ โ”‚ Priority: P1 (High)     โ”‚          โ”‚
โ”‚             โฌค               โ”‚ โ”‚ Type: Feature           โ”‚          โ”‚
โ”‚            /โ”‚\               โ”‚ โ”‚ Status: In Progress     โ”‚          โ”‚
โ”‚           / โ”‚ \              โ”‚ โ”‚                         โ”‚          โ”‚
โ”‚          โฌค  โฌค  โฌค           โ”‚ โ”‚ **Description**         โ”‚          โ”‚
โ”‚                              โ”‚ โ”‚ Refactor auth module... โ”‚          โ”‚
โ”‚                              โ”‚ โ”‚                         โ”‚          โ”‚
โ”‚                              โ”‚ โ”‚ โ›” 3 blockers           โ”‚          โ”‚
โ”‚                              โ”‚ โ”‚ ๐Ÿ“ค blocks 5 issues      โ”‚          โ”‚
โ”‚                              โ”‚ โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ          โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Detail pane includes:

  • Full issue title and description (markdown rendered)
  • Priority, type, status with visual indicators
  • Blockers count ("โ›” 3 blockers")โ€”issues that must complete first
  • Blocks count ("๐Ÿ“ค blocks 5 issues")โ€”downstream work waiting on this
  • PageRank, betweenness metrics (from pre-computed data)

Features

  • Search: Search titles and descriptions without a server. The shipped browser SQLite engine uses substring matching; the export also contains an FTS5 index for engines that support it. Hybrid mode adds graph and issue-metadata ranking to either text backend, and the viewer identifies substring matching when active.
  • Interactive Graph: Visualize dependencies with D3.js force-graph, featuring zoom, pan, and node selection
  • Detail Pane: Click any node to see full issue details with dependency info
  • Comments: Issue discussion threads render in the detail view with author, timestamp, and markdown (#187)
  • Triage View: Same recommendations as --robot-triage
  • Offline Support: A service worker verifies and caches the complete exported bundle before activation. After that first online load, ordinary offline reloads preserve search, detail routes and graph access. A new export installs a separate cache before switching to its updated files and database.
  • Mobile Responsive: Adapts to phone/tablet screens with touch-friendly interactions

Technical Notes

The static export uses a hybrid architecture combining:

  1. Pure-Go SQLite (modernc.org/sqlite):

    • No C compiler requiredโ€”works on any system without CGO
    • Cross-platform bundle generation
    • FTS5 full-text search built-in
  2. Pre-computed Graph Layout:

    • BFS hierarchical layout with depth-based X positioning
    • Node positions stored as [x, y] pairs
    • Metrics stored as compact 5-element arrays: [pagerank, betweenness, inDegree, outDegree, inCycle]
    • ~91% size reduction vs. full graph JSON
  3. WASM Graph Engine (bv_graph.js):

    • Client-side cycle detection
    • Efficient neighbor lookups
    • Path finding for blocker chains

Deployment Options

PlatformCommandNotes
GitHub Pagesbv --pages (wizard)Pushes the bundle to main with a .github/workflows/static.yml Pages workflow; falls back to a gh-pages branch only if Actions looks rate-limited
Cloudflare Pagesbv --export-pages ./dist + CF dashboardConnect to git repo
Any Static Hostbv --export-pages ./distNetlify, Vercel, S3, etc.

๐Ÿšจ Alerts System: Proactive Health Monitoring

The Alerts System surfaces potential problems before they become blockers. It combines drift detection (changes from baseline) with proactive analysis (pattern-based warnings).

Alert Types

Alert types are the AlertType constants in pkg/drift/drift.go (AllAlertTypes() lists every one, and a test proves each has an emitter); thresholds are DefaultConfig() in pkg/drift/config.go, overridable per project in .bv/drift.yaml (keys below). Every alert carries a suggested_action, and issue-level alerts carry the issue's labels so --alert-label can filter on them.

Proactive checks (run on the current graph, no baseline needed):

TypeTriggerSeverity.bv/drift.yaml keys (default)
stale_issueNo activity for stale_warning_days (warning) or stale_critical_days (critical); thresholds are multiplied by in_progress_stale_multiplier for in_progress issues; label_overrides can tighten or loosen per labelWarning / Criticalstale_warning_days (14), stale_critical_days (30), in_progress_stale_multiplier (0.5)
blocking_cascadeActionable issue unblocks N+ othersInfo / Warningblocking_cascade_info_threshold (3), blocking_cascade_warning_threshold (5)
high_impact_unblockActionable issue unblocks N+ others of which at least one is P0/P1 (two or more urgent items escalate to warning)Info / Warninghigh_impact_unblock_min (3), high_impact_priority_max (1)
abandoned_claimAn in_progress issue with an assignee idle longer than stale_warning_days x in_progress_stale_multiplier x abandoned_claim_multiplier (14 days by default)Warningabandoned_claim_multiplier (2)
potential_duplicateTwo open issues whose title/description keyword Jaccard similarity reaches the threshold (same detector as --robot-suggest); closed issues are never pairedInfoduplicate_jaccard_threshold (0.7), duplicate_max_alerts (10)
priority_mismatch--robot-priority recommends a higher priority with confidence at or above the floor (downgrade suggestions stay in --robot-priority)Warningpriority_mismatch_min_confidence (0.6)
velocity_dropCloses in the last window fell by the percentage or more versus the previous window, which must contain at least the baseline count of closesWarningvelocity_drop_pct (50), velocity_window_days (7), velocity_min_baseline (5)

Drift checks (compare the current graph with the baseline saved by bv --save-baseline):

TypeTriggerSeverity.bv/drift.yaml keys (default)
new_cycleA cycle exists that the baseline did not haveCritical(always on unless disabled)
density_growthGraph density up by the info or warning percentageInfo / Warningdensity_info_pct (20), density_warning_pct (50)
node_count_changeNode count changed by the percentage or moreInfonode_growth_info_pct (25)
edge_count_changeEdge count changed by the percentage or moreInfoedge_growth_info_pct (25)
scope_creepOpen-issue count grew by the percentage or more since the baselineInfoscope_creep_pct (20)
blocked_increaseN or more additional blocked issuesWarningblocked_increase_threshold (5)
actionable_changeActionable count down by the warning percentage, or changed by the info percentageInfo / Warningactionable_decrease_warning_pct (30), actionable_increase_info_pct (20)
pagerank_changeA top-metric issue's PageRank moved by the percentage or moreWarningpagerank_change_warning_pct (50)

Any type can be switched off with disabled_alerts: [type, ...]. priority_mismatch and potential_duplicate re-run whole-graph analysis, so above proactive_max_issues (2000) they are skipped and listed in skipped_checks with the reason; set the key to 0 to remove the cap. --robot-alerts runs both groups (drift checks compare against the saved baseline when one exists, otherwise against the current graph and stay silent); --check-drift runs only the drift checks and exits 0 (no alerts or info only), 2 (warnings), or 1 (critical, or no baseline saved yet).

TUI Integration

Press ! to open the Alerts Panel:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿšจ ALERTS (3 active)                               [!] close โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  ๐Ÿ”ด CRITICAL: Issue bv-123 inactive for 45 days              โ”‚
โ”‚  โšก WARNING: Completing bv-456 unblocks 8 downstream item(s) โ”‚
โ”‚     Suggested: Prioritize this issue: closing it releases... โ”‚
โ”‚  โ„น๏ธ  INFO: Open issues grew 23% since the baseline (30 โ†’ 37) โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  j/k navigate โ€ข Enter jump to issue โ€ข d dismiss โ€ข q close   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Robot Integration

# Get all alerts as JSON
bv --robot-alerts

# Filter by severity (info, warning, critical)
bv --robot-alerts --severity=critical

# Filter by type
bv --robot-alerts --alert-type=blocking_cascade

# Filter by affected label
bv --robot-alerts --alert-label=backend

Output Schema

{
  "alerts": [
    {
      "type": "blocking_cascade",
      "severity": "critical",
      "issue_id": "bv-456",
      "message": "Blocks 8 downstream tasks",
      "blocked_ids": ["bv-101", "bv-102", "..."],
      "suggested_action": "Prioritize completion or break into smaller tasks"
    }
  ],
  "summary": {
    "total": 3,
    "critical": 1,
    "warning": 1,
    "info": 1
  }
}

๐Ÿค– Complete CLI Reference

Beyond the interactive TUI, bv provides a comprehensive command-line interface for scripting, automation, and AI agent integration.

Core Commands

bv                      # Launch interactive TUI
bv --help               # Show all options
bv --version            # Show version

Robot Protocol Commands

These commands output structured JSON designed for programmatic consumption:

CommandOutputUse Case
--robot-triageTHE MEGA-COMMAND: unified triage with all analysisSingle entry point for agents
--robot-nextSingle top recommendation + claim commandQuick "what's next?" answer
--robot-insightsGraph metrics + top N listsProject health assessment
--robot-planActionable tracks + dependenciesWork queue generation
--robot-priorityPriority recommendationsAutomated priority fixing
--robot-historyBead-to-commit correlationsCode change tracking
--robot-label-healthPer-label health metricsDomain health monitoring
--robot-label-flowCross-label dependency matrixInter-domain analysis
--robot-label-attentionAttention-ranked labelsDomain prioritization
--robot-sprint-listAll sprints as JSONSprint planning
--robot-burndownSprint burndown dataProgress tracking
--robot-suggestHygiene suggestions (deps/dupes/labels/cycles)Project cleanup automation
--robot-diffJSON diff (with --diff-since)Change tracking
--robot-recipesAvailable recipe listRecipe discovery
--robot-graphDependency graph as JSON/DOT/MermaidGraph visualization & export
--robot-forecastETA estimate per issue (heuristic duration / velocity)Rough completion timelines
--robot-capacitySerial + parallel-over-agents capacity estimateRough resource planning
--robot-alertsDrift + proactive warningsHealth monitoring
--robot-blocker-chain <id>Full blocker chain analysis for one issueExplaining why work is stuck
--robot-impact <paths>Impact of modifying the given comma-separated filesChange risk assessment
--robot-file-hotspotsFiles touched by the most beadsFinding churn hotspots
--robot-file-relations <path>Files that frequently co-change with the given fileRelated-code discovery
--robot-metricsIn-process counters from the real caches and timers: graph_cache (analysis in-memory + disk cache), correlation_cache (history report/artifact caches), search_cache (on-disk vector index), triage_cache; timings loader.parse, analysis.phase1, analysis.phase2; plus memory stats. Counts cover the current process only, so a bare --robot-metrics shows the load it just did; BV_METRICS=0 disables collectionDiagnosing slow runs
--robot-capabilitiesMachine-readable command capabilitiesAgent self-configuration
--robot-schemaJSON Schema definitions for all robot commandsOutput validation
--robot-docs <topic>Machine-readable JSON docs: guide, commands, examples, env, exit-codes, allAgent onboarding
--robot-helpDetailed AI agent documentationAgent onboarding

Issue-backed analysis commands support --as-of <ref> and include as_of and as_of_commit metadata. Commands such as capabilities, schemas, and recipes describe the current installation or configuration rather than a historical issue snapshot.

Output tuning flags that apply across robot commands:

bv --robot-triage --robot-max-results 10          # Limit robot output count (0 = use defaults)
bv --robot-priority --robot-min-confidence 0.6    # Filter robot outputs by minimum confidence (0.0-1.0)
bv --robot-next --robot-not-ready-labels needs-design,blocked-upstream
                                                  # Labels marking a bead not-ready: excluded from claimable
                                                  # --robot-next/--robot-triage top picks (env: BV_ROBOT_NOT_READY_LABELS)
bv --robot-insights --force-full-analysis         # Compute all metrics regardless of graph size (may be slow)
bv --robot-triage --no-cache                      # Bypass the disk cache for this run (also: BV_NO_CACHE=1)
bv --robot-triage --db /path/to/.beads            # Beads database file or .beads directory (overrides BEADS_DB and BEADS_DIR)
bv --robot-triage --format toon --stats           # Show JSON vs TOON token estimates on stderr (env: TOON_STATS=1)

Command-Line Flags

FlagTypeDefaultDescriptionGroup
--agents-addboolfalseAdd beads workflow instructions to AGENTS.md (creates file if needed)Agent File Management
--agents-checkboolfalseCheck AGENTS.md blurb status (default if no --agents-* action)Agent File Management
--agents-dry-runboolfalseShow what would happen without executing (use with --agents-*)Agent File Management
--agents-forceboolfalseSkip confirmation prompts (use with --agents-*)Agent File Management
--agents-removeboolfalseRemove beads workflow instructions from AGENTS.mdAgent File Management
--agents-updateboolfalseUpdate beads workflow instructions to latest versionAgent File Management
--agent-briefstring(empty)Export agent brief bundle to directory (includes triage.json, insights.json, brief.md, helpers.md)Export & Reporting
--debug-heightint50Height for debug renderExport & Reporting
--debug-renderstring(empty)Render a view and output to file (views: insights, board)Export & Reporting
--debug-widthint180Width for debug renderExport & Reporting
--emit-scriptboolfalseEmit shell script for top-N recommendations (agent workflows)Export & Reporting
--exportstring(empty)Export a report using recipe defaults or explicit export optionsExport & Reporting
--export-formatstring(empty)Report format: markdown, json, csv or mermaidExport & Reporting
--export-graphstring(empty)Export graph: .html for interactive, .png/.svg for static (auto-names if empty)Export & Reporting
--export-include-graphbooltrueInclude dependency context in the report (explicit false overrides recipe)Export & Reporting
--export-mdstring(empty)Export issues to a Markdown file (e.g., report.md)Export & Reporting
--export-pagesstring(empty)Export static site to directory (e.g., ./bv-pages)Export & Reporting
--export-templatestring(empty)Markdown template path; explicit empty disables a recipe templateExport & Reporting
--graph-presetstringcompactGraph layout preset: compact (default) or roomyExport & Reporting
--graph-titlestring(empty)Title for graph export (default: project name)Export & Reporting
--no-hooksboolfalseSkip running hooks during exportExport & Reporting
--no-live-reloadboolfalseDisable live-reload in preview modeExport & Reporting
--pagesboolfalseLaunch interactive Pages deployment wizardExport & Reporting
--pages-include-closedbooltrueInclude closed issues in export (default: true)Export & Reporting
--pages-include-historybooltrueInclude git history for time-travel (default: true)Export & Reporting
--pages-titlestring(empty)Custom title for static siteExport & Reporting
--preview-pagesstring(empty)Preview existing static site bundleExport & Reporting
--priority-briefstring(empty)Export priority brief to Markdown file (e.g., brief.md)Export & Reporting
--script-formatstringbashScript format: bash, fish, or zsh (use with --emit-script)Export & Reporting
--script-limitint5Limit number of items in emitted script (use with --emit-script)Export & Reporting
--watch-exportboolfalseWatch for beads changes and auto-regenerate export (use with --export-pages)Export & Reporting
--background-modeboolfalseEnable experimental background snapshot loading (TUI only)General Flags
--check-updateboolfalseCheck if a new version is availableGeneral Flags
--cpu-profilestring(empty)Write CPU profile to fileGeneral Flags
--dbstring(empty)Path to beads database file or .beads directory (overrides BEADS_DB and BEADS_DIR env vars)General Flags
--force-full-analysisboolfalseCompute all metrics regardless of graph size (may be slow for large graphs)General Flags
--formatstring(empty)Structured output format for --robot-* commands: json or toon (env: BV_OUTPUT_FORMAT, TOON_DEFAULT_FORMAT)General Flags
--no-background-modeboolfalseDisable experimental background snapshot loading (TUI only)General Flags
--no-cacheboolfalseBypass disk cache for robot triage (also: BV_NO_CACHE=1)General Flags
--profile-jsonboolfalseOutput profile in JSON format (use with --profile-startup)General Flags
--profile-startupboolfalseOutput detailed startup timing profile for diagnosticsGeneral Flags
--rollbackboolfalseRollback to the previous version (from backup)General Flags
--statsboolfalseShow JSON vs TOON token estimates on stderr (env: TOON_STATS=1)General Flags
--themestring(empty)Color theme: light, dark, or auto (default: detect terminal background)General Flags
--updateboolfalseUpdate bv to the latest versionGeneral Flags
--update-dry-runboolfalseShow what an update would do without installing (use via 'bv upgrade --dry-run')General Flags
--versionboolfalseShow versionGeneral Flags
--yesboolfalseSkip confirmation prompts (use with --update)General Flags
--as-ofstring(empty)View state at point in time (commit SHA, branch, tag, or date)History & Drift
--baseline-infoboolfalseShow information about the current baselineHistory & Drift
--bead-historystring(empty)Show history for specific bead IDHistory & Drift
--check-driftboolfalseCheck for drift from baseline (exit codes: 0=OK, 1=critical, 2=warning)History & Drift
--diff-sincestring(empty)Show changes since historical point (commit SHA, branch, tag, or date)History & Drift
--history-limitint500Max commits to analyze (0 = unlimited)History & Drift
--history-sincestring(empty)Limit history to commits after this date/ref (e.g., '30 days ago', '2024-01-01')History & Drift
--min-confidencefloat640Filter correlations by minimum confidence (0.0-1.0)History & Drift
--save-baselinestring(empty)Save current metrics as baseline with optional descriptionHistory & Drift
--feedback-acceptstring(empty)Record accept feedback for issue ID (tunes recommendation weights)Other
--feedback-ignorestring(empty)Record ignore feedback for issue ID (tunes recommendation weights)Other
--feedback-resetboolfalseReset all feedback data to defaultsOther
--feedback-showboolfalseShow current feedback status and weight adjustmentsOther
--generate-docsboolfalseGenerate documentation markdown and JSON artifactsOther
--id-patternstringArray[]Custom bead ID regex for commit-message matching, e.g. 'bh-[a-z0-9]{5}' (repeatable; capture group 1 is the ID, else the whole match) (#188)Other
--network-depthint2Depth of subnetwork when querying specific bead (1-3)Other
--agentsint1Number of parallel agents for capacity simulationRobot & Planning Flags
--attention-limitint5Limit number of labels in --robot-label-attention outputRobot & Planning Flags
--briefboolfalseCompact --robot-triage output: only decision-relevant fields (id, title, status, assignee, blockers, unblocks) (#183)Robot & Planning Flags
--capacity-labelstring(empty)Filter capacity simulation by labelRobot & Planning Flags
--correlation-bystring(empty)Agent/user identifier for correlation feedbackRobot & Planning Flags
--correlation-reasonstring(empty)Reason for correlation feedbackRobot & Planning Flags
--file-beads-limitint20Max closed beads to show (use with --robot-file-beads)Robot & Planning Flags
--forecast-agentsint1Number of parallel agents for capacity calculationRobot & Planning Flags
--forecast-labelstring(empty)Filter forecast by labelRobot & Planning Flags
--forecast-sprintstring(empty)Filter forecast by sprint IDRobot & Planning Flags
--graph-depthint0Max depth for subgraph (0 = unlimited)Robot & Planning Flags
--graph-formatstringjsonGraph output format: json, dot, mermaidRobot & Planning Flags
--graph-rootstring(empty)Subgraph from specific root issue IDRobot & Planning Flags
--hotspots-limitint10Max hotspots to show (use with --robot-file-hotspots)Robot & Planning Flags
--orphans-min-scoreint30Minimum suspicion score for orphan candidates (0-100)Robot & Planning Flags
--related-include-closedboolfalseInclude closed beads in related work resultsRobot & Planning Flags
--related-max-resultsint10Max results per category for related workRobot & Planning Flags
--related-min-relevancepercent_or_fraction20Minimum relevance score for related work (int 0-100 percent OR float 0.0-1.0 fraction)Robot & Planning Flags
--relations-limitint10Max related files to showRobot & Planning Flags
--relations-thresholdfloat640.5Minimum correlation threshold (0.0-1.0) for related filesRobot & Planning Flags
--robot-alertsboolfalseOutput alerts (drift + proactive) as JSON for AI agentsRobot & Planning Flags
--robot-blocker-chainstring(empty)Output full blocker chain analysis for issue ID as JSONRobot & Planning Flags
--robot-burndownstring(empty)Output burndown data for sprint ID, or 'current' for active sprintRobot & Planning Flags
--robot-capabilitiesboolfalseOutput machine-readable command capabilities for AI agentsRobot & Planning Flags
--robot-capacityboolfalseOutput capacity simulation and completion projection as JSONRobot & Planning Flags
--robot-causalitystring(empty)Output causal chain analysis for bead ID as JSONRobot & Planning Flags
--robot-confirm-correlationstring(empty)Confirm a correlation is correct (format: SHA:beadID)Robot & Planning Flags
--robot-correlation-statsboolfalseOutput correlation feedback statistics as JSONRobot & Planning Flags
--robot-diffboolfalseOutput diff as JSON (use with --diff-since)Robot & Planning Flags
--robot-docsstring(empty)Machine-readable JSON docs for AI agents. Topics: guide, commands, examples, env, exit-codes, allRobot & Planning Flags
--robot-driftboolfalseOutput drift check as JSON (use with --check-drift)Robot & Planning Flags
--robot-explain-correlationstring(empty)Explain why a commit is linked to a bead (format: SHA:beadID)Robot & Planning Flags
--robot-file-beadsstring(empty)Output beads that touched a file path as JSONRobot & Planning Flags
--robot-file-hotspotsboolfalseOutput files touched by most beads as JSONRobot & Planning Flags
--robot-file-relationsstring(empty)Output files that frequently co-change with the given file pathRobot & Planning Flags
--robot-forecaststring(empty)Output ETA forecast for bead ID, or 'all' for all open issuesRobot & Planning Flags
--robot-graphboolfalseOutput dependency graph as JSON/DOT/Mermaid for AI agentsRobot & Planning Flags
--robot-helpboolfalseShow AI agent helpRobot & Planning Flags
--robot-historyboolfalseOutput bead-to-commit correlations as JSONRobot & Planning Flags
--robot-history-timeout-msint-1Budget in ms for the git-history prologue of robot triage (0 = unbounded; default 10000, env BV_ROBOT_HISTORY_TIMEOUT_MS)Robot & Planning Flags
--robot-impactstring(empty)Analyze impact of modifying files (comma-separated paths)Robot & Planning Flags
--robot-impact-networkstring(empty)Output bead impact network as JSON (empty for full, or bead ID for subnetwork)Robot & Planning Flags
--robot-insightsboolfalseOutput graph analysis and insights as JSON for AI agentsRobot & Planning Flags
--robot-label-attentionboolfalseOutput attention-ranked labels as JSON for AI agentsRobot & Planning Flags
--robot-label-flowboolfalseOutput cross-label dependency flow as JSON for AI agentsRobot & Planning Flags
--robot-label-healthboolfalseOutput label health metrics as JSON for AI agentsRobot & Planning Flags
--robot-metricsboolfalseOutput performance metrics (timing, cache, memory) as JSONRobot & Planning Flags
--robot-nextboolfalseOutput only the top pick recommendation as JSON (minimal triage)Robot & Planning Flags
--robot-not-ready-labelsstring(empty)Comma-separated labels marking a bead not-ready: excluded from claimable --robot-next/--robot-triage top picks (env: BV_ROBOT_NOT_READY_LABELS; #173)Robot & Planning Flags
--robot-orphansboolfalseOutput orphan commit candidates (commits that should be linked but aren't) as JSONRobot & Planning Flags
--robot-planboolfalseOutput dependency-respecting execution plan as JSON for AI agentsRobot & Planning Flags
--robot-priorityboolfalseOutput priority recommendations as JSON for AI agentsRobot & Planning Flags
--robot-recipesboolfalseOutput available recipes as JSON for AI agentsRobot & Planning Flags
--robot-reject-correlationstring(empty)Reject an incorrect correlation (format: SHA:beadID)Robot & Planning Flags
--robot-relatedstring(empty)Output beads related to a specific bead ID as JSONRobot & Planning Flags
--robot-schemaboolfalseOutput JSON Schema definitions for all robot commandsRobot & Planning Flags
--robot-searchboolfalseOutput keyword or hybrid search results as JSON for AI agents (use with --search)Robot & Planning Flags
--robot-sprint-listboolfalseOutput sprints as JSONRobot & Planning Flags
--robot-sprint-showstring(empty)Output specific sprint details as JSONRobot & Planning Flags
--robot-suggestboolfalseOutput smart suggestions (duplicates, dependencies, labels, cycles) as JSONRobot & Planning Flags
--robot-triageboolfalseOutput unified triage as JSON (the mega-command for AI agents)Robot & Planning Flags
--robot-triage-by-labelboolfalseGroup triage recommendations by label (bv-87)Robot & Planning Flags
--robot-triage-by-trackboolfalseGroup triage recommendations by execution track (bv-87)Robot & Planning Flags
--schema-commandstring(empty)Output schema for specific command only (e.g., robot-triage)Robot & Planning Flags
--suggest-beadstring(empty)Filter suggestions for specific bead IDRobot & Planning Flags
--suggest-confidencefloat640Minimum confidence for suggestions (0.0-1.0)Robot & Planning Flags
--suggest-typestring(empty)Filter suggestions by type: duplicate, dependency, label, cycleRobot & Planning Flags
--alert-labelstring(empty)Filter robot alerts by label matchSearch & Filters
--alert-typestring(empty)Filter robot alerts by alert type (e.g., stale_issue)Search & Filters
--labelstring(empty)Scope analysis to label's subgraph (affects --robot-insights, --robot-plan, --robot-priority)Search & Filters
--recipestring(empty)Apply a recipe by name (e.g., triage, actionable, high-impact) or by .yaml/.yml file path (e.g., .beads/recipes/sprint.yaml)Search & Filters
--repostring(empty)Filter issues by repository prefix (e.g., 'api-' or 'api')Search & Filters
--robot-by-assigneestring(empty)Filter robot outputs by assignee (exact match)Search & Filters
--robot-by-labelstring(empty)Filter robot outputs by label (exact match)Search & Filters
--robot-max-resultsint0Limit robot output count (0 = use defaults)Search & Filters
--robot-min-confidencefloat640Filter robot outputs by minimum confidence (0.0-1.0)Search & Filters
--searchstring(empty)Hashed keyword search query (builds/updates index on first run)Search & Filters
--search-limitint10Max results for --search/--robot-searchSearch & Filters
--search-min-scorestring(empty)Minimum text similarity before hybrid ranking (-1..1); exact IDs also obey this thresholdSearch & Filters
--search-modestring(empty)Search ranking mode: text or hybrid (default: BV_SEARCH_MODE or text)Search & Filters
--search-presetstring(empty)Hybrid preset name (default: BV_SEARCH_PRESET or default)Search & Filters
--search-weightsstring(empty)Hybrid weights JSON (overrides preset; keys: text,pagerank,status,impact,priority,recency)Search & Filters
--severitystring(empty)Filter robot alerts by severity (infowarning
--workspacestring(empty)Load issues from workspace config file (.bv/workspace.yaml)Search & Filters

Time-Travel Commands

The --as-of flag loads issue state from a Git revision without modifying your working tree. It works with the interactive TUI and issue-backed robot analysis commands; the revision must contain a readable tracked Beads export.

# View historical state (TUI)
bv --as-of HEAD~10              # 10 commits ago
bv --as-of v1.0.0               # At release tag
bv --as-of 2024-01-15           # At specific date
bv --as-of main@{2024-01-15}    # Branch at date

# Historical analysis with robot commands
bv --robot-insights --as-of HEAD~30    # Graph metrics from 30 commits ago
bv --robot-plan --as-of v1.0.0         # Execution plan at release
bv --robot-triage --as-of 2024-06-01   # Full triage from specific date
bv --robot-priority --as-of HEAD~5     # Priority recs from 5 commits ago

# Compare changes
bv --diff-since HEAD~5          # Changes in last 5 commits
bv --diff-since v1.0.0          # Changes since release
bv --diff-since 2024-01-01      # Changes since date

# JSON diff output (combines --as-of for "to" snapshot)
bv --diff-since HEAD~10 --robot-diff                # From HEAD~10 to current
bv --diff-since HEAD~10 --as-of HEAD~5 --robot-diff # From HEAD~10 to HEAD~5

When using --as-of with robot commands, the JSON output includes additional metadata:

  • as_of: The ref you specified (e.g., "HEAD~30", "v1.0.0")
  • as_of_commit: The resolved commit SHA for reproducibility

Recipe Commands

# List available recipes
bv --robot-recipes

# Apply built-in recipes
bv --recipe actionable          # Ready to work
bv --recipe high-impact         # Top PageRank scores
bv --recipe stale               # Untouched 30+ days
bv --recipe blocked             # Waiting on dependencies
bv -r recent                    # Short flag, updated in 7 days

# Apply a project or user recipe by name (defined under `recipes:` in
# .bv/recipes.yaml or ~/.config/bv/recipes.yaml, or as .beads/recipes/<name>.yaml)
bv --recipe sprint-review

# Or load one recipe file directly by path (.yaml / .yml)
bv --recipe .beads/recipes/sprint.yaml --robot-triage

Export Commands

# Generate Markdown report with Mermaid diagrams
bv --export-md report.md

# Export priority brief (focused summary)
bv --priority-brief brief.md

# Export complete agent brief bundle
bv --agent-brief ./agent-bundle/
# Creates: triage.json, insights.json, brief.md, helpers.md

ETA Forecasting & Capacity Planning

These are heuristics, not a scheduler. For --robot-forecast, choose a base from a positive estimated_minutes, otherwise the median positive estimate in the loaded issues (default 60 minutes). Both explicit and inferred bases receive all multipliers: type (task/bug: 1, chore: 0.8, feature: 1.3, epic: 2), dependency depth (1 + min(1, depth/10)), and description length (1 + min(1, Unicode runes/2000)). The product is truncated to integer minutes. Depth uses the available critical-path score; unavailable scores contribute zero depth.

Velocity is estimated minutes closed in the last 30 days divided by 30, using the slowest nonzero matching-label velocity, then global velocity, then median/5 (with 60 min/day as a final fallback). ETA days = work minutes / (velocity ร— agents). Its confidence band is rule-based and has not been calibrated as a statistical probability. --robot-capacity sums serial work on the critical path with remaining parallel work divided by --agents; it does not assign issues to agents or account for their availability. Payloads expose the factors behind these estimates.

For a worked example, take two feature issues with depth 2 and descriptions of 1,000 Unicode characters. One has an explicit 120-minute estimate; the other has none. The only other positive estimate is a 240-minute issue closed within the last 30 days, so the median is 180 minutes and velocity is 8 min/day. With two agents, applying all multipliers gives:

Estimate sourceWork minutesETA days
explicit28017.5
median42126.3125
# Forecast completion ETA for a specific issue
bv --robot-forecast bv-123

# Forecast all open issues with filtering
bv --robot-forecast all --forecast-label=backend
bv --robot-forecast all --forecast-sprint=sprint-1
bv --robot-forecast all --forecast-agents=2     # Multi-agent parallelism

# Capacity simulation: when will everything be done?
bv --robot-capacity                              # Default: 1 agent
bv --robot-capacity --agents=3                   # 3 parallel agents
bv --robot-capacity --capacity-label=frontend    # Scoped to label

Alerts & Health Monitoring

# Get all alerts (drift warnings + proactive health checks)
bv --robot-alerts

# Filter by severity
bv --robot-alerts --severity=critical
bv --robot-alerts --severity=warning

# Filter by alert type
bv --robot-alerts --alert-type=stale_issue
bv --robot-alerts --alert-type=blocking_cascade

# Filter by label scope
bv --robot-alerts --alert-label=backend

Triage Grouping (Multi-Agent Coordination)

# Group recommendations by execution track (parallel work streams)
bv --robot-triage --robot-triage-by-track

# Group recommendations by label (domain-focused agents)
bv --robot-triage --robot-triage-by-label

Shell Script Emission

Generate executable shell scripts from recommendations for automated workflows:

# Emit bash script for top 5 recommendations
bv --robot-triage --emit-script --script-limit=5

# Different shell formats
bv --robot-triage --emit-script --script-format=fish
bv --robot-triage --emit-script --script-format=zsh

Feedback System (Adaptive Recommendations)

The feedback system learns from your accept/ignore decisions to tune recommendation weights:

# Record positive feedback (you worked on this recommendation)
bv --feedback-accept bv-123

# Record negative feedback (you skipped this recommendation)
bv --feedback-ignore bv-456

# View current feedback state and weight adjustments
bv --feedback-show

# Reset feedback to defaults
bv --feedback-reset

Baseline & Drift Detection

# Save current state as baseline
bv --save-baseline "Pre-release v2.0"

# Show baseline information
bv --baseline-info

# Check for drift from baseline
bv --check-drift                    # Exit codes: 0=OK, 1=critical, 2=warning
bv --check-drift --robot-drift      # JSON output
# Hashed keyword search over weighted issue text
bv --search "login oauth"

# JSON output for automation
bv --search "login oauth" --robot-search

# Hybrid search (text + graph metrics); a preset implies --search-mode hybrid
bv --search "login oauth" --search-preset impact-first
bv --search "login oauth" --search-limit 25          # Max results for --search/--robot-search (default 10)

# Hybrid with custom weights
bv --search "login oauth" --search-mode hybrid \
  --search-weights '{"text":0.4,"pagerank":0.2,"status":0.15,"impact":0.1,"priority":0.1,"recency":0.05}'

"Semantic" search builds a lightweight vector index from a weighted issue document (ID and title repeated, labels and description included). The vectors are hashed keyword features (FNV-1a feature hashing, pkg/search/hash_embedder.go), not a learned language model: two issues score as similar when they share words, not when they share meaning. That keeps the index dependency-free and instant to build, and it is the only embedder that ships; BV_SEMANTIC_EMBEDDER accepts hash only, and the python-sentence-transformers / openai provider names are reserved placeholders that fail with "not implemented".

Hybrid mode first retrieves candidates by hashed keyword similarity and literal prefix evidence, then re-ranks them using graph signals (PageRank, status, impact, priority, recency). It combines textual matches with project importance; learned embeddings and synonym understanding are not implemented.

Short, intent-heavy queries (e.g., โ€œbenchmarksโ€, โ€œoauthโ€) are treated differently on purpose. bv widens the candidate pool, boosts literal matches, and raises the text weight so quick lookups behave like a precise search. Longer, descriptive queries lean more on graph signals for smart tieโ€‘breaking and prioritization.

The CLI applies literal prefix evidence before selecting candidates, so a prefix match can enter the result set even when its raw hash similarity is zero. Scope and --search-min-score still apply first; the threshold uses raw text similarity. Exact issue-ID navigation retains priority within eligible results.

The frozen relevance corpus contains 40 agent-authored intents with graded rationales: six tuning examples and 34 evaluation queries. These are not human-reviewed judgments. At 10,000 administrative distractors, the 30 evaluation queries with positive judgments produced the following means (the four absent/empty queries are reported separately):

ConfigurationRecall@10nDCG@10
Text1.0000.950
Default hybrid1.0000.962
Bug hunting1.0000.942
Sprint planning0.9720.955
Impact first1.0000.954

The prefix wiring improved both evaluation prefix intents without changing any other query's returned IDs or scores in the 600-run comparison. Exact-ID cases ranked first in all 105 runs across both subsets. Sprint planning still omits some completed-issue context, and unmatched nonblank queries return nearest candidates rather than guaranteeing an empty result. Blank queries are rejected. Human usefulness and synonym understanding remain unproven. To retain all per-query results, corpus/configuration hashes, and broken-ranking controls:

BV_SEARCH_RELEVANCE_REPORT=/tmp/bv-relevance-new.json \
  go test ./tests/e2e -run '^(TestSearchRelevance.*|TestRobotSearchJudgedRelevance)$' -count=1 -v

The report path must be new; existing evidence is never overwritten. This is a retrieval-quality evaluation, separate from the performance benchmarks.

Hybrid defaults can be set via:

  • BV_SEARCH_MODE (text|hybrid)
  • BV_SEARCH_PRESET (default|bug-hunting|sprint-planning|impact-first|text-only)
  • BV_SEARCH_WEIGHTS (JSON string, overrides preset)

In --robot-search JSON, hybrid results include mode, preset, weights, plus per-result text_score and component_scores.

Hybrid Search Presets

PresetTextPageRankStatusImpactPriorityRecencyDescription
default0.400.200.150.100.100.05Balanced general-purpose search (text-led with graph context)
bug-hunting0.300.150.150.150.200.05Prioritizes open issues with high impact and recency
sprint-planning0.300.200.250.150.050.05Heavily weights PageRank and blocker impact for sprint grooming
impact-first0.250.300.100.200.100.05Centrality-first: PageRank and graph impact dominate text matches
text-only1.000.000.000.000.000.00Hashed keyword similarity with zero graph metric weighting

Example: AI Agent Workflow

#!/bin/bash
# agent-workflow.sh - Read-only task and action inspection

# 1. Get the execution plan
PLAN=$(bv --robot-plan)

# 2. Inspect the plan's highest-impact item (it may already be assigned/in progress)
TASK=$(echo "$PLAN" | jq -r '.plan.summary.highest_impact')

# 3. Get full insights for context
INSIGHTS=$(bv --robot-insights)

# 4. Inspect recorded changes since the prior commit (not a prediction)
BASELINE=$(bv --diff-since HEAD~1 --robot-diff)

echo "Working on: $TASK"
echo "Unblocks: $(echo "$PLAN" | jq '.plan.summary.unblocks_count') tasks"

# 5. Inspect a new-claim candidate and its actual origin-bound route
NEXT=$(bv --robot-next)
printf '%s\n' "$NEXT" | jq '{actionable, id, diagnostic_top_pick, actions}'
# No-action responses intentionally fail this check; do not invent a tracker command
printf '%s\n' "$NEXT" | jq -e '.actionable == true and .source_authority.claim_safe == true and (.actions.claim.argv | type == "array")'

Each typed action contains argv and working_directory. Inspect .actions.show against current tracker state before considering .actions.claim. Execute arrays directly in that directory, rather than splitting .shell text or replacing the local ID with a namespaced display ID. For example, a Python caller uses subprocess.run(action["argv"], cwd=action["working_directory"], check=True). The snippet above only inspects actions; it does not claim or close work.

Output Examples

--robot-priority Output:

{
  "generated_at": "2025-01-15T10:30:00Z",
  "recommendations": [
    {
      "issue_id": "CORE-123",
      "current_priority": 3,
      "suggested_priority": 1,
      "confidence": 0.87,
      "direction": "increase",
      "reasoning": "High PageRank (0.15) + High Betweenness (0.45) indicates foundational blocker"
    }
  ],
  "summary": {
    "total_issues": 58,
    "recommendations": 12,
    "high_confidence": 5
  }
}

--robot-recipes Output:

{
  "recipes": [
    { "name": "actionable", "description": "Ready to work (no blockers)", "source": "builtin" },
    { "name": "high-impact", "description": "Top PageRank scores", "source": "builtin" },
    { "name": "sprint-review", "description": "Current sprint issues", "source": "project" }
  ]
}

๐Ÿข Multi-Repository Workspace Support

For monorepo and multi-package architectures, bv provides workspace configuration that unifies issues across multiple repositories into a single coherent view.

Workspace Configuration (.bv/workspace.yaml)

Workspaces are auto-discovered: when the working directory has no .beads directory reachable (directly, via a git worktree's main checkout, or via BEADS_DIR / BEADS_DB), bv looks for .bv/workspace.yaml in that directory and each parent and loads the workspace for the TUI and every robot command. Pass --workspace <path/to/.bv/workspace.yaml> to force a specific workspace (for example from inside one of its repos, where the repo's own .beads would otherwise win). Robot payloads report source_kind: "workspace" with the config path as source_path.

# .bv/workspace.yaml - Multi-repo workspace definition
name: my-workspace

repos:
  - name: api
    path: services/api
    prefix: "api-"        # Issues become api-AUTH-123
    beads_path: .beads    # Optional per-repo override (defaults to .beads)

  - name: web
    path: apps/web
    prefix: "web-"        # Issues become web-UI-456

  - name: shared
    path: packages/shared
    prefix: "lib-"        # Issues become lib-UTIL-789

discovery:
  enabled: true
  patterns:
    - "*"                 # Direct children
    - "packages/*"        # npm/pnpm workspaces
    - "apps/*"            # Next.js/Turborepo
    - "services/*"        # Microservices
    - "libs/*"            # Library packages
  exclude:
    - node_modules
    - vendor
    - .git
  max_depth: 2

defaults:
  beads_path: .beads      # Where to find Beads JSONL in each repo

ID Namespacing

When working across repositories, issues are automatically namespaced:

Local IDRepo PrefixNamespaced ID
AUTH-123api-api-AUTH-123
UI-456web-web-UI-456
UTIL-789lib-lib-UTIL-789

Cross-Repository Dependencies

The workspace system enables cross-repo blocking relationships:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  web-UI-456 (apps/web)                                  โ”‚
โ”‚  "Implement OAuth login page"                           โ”‚
โ”‚                                                         โ”‚
โ”‚  blocks: api-AUTH-123, lib-UTIL-789                     โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜
         โ”‚                      โ”‚
         โ–ผ                      โ–ผ
โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”    โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚ api-AUTH-123    โ”‚    โ”‚ lib-UTIL-789    โ”‚
โ”‚ (services/api)  โ”‚    โ”‚ (packages/lib)  โ”‚
โ”‚ "Auth endpoint" โ”‚    โ”‚ "Token utils"   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜    โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Filtering Within a Workspace

Use --repo to scope the view (and robot outputs) to a specific repository prefix. Matching is case-insensitive and accepts common separators (-, :, _); it also honors the source_repo field when present.

Supported Monorepo Layouts

LayoutPatternExample Projects
npm/pnpm workspacespackages/*Lerna, Turborepo
Next.js appsapps/*Vercel monorepos
Microservicesservices/*Backend platforms
Go modulesmodules/*Multi-module Go
Flat*Simple monorepos

ID Resolution

The IDResolver handles cross-repo references intelligently:

resolver := NewIDResolver(config, "api")

// From api repo context:
resolver.Resolve("AUTH-123")      // โ†’ {Namespace: "", LocalID: "AUTH-123"} (no known prefix: a local ID)
resolver.Qualify("AUTH-123")      // โ†’ "api-AUTH-123" (adds the current repo's prefix)
resolver.Resolve("web-UI-456")    // โ†’ {Namespace: "web-", LocalID: "UI-456"}
resolver.IsCrossRepo("web-UI-456") // โ†’ true
resolver.DisplayID("api-AUTH-123") // โ†’ "AUTH-123" (local, strip prefix)
resolver.DisplayID("web-UI-456")   // โ†’ "web-UI-456" (cross-repo, keep prefix)

โฐ Interactive Time-Travel Mode

Beyond CLI diff commands, bv supports interactive time-travel within the TUI itself. This mode overlays diff badges on your issue list, letting you visually explore what changed.

Activating Time-Travel Mode

Press t in the main list view to enter time-travel mode with a custom revision prompt:

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  โฑ๏ธ  Time-Travel Mode                    โ”‚
โ”‚                                          โ”‚
โ”‚  Compare current state with a            โ”‚
โ”‚  historical revision                     โ”‚
โ”‚                                          โ”‚
โ”‚  โฑ๏ธ  Revision: HEAD~5โ–ˆ                   โ”‚
โ”‚                                          โ”‚
โ”‚  Examples: HEAD~5, main, v1.0.0,         โ”‚
โ”‚           2024-01-01, abc123             โ”‚
โ”‚                                          โ”‚
โ”‚  Press Enter to compare, Esc to cancel   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

For quick access, press T (uppercase) to instantly compare against HEAD~5 without the prompt.

Diff Badges

Once activated, issues display visual badges indicating their diff status:

BadgeMeaningColor
[NEW]Issue created since baselineGreen
[CLOSED]Issue closed since baselineGray
[MODIFIED]Issue fields changedYellow
[REOPENED]Issue reopened since baselineOrange

Visual Example

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚  ๐Ÿ“‹ ISSUES (since HEAD~5)                          58 total โ”‚
โ”œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”ค
โ”‚  [NEW]      โœจ FEAT-789  Add dark mode toggle      P2  ๐ŸŸข  โ”‚
โ”‚  [NEW]      ๐Ÿ› BUG-456   Fix login race condition  P1  ๐ŸŸข  โ”‚
โ”‚  [MODIFIED] ๐Ÿ“ TASK-123  Update documentation     P3  ๐ŸŸก  โ”‚
โ”‚             โœจ FEAT-100  OAuth integration        P1  ๐ŸŸข  โ”‚
โ”‚  [CLOSED]   ๐Ÿ› BUG-001   Memory leak in parser    P0  โšซ  โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

Time-Travel Summary Panel

The footer shows aggregate statistics:

โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€
๐Ÿ“Š Changes: +3 new  โœ“2 closed  ~1 modified  โ†บ0 reopened
Health: โ†‘ improving (density: -0.02, cycles: -1)
โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€

Time-Travel Navigation

KeyAction
tEnter time-travel (custom revision prompt)
TQuick time-travel (HEAD~5)
t (while in time-travel)Exit time-travel mode
n / N (while in time-travel)Jump to the next / previous changed issue in list order

๐Ÿงช Quality Assurance & Robustness

Trust is earned. bv employs a rigorous testing strategy to ensure it can handle the messy reality of real-world repositories.

1. Synthetic Data Fuzzing

We don't just test on "happy path" data. The test suite (pkg/loader/synthetic_test.go) generates Synthetic Complex Graphsโ€”large JSONL files with thousands of nodes, intricate dependency cycles, and edge-case UTF-8 charactersโ€”to verify that the graph engine and rendering logic never panic under load.

2. Robustness Against Corruption

In a git-based workflow, merge conflicts and partial writes happen. The TestLoadIssuesRobustness suite explicitly injects garbage lines and corrupted JSON into the data stream.

  • Result: bv detects corruption, logs a warning to stderr, and continues loading the valid data. It never crashes the user session due to a single bad line.

Contributing Tests

For contributors writing tests, see the comprehensive Testing Guide which covers:

  • Test philosophy (no mocks, table-driven tests, golden files)
  • Using the testutil package for fixture generation
  • Running tests, coverage, and benchmarks
  • E2E test patterns and CI integration

๐Ÿ”„ The Zero-Friction Update Engine

bv includes a proactive, non-intrusive update check to ensure you never miss a feature. We believe tools should maintain themselves without interrupting your flow.

Design & Implementation

The updater (pkg/updater/updater.go) is architected for silence and safety:

  1. Non-Blocking Concurrency: The TUI runs the check as a background command with a strict 10-second timeout. It never delays startup or UI input handling.
  2. Semantic Versioning: It doesn't just match strings. A validated SemVer comparator only accepts strictly newer stable releases, handles prerelease precedence correctly, and ignores build metadata when determining precedence.
  3. Installability Before Notification: A newer tag is not enough. The release must have an uploaded asset for the current OS/architecture, bounded non-zero sizes, HTTPS URLs bound to this repository/tag, and valid GitHub SHA-256 digests. The check also downloads and authenticates the small checksum manifest, then requires its platform entry to agree with the asset digest before bv advertises the update.
  4. Fail-Closed Integrity: Installation verifies the checksum manifest against GitHub's digest, requires the selected archive to agree with both checksum sources, and confirms the downloaded binary reports the expected version before replacing the current executable.
  5. Quiet Background Failure, Honest Explicit Checks: TUI startup silently ignores network partitions, rate limits, and timeouts. Explicit bv --check-update calls surface those failures instead of claiming the installed version is current when GitHub was never checked successfully.
  6. Unobtrusive Notification: When an update is found, bv doesn't pop a modal. It simply renders a subtle Update Available indicator (โญ) in the footer, letting you choose when to upgrade.

Self-update commands (bv upgrade is an alias for the flags):

bv --check-update        # Check if a new version is available
bv --update              # Update bv to the latest version
bv --update --yes        # Skip confirmation prompts (use with --update)
bv --update-dry-run      # Show what an update would do without installing (bv upgrade --dry-run)
bv --rollback            # Rollback to the previous version (from backup)

The startup check is opt-out: set BV_NO_UPDATE_CHECK=1 or put updates: {check: false} in ~/.config/bv/config.yaml to skip it (explicit --check-update / --update still work). The check never sends an ambient GitHub token unless BV_UPDATE_USE_TOKEN=1 or updates: {use_token: true} is set, and the first time it runs the TUI footer discloses once that github.com was contacted.


๐Ÿ—‚๏ธ Data Loading & Self-Healing

Reliability is key. bv doesn't assume a perfect environment; it actively handles common file system inconsistencies.

1. Intelligent Path Discovery

The loader (pkg/loader/loader.go, internal/datasource) doesn't blindly open one hard-coded JSONL path:

  1. Explicit override: --db <file-or-dir>, then BEADS_DB, then BEADS_DIR bypass discovery entirely. --db accepts a database file or a .beads directory.
  2. Redirect: If .beads/redirect exists, its target directory is followed (up to 10 hops, loops and missing targets are errors) so bv reads the same store br where reports.
  3. Allowlist: Only three file names are ever considered: issues.jsonl (preferred), beads.jsonl (legacy), and beads.base.jsonl (loader.PreferredJSONLNames). Sidecars that sit beside them (sync_base.jsonl, sprints.jsonl, correlation_feedback.jsonl, deletions.jsonl, backups, merge artifacts) never load as issues.
  4. Freshness gate: Robot loads pick the most recently modified candidate and fall through to the next name when a file fails the malformed-line rate check; the TUI loader takes the first non-empty name in preference order.

2. Robust Parsing

The JSONL parser is designed to be Lossy-Tolerant.

  • It reads with a bufio.Reader (ReadLine, so CRLF is tolerated) and a 10 MB per-line cap by default. BV_MAX_LINE_SIZE_MB raises the cap for both the TUI and robot loads; oversized lines are skipped with a warning.
  • Malformed lines (e.g., from a merge conflict) are skipped with a warning rather than crashing the application, ensuring you can still view the readable parts of your project even during a bad git merge.

๐Ÿงฉ Design Philosophy: Why Graphs?

Traditional issue trackers (Jira, GitHub Issues, Trello) model work as Buckets: "To Do", "In Progress", "Done". This is fine for simple task lists, but it fails at scale because it ignores Structure.

In complex software projects, tasks are not isolated. They are deeply interconnected. A "simple" frontend task might depend on a backend endpoint, which depends on a schema change, which depends on a migration script.

bv adopts a Graph-First philosophy:

  1. Structure is Reality: The dependency graph is the project. The list view is just a projection of that graph.
  2. Explicit Blocking: We don't just "relate" tasks; we define strict "blocks". If A blocks B, you literally cannot mark B as "Ready" in bv until A is Closed.
  3. Local-First, Text-Based: Your project data lives in your repo (.beads/issues.jsonl, or legacy .beads/beads.jsonl), not on a remote server. It travels with your code, branches with your git, and merges with your PRs.

โšก Performance Specs

bv is engineered for speed. We believe that latency is the enemy of flow.

  • Startup Time: about 20 ms of graph analysis (bv --profile-startup) for this repository's 611 issues. Wall time per robot command on the shared reference VM (AMD EPYC-Milan, Go 1.25) is 40-50 ms for bv --version, roughly 180-250 ms for --robot-next, --robot-triage, and --robot-insights with warm caches, and 500-700 ms for a first cold run; the per-command numbers are recorded by scripts/robot_smoke.sh in tests/artifacts/perf/robot_wall.json (single cold run per command). Engine benchmarks (BenchmarkRealData_*: full triage 1.2 ms, graph build 0.7 ms, exact full analysis 43 ms) are in tests/artifacts/perf/analysis_bench.md, and dashboard bundle sizes in tests/artifacts/perf/pages_load.json. All of these are point measurements on a shared machine. Regressions are caught by release-gate stage 8: scripts/benchmark.sh compare runs ten tracked benchmarks against the frozen tests/testdata/benchmark/medium.jsonl dataset and fails when any benchmark's best observed ns/op is more than 20% above a fresh, interleaved run of the baseline commit on the same machine (benchmarks/baseline.txt records that commit, the machine, Go version, and dataset hash, and is the fallback when the commit is not in the clone).
  • Rendering: Bubble Tea drives the UI. The 16.67 ms frame target and the reference-host 50 ms p99 interaction SLO are distinct. The September 5 source verification passed all 144 current-code UI cohorts, with a worst cohort p99 of 30.9 ms; the performance guide records the source, workloads and limits. Update + View measurements cover event handling and string rendering; they do not measure physical terminal paint.
  • Virtualization: List and Markdown views render visible windows. Frozen 1k/5k/10k workloads exercise navigation, Unicode text, dense/cyclic dependencies, and concurrent snapshot refresh. This is test coverage, not a guarantee of lag-free operation or bounded RAM on every host; inspect the retained distributions and metric states described in the performance guide.
  • Graph Compute: A two-phase analyzer computes topo/degree/density instantly, then PageRank/Betweenness/HITS/Critical Path/Cycles asynchronously with size-aware timeouts.
  • Caching: Repeated analyses reuse hashed results automatically, avoiding recomputation when the bead graph hasnโ€™t changed.

Cache

Robot commands (BV_ROBOT=1, which every --robot-* flag sets) keep a disk cache of analysis results in <user cache dir>/bv/analysis_cache/ (os.UserCacheDir(), so ~/.cache/bv on Linux and ~/Library/Caches/bv on macOS). Correlation caches share the same base directory. Entries are keyed by the data hash and analysis config, invalidated when the .beads directory is newer than the entry, and expire after 24 hours. --no-cache or BV_NO_CACHE=1 bypasses the cache for one run; BV_CACHE_DIR relocates it.

Performance Benchmarking

bv includes engine microbenchmarks and a separate latency harness. The release gate's best observed ns/op comparison does not establish p95/p99 interaction latency:

# Run all benchmarks
./scripts/benchmark.sh

# Save current performance as baseline
./scripts/benchmark.sh baseline

# Compare against baseline (requires benchstat)
./scripts/benchmark.sh compare

# Quick benchmarks (CI mode)
./scripts/benchmark.sh quick

Benchmark Categories:

  • Full Analysis: End-to-end Analyze() pipeline at various scales
  • Individual Algorithms: PageRank, Betweenness, HITS, TopoSort isolation
  • Pathological Graphs: Stress tests for timeout protection (many cycles, complete graphs)
  • Timeout Verification: Ensures large graphs don't hang

Timeout Protection: All expensive algorithms (Betweenness, PageRank, HITS, Cycle detection) have per-metric timeouts chosen by graph size (2 s under 100 nodes, 500 ms under 500, 300 ms under 2,000, 200 ms above; see ConfigForSize in pkg/analysis/config.go) to prevent blocking on large or pathological graphs.

Detailed Tuning Guide: For comprehensive performance documentation including troubleshooting, size-based algorithm selection, and tuning options, see docs/performance.md.

Graph Engine Optimization

The analysis engine uses a compact adjacency-list graph (compactDirectedGraph) instead of the standard Gonum map-backed implementation. The table below is the historical before/after from the January 2026 optimization round (696 issues, one developer machine); it is not regenerated by CI. Current numbers come from benchmarks/current.txt (AMD Ryzen Threadripper PRO 5975WX) and go test -bench=BenchmarkRealData ./pkg/analysis/..., where BenchmarkRealData_FullAnalysis uses the exact-betweenness FullAnalysisConfig and measures in the tens of milliseconds:

Benchmark (696 issues, Jan 2026)BeforeAfterImprovement
Full Triage67ms1.3ms52ร— faster
Graph Build1.2ms323ฮผs3.7ร— faster
Memory (Graph Build)735KB444KB40% less
Allocations4,6472,51246% fewer

Why it matters: The default Gonum DirectedGraph uses map-backed edge sets, which cause heavy allocations during graph construction. Our compact implementation:

  • Pre-allocates node arrays at known size
  • Uses []int64 adjacency lists instead of map[int64]set
  • Eliminates map grow/rehash overhead entirely

Tracked dataset benchmarks: go test -bench=BenchmarkRealData ./pkg/analysis/... uses the committed 1,000-issue synthetic tests/testdata/benchmark/medium.jsonl through the production loader. The historical benchmark name does not mean it measures the caller's current project data.


โ“ Troubleshooting & FAQ

Q: My icons look weird / text is misaligned.

  • bv requires a terminal with TrueColor support and a Nerd Font installed.
  • Recommended: Nerd Fonts (e.g., "JetBrains Mono Nerd Font" or "Hack Nerd Font").
  • Terminals: Windows Terminal, iTerm2, Alacritty, Kitty, WezTerm.

Q: Live reload isnโ€™t updating (especially on NFS/SMB/SSHFS/FUSE).

  • Some filesystems donโ€™t reliably deliver filesystem events. bv will try to auto-detect this and switch to polling.
  • If it still misbehaves, force polling:
    BV_FORCE_POLLING=1 bv
    # or
    BV_FORCE_POLL=1 bv
    

Q: I see polling โ€ฆ in the footer. Is that bad? No โ€” it just means bv is using polling instead of filesystem events for live reload (common on remote filesystems). Polling can add a small delay before updates appear.

Q: I see โš  STALE / โœ— bg โ€ฆ / โš  worker unresponsive / โ†ป recovered in the footer. These indicators mean the background worker hasnโ€™t produced a fresh snapshot recently (or needed to self-heal). Try Ctrl+R/F5, check filesystem permissions/health, or temporarily disable background mode (BV_BACKGROUND_MODE=0) to fall back to synchronous reload.

Q: I see "Cycles Detected" in the dashboard. What now? A: A cycle (e.g., A โ†’ B โ†’ A) means your project logic is broken; no task can be finished first. Use the Insights Dashboard (i) to find the specific cycle members, then use br to remove one of the dependency links (e.g., br unblock A --from B).

Q: Does this work with Jira/GitHub? A: bv is data-agnostic. The Beads data schema supports an external_ref field. If you populate your Beads JSONL export with issues from external trackers (e.g., using a custom script or sync tool), bv will render them alongside your local tasks. Future versions of the br CLI may support native syncing, but bv is ready for that data today.

Q: What's the difference between "bead" and "issue"? A: They're the same thing! In the Beads ecosystem, the unit of work is called a "bead" (hence the name). However, bv uses "issue" in many places since that's the more familiar term for most developers. The CLI flags use both interchangeably: --robot-file-beads, --pages-include-closed (issues), etc. Think of "bead" as the Beads-specific term and "issue" as the general concept.


๐Ÿ“ฆ Installation

One-Line Install (Linux/macOS)

The fastest way to get started. Detects your OS and architecture automatically.

Prefer Homebrew, Scoop, or a checksum-verified release archive above. If you do pipe the script, pin it to a commit you have read instead of the moving main branch:

# Pinned to a reviewed commit; read it first: https://github.com/Dicklesworthstone/beads_viewer/blob/03f92509bceb9da31540167c223c10f16c279767/install.sh
curl -fsSL "https://raw.githubusercontent.com/Dicklesworthstone/beads_viewer/03f92509bceb9da31540167c223c10f16c279767/install.sh" | bash

Warning: curl ... | bash runs whatever the URL serves at that moment. The pinned form above cannot change under you; the main form can. install.sh downloads the release archive for your platform, verifies it against the release checksums.txt, and refuses to install on a mismatch.

One-Line Install (Windows)

For Windows users using PowerShell:

# Pinned to a reviewed commit; read it first: https://github.com/Dicklesworthstone/beads_viewer/blob/3ca2176f11cc6106be452815e03fc4164b581761/install.ps1
irm "https://raw.githubusercontent.com/Dicklesworthstone/beads_viewer/3ca2176f11cc6106be452815e03fc4164b581761/install.ps1" | iex

Requirements:

Build from Source

Requires Go 1.25+ (see go.mod).

git clone https://github.com/Dicklesworthstone/beads_viewer.git
cd beads_viewer
go install ./cmd/bv

Nix Flake

For Nix users, bv provides a flake for reproducible builds and development environments.

# Run directly
NIXPKGS_ALLOW_UNFREE=1 nix run --impure github:Dicklesworthstone/beads_viewer

# Install to profile
NIXPKGS_ALLOW_UNFREE=1 nix profile install --impure github:Dicklesworthstone/beads_viewer

# Development shell with Go toolchain
NIXPKGS_ALLOW_UNFREE=1 nix develop --impure github:Dicklesworthstone/beads_viewer

The explicit unfree allowance is required because Nix correctly treats the OpenAI/Anthropic rider as nonfree. When adding bv as a flake input, configure the consuming nixpkgs import with allowUnfree = true or a narrow allowUnfreePredicate for bv.

Or add to your flake inputs:

{
  inputs.bv.url = "github:Dicklesworthstone/beads_viewer";
  # Use: bv.packages.${system}.default
}

๐Ÿš€ Usage Guide

Navigate to any project initialized with br init and run:

bv

๐ŸŽ“ Getting Help

bv has a comprehensive built-in help system:

Quick Reference (?) - Press anywhere to see keyboard shortcuts for your current view. From here, press Space to jump directly to the full tutorial.

Interactive Tutorial (` backtick) - A multi-page walkthrough covering all features:

  • Concepts: beads, dependencies, labels, priorities
  • Views: list, board, graph, tree, insights, history
  • Workflows: AI agent integration, triage, planning
  • 30 pages in 6 sections; progress is saved between sessions and the tutorial resumes where you left off

Keyboard Control Map

ContextKeyAction
alljMove down
kMove up
GGo to end
listhomeGo to start
board,treeggGo to start
allctrl+dPage down
ctrl+uPage up
enterOpen details
escBack/close (list: clear filters)
qQuit
list,detailaActionable view
bBoard view
gGraph view
hHistory view
iInsights panel
ETree view (parent-child hierarchy)
fFlow matrix (cross-label dependencies)
PSprint dashboard
[Label dashboard
]Attention view
list!Alerts panel
wRepo picker (workspace mode)
all?Help overlay
;Shortcuts sidebar
list,detailpPriority hints
listoOpen issues only
cClosed issues only
rReady (unblocked)
lLabel picker
/Search/filter
sCycle sort mode
SSort by triage score (triage recipe)
list,detailtTime travel (custom revision)
TTime travel (HEAD~5)
listnNext changed issue (time travel)
NPrevious changed issue (time travel)
list,detailxExport to markdown
allyCopy issue ID
detailCCopy full issue
OOpen in
list'Recipe picker
allUSelf-update check
listVCass sessions
graphhjklNavigate graph
HScroll left
LScroll right
J/KScroll graph vertically
spaceExpand/collapse dependency paths
PgUpPrevious 10 nodes
PgDnNext 10 nodes
boardhPrevious column
lNext column
HFirst column
LLast column
sCycle swimlane mode
tabToggle detail
treeEExit tree view
boardctrl+jScroll detail down
ctrl+kScroll detail up
insightshPrevious panel
lNext panel
tabNext panel
shift+tabPrevious panel
eToggle explanations
xCalculation proof
mHeatmap toggle
historyvToggle git/bead mode
tabToggle focus
tToggle timeline pane
fToggle file tree
JDetail scroll down
KDetail scroll up
oOpen in browser
attentiongGo to top
enterLabel drilldown
1-9Filter list by rank
]Close attention view
sprintPClose sprint dashboard
jNext sprint
kPrevious sprint

๐Ÿ› ๏ธ Configuration

bv automatically detects your terminal capabilities to render the best possible UI. It looks for .beads/issues.jsonl, .beads/beads.jsonl, or .beads/beads.base.jsonl in your current directory.

Environment Variables

VariableDescriptionDefault
BEADS_DBPath to a beads database file or .beads directory. Overrides BEADS_DIR; overridden by --db.(unset)
BEADS_DIRCustom beads directory path. When set, overrides the default .beads directory lookup..beads in cwd
BV_BACKGROUND_MODEStartup default for the background snapshot worker (1 on, 0 off). At runtime the TUI promotes itself to the worker after any synchronous reload that takes 1 s or longer; 0 pins synchronous reload and disables that promotion.sync at startup, auto-promote after a slow reload
BV_BUILD_HYBRID_WASMSet to 1 to build the hybrid search WASM scorer during --export-pages (requires wasm-pack).(skip)
BV_CACHE_DIRBase directory for the disk caches (analysis_cache/ and correlation caches live under it).<user cache dir>/bv
BV_DEBOUNCE_MSDebounce window (milliseconds) for live reload events in background mode.200
BV_DEBUGAny value: write [BV_DEBUG] diagnostics to stderr.(off)
BV_FORCE_POLLAlias for BV_FORCE_POLLING.(auto)
BV_FORCE_POLLINGForce polling-based live reload (useful on NFS/SMB/SSHFS/FUSE or any setup where filesystem events are unreliable) (1/0).(auto)
BV_FRESHNESS_STALE_SSnapshot staleness critical threshold (seconds).120
BV_FRESHNESS_WARN_SSnapshot staleness warning threshold (seconds).30
BV_HEARTBEAT_INTERVAL_SBackground worker heartbeat interval (seconds).5
BV_INSIGHTS_MAP_LIMITCap on the number of entries in each --robot-insights metric map.(all)
BV_MAX_LINE_SIZE_MBMax JSONL line size in MB (lines larger than this are skipped with a warning). Applies to the TUI, the background worker, and robot loads.10
BV_METRICSSet to 0 to disable internal timing metrics collection (--robot-metrics).(enabled)
BV_NO_BROWSERAny value: never open a browser after exports or deployments.(unset)
BV_NO_CACHESet to 1 to bypass the robot analysis and correlation disk caches (--no-cache sets it).(cache on)
BV_NO_GITIGNOREDisable automatic ignore-file management for .bv/ entirely (any non-empty value). See Automatic .bv/ ignore handling.(enabled)
BV_NO_SAVED_CONFIGAny value: the --pages wizard ignores the saved deployment configuration.(unset)
BV_NO_UPDATE_CHECKSet to 1 to skip the TUI's startup release check (updates: {check: false} in ~/.config/bv/config.yaml does the same); explicit --check-update / --update still work.(check on)
BV_OUTPUT_FORMATDefault robot output format: json or toon (overridden by --format).json
BV_PHASE2_TIMEOUT_SOverride per-metric Phase 2 timeouts (seconds).(size-based)
BV_PRETTY_JSONSet to 1 for indented JSON output.(compact)
BV_ROBOTSet to 1 to force robot mode (clean stdout, JSON logs, disk cache on). Every --robot-* flag sets it.(unset)
BV_ROBOT_HISTORY_TIMEOUT_MSBound on the git-history prologue of --robot-triage in milliseconds; 0 = unbounded.10000
BV_ROBOT_NOT_READY_LABELSComma-separated labels marking a bead not-ready; excluded from claimable --robot-next/--robot-triage top picks (--robot-not-ready-labels overrides).(none)
BV_SEARCH_MODEDefault search mode: text or hybrid (--search-mode overrides).text
BV_SEARCH_PRESETDefault hybrid preset: default, bug-hunting, sprint-planning, impact-first, text-only; setting one implies hybrid mode.default
BV_SEARCH_WEIGHTSJSON weight map for hybrid search; overrides the preset.(preset)
BV_SEMANTIC_DIMEmbedding dimension for the hashed search index.384
BV_SEMANTIC_EMBEDDEREmbedding provider for bv --search and TUI search. Only hash (FNV-1a keyword feature hashing) is implemented; python-sentence-transformers and openai are reserved names that fail with "not implemented".hash
BV_SEMANTIC_MODELModel name for a future non-hash provider; ignored by hash.(empty)
BV_SKIP_PHASE2Skip Phase 2 graph metrics (centrality, cycles, critical path) (1/0).(disabled)
BV_TEST_MODEAny value: test harness mode; suppresses browser opening, terminal capability queries, and the background worker's idle GC tuning.(unset)
BV_THEMEPin the TUI palette: light or dark (overridden by --theme).(auto-detect)
BV_TUI_AUTOCLOSE_MSQuit the TUI automatically after this many milliseconds (for automated tests).(unset)
BV_UPDATE_USE_TOKENSet to 1 to let the update check and --update send the ambient GITHUB_TOKEN / GH_TOKEN to api.github.com (updates: {use_token: true} in config.yaml does the same).(never sent)
BV_WATCHDOG_INTERVAL_SBackground worker watchdog interval (seconds).10
BV_WORKER_LOG_LEVELLog level for the background snapshot worker.(default)
BV_WORKER_METRICSTruthy value: the background worker records its own metrics.(off)
BV_WORKER_TRACEPath to a trace file the background worker appends to.(off)

Use cases for BEADS_DIR:

  • Monorepos: Single beads directory shared across multiple packages
  • Non-standard layouts: Projects where .beads isn't in the working directory
  • Testing: Point to test fixtures without changing directory
  • Cross-directory access: View beads from anywhere on the filesystem
# Example: Point to a different beads directory
BEADS_DIR=/path/to/shared/beads bv

# Example: Use in monorepo
export BEADS_DIR=$(git rev-parse --show-toplevel)/.beads

Automatic .bv/ ignore handling

bv keeps its local artifacts (semantic search index, baselines, drift config โ€” all under .bv/) out of your git history automatically, without littering committed files:

  1. Opt-out first: if BV_NO_GITIGNORE is set (any non-empty value), bv never touches any ignore file.
  2. Not a git repo? If there is no .git in the project root, nothing is written.
  3. Already ignored? If .bv is already covered by the repo's .gitignore, by .git/info/exclude, or by your global gitignore (core.excludesFile, or the $XDG_CONFIG_HOME/git/ignore default), bv leaves everything alone.
  4. Otherwise: bv appends .bv/ to .git/info/exclude โ€” the per-repo exclude file that is invisible to collaborators, shared across linked worktrees (worktree .git pointer files are resolved to the common git dir), and never needs a commit. Only if that file is unusable does bv fall back to appending to .gitignore.

Everything is pure file I/O โ€” no git subprocess is spawned, and git does not need to be installed. bv never deletes or rewrites existing ignore entries; if an earlier version added .bv/ to your .gitignore, that line is respected (and you are free to remove it โ€” bv will switch to .git/info/exclude on the next run).

Experimental: Background Mode (Live Reload)

The TUI can run live reload using an experimental background snapshot worker (moves file I/O + analysis off the UI thread).

Startup default: synchronous reload. Runtime promotion: whenever a synchronous reload takes 1 s or longer, the TUI starts the background worker on its own and reports background mode auto-enabled in the status bar (pkg/ui/model.go). Setting BV_BACKGROUND_MODE=0 pins synchronous reload and disables that promotion.

Enable at startup:

BV_BACKGROUND_MODE=1 bv
bv --background-mode

Disable / pin synchronous reload:

BV_BACKGROUND_MODE=0 bv
bv --no-background-mode

User config file (when neither CLI flags nor BV_BACKGROUND_MODE are set):

# ~/.config/bv/config.yaml
experimental:
  background_mode: true

Precedence: CLI flags โ†’ BV_BACKGROUND_MODE โ†’ ~/.config/bv/config.yaml.

Migration plan (high level):

  • Phase A (now): sync remains the startup default; background mode is enabled explicitly or auto-promoted after a slow reload.
  • Phase B: broaden rollout; keep explicit rollback (--no-background-mode / BV_BACKGROUND_MODE=0).
  • Phase C: flip default when stable; keep sync as fallback for a period.
  • Phase D: remove legacy sync reload path after deprecation window.

Monitoring plan: no automatic telemetry today; rely on CI + regression tests and user reports during Phase A/B.

Status Indicators (Background Mode + Live Reload)

When background mode or live reload is enabled, the footer may display these indicators:

  • โ—Œ metricsโ€ฆ โ€” Phase 2 metrics are still computing; the UI renders immediately with Phase 1 data.
  • โš  45s ago โ€” snapshot age warning (data is getting stale).
  • โš  STALE: 3m ago โ€” snapshot is stale.
  • โœ— bg <phase> (3x) โ€” background worker hit repeated errors building snapshots (phase shown; retry count in parentheses).
  • โ†ป recovered xN โ€” watchdog recovered the background worker N times (transient failures/self-healing).
  • โš  worker unresponsive โ€” watchdog detected the worker is stuck and is recovering.
  • polling โ€ฆ โ€” live reload is using polling instead of filesystem events (common on remote filesystems); changes may appear with a small delay.

Tip: Ctrl+R (or F5) forces a refresh.

Visual Theme

The UI uses a visually distinct, high-contrast theme inspired by Dracula Principles to ensure readability.

  • Primary: #BD93F9 (Purple)
  • Status Open: #50FA7B (Green)
  • Status Blocked: #FF5555 (Red)

Light terminals (--theme)

Every color ships as an adaptive light/dark pair (WCAG-AA tuned for each background), and bv normally picks the right variant by auto-detecting the terminal background. That detection can fail โ€” over SSH, inside tmux/screen, or in emulators that don't answer the background query โ€” in which case bv assumes a dark background, which makes text nearly unreadable on a light terminal. When that happens, pin the theme explicitly:

bv --theme light   # force the light palette (dark text)
bv --theme dark    # force the dark palette (light text)
bv --theme auto    # auto-detect (the default)

To make the choice persistent, set the BV_THEME environment variable (light | dark) in your shell profile, or add a top-level key to ~/.config/bv/config.yaml:

theme: light   # light | dark | auto

Precedence: --theme โ†’ BV_THEME โ†’ config file โ†’ auto-detect.


๐Ÿ“„ License

MIT License (with OpenAI/Anthropic Rider). See LICENSE.

Copyright (c) 2026 Jeffrey Emanuel


๐Ÿค– Why Robots Love bv

  • Deterministic JSON contracts: robot commands emit stable field names, stable ordering (ties broken by ID), and include data_hash, analysis_config, and generated_at so multiple calls can be correlated safely.
  • Health flags: every expensive metric reports status (computed, timeout, skipped) plus elapsed ms; sampled betweenness stays computed with reason: "approximate" and the sample size used.
  • Consistent analysis: robot subcommands use common analysis and cache code. Cache reuse depends on issue data and analysis configuration; different candidate scopes, reference clocks, or metric timeouts can legitimately produce different outputs.
  • Instant + eventual completeness: Phase 1 metrics are available immediately; Phase 2 fills in and the status flags tell you when it is done or if it degraded.

๐Ÿงญ Data Flow at a Glance

.beads/issues.jsonl or .beads/beads.jsonl
   โ†“ tolerant loader (BOM strip, 10MB lines, skip malformed)
   โ†“ graph builder (blocking deps only)
   โ†“ analyzer (Phase 1 fast; Phase 2 centralities with timeouts)
   โ†“ cache (hash-keyed)
   โ†“ outputs: TUI | robot JSON | exports/hooks
  • Issue-backed responses carry source and scope identity. Metric-bearing commands also carry analysis configuration/status; graph and metadata commands have their own schemas.

๐Ÿ“ Graph Analysis Algorithms (plain English)

  • PageRank: โ€œblocking authorityโ€ โ€” foundational tasks with many (or important) dependents.
  • Betweenness: โ€œbridgesโ€ โ€” nodes on many shortest paths; bottlenecks between clusters.
  • HITS: hubs (aggregators) vs authorities (prerequisites).
  • Critical-path depth: longest dependent chain in task counts; a structural score, not elapsed delivery time.
  • Eigenvector: influence via influential neighbors.
  • Density, degree, topo sort: structural backbone.
  • Cycles: Tarjan SCC plus one representative cycle per cyclic component; capped with timeouts and stored count. Breaking a representative can leave other cycles in that component.
  • Each appears in robot insights with its status flag and, when ready, per-issue scores.

โšก Phase 1 vs Phase 2

  • Phase 1 (instant): degree, topo sort, density; always present.
  • Phase 2 (async): PageRank, Betweenness, HITS, Eigenvector, Critical Path, Cycles, k-core, articulation points, slack; timeouts are chosen per size tier (ConfigForSize in pkg/analysis/config.go). Status flag reflects computed/timeout/skipped, with reason: "approximate" when betweenness was sampled.

โฑ๏ธ Timeout & Approximation Semantics

  • Size tiers (node count): < 100 exact betweenness, 2 s timeouts, up to 1,000 cycles stored; < 500 exact betweenness, 500 ms timeouts, 100 cycles; < 2,000 approximate (sampled) betweenness with a 500 ms timeout when density < 0.01, otherwise betweenness skipped, 300 ms for the rest, 50 cycles; โ‰ฅ 2,000 sampled betweenness (500 ms), PageRank 200 ms, cycles skipped, HITS only when density < 0.001 (200 ms). --force-full-analysis uses exact betweenness with 30 s timeouts regardless of size; BV_PHASE2_TIMEOUT_S and BV_SKIP_PHASE2 override the tiers.
  • Per-metric status states: pending (Phase 2 still running), computed (finished, including sampled runs), timeout (deadline hit, fallback values), skipped (size/density guard or Phase 2 disabled). Sampled betweenness is not a separate state: it reports state: "computed" with reason: "approximate" and sample set to the pivot count; skipped metrics carry the guard text in reason.
  • Keys are capitalized metric names (PageRank, Betweenness, Eigenvector, HITS, Critical, Cycles, KCore, Articulation, Slack). Payload example:
    {
      "status": {
        "PageRank": {"state":"computed","ms":142},
        "Betweenness": {"state":"computed","ms":480,"reason":"approximate","sample":120},
        "Cycles": {"state":"skipped","ms":0,"reason":"graph too large (>2000 nodes)"}
      }
    }
    

๐Ÿงฎ Execution Plan Logic

  • Actionable set: selected open/in-progress issues whose deferral has elapsed and whose direct/inherited dependency gates are satisfied in the full source. Missing blockers withhold readiness; closed/tombstoned predecessors satisfy gates.
  • Unblocks: selected issues that become ready if that item completes, using the same status, clock and dependency rules. This is distinct from eligibility for a new claim.
  • Tracks: undirected connected components group actionable items into parallelizable streams; items inside a track are ordered by priority, then ID.
  • Summary: highest-impact item = most unblocks, then highest priority (lowest number), then lowest ID for determinism (pkg/analysis/plan.go).

๐ŸŽฏ Priority Recommendation Model

  • Composite score weights: PageRank 22%, Betweenness 20%, blocker ratio 13%, staleness 5%, priority boost 10%, time-to-impact 10%, urgency 10%, risk 10% (feedback can retune them once 3 or more accept/ignore events exist).
  • Thresholds: high PR >0.30, high BW >0.50, staleness 14 days, min confidence 0.30, significant delta 0.15 by default (DefaultThresholds in pkg/analysis/priority.go).
  • Direction: โ€œincreaseโ€ or โ€œdecreaseโ€ priority derived from score vs current priority; confidence blends signal count, strength, and score delta.

๐Ÿ” Diff & Time-Travel Safety Notes

  • When stdout is non-TTY or BV_ROBOT=1, --diff-since auto-emits JSON (or requires --robot-diff in strict setups); resolved revision is echoed in the payload.
  • TUI time-travel badges: [NEW], [CLOSED], [MODIFIED], [REOPENED], matching the robot diff summary.

๐Ÿ›ก๏ธ Performance Guardrails

  • Two-phase analysis with size-aware configs (approx betweenness on large sparse graphs, cycle caps, HITS skipped on dense XL graphs).
  • Per-metric timeouts from 2 s (small graphs) down to 200 ms (XL graphs); results marked with status.
  • Graph-stat disk entries use data/configuration keys and a 24 h maximum age; invalid, missing or expired entries recompute. Cached metrics do not freeze clock-dependent readiness or ranking. Bypass with --no-cache or BV_NO_CACHE=1.
  • Bench quick check: ./scripts/benchmark.sh quick or diagnostics via bv --profile-startup.

๐Ÿงท Robustness & Self-Healing

  • Loader skips malformed lines with warnings, strips UTF-8 BOM, tolerates large lines (10MB).
  • Beads file discovery considers only issues.jsonl, beads.jsonl, and beads.base.jsonl (in that preference order); every other file beside them, including sync_base.jsonl, sprints.jsonl, backups, merge artifacts, and deletions manifests, is ignored. .beads/redirect is followed; --db/BEADS_DB bypass discovery.
  • Live reload is debounced; update check is non-blocking with graceful failure on network issues.

๐Ÿ”— Integrating with CI & Agents

  • Typical pipeline:
    bv --robot-insights > insights.json
    bv --robot-plan | jq '.plan.summary'
    bv --robot-priority | jq '.recommendations[0]'
    bv --check-drift --robot-drift --diff-since HEAD~5 > drift.json
    
  • Compare data_hash, authority_hash, scope_hash, effective analysis configuration, reference clock and metric status. Equal data hashes alone do not mean two responses came from the same run or scope.
  • Exit codes: drift check (0 ok, 1 critical, 2 warning).

๐Ÿฉบ Troubleshooting Matrix (robot mode)

  • Empty metric maps โ†’ Phase 2 still running or timed out; check status flags.
  • Large payloads โ†’ use jq to slice top items; re-run after filtering via recipes.
  • Missing cycles โ†’ inspect .status.Cycles; skipped/timed-out analysis does not establish acyclicity.
  • Inconsistent outputs between commands โ†’ compare source/scope identity, reference clock, configuration and status before interpreting a difference.

๐Ÿ”’ Security & Privacy Notes

  • Local-first: all analysis happens on your repo's JSONL; no network required for robots.
  • Exports run only when you ask for them; hooks run whenever .bv/hooks.yaml exists in the project (--no-hooks skips them, and credential-bearing environment variables are scrubbed from hook subprocesses). Update checks are silent and tolerate network failures without impacting startup.

๐Ÿ™ Acknowledgments & Credits

bv stands on the shoulders of giants. We're deeply grateful to the maintainers and contributors of these exceptional open source projects:

Foundation

ProjectAuthorDescription
BeadsSteve YeggeThe elegant git-native issue tracking system that bv was built to complement

Go Libraries (TUI & CLI)

LibraryAuthorWhat We Use It For
Bubble TeaCharmThe Elm-inspired TUI framework powering all interactive views
Lip GlossCharmBeautiful terminal stylingโ€”colors, borders, layouts
BubblesCharmReady-made components: lists, text inputs, spinners, viewports
HuhCharmInteractive forms and prompts for the deployment wizard
GlamourCharmMarkdown rendering with syntax highlighting in terminal
modernc.org/sqlitemodernc.orgPure-Go SQLite with FTS5 full-text search for static site export
GonumGonum AuthorsGraph algorithms: PageRank, betweenness centrality, SCC
fsnotifyfsnotifyFile system watching for live reload
clipboardatottoCross-platform clipboard for copy-to-clipboard features

JavaScript Libraries (Static Viewer)

LibraryAuthorWhat We Use It For
force-graphVasco AsturianoBeautiful interactive force-directed graph visualization
D3.jsMike Bostock / ObservableData visualization foundation and graph physics
Alpine.jsCaleb PorzioLightweight reactive UI framework
sql.jssql.js contributorsSQLite compiled to WebAssembly for client-side queries
Chart.jsChart.js contributorsInteractive charts: burndown, priority distribution, heatmaps
MermaidKnut SveidqvistDependency graph diagrams in Markdown
DOMPurifycure53XSS-safe HTML sanitization
Markedmarked contributorsFast Markdown parsing
Tailwind CSSTailwind LabsUtility-first CSS framework

Special Thanks

  • The entire Charm team for creating the most delightful terminal UI ecosystem in existence. Their libraries make building beautiful CLI tools a joy.
  • Vasco Asturiano for the incredible force-graph library and the broader ecosystem of visualization tools.
  • Steve Yegge for the vision behind Beadsโ€”a refreshingly simple approach to issue tracking that respects developers' workflows.

About Contributions: Please don't take this the wrong way, but I do not accept outside contributions for any of my projects. I simply don't have the mental bandwidth to review anything, and it's my name on the thing, so I'm responsible for any problems it causes; thus, the risk-reward is highly asymmetric from my perspective. I'd also have to worry about other "stakeholders," which seems unwise for tools I mostly make for myself for free. Feel free to submit issues, and even PRs if you want to illustrate a proposed fix, but know I won't merge them directly. Instead, I'll have Claude or Codex review submissions via gh and independently decide whether and how to address them. Bug reports in particular are welcome. Sorry if this offends, but I want to avoid wasted time and hurt feelings. I understand this isn't in sync with the prevailing open-source ethos that seeks community contributions, but it's the only way I can move at this velocity and keep my sanity.


๐Ÿ“„ License

MIT License with an OpenAI/Anthropic rider. The rider is part of the license and restricts use by the named parties; see LICENSE for the complete controlling terms.

๐Ÿค– Robot JSON contract โ€” quick cheat sheet

Issue-backed analysis envelopes

  • data_hash: fingerprint of issue data used by the response (use alongside scope, configuration, and reference time when comparing calls).
  • analysis_config: exact analysis settings (timeouts, modes, cycle caps) for reproducibility.
  • status: per-metric state computed|timeout|skipped (plus pending while Phase 2 runs) with elapsed ms/reason, keyed by capitalized metric name; sampled betweenness is computed with reason: "approximate". Always check before trusting heavy metrics like PageRank/Betweenness/HITS.
  • as_of / as_of_commit: present when using --as-of; contains the ref you specified and the resolved commit SHA for reproducibility.

Metric-bearing commands such as insights, plan, and priority include analysis_config and status. Graph export and metadata-only commands such as capabilities and recipes have their own schemas. Use --robot-schema for the exact fields required by each command.

Issue-backed robot responses also include source_authority: per-source loaded, failed, or disabled status; valid, dropped, metadata, and tombstone record counts; related-record read errors; and stale fallback diagnostics. Warnings retain their total count and at most 10 messages per source. authority_hash fingerprints those sources and their completeness before filtering; scope_hash identifies the selected candidates and active filters.

When authority is partial or unknown, readiness is labeled provisional. Exploratory recommendations, counts, and graphs remain available, but claim commands and proven actionable picks are withheld. Check source_authority.claim_safe before claiming work. Local Pages exports and agent briefs carry the same diagnostics; watch exports refresh them even when the visible issue data stays unchanged.

Schemas in 5 seconds (jq-friendly)

  • bv --robot-triage โ†’ .triage.quick_ref, .triage.recommendations[], .triage.quick_wins; recommendations can include work that is not claimable.
  • bv --robot-next โ†’ .id and .actions when actionable; otherwise .actionable: false, diagnostics and, when available, .diagnostic_top_pick.
  • bv --robot-graph โ†’ numeric .nodes/.edges plus .adjacency.nodes[]/.adjacency.edges[] in JSON mode; .graph contains DOT/Mermaid text in those modes.
  • bv --robot-insights โ†’ .status, .analysis_config, metric maps (capped by BV_INSIGHTS_MAP_LIMIT), Bottlenecks, Keystones (critical-path scores), Cycles, plus advanced signals: Cores (k-core), Articulation (cut vertices), Slack (longest-path slack).
  • bv --robot-plan โ†’ .plan.tracks[].items[] | {id,unblocks} for downstream unlocks; .plan.summary.highest_impact.
  • bv --robot-priority โ†’ .recommendations[] | {issue_id,current_priority,suggested_priority,confidence,reasoning}.
  • bv --robot-suggest โ†’ .suggestions.suggestions[] (ranked suggestions) + .suggestions.stats (counts) + .usage_hints.
  • bv --robot-diff --diff-since <ref> โ†’ {from_data_hash,to_data_hash,diff.summary,diff.new_issues,diff.cycle_*}.
  • bv --robot-history โ†’ .histories[ID].events + .commit_index for reverse lookup; .stats.method_distribution shows how correlations were inferred.

Copy/paste guardrails

# Ensure metrics are ready
bv --robot-insights | jq '.status'

# Top unblockers from plan
bv --robot-plan | jq '.plan.tracks[].items[] | {id, unblocks}'

# High-confidence priority fixes
bv --robot-priority | jq '.recommendations[] | select(.confidence > 0.6)'

# Structural strength and parallelism
bv --robot-insights | jq '.full_stats.core_number | to_entries | sort_by(-.value)[:5]'
bv --robot-insights | jq '.Articulation'
bv --robot-insights | jq '.Slack[:5]'

# Verify diff hashes match expectations
bv --robot-diff --diff-since HEAD~1 | jq '{from: .from_data_hash, to: .to_data_hash}'

# Historical analysis (verify as_of metadata)
bv --robot-insights --as-of HEAD~30 | jq '{as_of, as_of_commit, data_hash}'