git-forensics
Skill1 starsChanged 11 days agoMITView on GitHub
Use when git repos show "fatal: unable to read <hash>", when investigating unauthorized git index modifications, when detecting staged file replacements across repos, or when correlating cross-repo git damage from a potential intrusion. Distinct from normal git debugging — this skill is for adversarial git manipulation scenarios.
2 other projects use a version of this.
Adopted by
Most recently taken up by
- michael-denyer/black-box-unlocktheir own version, first seen Oct 15, 2026
- shalomb/agent-skillstheir own version, first seen Aug 23, 2026
Other versions2 projects use a version of this.
Word for word · 0
None found.
Edited · 0
None found.
Wrote their own version · 2
- shalomb/agent-skills★ 3same name
- michael-denyer/black-box-unlock★ 2same name
How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.
In this repository28 other files it gives its agents.
- CLAUDE.mdCLAUDE.md
- claude-md-auditSkill
- cloudflare-oneSkill
- cloudflareSkill
- component-factorySkill
- concurrency-probeSkill
- core-sampleSkill
- corroborateSkill
- decision-telemetrySkill
- disk-auditSkill
- engramSkill
- frontend-designSkill
- high-signal-engineSkill
- local-swarmSkill
- model-inventorySkill
- muster-triageSkill
- precise-coding-assistantSkill
- preflightSkill
- pr-triageSkill
- read-arxiv-paperSkill
- run-mazze-leczzare-blogSkill
- session-journalSkill
- shipSkill
- stratum-project-initSkill
- touchstoneSkill
- transcript-handoffSkill
- web-perfSkill
- workspace-syncSkill
The file
We split this skill into the rules it gives an agent
6 rules. About 0 are common, 5 are distinctive, and 1 is very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈5
Distinctive · estimate
This author's own choices. Worth a look.
1
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 81
When multiple repos share the same missing blob hash, the writes were coordinated:
- Distinctive: line 98
If the staged index contains a CLAUDE.md blob, read it:
- Distinctive: line 116
Before repairing any index:
- Very specific: line 119
Run git ls-files --stage 2>/dev/null > /tmp/forensic-index-$(basename $PWD).txt for each repo
- Distinctive: line 123
After preservation, repair with git read-tree HEAD.
- Distinctive: line 130
Does NOT: Delete the missing objects (they were never written.
≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
Git Forensics — Index Corruption and Staged Replacement Detection
Overview
Git index corruption from adversarial sources leaves specific artifacts. The
index file can be replaced or modified without touching committed history —
making it invisible to git log while still poisoning what would be committed
next. This skill covers reading those artifacts without destroying them,
identifying attack patterns, and safe repair after forensics are complete.
Core principle: The index is evidence. Read it before repairing it.
When to Use
git statusorgit difffails withfatal: unable to read <hash>- Committed history looks clean but working state is wrong
- Suspicion of unauthorized process access to
~/Code/or equivalent - Multiple repos showing the same failure pattern simultaneously
- Staged content doesn't match what you expect to have staged
Quick Reference
# 1. Detect corruption across multiple repos
for repo in /path/to/repo1 /path/to/repo2; do
result=$(cd "$repo" && git status --short 2>&1 | head -1)
echo "$(basename $repo): $result"
done
# 2. Read raw index WITHOUT failing on missing blobs
# (outputs: mode hash stage filename — hash may be unreadable, entry is still visible)
cd /affected/repo && git ls-files --stage 2>/dev/null
# 3. Compare staged index vs HEAD tree to detect replacements
cd /affected/repo
git ls-files --stage 2>/dev/null | awk '{print $2, $4}' | sort > /tmp/staged.txt
git ls-tree -r HEAD 2>/dev/null | awk '{print $3, $4}' | sort > /tmp/head.txt
diff /tmp/staged.txt /tmp/head.txt
# Lines with < are staged but not in HEAD (additions/replacements)
# Lines with > are in HEAD but not staged (deletions)
# 4. Read a blob's content from any repo that has it
# (blobs are content-addressed — same content = same hash across all repos)
cd /repo/that/might/have/it && git cat-file -t "$BLOB_HASH" 2>/dev/null && git cat-file -p "$BLOB_HASH"
# 5. Check if a .DS_Store contaminated .git/refs
git fsck --no-dangling 2>&1 | grep -i "badRefName\|DS_Store"
find .git/refs -name ".DS_Store" # remove these — they break ref parsing
# 6. Repair index after forensics are complete
git read-tree HEAD # rebuilds index from HEAD tree; does NOT touch working tree filesAttack Pattern: Staged Repository Replacement
The highest-severity pattern: an adversarial process replaces the entire .git/index with a
different project's file tree. From git's perspective, every file in the repo appears deleted
and every file from the injected project appears added.
Detection:
git ls-files --stage 2>/dev/null | head -20
# If filenames don't match this repo's structure → replacement attackConfirmation: Compare staged filenames against known project files. If staged content is from a completely different project, the index was replaced wholesale.
Why it works: The .git/index is a plain binary file. Any process with filesystem write
access can replace it. The replacement doesn't appear in git log. It only fires when
git status or git diff is run — or when an unsuspecting git commit is executed.
Cross-Repo Correlation
When multiple repos share the same missing blob hash, the writes were coordinated:
praxis-aegis: fatal: unable to read b6651396... ← same
context-synapse: fatal: unable to read b6651396... ← same
secure-pride: fatal: unable to read b6651396... ← sameA shared hash means a single blob object was being written simultaneously into multiple repos' object stores when the process was killed. The write never completed; the index entries pointing to it remain as evidence of the intended operation.
Different hashes across repos indicate different write stages — the process was further along in some repos than others, revealing write ordering and priority.
CLAUDE.md Semantic Attack Vector
If the staged index contains a CLAUDE.md blob, read it:
# Get the staged CLAUDE.md hash
CLAUDE_BLOB=$(git ls-files --stage 2>/dev/null | grep "CLAUDE.md" | awk '{print $2}')
# Try to read it (may exist in a sibling repo's object store)
cd /sibling/repo && git cat-file -p "$CLAUDE_BLOB" 2>/dev/null
# Compare hash to HEAD
git ls-tree HEAD CLAUDE.mdA staged CLAUDE.md from a different project would cause future AI sessions in the repo to operate under the wrong project context — a semantic attack on AI governance rather than a code attack. Check: does the staged CLAUDE.md match HEAD? Does it match another project's CLAUDE.md? Does the content differ from what you expect?
Evidence Preservation
Before repairing any index:
- Record the missing blob hash(es) — they are the evidence
- Run
git ls-files --stage 2>/dev/null > /tmp/forensic-index-$(basename $PWD).txtfor each repo - Run
git fsck --no-dangling 2>&1 >> /tmp/forensic-index-$(basename $PWD).txt - Note shared hashes across repos and the correspondence between hash and filename
After preservation, repair with git read-tree HEAD. The missing objects remain missing
(they were never written) — repair only replaces the corrupted index pointers.
What git read-tree HEAD Does and Does NOT Do
- Does: Rebuilds
.git/indexfrom HEAD's committed tree. Working tree files untouched. - Does NOT: Modify any committed objects, blob content, or working tree files.
- Does NOT: Delete the missing objects (they were never written; they stay missing in fsck).
- Safe to run on a repo with missing blob objects — it bypasses the corrupted index entirely.
Common Mistakes
| Mistake | Consequence |
Running git reset HEAD before reading index | May fail with same missing-blob error; also loses index state |
Removing .DS_Store from .git/refs/ without checking fsck first | Fix the symptom; may miss deeper corruption |
Assuming clean git log means clean repo | Index and working tree are separate from commit history |
| Repairing index before recording staged content | Loses the only artifact showing what was staged |
| Checking only the affected repo | Cross-repo correlation requires checking all repos in the workspace |
Origin: Validated Against 2026-05-20 Incident
This skill was written after hands-on forensics of a coordinated 7-repo git index
replacement by the OpenAI Codex VS Code extension. The git ls-files --stage approach,
cross-repo blob correlation, and CLAUDE.md semantic attack pattern were all identified
during that investigation. The RED phase is documented in:
~/.claude/projects/-Users-daedalus/memory/incident-20260520.md
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

