Skip to content

feat: beads-backed dev-loop information surfacing - #140

Merged
George-RD merged 1 commit into
mainfrom
feature/loop-info-surfacing
Jun 23, 2026
Merged

feat: beads-backed dev-loop information surfacing#140
George-RD merged 1 commit into
mainfrom
feature/loop-info-surfacing

Conversation

@George-RD

Copy link
Copy Markdown
Collaborator

Why

Driving /cairn-loop once shows it repeatedly falls out of cairn into bd/grep/session-handoff.md at exactly the moments it needs to know what to work on next, what a task touches, the provenance for an area, and where to resume. Those are cairn's job. This wires cairn to surface them directly, in both the text CLI and the structured JSON/MCP interface.

Since this repo uses bd as cairn's task layer, cairn reads the beads export to surface ready work (read-only; beads stays the single source of truth).

What

Loop fallback cairn substitute text json
bd ready cairn next / context Backlog / status Next recommended
bd show <id> cairn get <bead> (status/priority/type/node + full description)
grep meta/decisions cairn decisions --grep <kw>
session-handoff.md cairn status Next recommended + recent log
  • src/state/backlog.rs: read-only loader of .beads/issues.jsonl.
  • Blocker-aware ready(): excludes beads blocked by open work (bd ready parity); a closed/absent blocker does not block; parent-child is not a blocker.
  • cairn-node:<id> link label is parsed (forward-compatible; none set yet).
  • JSON/MCP parity lives in the canonical query_api handlers; fixed cairn next --json (was CAIRN_QUERY_UNKNOWN_TOOL).

Tests / gates

New unit tests: backlog reader, blocker logic, query_api parity handlers. All green: cargo clippy --all-targets --all-features -- -D warnings, cargo test (1359 pass / 5 ignored), cairn scan (0 findings), cairn hook all (pass).

Notes

The autoresearch benchmark harness (autoresearch.sh) that grounded this work is intentionally not included; it lives on the autoresearch/... branch. Happy to land it separately as a dogfood regression guard if wanted.

Drive /cairn-loop once and it falls out of cairn into bd/grep/handoff at exactly
the moments it needs to know what to work on next, what a task touches, the
provenance for an area, and where to resume. This wires cairn to surface that
information directly, in both the text CLI and the structured json/MCP interface.

- decisions --grep <kw>: keyword search over decision id/body/nodes (no node arg)
- src/state/backlog.rs: read-only loader of the beads export (.beads/issues.jsonl);
  beads stays the single source of truth, cairn only reads it
- cairn next: recommends the top ready bead when the graph is clean
- cairn context: 'Backlog: N ready' section
- cairn get <bead>: resolves a task id to status/priority/type/linked-node +
  full description (a bd show substitute); cairn-node:<id> link is forward-compatible
- cairn status: 'Next recommended' continuity line
- json/MCP parity via query_api handlers (status/context/get) + next --json fixed
- blocker-aware ready(): excludes beads blocked by open work (bd-ready parity)

Tests: backlog reader + blocker logic + query_api parity handlers. All gates green
(clippy -D warnings, cargo test, cairn scan clean, cairn hook all).
@coderabbitai

coderabbitai Bot commented Jun 23, 2026

Copy link
Copy Markdown

Review Change Stack

Caution

Review failed

Pull request was closed or merged during review

📝 Walkthrough

Summary by CodeRabbit

  • New Features
    • Decisions command now supports --grep flag for filtering by keyword across decision id, body, and node references
    • Context and status outputs now display backlog information, including ready tasks and next recommended item
    • Query results can fall back to backlog items when graph nodes aren't found, enabling lookup by backlog id

Walkthrough

A new read-only state::backlog module is introduced that loads .beads/issues.jsonl into BacklogItem structs with readiness and blocking logic. This backlog state is then surfaced across the CLI (get fallback, context, status, next) and the query API (get, context, status). A separate --grep flag is added to the decisions command for case-insensitive full-text search.

