beads_viewer_rust 0.2.1

Spec-first Rust port of beads_viewer (bv) — graph-aware triage for beads issue trackers (CLI binary: bvr)
Documentation

beads_viewer_rust (bvr)

JSONL / workspace config / git history
                │
                ▼
         loader + model validation
                │
                ▼
   IssueGraph + Analyzer + graph metrics
                │
     ┌──────────┼──────────┬───────────────┐
     ▼          ▼          ▼               ▼
  robot JSON   TOON       FrankenTUI      static pages

CI License: MIT

bvr is a graph-aware issue triage engine for .beads data that gives you machine-friendly robot output, an interactive terminal UI, and a self-contained static dashboard export from the same binary.

Quick Install

cargo install --git https://github.com/Dicklesworthstone/beads_viewer_rust.git bvr

TL;DR

The Problem: issue backlogs are easy to store but hard to prioritize. Once dependencies, blockers, stale work, cross-label bottlenecks, workspace layouts, and git history enter the picture, manual sorting or ad-hoc jq scripts stop being trustworthy.

The Solution: bvr loads .beads issue data, builds a dependency graph, computes centrality and planning metrics, and then exposes the result through robot commands, a TUI, markdown briefs, graph export, and static pages bundles.

Why Use bvr?

Capability What It Does
Robot-first triage Emits structured JSON or TOON for agents, scripts, and automation via --robot-* commands.
Graph-aware planning Computes PageRank, betweenness, HITS, eigenvector, k-core, cycles, critical path, articulation points, and slack.
Multiple operator surfaces Supports automation, a FrankenTUI, markdown briefs, graph export, and pages export from one codebase.
Workspace-aware loading Understands .beads/ layouts, compatibility filenames, and .bv/workspace.yaml aggregation.
History and feedback loops Correlates git history, supports drift baselines, recommendation feedback, and correlation review commands.
Evidence-heavy testing Backed by conformance, schema, e2e, workspace/history, export, snapshot, and stress tests.

Quick Example

# 1. Ask for the single best next move
bvr --robot-next

# 2. Get a compact orientation snapshot
bvr --robot-overview

# 3. Get the full triage payload
bvr --robot-triage

# 4. Inspect graph metrics and cycles
bvr --robot-insights

# 5. See an execution plan grouped into parallel tracks
bvr --robot-plan

# 6. Search across issue text and metadata
bvr --robot-search --search "auth" --search-limit 5

# 7. Export a static bundle for sharing
bvr --export-pages ./bv-pages --pages-title "Sprint Dashboard"

# 8. Preview it locally
bvr --preview-pages ./bv-pages

What bvr Solves

bvr is the Rust port of the legacy Go bv tool, but the current codebase is no longer just a straight porting spike. Today it includes:

  • Robot-mode parity work for the legacy CLI surface.
  • A much larger analysis surface than simple ranking.
  • A functional FrankenTUI with the main issue view plus 11 specialized modes.
  • Static pages export, preview, watch mode, and a pages deployment wizard.
  • Workspace-aware loading and git-history-aware analysis.

The current direction is to lock down parity first, then extend from there:

  • Keep the machine-facing behavior compatible and evidence-driven.
  • Recover operator confidence in the interactive workflows.
  • Extend the Rust version with capabilities that make sense natively here.

Problem Cases bvr Handles Well

bvr is most useful when a backlog has enough structure that naive sorting starts lying to you. Common cases:

1. A high-priority issue is noisy, but not actually central

An issue can be marked urgent and still not unblock much of anything. bvr distinguishes declared priority from structural importance, which is why the triage surface includes both priority signals and graph-derived signals.

2. A mediocre-looking issue is the real bottleneck

Sometimes the most important work is a root blocker, a bridge between clusters, or an articulation point that keeps whole branches connected. Those rarely stand out in a plain list view.

3. A team is drowning in stale work and cannot tell what is safely ignorable

Staleness alone is not enough. A stale leaf item and a stale central blocker are very different problems. bvr combines freshness, dependency structure, and blocker counts, so stale-work review does not collapse into "oldest first."

4. Multiple repos act like one delivery system

In a workspace layout, the API repo, frontend repo, and shared library repo can form one planning graph. bvr can aggregate that via .bv/workspace.yaml instead of forcing you to triage each repo in isolation.

5. Operators need different surfaces for the same underlying truth

Agents want structured output. Humans want TUI workflows. Stakeholders may want a static dashboard. bvr exists so those do not drift into separate, contradictory tools.

6. "What changed?" matters as much as "What exists?"

Baselines, diffs, history correlation, and export/watch flows exist because triage is usually about movement over time, not a single snapshot of open issues.

Design Philosophy

1. One source of truth, many surfaces

The loader and analyzer feed everything else. Robot output, TUI screens, markdown briefs, and pages export all work from the same issue graph instead of reimplementing their own logic.

2. Graph structure matters more than raw counts

Priority is only one field on an issue. bvr also looks at blockers, centrality, flow, and path structure so it can distinguish a noisy task from a true bottleneck.

3. Automation should not scrape terminal output

Robot commands are first-class. If you are integrating with agents or scripts, use --robot-* and optionally --format toon instead of screen-scraping the TUI.

4. Workspace and path semantics are product behavior

This project treats .beads discovery, workspace aggregation, repo-path handling, watch paths, preview serving, and history resolution as part of the real contract, not implementation trivia.

5. Parity claims need evidence

The repo carries conformance fixtures, schema validation, e2e coverage, snapshots, and stress fixtures because "probably compatible" is not a useful standard for a triage engine.

Why Graph-Aware Triage Beats Naive Sorting

A normal issue list encourages bad habits:

  • sort by declared priority
  • maybe filter by status
  • maybe scan titles by hand

That works until dependencies matter. Once issues block each other, connect teams, span repos, or form cycles, the backlog becomes a graph problem rather than a spreadsheet problem.

bvr treats the backlog that way. Instead of asking only "what is marked important?", it also asks:

  • what work influences the most downstream work?
  • what issues sit on the bridges between clusters?
  • what items are central but not obviously loud?
  • what gets value moving fastest if finished now?
  • what work is risky because it is in cycles or behind blockers?

That is why --robot-next and --robot-triage are graph-aware ranking outputs, not dressed-up sort orders.

How Scoring Works

The recommendation engine does not rely on a single metric. The current impact score combines multiple normalized components and then renormalizes them into a single score.

At a high level, the scoring model considers:

Component What It Captures Why It Matters
PageRank Global centrality in the dependency graph Finds issues that influence a lot of important work
Betweenness Bridge importance between regions of the graph Finds chokepoints and routing issues
BlockerRatio How much open work this issue blocks Rewards high-unblock items
Staleness How recently the issue moved Prevents long-dead work from floating to the top by default
PriorityBoost Declared issue priority Respects operator intent without blindly obeying it
TimeToImpact How quickly value propagates after completion Rewards work near the roots of dependency chains
Urgency Status-based urgency signal Distinguishes active, open, review, blocked, and deferred states
Risk Open blockers, cycle membership, articulation-point risk Discounts work that is structurally risky to execute now

Two important design choices:

  • The model is multi-signal, so no single bad field dominates the ranking.
  • The model is explainable, because recommendations carry reasons rather than just a score.

This is also why bvr can support recommendation feedback: the score is composed from named components, not a black-box classifier.

Algorithms Under the Hood

The analysis engine uses standard graph algorithms, but it applies them to issue planning rather than academic toy graphs.

Core metrics

Algorithm Used For
PageRank Global influence / importance
Betweenness centrality Bridge and bottleneck detection
Eigenvector centrality Influence based on influential neighbors
HITS Hub and authority style ranking
K-core decomposition Dense structural cores in the graph
Articulation point detection Single points of structural failure
Critical depth / critical path signals Long dependency-chain importance
Slack computation How much scheduling flexibility exists
Strongly connected component cycle detection Detecting circular dependencies

Related analysis families

Beyond pure graph centrality, the repo also includes:

  • forecast analysis
  • execution plan grouping
  • label health and cross-label flow
  • git-history correlation
  • drift against saved baselines
  • search and recipe filtering
  • file-to-bead and hotspot analysis
  • blocker-chain, impact-network, and causality views

Practical note on scale

The code intentionally treats some metrics as more expensive than others. Faster metrics can be computed immediately, while slower metrics can be deferred or sampled on larger graphs.

Why These Algorithms Matter for Issue Triage

Listing algorithms is not enough. Their value in this repo is operational:

  • PageRank helps surface issues that matter globally, not just locally.
  • Betweenness highlights bridge work that sits between clusters or teams.
  • Articulation points expose single issues whose removal would fragment the dependency graph.
  • K-core helps distinguish deep structural clusters from shallow leaves.
  • Cycle detection catches planning deadlocks that look normal in a flat list.
  • Critical depth and slack make scheduling more defensible than gut feel.

If you have ever asked "why is this weird-looking issue ranked so high?", the answer is usually one of those structural effects.

How bvr Compares

Feature bvr legacy Go bv ad-hoc jq / scripts manual triage
Structured robot output ✅ JSON + TOON ✅ JSON-style robot output ⚠️ custom per script
Interactive TUI ✅ functional, expanding ✅ mature baseline
Static pages export ✅ built in
Workspace-aware loading .bv/workspace.yaml + repo-path semantics ✅ baseline behavior ❌ usually custom
Graph metrics ✅ broad built-in set ✅ core set ⚠️ manual and brittle
Drift/correlation/file intel surfaces ✅ built in ⚠️ mixed / legacy-dependent
Best fit today automation + analysis + export legacy operator muscle memory one-off filtering small backlogs

Use bvr when:

  • You want a single binary for triage, diagnostics, dashboards, and automation.
  • You are working in a .beads-based repo and need dependency-aware ranking.
  • You want machine output that is easier to consume than terminal text.

Prefer something else when:

  • You only need one quick text filter on a tiny file.
  • You require exact legacy TUI feel today and do not want parity-in-progress behavior.

Installation

1. Install from GitHub with Cargo

cargo install --git https://github.com/Dicklesworthstone/beads_viewer_rust.git bvr

2. Build from a local checkout

git clone https://github.com/Dicklesworthstone/beads_viewer_rust.git
cd beads_viewer_rust
cargo build --release
./target/release/bvr --robot-help

