fix(file-safety): refuse writes into git-managed state under .git directories - #78806
Open
andrexibiza wants to merge 3 commits into
Open
fix(file-safety): refuse writes into git-managed state under .git directories#78806andrexibiza wants to merge 3 commits into
andrexibiza wants to merge 3 commits into
Conversation
…files Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>
….git pointer guard The shared deny-layer guard (file_safety) covers FileOperations verbs; the write_file_tool entry point and the V4A patch wrapper guard via _check_sensitive_path. Wire the same worktree .git pointer check there so every mutating file surface refuses pointer-file targets, and add wrapper-level regression tests. Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>
…ectories Signed-off-by: andrexibiza <84248988+andrexibiza@users.noreply.github.com>
This was referenced Aug 4, 2026
14 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Related #76246 #78565 #78652 #78653 #78793
Summary
write_file/patch/delete/movesilently rewrite git-managed state inside anormal repository's
.gitdirectory (HEAD, index, refs/, objects/, logs/,packed-refs, ...). Reproduced on current main:
.git/HEAD→ repo jumps to a phantom branch (On branch nonexistent),git logfatal.git/refs/heads/x→git fsck: invalid sha1 pointer deadbeef….git/index→git status/git fsckfatal:index file smaller than expectedThe #78565 guard (worktree
.gitpointer FILES, PR #78652) does not cover this — a.gitcomponent that is a DIRECTORY passes it. This PR closes the class: git-managedstate under a
.gitdirectory is refused; user-owned paths stay writable.Fix
agent/file_safety.py:find_git_managed_state_target(resolved_path)— walks every.gitcomponent; forDIRECTORY components, classifies the remainder: refused unless user-owned
(allowlist:
config,hooks/*,info/exclude,description); empty remainder(the
.gitdir itself) refused;.gitFILE components are left to the existingpointer check.
git_managed_statewired into_classify_write_denialandget_write_denied_errorwith a corruption-explaining message (use terminal gitinstead).
tools/file_tools.py:_check_sensitive_path(thewrite_file_tool/V4A wrapper surface).
Allowlist verified against git's repository-layout semantics: git itself never
rewrites
config,hooks/*,info/exclude,descriptionduring normal operations —those are user-owned; everything else under
.gitis git state.Class audit (verified at this SHA): every mutating file surface is chokepointed through
get_write_denied_error(write_file :1457, patch_replace :1675,_python_delete:1351, move_file :1397) or
_check_sensitive_path(write_file_tool, patch_tool V4Aincl. both Move endpoints); V4A ops route through guarded methods; the ACP shim passes
the same guard. A rule in both functions = zero bypass through tools. Reads stay
permissive; terminal unaffected. Bare repositories (no
.gitcomponent) remain out ofscope, noted for a separate hardening.
Note on the branch base
The #78565 guard family is not yet on main (open PR #78652). This branch cherry-picks
its two commits (
6499b55335,90483f2fe3) as the foundation — the git-state testsdepend on the pointer guard existing. When #78652 merges, those hunks dedupe; the new
material here is the git-managed-state guard (HEAD of the branch).
Tests
tests/tools/test_write_deny.py— refuse:.git/HEAD,.git/index,.git/refs/heads/x,.git/objects/ab/cdef,.git/logs/HEAD,.git/packed-refs,.git/ORIG_HEAD,.git/COMMIT_EDITMSG,.git/info/refs,.gititself; allow:.git/config,.git/hooks/pre-commit,.git/hooks/applypatch-msg,.git/info/exclude,.git/description, sibling files outside.git, and theworktree-pointer cases.
tests/tools/test_file_write_safety.py—_check_sensitive_pathsurface, sameallow/refuse split.
git-state classes).
Links
C:/tmp/wtgitstate-verify-scratch/verify-report.mdC:/tmp/wtgitstate-allow/class-audit-report.mdPart of #78565