Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Tighten hook classification, add refine targeting flags, improve TUI hint bar#272

Merged
wesm merged 11 commits intomainfrom
follow-ups
Feb 16, 2026
Merged

Tighten hook classification, add refine targeting flags, improve TUI hint bar#272
wesm merged 11 commits intomainfrom
follow-ups

Conversation

@wesm
Copy link
Collaborator

@wesm wesm commented Feb 16, 2026

Summary

  • Tighten hook failure classification: isHookCausingFailure now requires at least one commit hook to be installed before classifying a failure as hook-caused. Prevents GPG signing errors and other non-hook failures from triggering agent retry loops. Includes IsDir guard to skip directories named like hooks.
  • Add --branch, --all-branches, --list, --newest-first to refine: Match the targeting flags from fix so the two commands have consistent interfaces. Includes refineOptions struct refactor, queryUnaddressedJobs returning full jobs, and git.CheckoutBranch helper.
  • Fix --newest-first ordering: Sort branches by most recent failed job timestamp instead of alphabetical order.
  • Fix --all-branches error handling: Return non-nil error when any branch fails refinement. Restore detached-HEAD state correctly. Reset dirty working tree between branches to prevent cascade failures.
  • Fix --list edge cases: Reject --list --since (previously silently ignored). Use correct worktree root for branch detection in linked worktrees. Fail fast when not in a git repo.
  • Tighten test assertions: Flag validation tests catch all validation error patterns.
  • Improve TUI hint bar (closes TUI status bar missing c (comment) keyboard shortcut #271): Add a second hint line to the review view showing action shortcuts (p: prompt | c: comment | m: commit msg | a: addressed | y: copy). Change ?: help to ?: commands in all TUI views. Only advertises keys that work in review view.

Fixes #271

Test plan

  • go test ./... passes
  • go vet ./... clean
  • Manual: roborev refine --list
  • Manual: roborev refine --list --all-branches
  • Manual: roborev refine --branch <current-branch>
  • Manual: Verify TUI review view shows both hint lines with correct keys

🤖 Generated with Claude Code

wesm and others added 5 commits February 16, 2026 06:45
isHookCausingFailure could misclassify non-hook commit failures
(e.g., GPG signing errors) as hook-caused, because the dry-run
probe passes for any failure that isn't about staged changes or
identity. The retry logic would then waste agent runs on an
unfixable root cause.

Add a hasCommitHooks guard: if no commit hooks (pre-commit,
prepare-commit-msg, commit-msg) are installed, the failure
cannot be hook-caused regardless of the probe result.

Add tests for the GPG false-positive path and hook detection.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Match the targeting flags from `fix` so the two commands have consistent
interfaces:

- --branch: validates the user is on the named branch (guardrail, not
  a branch switch)
- --all-branches: discovers branches with failed reviews via the daemon
  API, checks out each one, runs the refine loop, then restores the
  original branch
- --list: shows failed reviews that would be refined without running
- --newest-first: controls processing order for --list and --all-branches

Refactors:
- runRefine now takes a refineOptions struct instead of 8 positional params
- validateRefineContext gains a branchFlag parameter
- queryUnaddressedJobs in fix.go now returns []storage.ReviewJob; the
  old []int64 behavior moves to queryUnaddressedJobIDs
- New git.CheckoutBranch helper in internal/git/git.go

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Address review findings from job 5469:

- --newest-first now sorts branches by most recent failed job
  timestamp instead of reverse-alphabetical order
- --all-branches returns a non-nil error when any branch fails
  refinement, after attempting all branches and restoring the
  original branch
- Add flag validation tests (mutual exclusivity combos)
- Add --branch validation tests (mismatch and match cases)

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- --list and --since are now mutually exclusive. Previously --since
  was silently ignored when combined with --list, making the output
  misleading about what would actually be refined.

- runRefineList now uses GetRepoRoot for branch detection (correct
  for linked worktrees) and GetMainRepoRoot only for the daemon API
  query path. Previously both used GetMainRepoRoot, which could read
  the main worktree's branch instead of the current worktree's.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
- runRefineAllBranches now captures original HEAD SHA and restores
  detached-HEAD state after processing branches (previously left user
  on the last processed branch)
- runRefineList fails fast when not in a git repo instead of silently
  falling back to cwd for daemon queries
- Flag validation tests now catch all validation error patterns, not
  just "mutually exclusive"

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@roborev-ci
Copy link

roborev-ci bot commented Feb 16, 2026

roborev: Combined Review

Verdict: Changes are mostly solid, but there is one Medium-severity security issue that should be fixed before merge.

Medium

  1. Git argument/option ambiguity in branch checkout
    • Location: internal/git/git.go:866 (called from cmd/roborev/refine.go:828, cmd/roborev/refine.go:851, cmd/roborev/refine.go:860)
    • Issue: CheckoutBranch executes git checkout <branch> with branch input that can originate from daemon/API/DB job data. If malformed (for example, starts with -), Git may interpret it as an option or unintended revision target.
    • Recommended fix: Treat branch input as untrusted. Validate branch names (git check-ref-format --branch), ensure it resolves to a local head (refs/heads/<name>), and use explicit checkout semantics (for example, -- separator and/or separate branch vs SHA checkout paths).

Synthesized from 4 reviews (agents: codex, gemini | types: security, default)

Add a second hint line above the navigation hints showing key actions
(prompt, comment, cancel, rerun, tail, commit msg). Change "?: help"
to "?: commands" in all TUI views (review, queue, prompt).

Closes #271

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@wesm wesm changed the title Tighten hook classification, add refine targeting flags, fix edge cases Tighten hook classification, add refine targeting flags, improve TUI hint bar Feb 16, 2026
- Remove x/r/t from review hint line (queue-only handlers); replace
  with a/y which do work in review view
- Add IsDir guard in hasCommitHooks to skip directories named like hooks
- Defer HEAD resolution in runRefineAllBranches until needed (only for
  detached-HEAD restore), avoiding failure in unborn repos
- Reset dirty working tree between branches in --all-branches to
  prevent cascade failures after a failed runRefine

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@roborev-ci
Copy link

roborev-ci bot commented Feb 16, 2026

roborev: Combined Review

Verdict: Changes are not clean yet; 3 Medium-severity issues should be addressed before merge.

Medium

  1. Potential git option injection via branch name handling

    • Locations: internal/git/git.go:869, internal/git/git.go:872, cmd/roborev/refine.go:832
    • Why it matters: Branch names are passed to git checkout without strict validation. Names beginning with - can be interpreted as git options, causing unintended behavior.
    • Recommended fix: Validate branch names (git check-ref-format --branch, reject leading -), resolve explicit refs, and/or enforce option termination (--) where appropriate.
  2. Possible data loss in all-branches refine failure path

    • Location: cmd/roborev/refine.go:851
    • Why it matters: On per-branch refine failure with a dirty worktree, git.ResetWorkingTree can discard local user changes.
    • Recommended fix: Prefer fail-fast with clear error and branch restore, or gate destructive reset behind explicit opt-in.
  3. refine --list branch scoping appears inaccurate

    • Locations: cmd/roborev/refine.go:659, cmd/roborev/fix.go:445
    • Why it matters: Reusing queryUnaddressedJobs with branch_include_empty=true can include branchless jobs outside intended branch scope, making list output misleading.
    • Recommended fix: Use strict branch filtering for list mode, or post-filter branchless jobs by ancestry/range.

Synthesized from 4 reviews (agents: codex, gemini | types: security, default)

wesm and others added 2 commits February 16, 2026 07:46
- Gate ResolveSHA("HEAD") with IsUnbornHead check so --all-branches
  does not fail in repos with no commits
- Log ResetWorkingTree errors instead of discarding them
- Add test verifying hasCommitHooks ignores directories named like hooks

Co-Authored-By: Claude Opus 4.6 <[email protected]>
Instead of silently skipping HEAD resolution and later failing on
restore, reject --all-branches upfront when HEAD is unborn (no commits
on current branch). Also guard the restore path against empty
originalHEAD to prevent git checkout "".

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@roborev-ci
Copy link

roborev-ci bot commented Feb 16, 2026

roborev: Combined Review

Verdict: 2 Medium security issues were identified; fix before merge.

Medium

  1. Terminal injection via unsanitized --list output
    Files/lines: cmd/roborev/refine.go:706, cmd/roborev/refine.go:719 (inside runRefineList)
    Finding: API/daemon-provided fields (Branch, CommitSubject, Agent, Model, first line of review.Output) are printed directly to terminal output. Malicious control sequences (ANSI/OSC) could spoof or obscure terminal content.
    Recommended fix: Sanitize untrusted strings before printing (strip/escape control chars and ANSI/OSC sequences) via a shared helper used for all displayed review/job fields.

  2. Unvalidated branch name passed to git checkout
    Files/lines: cmd/roborev/refine.go:806 (in runRefineAllBranches), internal/git/git.go:869 (also reported at internal/git/git.go:868)
    Finding: Branch names sourced from job/API data flow into CheckoutBranch (git checkout <branch>) without strict validation. This is not shell injection, but can still cause Git argument/ref ambiguity (e.g., option-like names, non-branch refs, path/ref ambiguity), leading to unintended checkout behavior.
    Recommended fix: Validate branch names (git check-ref-format --branch), require local refs/heads/<name> existence, and switch using explicit refs (or a safer branch-switch helper such as git switch where supported).


Synthesized from 4 reviews (agents: gemini, codex | types: security, default)

Show queue-specific actions (cancel, rerun, tail, prompt, comment,
copy, commit msg) on a second hint line above the navigation hints,
matching the review view pattern.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@roborev-ci
Copy link

roborev-ci bot commented Feb 16, 2026

roborev: Combined Review

Verdict: One Medium-severity issue should be fixed before merge; no High or Critical findings.

Medium

  1. Potential git option injection in branch checkout
    • Location: internal/git/git.go:867 (also reported at internal/git/git.go:873)
    • Deduplicated from: Review 2, Review 3, Review 4
    • Issue: exec.Command("git", "checkout", branch) can treat a branch/ref starting with - as a git flag, which may cause unintended checkout behavior during branch-processing flows (e.g., --all-branches).
    • Recommended fix: Delimit args with -- (e.g., git checkout -- <branch>) and/or reject option-like ref names before checkout.

Synthesized from 4 reviews (agents: codex, gemini | types: security, default)

Extract queue help strings as constants and compute wrapping at
runtime (matching the review view pattern), instead of hardcoding
reservedLines. Prevents layout desync when help lines wrap on
terminals narrower than ~90 columns.

Co-Authored-By: Claude Opus 4.6 <[email protected]>
@roborev-ci
Copy link

roborev-ci bot commented Feb 16, 2026

roborev: Combined Review

Verdict: 1 Medium-severity issue should be addressed before merge.

Medium

  1. Potential Git option/argument injection via untrusted branch names
    • File/line references: internal/git/git.go:867, internal/git/git.go:868, internal/git/git.go:869, cmd/roborev/refine.go:766, cmd/roborev/refine.go:837
    • Issue: runRefineAllBranches uses branch names from stored job/daemon metadata, and CheckoutBranch passes that value into git checkout <branch>. A malformed value (for example starting with -) can be interpreted by Git as an option/revision instead of a safe local branch ref.
    • Recommended fix: Validate and constrain branch names before checkout (for example git check-ref-format --branch, explicitly reject leading -), resolve to verified local refs (refs/heads/<name>), and invoke checkout in a way that prevents option interpretation of untrusted input.

Synthesized from 4 reviews (agents: codex, gemini | types: security, default)

@wesm
Copy link
Collaborator Author

wesm commented Feb 16, 2026

The windows CI failure is a flake. Merging

@wesm wesm merged commit ebf5478 into main Feb 16, 2026
6 of 7 checks passed
@wesm wesm deleted the follow-ups branch February 16, 2026 14:20
hughdbrown pushed a commit to hughdbrown/roborev that referenced this pull request Feb 16, 2026
…hint bar (roborev-dev#272)

## Summary

- **Tighten hook failure classification**: `isHookCausingFailure` now
requires at least one commit hook to be installed before classifying a
failure as hook-caused. Prevents GPG signing errors and other non-hook
failures from triggering agent retry loops. Includes `IsDir` guard to
skip directories named like hooks.
- **Add `--branch`, `--all-branches`, `--list`, `--newest-first` to
`refine`**: Match the targeting flags from `fix` so the two commands
have consistent interfaces. Includes `refineOptions` struct refactor,
`queryUnaddressedJobs` returning full jobs, and `git.CheckoutBranch`
helper.
- **Fix `--newest-first` ordering**: Sort branches by most recent failed
job timestamp instead of alphabetical order.
- **Fix `--all-branches` error handling**: Return non-nil error when any
branch fails refinement. Restore detached-HEAD state correctly. Reset
dirty working tree between branches to prevent cascade failures.
- **Fix `--list` edge cases**: Reject `--list --since` (previously
silently ignored). Use correct worktree root for branch detection in
linked worktrees. Fail fast when not in a git repo.
- **Tighten test assertions**: Flag validation tests catch all
validation error patterns.
- **Improve TUI hint bar** (closes roborev-dev#271): Add a second hint line to the
review view showing action shortcuts (`p: prompt | c: comment | m:
commit msg | a: addressed | y: copy`). Change `?: help` to `?: commands`
in all TUI views. Only advertises keys that work in review view.

Fixes roborev-dev#271

## Test plan

- [x] `go test ./...` passes
- [x] `go vet ./...` clean
- [ ] Manual: `roborev refine --list`
- [ ] Manual: `roborev refine --list --all-branches`
- [ ] Manual: `roborev refine --branch <current-branch>`
- [x] Manual: Verify TUI review view shows both hint lines with correct
keys

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

---------

Co-authored-by: Claude Opus 4.6 <[email protected]>
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.

TUI status bar missing c (comment) keyboard shortcut

1 participant