When validating the current checkout, prefer the binary built from that checkout (./target/debug/bvr or ./target/release/bvr). Do not assume a global bv wrapper or previously installed binary matches the source tree you are editing.

3. Install from a local checkout into your Cargo bin dir

git clone https://github.com/Dicklesworthstone/beads_viewer_rust.git
cd beads_viewer_rust
cargo install --path .

Toolchain

  • Rust edition: 2024
  • Minimum Rust version: 1.85
  • Binary name: bvr

Quick Start

1. Point bvr at issue data

By default, bvr looks for .beads/ data in the current repository. It also supports compatibility filenames such as issues.jsonl and beads.base.jsonl.

bvr --robot-triage

If you want to bypass auto-discovery:

bvr --robot-triage --beads-file tests/testdata/minimal.jsonl

2. Use workspace mode when one repo is not enough

bvr can aggregate multiple repos through .bv/workspace.yaml.

repos:
  - path: services/api
  - path: apps/web
bvr --workspace .bv/workspace.yaml --robot-plan

3. Start with the high-signal robot commands

bvr --robot-next
bvr --robot-overview
bvr --robot-triage
bvr --robot-plan
bvr --robot-insights

4. Use the TUI for operator workflows

bvr

5. Export a shareable dashboard bundle

bvr --export-pages ./bv-pages --pages-title "Sprint Dashboard"
bvr --preview-pages ./bv-pages

Input Model

Default data sources

bvr loads issues from .beads by default, with compatibility for:

  • beads.jsonl
  • issues.jsonl
  • beads.base.jsonl

It can also aggregate repositories via .bv/workspace.yaml.

Output formats

Robot commands can emit:

  • json via --format json
  • toon via --format toon

Examples:

bvr --robot-triage --format json
bvr --robot-triage --format toon
BV_OUTPUT_FORMAT=toon bvr --robot-next

Robot Output Philosophy

The robot surface exists so external automation does not have to guess at terminal text.

Design goals

  • Deterministic structure for scripts and agents
  • Shared envelope fields such as generation timestamp, data hash, output format, and version
  • Discoverability through --robot-help, --robot-docs, and --robot-schema
  • Compact output through TOON when JSON is too expensive for agent loops

Why both JSON and TOON exist

JSON is the safest default for downstream tooling. TOON exists because agent workflows often care about token cost and readability more than strict JSON syntax.

Why the schema/docs commands matter

The repo emits payloads and machine-readable descriptions of their contracts. That matters for:

  • agent integration
  • regression detection
  • contract review
  • new command discovery

Workspace and Path Semantics

Path handling is one of the subtle but critical parts of bvr.

What can be discovered automatically

bvr can look for:

  • .beads/ in the current repo or ancestors
  • compatibility JSONL filenames
  • .bv/workspace.yaml for multi-repo aggregation

Why this gets its own section

In this project, path resolution affects:

  • which issues are loaded
  • whether workspace aggregation happens
  • where watch mode listens for changes
  • where historical loads and diffs resolve from
  • where pages workflows and persisted state live

Practical usage rules

  • Use --beads-file when you want an exact source file and do not want discovery.
  • Use --workspace when you want an exact workspace config and do not want discovery.
  • Let auto-discovery work when the repo layout is conventional and you want convenience.

Static Pages, Preview, Watch, and Wizard

The pages system is a first-class surface, not an afterthought.

What export produces

The bundle includes:

  • index.html
  • local viewer assets
  • JSON payloads for issues, metadata, triage, and optional history
  • a SQLite database bundle
  • static-host helper files such as _headers
  • a deploy-facing bundle README

Why pages export exists

It solves a different problem than robot mode:

  • robot mode is for agents and automation
  • the TUI is for interactive operators
  • pages export is for sharing, review, and lightweight dashboard publishing

Preview server

The preview flow provides a local HTTP server for the exported bundle, a status endpoint, and optional live reload. It is intentionally geared toward testing the real exported artifact rather than a separate dev-only web app.

Watch mode

--watch-export exists for a fast edit-refresh cycle when the issue data changes and you want the static bundle to keep up.

Pages wizard

--pages is an interactive deployment-oriented workflow that helps collect export options, target settings, preview choices, and deployment instructions without requiring the operator to remember every flag.

Command Reference

For the machine-readable inventory, use:

bvr --robot-help
bvr --robot-docs commands
bvr --robot-schema

Core triage and planning

bvr --robot-next
bvr --robot-overview
bvr --robot-triage
bvr --robot-triage-by-track
bvr --robot-triage-by-label
bvr --robot-plan
bvr --robot-priority
bvr --robot-alerts
bvr --robot-suggest

Use these when you want a fast orientation snapshot, ranked recommendations, quick wins, blockers to clear, grouped tracks, or priority mismatch detection.

Graph analysis and forecasting

bvr --robot-insights
bvr --robot-graph --graph-format json
bvr --robot-graph --graph-format dot --graph-root B --graph-depth 2
bvr --robot-forecast all --forecast-agents 2
bvr --robot-capacity --agents 3
bvr --robot-burndown current
bvr --robot-sprint-list
bvr --robot-sprint-show sprint-1

Use these when you need graph metrics, projected execution, sprint state, or graph exports for downstream tools.

History, diff, drift, and correlation

bvr --robot-history --history-limit 20
bvr --robot-diff --diff-since HEAD~10
bvr --save-baseline baseline.json
bvr --robot-drift
bvr --check-drift
bvr --robot-explain-correlation <sha:bead>
bvr --robot-confirm-correlation <sha:bead>
bvr --robot-reject-correlation <sha:bead>
bvr --robot-correlation-stats

Use these when you want git-aware change tracking, baseline comparisons, or a feedback loop for commit-to-bead correlations.

Label, search, and file intelligence

bvr --robot-label-health
bvr --robot-label-flow
bvr --robot-label-attention --attention-limit 5
bvr --robot-search --search "auth" --search-limit 10
bvr --robot-recipes
bvr --robot-orphans
bvr --robot-file-beads src/main.rs
bvr --robot-file-hotspots
bvr --robot-impact bd-123
bvr --robot-file-relations src/main.rs
bvr --robot-related bd-123
bvr --robot-blocker-chain bd-123
bvr --robot-impact-network bd-123 --network-depth 3
bvr --robot-causality bd-123

Use these when you need label health, workspace search, orphan detection, file-to-bead mapping, or impact analysis.

Export, reports, and automation helpers

bvr --export-md /tmp/report.md
bvr --priority-brief /tmp/priority-brief.md
bvr --agent-brief /tmp/agent-brief
bvr --export-graph /tmp/deps.json
bvr --export-pages ./bv-pages
bvr --preview-pages ./bv-pages
bvr --export-pages ./bv-pages --watch-export
bvr --pages

These commands generate static artifacts, local previews, and operator-facing deployment guidance.

TUI and diagnostics

bvr
bvr --debug-render graph --debug-width 160 --debug-height 50
bvr --profile-startup
bvr --profile-startup --profile-json
bvr --background-mode --robot-triage
bvr --no-background-mode --robot-triage

Use these when you want the interactive UI, deterministic render output for debugging, or startup timing diagnostics.

AGENTS.md workflow helpers

bvr --agents-check
bvr --agents-add
bvr --agents-update
bvr --agents-remove

These commands inspect or manage the beads workflow blurb inside AGENTS.md.

TUI Overview

Bare bvr launches the interactive terminal UI. For automation, do not run the bare command; use --robot-*.

Main view plus 11 specialized modes

Key Mode Purpose
default Main Issue list with detail pane
b Board Kanban-style lane view
i Insights Metric and explanation panels
g Graph Dependency graph and edge inspection
h History Bead/git timeline and file tree
a Actionable Parallel execution tracks
! Attention Label attention ranking
T Tree Dependency tree
[ Labels Label health dashboard
] Flow Cross-label flow matrix
t Time Travel Diff-against-ref view
S Sprint Sprint planning/detail view

Common keys

Key Action
? Toggle help overlay
Tab Toggle list/detail focus
Esc Back, clear, or quit confirm
j / k Move within the focused pane
/ Search in supported views

TUI Design Goals

The TUI is not trying to be a pretty wrapper around one list. Its job is to support different operator tasks without making the user mentally re-derive the graph from a table every time.

Why there are many modes

Different planning questions need different visual structures:

  • Main for backlog scanning and detail reading
  • Board for lane-based operational overview
  • Insights for metric interpretation
  • Graph for structural debugging
  • History for time and git context
  • Actionable for "what can teams do in parallel right now?"
  • Attention / Labels / Flow for label-centric health and bottleneck analysis
  • Tree / Time Travel / Sprint for dependency, comparison, and planning workflows

Why the TUI is still evolving

The project explicitly treats operator trust as something that has to be earned. The Rust TUI is already useful, but parity and workflow polish are still active goals rather than a finished story.

Configuration

Workspace config: .bv/workspace.yaml

repos:
  - path: services/api
  - path: apps/web
discovery:
  patterns:
    - services/*
    - apps/*

User config for TUI background reload: ~/.config/bv/config.yaml

experimental:
  background_mode: true

Useful environment variables

Variable Purpose
BV_OUTPUT_FORMAT Default robot output format: json or toon
TOON_DEFAULT_FORMAT Fallback output format if BV_OUTPUT_FORMAT is unset
TOON_STATS Print JSON vs TOON token estimates on stderr
TOON_KEY_FOLDING Configure TOON key folding
TOON_INDENT Configure TOON indentation
BV_SEARCH_PRESET Default hybrid search preset
BVR_PREVIEW_PORT Preferred preview server port
BVR_PREVIEW_MAX_REQUESTS Auto-stop the preview server after N requests
BV_BACKGROUND_MODE Enable or disable TUI background reload
BVR_E2E_ARTIFACT_DIR Persist e2e regression artifacts for test runs

Architecture

┌────────────────────────────────────────────────────────────────────┐
│ Input layer                                                       │
│  - .beads/*.jsonl                                                 │
│  - compatibility filenames                                        │
│  - .bv/workspace.yaml                                             │
│  - git history / baselines / feedback files                       │
└────────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌────────────────────────────────────────────────────────────────────┐
│ Loader + model validation                                         │
│  - path discovery                                                 │
│  - workspace aggregation                                          │
│  - issue parsing + validation                                     │
│  - warning suppression for robot mode                             │
└────────────────────────────────────────────────────────────────────┘
                                │
                                ▼
┌────────────────────────────────────────────────────────────────────┐
│ Analyzer                                                          │
│  - IssueGraph build                                               │
│  - fast metrics phase                                             │
│  - optional slow metrics phase in background thread               │
│  - triage / plan / alerts / search / history / drift / file intel │
└────────────────────────────────────────────────────────────────────┘
                                │
        ┌───────────────────────┼────────────────────────┐
        ▼                       ▼                        ▼
┌────────────────────┐  ┌────────────────────┐  ┌────────────────────┐
│ Robot surfaces     │  │ Operator surfaces  │  │ Export surfaces    │
│ JSON / TOON        │  │ FrankenTUI         │  │ MD / pages / SQLite│
└────────────────────┘  └────────────────────┘  └────────────────────┘

Performance Model

Not all analysis work costs the same amount, and the code reflects that.

Two-phase analysis

The engine distinguishes between:

  • fast structural work that is cheap enough to do immediately
  • slower graph work that can be deferred, backgrounded, or sampled on larger graphs

This lets the tool stay responsive without pretending expensive graph algorithms are free.

Large-graph behavior

For larger graphs, some computations change strategy instead of doing the most expensive exact version every time. One example is sampled betweenness on larger graphs.

Why background mode exists

Background mode exists to keep the TUI usable while deeper analysis catches up.

Data and Artifact Layout

Input-side layout

Path / Artifact Role
.beads/ Primary issue-data home
beads.jsonl / issues.jsonl / beads.base.jsonl Supported JSONL issue sources
.bv/workspace.yaml Multi-repo aggregation config
git history History correlation and timeline input

Output-side layout

Artifact Produced By
robot JSON / TOON payloads --robot-*
markdown reports and briefs --export-md, --priority-brief, --agent-brief
graph exports --export-graph, --robot-graph
static pages bundle --export-pages
preview server responses --preview-pages
baseline comparisons --save-baseline, --robot-drift, --check-drift

Pages bundle layout

At a high level, exported bundles contain:

  • a root HTML entry point
  • local viewer assets
  • data/ payloads
  • a SQLite database export
  • deployment helper files

That layout is intentionally self-contained so preview and static hosting use the same artifact shape.

Testing and Verification

This repo carries multiple verification layers rather than relying on a single happy-path suite:

  • Conformance tests against a Go reference harness.
  • JSON schema validation for robot output contracts.
  • E2E robot, export, and workspace/history integration tests.
  • TUI snapshots and keyflow journeys.
  • Stress fixtures for large and pathological graphs.
  • Benchmarks for the analysis pipeline.

Useful commands:

cargo test --test conformance
cargo test --test schema_validation
cargo test --test e2e_robot_matrix
cargo test --test e2e_workspace_history
cargo test --test export_pages
cargo bench --bench triage

Optional artifact capture for robot regressions:

BVR_E2E_ARTIFACT_DIR=target/bvr-e2e-artifacts cargo test --test e2e_robot_matrix

Workflow Recipes

I am an agent and need the next best move

bvr --robot-next
bvr --robot-overview
bvr --robot-triage
bvr --robot-plan

Start narrow, then expand. --robot-next gives the top pick, --robot-overview gives a compact project snapshot, --robot-triage gives deeper context, and --robot-plan tells you whether parallel work exists.

I am a human operator triaging a sprint

bvr
# then use Main, Actionable, Sprint, and History modes

Use this when you need to move between ranking, dependency structure, and recent changes interactively.

I need to understand dependency bottlenecks

bvr --robot-insights
bvr --robot-graph --graph-format dot
bvr --robot-blocker-chain bd-123

Use graph metrics for global context and blocker-chain output for a specific issue.

I need to review what changed since the last checkpoint

bvr --save-baseline baseline.json
# later
bvr --robot-drift
bvr --check-drift
bvr --robot-diff --diff-since HEAD~10

Use baselines for structural drift and --robot-diff for issue-level change summaries.

I need a shareable dashboard

bvr --export-pages ./bv-pages --pages-title "Review Dashboard"
bvr --preview-pages ./bv-pages

Use this when you want to share triage output with someone who is not going to run the CLI locally.

Testing Philosophy

The test strategy exists because this tool has several different contracts at once.

1. Parity contract

Conformance tests protect behavior that is supposed to match legacy expectations.

2. Robot contract

Schema validation protects machine-facing output shape. This matters because agents and scripts are less forgiving than humans.

3. Operator contract

Snapshot and journey tests protect the TUI from accidental regressions in navigation and rendering.

4. Integration contract

Workspace/history/export tests exist because path semantics, workspace promotion, preview behavior, and pages flows are easy to break accidentally.

5. Stress contract

Stress fixtures protect the tool from becoming "correct only on toy graphs."

Troubleshooting

"My script hung"

You probably ran bare bvr, which launches the TUI.

# Use robot mode for automation
bvr --robot-triage

"No issues were found"

Be explicit about the source instead of relying on discovery.

bvr --robot-triage --beads-file /path/to/issues.jsonl
bvr --workspace /path/to/.bv/workspace.yaml --robot-triage

"Workspace auto-discovery is ambiguous"

Tell bvr exactly which workspace or beads file you want.

bvr --workspace .bv/workspace.yaml --robot-plan
# or
bvr --beads-file .beads/beads.jsonl --robot-plan

"Preview pages failed to bind a port"

Pick an explicit port.

BVR_PREVIEW_PORT=9010 bvr --preview-pages ./bv-pages

"Robot output is too verbose"

Use TOON.

bvr --robot-next --format toon
BV_OUTPUT_FORMAT=toon bvr --robot-triage

Non-Goals

bvr is intentionally not trying to be all things:

  • It is not a hosted project-management platform.
  • It is not a replacement for issue creation or collaboration systems.
  • It is not just a pretty terminal wrapper around jq.
  • It is not optimized around community contribution workflows.

Those boundaries help keep the project focused on triage, analysis, automation, and export.

Roadmap and Current Priorities

The current high-level priorities are:

1. Preserve verified legacy parity

Robot, CLI, export, workspace, and interactive TUI behavior now have a parity proof surface. The job is to keep that contract stable as the code evolves.

2. Harden regression evidence

Conformance, schema, snapshot, keyflow, journey, stress, and integration suites are part of the product contract, not optional maintenance.

3. Extend only where Rust-native additions stay coherent

Search, label intelligence, drift, correlation review, file-intel, and future async/runtime upgrades should build on top of the locked parity baseline rather than destabilize it.

4. Keep pages/export/workspace workflows polished

Export, preview, watch mode, wizard flows, and workspace path semantics remain high-value operator workflows and should stay first-class.

Why This Exists

Issue data is easy to store. The harder problem is turning it into trustworthy action.

Flat issue lists fail in predictable ways:

  • they hide structural blockers behind cosmetic metadata
  • they over-trust stale priority fields
  • they fragment multi-repo work into separate local truths
  • they make humans and agents consume different, often contradictory, surfaces

bvr exists because the underlying problem is bigger than printing a list of issues. The real question is how to reason about dependency-shaped work across multiple consumers without duplicating logic everywhere.

For that reason, the project is built around a shared analyzer and projected into multiple surfaces, instead of building one-off ranking logic for each output mode.

System Tour

One straightforward way to understand bvr is to follow one issue through the system.

Step 1. The issue is discovered and loaded

The loader finds .beads data, compatibility JSONL sources, or workspace repo inputs, then parses and validates issues into the in-memory model.

Step 2. The issue enters the graph

Its dependencies become edges in IssueGraph, which means the issue is no longer treated as an isolated row. It now has predecessors, successors, graph depth, blocker relationships, and possible cycle membership.

Step 3. Metrics are computed around it

The analyzer computes centrality, blocker counts, critical depth, slack, cycle membership, and other structural signals. At this point, the issue stops being "just title + priority + status."

Step 4. Triage synthesizes a recommendation

The triage layer combines graph signals with declared metadata such as priority, status, freshness, and risk signals. This is where the issue may become a top pick, a blocker to clear, a quick win, or a lower-confidence candidate.

Step 5. The same truth is projected outward

That result can then appear as:

  • a --robot-next top recommendation
  • one row inside --robot-triage
  • a node in the graph view
  • a detail pane entry in the TUI
  • a track item in Actionable mode
  • a row in exported pages JSON / SQLite payloads

These are not separate systems with separate logic. They are projections of the same analyzed issue state.

From Data to Recommendation

Here is the end-to-end pipeline in slightly more explicit form:

  1. Discover inputs
    • locate .beads data, compatibility JSONL files, or .bv/workspace.yaml
  2. Parse and validate
    • read JSONL
    • normalize issue fields
    • validate timestamps, statuses, and dependency references
  3. Build the graph
    • construct IssueGraph with IDs, edges, successors, and predecessors
  4. Compute metrics
    • run fast structural analysis first
    • run deeper graph metrics when appropriate
  5. Synthesize analysis products
    • triage
    • planning
    • forecasting
    • alerts
    • search
    • label/file/history/drift/correlation outputs
  6. Project into surfaces
    • robot JSON / TOON
    • TUI
    • markdown reports and briefs
    • graph export
    • pages bundle and preview flows

That pipeline is the real architecture of the project. The flags are just ways of selecting which projection you want.

Metric Glossary

PageRank

Mathematically: a recursive influence score over the dependency graph.

Operationally: "if I care about globally important work, how central is this issue?"

Can mislead when: a graph is tiny or nearly flat, where everything is structurally similar.

Betweenness

Mathematically: how often a node lies on shortest paths between other nodes.

Operationally: "is this issue a bridge or chokepoint between clusters?"

Can mislead when: there are many equivalent alternate routes or the graph is too small to make bridging meaningful.

Eigenvector Centrality

Mathematically: influence weighted by the influence of neighbors.

Operationally: "is this issue connected to other important issues?"

HITS

Mathematically: separates hub-like and authority-like roles in a graph.

Operationally: useful for distinguishing issues that point to many important dependencies from issues that are important dependency targets themselves.

K-Core

Mathematically: the deepest dense subgraph layer a node belongs to.

Operationally: "how embedded is this issue in the core of the dependency structure?"

Articulation Point

Mathematically: a node whose removal disconnects part of the graph.

Operationally: "is this a single point of structural failure?"

Critical Depth

Mathematically: a depth-like measure over dependency structure.

Operationally: "if this moves, how far does value propagate down the chain?"

Slack

Mathematically: scheduling flexibility relative to critical structure.

Operationally: "how little room for delay does this issue have?"

Cycle Membership

Mathematically: membership in a strongly connected component with a cycle.

Operationally: "is this issue trapped in a circular dependency?"

Scoring Breakdown Example

Imagine an issue with this profile:

  • blocks several open items
  • sits near the root of a dependency chain
  • has decent declared priority
  • is not currently blocked itself
  • is part of an important bridge between two graph regions

Its score might look conceptually like this:

Component Interpretation
PageRank: high globally central work
Betweenness: high connects otherwise separate work streams
BlockerRatio: medium-high unblocks real downstream work
PriorityBoost: medium operator intent supports it but is not the only reason
TimeToImpact: high finishing it moves value quickly
Urgency: medium status says it is live work, not deferred noise
Risk discount: low penalty no blockers or cycles holding it back

The final recommendation is strong not because one number said so, but because several independent signals agree.

Design Tradeoffs

Several design choices shape the project:

Explainable ranking over black-box ranking

It would be easier to make the ranking opaque than to make it transparent. This project chooses transparency and defensibility.

Deterministic outputs over clever nondeterminism

For agent workflows, stable output shape and ordering are more valuable than vaguely smarter but unstable behavior.

Shared analyzer over per-surface duplication

Robot mode, TUI, and export all use the same core analysis instead of each surface inventing its own rules.

Single binary over service sprawl

bvr is intentionally a CLI/TUI/export tool, not a distributed backend with several moving processes.

Cargo-first distribution over premature packaging sprawl

Right now, the project supports Cargo and source installation cleanly. It does not claim a broader packaging story than it actually has.

Why TOON Exists

TOON exists because machine-facing output has two competing goals:

  • strict machine readability
  • compactness and lower token cost

JSON wins the first goal. TOON helps with the second.

Prefer TOON when:

  • an agent is repeatedly consuming large robot payloads
  • you want a more compact representation for iterative loops
  • strict JSON parsing is not required by the caller

Prefer JSON when:

  • another tool expects JSON directly
  • you want maximal interoperability
  • the payload will be fed into standard JSON tooling

TOON exists because agent ergonomics are part of the product surface.

Failure Modes and Defensive Behavior

Many failure cases are treated as part of the real contract.

Malformed JSONL lines

The loader does not assume pristine input forever. Robot mode also treats warning behavior differently because leaking noisy warnings into machine-facing stderr can break automation expectations.

Empty datasets

An empty issue set is handled as a real scenario, not as a crash-worthy anomaly.

Missing or ambiguous workspace configs

When discovery becomes ambiguous, the tool prefers explicit guidance over silently loading the wrong project shape.

Changed path / filename conventions across history

Historical and workspace-aware loading are real concerns in this repo because path semantics affect correctness, not convenience alone.

Large graphs

The engine does not pretend every metric is equally cheap. It uses staged computation and alternate strategies where appropriate.

Preview server conflicts

The preview workflow explicitly handles port conflicts and exposes overrides, because export-preview loops are meant to be operational, not toy demos.

Historical and Temporal Analysis

bvr is not only about ranking the current graph snapshot.

The temporal surfaces include:

  • --robot-history
  • --robot-diff
  • saved baselines
  • --robot-drift
  • human-readable --check-drift
  • correlation explanation / confirmation / rejection

Together, those features answer a broader class of questions:

  • what changed?
  • what drifted?
  • what newly matters?
  • what used to be true but is no longer true?
  • which commit history seems to explain this issue movement?

Together, those features make bvr more of a backlog-analysis engine than a static ranking script.

Why Static Pages Matter

Static pages solve a product problem that robot mode and the TUI do not.

Robot mode is ideal for automation. The TUI is ideal for operators. Static pages matter because sometimes you need:

  • a shareable artifact
  • a dashboard for someone who will not run the CLI
  • a reproducible snapshot of analysis
  • something previewable locally and publishable to a static host

That is also why export includes the real viewer assets and SQLite/data payloads instead of dumping one JSON file and calling it done.

Operator Personas

Agent / automation consumer

Wants deterministic machine-readable outputs, schema truthfulness, and low-friction command surfaces.

Solo engineer

Wants a fast answer to "what should I do next?" and "what is actually blocked?"

Tech lead / sprint planner

Wants prioritization, parallelization, bottleneck detection, label flow, and planning visibility across a broader surface area.

Stakeholder consuming pages export

Wants a shareable view of the analyzed state without learning the CLI or gaining repo access.

Real Query and Workflow Examples

Find high-signal next work

bvr --robot-next
bvr --robot-triage

Inspect structural bottlenecks

bvr --robot-insights
bvr --robot-graph --graph-format mermaid

Audit one label area

bvr --robot-triage --label backend
bvr --robot-label-health
bvr --robot-label-flow

Search with graph-aware ranking

bvr --robot-search --search "auth"
bvr --robot-search --search "auth" --search-mode hybrid
bvr --robot-search --search "auth" --search-preset impact-first

Review temporal change

bvr --robot-diff --diff-since HEAD~5
bvr --robot-history --history-limit 25
bvr --robot-drift

Produce a stakeholder-facing snapshot

bvr --export-pages ./bv-pages --pages-title "Weekly Review"
bvr --preview-pages ./bv-pages

Module-by-Module Architecture Map

Module / File Responsibility
src/loader.rs issue discovery, workspace loading, path semantics, JSONL parsing
src/model.rs core issue data model and validation rules
src/analysis/graph.rs graph construction and centrality / structural metrics
src/analysis/triage.rs ranking, impact score, recommendations, project health
src/analysis/plan.rs parallel execution-track grouping
src/analysis/history.rs / git_history.rs history and git correlation support
src/analysis/label_intel.rs label health, flow, and attention analysis
src/analysis/file_intel.rs file-bead mapping, hotspots, related work, orphans
src/analysis/search.rs text and hybrid search logic, presets, weights
src/analysis/drift.rs baseline comparison and drift reporting
src/robot.rs envelopes, docs, schemas, TOON rendering, payload contracts
src/tui.rs interactive multi-mode terminal UI
src/export_pages.rs static bundle export, preview, and watch flows
src/pages_wizard.rs interactive pages deployment-oriented wizard
src/export_md.rs / src/export_sqlite.rs report and export artifact generation
src/main.rs CLI dispatch and surface orchestration

What Makes This Hard

Several parts of this project are harder than they first look:

Behavioral parity is not a cosmetic problem

If robot output, warning behavior, path semantics, or workspace resolution drift, users and agents can make wrong decisions even when the binary "works."

Path semantics are a product feature

This repo has repeatedly surfaced subtle bugs around workspace roots, repo paths, historical loads, preview behavior, and related state resolution. Those are correctness problems, not housekeeping.

Graph metrics must become action, not ornament

It is easy to compute centrality and still fail to tell the user what to do. Turning metrics into usable recommendations is the harder job.

Multiple surfaces must agree

Robot mode, TUI, markdown export, graph export, and pages export all need to present coherent projections of the same analysis.

Responsiveness and depth are in tension

The richer the graph analysis gets, the easier it is to make the operator experience laggy. The staged computation model exists because this tension is real.

Determinism and Trust

The project leans hard on determinism because trust is the whole game in a triage tool.

Deterministic ordering matters

Agents, tests, and humans all benefit when repeated runs over the same input produce stable ordering and payload shape.

Data hashing matters

The shared envelope includes a data hash because "what exact source state generated this?" is a legitimate operational question.

Docs and schemas matter

--robot-docs and --robot-schema are not decorative. They help make the machine-facing surface inspectable and regression-resistant.

Test layers matter

Conformance, schema tests, e2e coverage, and snapshots are all part of building trust that the tool means what it says.

Future Research and Expansion Ideas

These are not promises; they are plausible directions that fit the design of the system:

  • richer search ranking and explainability
  • deeper causal / impact-path reasoning
  • stronger recommendation feedback loops
  • broader workspace-scale planning and aggregation views
  • more operator workflows in the TUI
  • more analysis surfaces that stay coherent with the shared analyzer model

Limitations

What bvr does not do perfectly yet

  • Legacy TUI parity is still in progress. The TUI is functional and much broader than a toy interface, but the project is still actively refining operator workflows relative to legacy bv.
  • Distribution is still Cargo-centric. The repo does not currently ship a dedicated curl installer, Homebrew formula, or packaged release manager workflow in this README.
  • Some surfaces are newer than the older README era. Search, correlation feedback, drift, file intel, and some label flows are current capabilities, but they are evolving quickly.
  • This is a CLI/TUI/dashboard tool, not a hosted service. You bring the .beads data, git history, and deployment target.

FAQ

Is bvr just a Rust rewrite of bv?

It started there, but the current repo now includes Rust-native surfaces such as richer pages export workflows, drift and baseline tooling, correlation review commands, file intelligence, and a broader TUI.

Should agents use the TUI?

Usually not. Agents and scripts should prefer --robot-* with json or toon; the TUI is for humans.

What should I run first?

Start with:

bvr --robot-next
bvr --robot-triage
bvr --robot-plan

Can it work across multiple repos?

Yes. Use .bv/workspace.yaml, then either let bvr discover it or pass --workspace explicitly.

Does it only read .beads/beads.jsonl?

No. It also supports compatibility filenames such as issues.jsonl and beads.base.jsonl, along with workspace aggregation.

Can I share results without giving people the repo?

Yes. Export a static bundle:

bvr --export-pages ./bv-pages
bvr --preview-pages ./bv-pages

Is TOON optional?

Yes. JSON remains the default. TOON is there for more compact agent-facing output.

Development Notes

Build metadata

build.rs embeds build timestamp, target triple, and rustc metadata via vergen-gix.

CI

GitHub Actions currently runs:

  • format + clippy
  • unit + snapshot verification
  • conformance + schema validation
  • e2e and integration suites
  • benchmark smoke
  • release build artifact creation

About Contributions

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 the OpenAI/Anthropic rider. See LICENSE.