Skip to content

feat(0.20.0): bstack cross-review CLI — restore P20 mechanism (BRO-1227 Fix B)#51

Merged
broomva merged 1 commit into
mainfrom
feat/bro-1227-cross-review-cli
May 22, 2026
Merged

feat(0.20.0): bstack cross-review CLI — restore P20 mechanism (BRO-1227 Fix B)#51
broomva merged 1 commit into
mainfrom
feat/bro-1227-cross-review-cli

Conversation

@broomva
Copy link
Copy Markdown
Owner

@broomva broomva commented May 22, 2026

Summary

  • Closes BRO-1227 via Fix B. Ships bstack cross-review <pr-num> --repo <owner/name> — a CLI that performs cross-vendor adversarial review of a GitHub PR by reading content via gh pr diff + gh api …/contents/<path>?ref=<sha>. Working-tree state is eliminated as a variable — the CLI works from any cwd; only --repo + PR number matter.
  • Failure mode this PR closes: during the 2026-05-21 Wave 3 dispatch, both Cato sub-agent invocations stalled within 6-7 tool uses because they tried to Read files from the local working tree, which was on a different branch than the PR's head SHA. The agents drifted into "let me locate the actual repo" loops and never produced output.
  • Verdict schema (anti-slop): verdict (pass/concerns/fail/skipped) × anti_slop_score (0-10) × criticality (high/medium/low) × findings[] × blind_spots_surfaced[] × summary. Anti-slop score ≥7/10 required for pass. Exit codes 0/10/20/30 (pass/concerns/fail/skipped); 2 on invocation/gh failure.

What ships

  • NEW scripts/cross-review.py (~340 LOC) — argparse CLI, the Python module
  • NEW bin/bstack-cross-review (16 LOC) — thin shim mirroring bin/bstack-wave
  • NEW tests/cross-review.test.sh (8 tests) — hermetic offline smoke
  • CHANGED bin/bstack — adds cross-review) dispatch + usage/Examples entries
  • CHANGED SKILL.md — Quick start lists the new subcommand
  • CHANGED VERSION0.19.0 → 0.20.0
  • CHANGED CHANGELOG.md — full 0.20.0 entry

P14 dep-chain

