Summary
The post-commit hook installed by graphify hook install (in graphify/hooks.py) gates the rebuild on a hardcoded CODE_EXTS allowlist that has drifted from the authoritative CODE_EXTENSIONS set in graphify/detect.py. The result: commits that change valid, supported code files exit silently with status 0 and the graph is never rebuilt — so users see a stale graph.json and assume the hook isn't working.
Repro
graphify . in any project (build the initial graph).
graphify hook install.
- Commit a change to a
.tsx, .jsx, .lua, .ex, .ps1, or .jl file.
- Inspect
graphify-out/graph.json mtime — unchanged. No log, no error, the hook just exited 0.
Same outcome for any markdown/config-only commit on a doc repo, even though graphify supports doc graphs and watch.py has a _notify_only fallback that the hook never reaches.
Root cause
In graphify/hooks.py the embedded post-commit script defines its own CODE_EXTS:
CODE_EXTS = {
'.py', '.ts', '.js', '.go', '.rs', '.java', '.cpp', '.c', '.rb', '.swift',
'.kt', '.cs', '.scala', '.php', '.cc', '.cxx', '.hpp', '.h', '.kts',
}
But graphify/detect.py (the source of truth used by _rebuild_code) ships:
CODE_EXTENSIONS = {'.py', '.ts', '.js', '.jsx', '.tsx', '.go', '.rs', '.java', '.cpp', '.cc', '.cxx', '.c', '.h', '.hpp', '.rb', '.swift', '.kt', '.kts', '.cs', '.scala', '.php', '.lua', '.toc', '.zig', '.ps1', '.ex', '.exs', '.m', '.mm', '.jl'}
11 extensions missing from the hook's copy: .jsx .tsx .lua .toc .zig .ps1 .ex .exs .m .mm .jl. Worse, _rebuild_code calls detect() internally which rescans the whole project from scratch using the authoritative set anyway — so the hook's filter doesn't even control what gets rebuilt. It only gates whether the rebuild fires. The whole filter block is dead weight that introduces a stale-duplicate bug class.
Impact
- React/Next/Vite repos (mostly
.tsx/.jsx) — hook never fires.
- Lua, Elixir, PowerShell, Julia, Objective-C repos — hook never fires.
- Doc-heavy repos (skills, knowledge bases, READMEs) — hook never fires.
- Silent failure: no log line, no error, exit 0. Users discover the staleness only when query results disagree with the code.
Proposed fix
Drop the filter entirely. The rebuild is cheap (~2s for 400 files, no LLM cost), detect() already handles "no code files found" cleanly, and removing the filter eliminates the duplication bug class permanently. PR incoming.
Bonus: log success/failure to a file under graphify-out/ so silent failures become visible if anything else goes wrong.
Summary
The
post-commithook installed bygraphify hook install(ingraphify/hooks.py) gates the rebuild on a hardcodedCODE_EXTSallowlist that has drifted from the authoritativeCODE_EXTENSIONSset ingraphify/detect.py. The result: commits that change valid, supported code files exit silently with status 0 and the graph is never rebuilt — so users see a stalegraph.jsonand assume the hook isn't working.Repro
graphify .in any project (build the initial graph).graphify hook install..tsx,.jsx,.lua,.ex,.ps1, or.jlfile.graphify-out/graph.jsonmtime — unchanged. No log, no error, the hook just exited 0.Same outcome for any markdown/config-only commit on a doc repo, even though
graphifysupports doc graphs andwatch.pyhas a_notify_onlyfallback that the hook never reaches.Root cause
In
graphify/hooks.pythe embedded post-commit script defines its ownCODE_EXTS:But
graphify/detect.py(the source of truth used by_rebuild_code) ships:11 extensions missing from the hook's copy:
.jsx .tsx .lua .toc .zig .ps1 .ex .exs .m .mm .jl. Worse,_rebuild_codecallsdetect()internally which rescans the whole project from scratch using the authoritative set anyway — so the hook's filter doesn't even control what gets rebuilt. It only gates whether the rebuild fires. The whole filter block is dead weight that introduces a stale-duplicate bug class.Impact
.tsx/.jsx) — hook never fires.Proposed fix
Drop the filter entirely. The rebuild is cheap (~2s for 400 files, no LLM cost),
detect()already handles "no code files found" cleanly, and removing the filter eliminates the duplication bug class permanently. PR incoming.Bonus: log success/failure to a file under
graphify-out/so silent failures become visible if anything else goes wrong.