Summary
Found via code audit. The ratchet loop's git operations are overly aggressive and can destroy unrelated user work.
Bug 1: `git add -A` stages ALL files (HIGH)
File: `recursive_improve/ratchet/git_ops.py`, line 27
The ratchet loop blindly stages ALL files. If a user has unrelated drafts, data files, or `.env` files, they get committed.
Bug 2: `git clean -fd` deletes untracked files on revert (HIGH)
File: `recursive_improve/ratchet/git_ops.py`, lines 45-47
On revert, `git checkout -- .` + `git clean -fd` destroys all untracked files in the repo.
Fix: Track which files the improvement step touched and only stage/revert those specific files.
Bug 3: Git commands silently succeed on error (MEDIUM)
File: `recursive_improve/ratchet/git_ops.py`, lines 20-24
`git status --porcelain` result is never checked for errors. If git is not installed or the directory is not a repo, the function silently returns None (as if nothing needs committing), losing changes.
Fix: Add `check=True` or verify `result.returncode == 0`.
Found via code audit.
Summary
Found via code audit. The ratchet loop's git operations are overly aggressive and can destroy unrelated user work.
Bug 1: `git add -A` stages ALL files (HIGH)
File: `recursive_improve/ratchet/git_ops.py`, line 27
The ratchet loop blindly stages ALL files. If a user has unrelated drafts, data files, or `.env` files, they get committed.
Bug 2: `git clean -fd` deletes untracked files on revert (HIGH)
File: `recursive_improve/ratchet/git_ops.py`, lines 45-47
On revert, `git checkout -- .` + `git clean -fd` destroys all untracked files in the repo.
Fix: Track which files the improvement step touched and only stage/revert those specific files.
Bug 3: Git commands silently succeed on error (MEDIUM)
File: `recursive_improve/ratchet/git_ops.py`, lines 20-24
`git status --porcelain` result is never checked for errors. If git is not installed or the directory is not a repo, the function silently returns None (as if nothing needs committing), losing changes.
Fix: Add `check=True` or verify `result.returncode == 0`.
Found via code audit.