Upstream: gh CLI (required; fail-fast if absent), codex CLI (optional; graceful degradation to verdict=skipped if missing), Python 3.8+ (stdlib only), bin/bstack dispatcher, ~/broomva/bstack/scripts/ directory, BRO-1227 (this PR's ticket).

Downstream:

  • broomva/cross-review skill at ~/.claude/skills/cross-review/ (currently absent — Fix C scope, deferred follow-up)
  • ~/.claude/agents/Cato.md — still callable independently; this CLI is the recommended path for PR-scoped review
  • All future P20-required PRs (auth, crypto, infra)
  • Retro-review queue: broomva.tech#195, broomva.tech#196, life#1427 — three PRs that merged last session without P20. Post-merge bstack cross-review <N> --repo <owner/name> --post-comment will attach verdicts; not in this PR.

P11 validation executed

```
bash -n bin/bstack bin/bstack-cross-review # syntax OK
python3 -m py_compile scripts/cross-review.py # OK
bin/bstack --help | grep cross-review # 2 lines surface
bin/bstack cross-review --help # argparse usage
bin/bstack cross-review 195 --repo broomva/broomva.tech --dry-run # 9 files (8 real + 1 lock skipped)
bash tests/cross-review.test.sh # 8/8 pass
```

End-to-end smoke (codex exec network-bound): deferred to operator-driven first invocation. The CLI emits verdict=skipped with the codex-missing reason when codex is unavailable, so the gate is observable, not silent.

Why Fix B (not A or C)

  • Fix A (add --cwd parameter to Cato dispatch) leaves the working-tree-state coupling intact. Failure mode returns next time someone Catos across repos.
  • Fix B (always read from git via gh, never the working tree) eliminates the failure mode by construction.
  • Fix C (full ~/.claude/skills/cross-review/ skill + Cato re-architecture + tmp-checkout pipeline) is the complete answer but larger blast radius. Deferred until Fix B has soaked through ≥3 P20 invocations.

P20 status on this PR

This PR ships the P20 mechanism itself, so a self-referential bootstrap exemption applies: the new CLI cannot review its own merge (the binary doesn't yet exist on main). Manual P20 via the broken Cato path is exactly the failure this PR fixes. Once merged, future PRs can use bstack cross-review against this PR retrospectively if desired.

What this PR does NOT do

  • Apply the new CLI to the 3 retro-review PRs (broomva.tech#195, #196, life#1427). That's a follow-up — no code change needed; just CLI invocations against existing merged PRs.
  • Ship the full Fix C ~/.claude/skills/cross-review/ skill repo + Cato re-architecture. Larger blast radius; deferred.

Test plan checklist

  • bash -n bin/bstack-cross-review syntax check
  • python3 -m py_compile scripts/cross-review.py syntax check
  • bin/bstack --help lists cross-review
  • bin/bstack cross-review --help returns argparse usage
  • bin/bstack cross-review 195 --repo broomva/broomva.tech --dry-run fetches 9 files
  • bash tests/cross-review.test.sh — 8/8 pass
  • Manual end-to-end: bin/bstack cross-review 195 --repo broomva/broomva.tech against a real PR with codex installed (operator-driven post-merge)

Backreferences

  • Linear: BRO-1227 — P20 cross-review mechanism gap (closes via Fix B)
  • Session handoff: /Users/broomva/conductor/archived-contexts/broomva/wave-3-dispatch-and-linear-updates/handoffs/2026-05-22-SESSION-HANDOFF.md §"Queued + ready to dispatch"
  • CLAUDE.md §"Cross-Review (P20)" — the discipline rule this mechanism enforces

🤖 Generated with Claude Code

…27 Fix B)

Closes the cross-vendor adversarial review gap that surfaced during the
2026-05-21 Wave 3 dispatch: both Cato sub-agent invocations stalled within
6-7 tool uses with path-resolution errors, because they tried to Read
files from the local working tree while it was on a different branch
than the PR's head SHA.

Fix B (this PR) reads PR contents via `gh pr diff` + `gh api
repos/.../contents/<path>?ref=<sha>`. Working-tree state is eliminated as
a variable — invokable from any cwd; only --repo + PR number matter.

## P14 dep-chain

Upstream:
- bin/bstack (dispatcher) — adds cross-review case
- scripts/cross-review.py — new Python module
- bin/bstack-cross-review — new shim (mirrors bstack-wave pattern)
- gh CLI — must be installed + authenticated (fail-fast if absent)
- codex CLI — optional; graceful degradation to verdict=skipped if missing

Downstream:
- broomva/cross-review skill at ~/.claude/skills/cross-review/ — Fix C
  follow-up; this PR is the substrate
- ~/.claude/agents/Cato.md — still callable independently; this CLI is
  the recommended path for PR-scoped review
- All future P20-required PRs (auth, crypto, infra)
- broomva.tech#195, #196 + life#1427 — retro-review queue (post-merge);
  use `bstack cross-review <N> --repo <owner/name> --post-comment` to
  attach verdicts

## P11 validation gates executed

  bash -n bin/bstack bin/bstack-cross-review       # syntax OK
  python3 -m py_compile scripts/cross-review.py    # OK
  bin/bstack --help | grep cross-review            # 2 lines surface
  bin/bstack cross-review --help                   # argparse usage
  bin/bstack cross-review 195 --repo broomva/broomva.tech --dry-run
    → 9 files fetched (8 real + 1 lock skipped), diff 53039 bytes
  bash tests/cross-review.test.sh                  # 8/8 pass

End-to-end smoke (codex exec network bound) — operator-driven; the CLI
emits verdict=skipped with the codex-missing reason when codex is
unavailable, so the gate is observable not silent.

## What this PR does NOT do

- Apply the new CLI to the 3 retro-review PRs (#195, #196, life#1427).
  That's a follow-up — no code change needed.
- Ship the full Fix C ~/.claude/skills/cross-review/ skill repo + Cato
  re-architecture. Larger blast radius; deferred until Fix B soaks ≥3
  P20 invocations.

## Why Fix B over A or C

A: --cwd parameter to Cato. Leaves working-tree coupling intact;
   failure mode returns next time someone Cato's across repos.
B (this PR): always read from git via gh. Eliminates the failure mode by
   construction.
C: full skill + agent + tmp-checkout pipeline. Complete answer but
   larger blast radius. Deferred to a follow-up.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@linear
Copy link
Copy Markdown

linear Bot commented May 22, 2026

BRO-1227

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented May 22, 2026

Warning

Review limit reached

@broomva, we couldn't start this review because you've used your available PR reviews for now.

Your plan currently allows 1 review/hour. Refill in 10 minutes and 18 seconds.

Your organization has run out of usage credits. Purchase more in the billing tab.

⌛ How to resolve this issue?

After more review capacity refills, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than trial, open-source, and free plans. In all cases, review capacity refills continuously over time.

Please see our FAQ for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: fd0046ce-71f6-4f80-984a-fc8c0882956e

📥 Commits

Reviewing files that changed from the base of the PR and between f2bf9ce and 16ea1d6.

📒 Files selected for processing (7)
  • CHANGELOG.md
  • SKILL.md
  • VERSION
  • bin/bstack
  • bin/bstack-cross-review
  • scripts/cross-review.py
  • tests/cross-review.test.sh
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/bro-1227-cross-review-cli

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 and usage tips.

@broomva broomva merged commit ac42639 into main May 22, 2026
4 of 5 checks passed
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