Changes

Backlog integration and decisions grep

Layer / File(s) Summary
Backlog state module
src/state/backlog.rs, src/state/mod.rs
Defines BacklogItem and Dependency structs with serde deserialization, linked_node/is_open/is_blocked helpers, and read, ready, find public functions; module is declared in state/mod.rs. Includes a full unit test suite covering malformed-line skipping, readiness sorting, blocking logic, and find behavior.
BacklogItem JSON serializers
src/query_api/serialise.rs
Adds backlog_item_json and backlog_item_detail_json that convert BacklogItem into serde_json::Value; the detail variant additionally includes the description field.
Query API handler backlog integration
src/query_api/handlers/project.rs, src/query_api/mod.rs, src/query_api/tests.rs
status_json adds next_recommended; context_json gains a root parameter and returns a backlog object. The get tool falls back to backlog::find when the graph node is missing, returning backlog_item_detail_json. Three new integration tests validate context, status, and get behaviors against a seeded backlog project.
CLI renderer backlog integration
src/cli/render/node.rs, src/cli/render/project.rs, src/cli/render/remediate.rs
render_get adds a backlog::find fallback path with a render_backlog_item helper. render_context gains root and appends up to 5 ready items. render_status adds a "Next recommended" line. render_next replaces fixed clean-state output with backlog-aware human text and JSON. Tests updated with temp backlog directories.
Decisions --grep rendering
src/cli/render/artefacts.rs
Adds render_decisions_grep performing case-insensitive matching against decision id, body, or node ids with optional --status filtering and different JSON vs human output. render_decisions short-circuits to this path when --grep is present. Includes unit tests for body matching, no-node-arg mode, JSON output shape, and status filtering.
CLI dispatch wiring
src/cli/mod.rs
Routes decisions --grep away from run_shared_json_command; passes root to render_get and render_context; removes "next" from uses_shared_json.

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant CLI_or_QueryAPI as CLI / Query API
  participant state_backlog as state::backlog
  participant issues_jsonl as .beads/issues.jsonl

  Client->>CLI_or_QueryAPI: get <bead-id>
  CLI_or_QueryAPI->>CLI_or_QueryAPI: query::get (graph lookup) → fails
  CLI_or_QueryAPI->>state_backlog: find(root, bead-id)
  state_backlog->>issues_jsonl: read JSONL lines
  issues_jsonl-->>state_backlog: raw records
  state_backlog-->>CLI_or_QueryAPI: BacklogItem
  CLI_or_QueryAPI-->>Client: rendered backlog item

  Client->>CLI_or_QueryAPI: context / status / next
  CLI_or_QueryAPI->>state_backlog: read(root) + ready(items)
  state_backlog->>issues_jsonl: read JSONL lines
  issues_jsonl-->>state_backlog: raw records
  state_backlog-->>CLI_or_QueryAPI: sorted ready BacklogItems
  CLI_or_QueryAPI-->>Client: response with backlog/next_recommended fields
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • cairn-framework/cairn#92: Introduced the context tool/renderer and dispatch wiring that this PR extends by adding root propagation and backlog-derived fields.

Poem

🐰 Hippity-hoppity, tasks in a queue,
The backlog now hops into every view!
issues.jsonl parsed line by line,
"Next recommended" — oh how divine!
With grep on decisions, the warren is bright,
A ready-sorted backlog, everything right! ✨


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error)

Check name Status Explanation Resolution
Docstring Coverage ❌ Error Docstring coverage is 75.47% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly summarizes the main feature: adding beads-backed information surfacing to improve the dev loop, which matches the extensive changes across multiple files to integrate backlog data.
Description check ✅ Passed The description comprehensively explains the motivation, implementation details, feature scope, and verification steps—all directly related to the changeset's goal of surfacing backlog information through cairn.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/loop-info-surfacing

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant