|
| 1 | +# Commit Approval Mechanism |
| 2 | + |
| 3 | +## Problem |
| 4 | + |
| 5 | +Despite having "Do **not** commit without explicit user approval" in conventions, Claude Code agents sometimes lose track of this instruction and commit without asking. The recent addition of explicit review language ("Do the changes that I am about to commit look good to you?") may help, but we need a backup enforcement mechanism. |
| 6 | + |
| 7 | +## Proposed Solution |
| 8 | + |
| 9 | +Implement a two-part system similar to the existing `pre-bash-python-check` hook: |
| 10 | + |
| 11 | +### 1. User Approval Command |
| 12 | + |
| 13 | +Create `git approve-staged` (or similar) that: |
| 14 | +- Captures a hash of currently staged changes |
| 15 | +- Creates `.git/COMMIT_APPROVED` sentinel file with the hash |
| 16 | +- Allows user to explicitly approve the current staged changeset |
| 17 | + |
| 18 | +Implementation options: |
| 19 | +- Git alias in project `.gitconfig` |
| 20 | +- Custom script in `.auxiliary/scripts/` |
| 21 | +- Shell function users add to their environment |
| 22 | + |
| 23 | +### 2. PreToolUse Hook |
| 24 | + |
| 25 | +Create `.auxiliary/scripts/claude/pre-git-commit-check` that: |
| 26 | +- Intercepts any `git commit` commands from Claude |
| 27 | +- Checks for valid `.git/COMMIT_APPROVED` file |
| 28 | +- Validates that staged changes hash matches approval hash |
| 29 | +- Blocks commit if approval missing or stale |
| 30 | +- Provides helpful error message directing Claude to request approval |
| 31 | + |
| 32 | +### Workflow |
| 33 | + |
| 34 | +1. User stages changes with `git add` |
| 35 | +2. User reviews changes with `git status` and `git diff --cached` |
| 36 | +3. User approves with `git approve-staged` |
| 37 | +4. Claude can now commit (or user can commit directly) |
| 38 | +5. Any new staging invalidates the approval |
| 39 | + |
| 40 | +### Benefits |
| 41 | + |
| 42 | +- **Explicit approval**: User must take deliberate action to approve changes |
| 43 | +- **Change integrity**: Approval becomes invalid if staged content changes |
| 44 | +- **Familiar pattern**: Follows existing hook architecture |
| 45 | +- **Fail-safe**: Blocks commits even if Claude ignores conventions |
| 46 | +- **Flexible**: Works for both Claude and direct user commits |
| 47 | + |
| 48 | +### Edge Cases to Handle |
| 49 | + |
| 50 | +- Multiple commit attempts with same approval |
| 51 | +- Partial staging after approval |
| 52 | +- Hook failures and error handling |
| 53 | +- Cleanup of stale approval files |
| 54 | +- Integration with existing Git workflows |
| 55 | + |
| 56 | +### Alternative Mechanisms Considered |
| 57 | + |
| 58 | +- **Git pre-commit hook**: Would work but PreToolUse gives better error messages to Claude |
| 59 | +- **Git aliases replacing commit**: Could be confusing for users |
| 60 | +- **Interactive prompts**: Don't work well in Claude Code environment |
| 61 | +- **Existing solutions**: Custom approach gives full control and clean integration |
| 62 | + |
| 63 | +## Next Steps |
| 64 | + |
| 65 | +1. Implement basic `git approve-staged` command |
| 66 | +2. Create PreToolUse hook for git commit blocking |
| 67 | +3. Test with various staging/approval scenarios |
| 68 | +4. Document usage in project conventions |
| 69 | +5. Consider integration with specialized commands that use commits |
| 70 | + |
| 71 | +## Notes |
| 72 | + |
| 73 | +- This enforces the "equal partner" philosophy - user explicitly approves rather than Claude asking permission |
| 74 | +- Maintains token efficiency by not showing diffs in Claude interactions |
| 75 | +- Provides safety net for complex multi-file changes where context might be lost |
0 commit comments