edit-guard
A tiny Claude Code hook that stops one agent session from editing a file another session changed underneath it.
The failure mode, quoted from a real-world report: "With several agent
sessions on one repository, session A reads createSession, session B
changes it, and A then edits on the old assumption." edit-guard watches every
Read/Edit/Write through the hook, remembers what each session last saw,
and blocks the write when the file moved on without you — telling the agent to
re-read first.
Zero dependencies. Python standard library only. Everything stays local.
Install
git clone https://github.com/hahahahahahahahah6/edit-guard
cd edit-guard
pip install .
edit-guard install
install merges three hook entries into ~/.claude/settings.json (backing it up
first, never clobbering your existing settings):
PreToolUseonEdit|Write|MultiEdit|NotebookEdit→edit-guard hook(may block)PostToolUseonEdit|Write|MultiEdit|NotebookEdit→edit-guard hook --post-write(records the digest after your write, never blocks — this is what keeps your own consecutive edits from looking stale)PreToolUseonRead→edit-guard hook --observe(records what you saw, never blocks)
Restart Claude Code afterwards. That's it — no MCP server, no daemon, no accounts.
How it works
Each hook invocation appends one line to ~/.config/edit-guard/writes.jsonl:
{session_id, tool, path, digest_seen, timestamp}. When a session tries to
write a file:
- Hash the file's current content (sha256; mtime+size for files over 50 MB).
- Compare against the digest that session last saw for that path.
- If it changed and another session touched the file in between → block (exit 2) with: "Stale edit blocked: '…' changed since you last saw it (last modified by session '…'). Re-read the file before editing."
Same-session rewrites, new files, and files only you touched are always allowed. The hook fails open: any internal error (corrupt log, unreadable file, malformed input) means "allow".
Inspect what's being tracked:
edit-guard log # recent guarded file events
edit-guard status # state dir / log / settings paths
Honest limitations
- Write-after-write staleness only. The guard compares against what your session last saw through the hook. Edits made outside any hooked session (your editor, a script) are treated as your own session's drift and allowed.
- Not a lock. This is advisory staleness detection, not mutual exclusion. Two sessions can still race within the same second; the loser is blocked, the winner wins.
- Digest, not semantics. A reformat that changes bytes but not meaning still counts as "changed" and can block you. Re-read and retry.
- Hook protocol is undocumented. The PreToolUse stdin shape (
session_id,tool_name,tool_input) and the exit-2-blocks convention come from community documentation, not a stable API. If Claude Code changes the protocol, the hook degrades to fail-open allow. - Per-machine only. Sessions on different machines don't share the log.
- The log is append-only with light pruning (keeps the last 10k of 20k lines); it is not a backup or audit trail.
Development
python3 tests/test_guard.py
License
MIT
Metadata
Release files for edit-guard 0.1.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| edit_guard-0.1.0.tar.gz | 9.5 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| edit_guard-0.1.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 18.1 kB
Release files / edit_guard-0.1.0.tar.gz
| Download URL | edit_guard-0.1.0.tar.gz |
|---|---|
| Size | 9.5 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
6a0902d07fe6bbade075c333c5775e71603dd0e965e10315245976d7e49132d8
|
|
BLAKE2b-256 checksum How to use checksums |
9e37c76447e81fbb7ea3c7a820f4420b26d84b3fd0977acda622b9ce1f372548
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / edit_guard-0.1.0-py3-none-any.whl
| Download URL | edit_guard-0.1.0-py3-none-any.whl |
|---|---|
| Size | 8.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
a289551696210ec3d958c49bcc50080ad0e74c43a7ca04bded5567fa25f0a266
|
|
BLAKE2b-256 checksum How to use checksums |
7c96af2c404cbaef9ed2a0476a75a7cf314a503a2b4c981f7dcffbd2fd7b1a5c
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|