fix(roborev): skip agent hooks outside branch checkouts

Merged
SH
18d ago
+62-0

Summary

  • roborev-agent.sh exits 0 without contacting the daemon when the hook's cwd is not on a branch (detached HEAD or not a git repo).

Why

On matic the RoboRev daemon was pinned at its 250% CPU quota (100/100 periods throttled) and every agent-hook run PostToolUse call failed after 5s with context deadline exceeded.

The daemon's goroutine dump showed the cause. On a detached HEAD, findOpenFailedReviewIDs lists every open failed review in the repo (no branch filter). It then calls git merge-base --is-ancestor once per review, with no context cancellation, on every PostToolUse and Stop event. The monorepo has 2604 open failed reviews, so each event from a detached worktree started thousands of git processes, and about 64 ran at any moment.

With turn_threshold = 0 and commit_threshold = 0, failed-review prompting is the only active agent-hook feature. In detached worktrees it never returned within the client timeout, so skipping those worktrees drops no working behavior.

decided: gate in the shared hook script on git symbolic-ref -q HEAD - one cheap git call; scoping by branch keeps reminders working in branch worktrees
decided: no change to the daemon cgroup quota - the quota was hiding the storm, not causing it

Test plan

  • shellspec spec/roborev_hooks_spec.sh (branch calls the daemon; detached HEAD skips it)
  • shellcheck on the changed files

Upstream follow-up: in internal/agenthook, the detached-HEAD path should batch the reachability check and honor request cancellation.

🤖 Generated with Claude Code


Summary by cubic

Skips RoboRev agent hooks outside branch checkouts, so hooks stop timing out in large repositories.

  • On a detached HEAD, the daemon matches every open failed review in the repo with a git merge-base --is-ancestor call per tool event and keeps going after the client gives up.
  • With about 2600 open failed reviews, events from detached worktrees pinned the daemon at its CPU quota and every agent hook timed out after 5s.
  • The hook now exits 0 before contacting the daemon unless it is inside a git work tree with a symbolic HEAD. Branch checkouts are unaffected; bare repositories and non-repositories are skipped too.