Conversation
Suppress post-checkout hooks during worktree creation by passing -c core.hooksPath=/dev/null to git worktree add. Add commitWithHookRetry helper that retries commits up to 3 times when pre-commit hooks fail, running the agent between attempts to fix the issues the hook flagged. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Address review findings: - Add HasExecutableHook to gate retries: non-hook commit failures (missing identity, empty commit, lockfile) return immediately without invoking the agent. - Add verifyRepoState checks before and after each agent fix run to abort if HEAD or branch drifts during the retry loop. - Add TestCommitWithHookRetrySkipsNonHookError covering the non-hook failure path. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined ReviewVerdict: Changes should not merge yet; there are unresolved High and Medium issues in the new hook-retry flow. High
Medium
Synthesized from 4 reviews (agents: codex, gemini | types: security, default) |
Address review findings:
- Add CommitError type with Phase field ("add" vs "commit") to
git.CreateCommit. commitWithHookRetry now only retries on
commit-phase failures with a hook present — add-phase errors
(index.lock, permissions) return immediately.
- Replace hardcoded /dev/null with os.DevNull for platform safety.
- Add TestCommitWithHookRetrySkipsAddPhaseError: verifies that an
index.lock failure is not misclassified as a hook failure even
when a pre-commit hook is installed.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined ReviewVerdict: Changes are directionally good, but there are 2 actionable issues (1 High, 1 Medium) that should be addressed before merge. High
Medium
Synthesized from 4 reviews (agents: codex, gemini | types: security, default) |
Add isPreCommitHookFailing that re-runs the hook after a commit failure to confirm it is actually rejecting. Set HookFailed flag on CommitError so commitWithHookRetry only retries when the hook is positively identified as the cause — commit-phase errors with a passing hook (e.g. nothing to commit, missing identity) are no longer misclassified as hook failures. Add TestCommitWithHookRetrySkipsCommitPhaseNonHookError covering the case where a hook is installed but the commit fails for an unrelated reason. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined ReviewVerdict: Changes introduce a meaningful security/regression risk in hook-failure handling and prompt construction that should be addressed before merge. High
Medium
Synthesized from 4 reviews (agents: codex, gemini | types: security, default) |
…etection Replace isPreCommitHookFailing's direct hook execution with "git commit --dry-run --no-verify" which avoids env mismatches (missing GIT_INDEX_FILE, etc.) that occur when running hooks outside git's normal commit flow. Remove now-unused HasExecutableHook. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add TestRepo.InstallHook in git_test.go and installGitHook in refine_test.go to replace repeated hooksDir/MkdirAll/WriteFile blocks across 8 test functions. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Rename isPreCommitHookFailing to isHookCausingFailure since the dry-run probe bypasses all hooks (--no-verify), not just pre-commit. Update messaging and agent prompt to say "hook" instead of "pre-commit hook". Add test for commit-msg hook failure detection. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined ReviewVerdict: Changes introduce one High and three Medium issues that should be addressed before merge. High
Medium
Synthesized from 4 reviews (agents: codex, gemini | types: security, default) |
Hook stderr forwarded to agents or the terminal is local-only data from the user's own scripts. Suppress false-positive findings for prompt injection, secret exposure, and unbounded capture of hook output. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
roborev: Combined ReviewVerdict: Changes are not yet merge-ready due to 3 Medium-severity issues. Medium
Synthesized from 4 reviews (agents: codex, gemini | types: security, default) |
roborev: Combined ReviewVerdict: 1 Medium-severity regression to address before merge; no security issues were identified. Medium
Synthesized from 4 reviews (agents: codex, gemini | types: security, default) |
## Summary - Strip `CLAUDECODE` from the child process environment when spawning the claude-code agent, preventing Claude Code's nested-session guard from rejecting the spawn - Make `filterEnv` variadic to support stripping multiple env vars cleanly - Add test for multi-key filtering Same class of fix as #267 (`GIT_DIR` stripping for daemon spawn). When the daemon starts from within a Claude Code session, or post-commit hooks fire during one, `CLAUDECODE` gets inherited by worker processes and Claude Code refuses to launch. Closes #270 ## Test plan - [x] `go test ./internal/agent/` passes (including new `TestFilterEnvMultipleKeys`) - [x] `go vet ./...` clean - [x] Manual: start daemon from within Claude Code session, verify reviews succeed 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
## Summary Closes roborev-dev#258. - Suppress post-checkout hooks during worktree creation by passing `-c core.hooksPath=/dev/null` to `git worktree add`. User hooks are irrelevant in internal worktrees and shouldn't kill the refine loop. - Add `commitWithHookRetry` helper that retries commits up to 3 times when a pre-commit hook rejects, running the agent between attempts to fix the flagged issues. - Only retry when a pre-commit hook is actually installed (`HasExecutableHook` check). Non-hook commit failures (missing identity, empty commit, lockfile) return immediately. - Add HEAD/branch safety checks before and after each agent fix run to abort if repo state drifts during the retry loop. ## Test plan - [ ] `TestCreateTempWorktreeIgnoresHooks` — worktree creation succeeds despite a failing post-checkout hook - [ ] `TestCommitWithHookRetrySucceeds` — retry succeeds when hook fails once then passes - [ ] `TestCommitWithHookRetryExhausted` — proper error after 3 failed attempts - [ ] `TestCommitWithHookRetrySkipsNonHookError` — non-hook failures return immediately without retrying - [ ] `TestCreateCommitPreCommitHookOutput` — `CreateCommit` includes hook stderr in error messages - [ ] Full suite: `go test ./...` 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
…#273) ## Summary - Strip `CLAUDECODE` from the child process environment when spawning the claude-code agent, preventing Claude Code's nested-session guard from rejecting the spawn - Make `filterEnv` variadic to support stripping multiple env vars cleanly - Add test for multi-key filtering Same class of fix as roborev-dev#267 (`GIT_DIR` stripping for daemon spawn). When the daemon starts from within a Claude Code session, or post-commit hooks fire during one, `CLAUDECODE` gets inherited by worker processes and Claude Code refuses to launch. Closes roborev-dev#270 ## Test plan - [x] `go test ./internal/agent/` passes (including new `TestFilterEnvMultipleKeys`) - [x] `go vet ./...` clean - [x] Manual: start daemon from within Claude Code session, verify reviews succeed 🤖 Generated with [Claude Code](https://claude.com/claude-code) --------- Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
Summary
Closes #258.
-c core.hooksPath=/dev/nulltogit worktree add. User hooks are irrelevant in internal worktrees and shouldn't kill the refine loop.commitWithHookRetryhelper that retries commits up to 3 times when a pre-commit hook rejects, running the agent between attempts to fix the flagged issues.HasExecutableHookcheck). Non-hook commit failures (missing identity, empty commit, lockfile) return immediately.Test plan
TestCreateTempWorktreeIgnoresHooks— worktree creation succeeds despite a failing post-checkout hookTestCommitWithHookRetrySucceeds— retry succeeds when hook fails once then passesTestCommitWithHookRetryExhausted— proper error after 3 failed attemptsTestCommitWithHookRetrySkipsNonHookError— non-hook failures return immediately without retryingTestCreateCommitPreCommitHookOutput—CreateCommitincludes hook stderr in error messagesgo test ./...🤖 Generated with Claude Code