Version: graphifyy 0.9.46 · Windows 11 · Python 3.12 (uv tool install)
Summary
On unchanged code, graph.json is byte-identical across runs and graphify correctly reports No code-graph topology changes detected; outputs left untouched. But manifest.json is rewritten anyway, and the only thing that differs is the per-file seen timestamp.
Because the git hooks commit graphify-out/ wholesale, graphify-out/ is never clean, and every git push leaves one trailing graph commit behind — permanently.
Reproduction
On a clean working tree, with no source change between runs:
graphify update . && sha256sum graphify-out/graph.json
graphify update . && sha256sum graphify-out/graph.json
graphify update . && sha256sum graphify-out/graph.json
graph.json is identical all three times (same sha256), and runs 2 and 3 print No code-graph topology changes detected; outputs left untouched.
Now diff two consecutive graph commits made by the hooks:
graphify-out/manifest.json | 772 ++++++++++++++++--------------
1 file changed, 386 insertions(+), 386 deletions(-)
graph.json, GRAPH_REPORT.md and .graphify_labels.json do not appear in the diff. Every changed line is a seen field — verified, zero changed lines are anything else:
"app/admin-ui/src/App.tsx": {
"mtime": 1785366505.196617,
- "seen": 1787000934.3112164,
+ "seen": 1787001063.5783465,
"ast_hash": "f8f7775881b973daf0c485283570a6c1",
"semantic_hash": "f8f7775881b973daf0c485283570a6c1"
}
386 entries, one line changed each.
Impact
The pre-push hook sees graphify-out/ as dirty, commits, and reports:
[graphify] Il grafo cambia a ogni run: committato, push lasciato passare.
Da guardare: 'graphify update .' non converge su questo repo.
Two problems with that:
- It never converges. Observed three pushes in a row: the hook commits, the push transfers up to the pre-hook HEAD, and the newly created commit stays local. Re-running
git push just produces another one. The repo sits permanently one graph commit ahead of origin.
- The message points at the wrong thing. It says the graph changes, which sends you looking for nondeterminism in extraction or clustering. The graph is fine — it's cache bookkeeping. I spent a while bisecting node/edge sets and reading
_rewire_unique_stub_nodes and cluster() before diffing the manifest.
Suggested fix
Any of these would do:
- Don't rewrite
seen when no other field in the entry changed — or skip writing manifest.json entirely on the outputs left untouched path.
- Or exclude
manifest.json from the hook's change detection, since it's cache bookkeeping rather than graph content.
- Or drop
!graphify-out/manifest.json from the .gitignore template that graphify install writes, so it isn't versioned in the first place.
Workaround
Untracking it fixes it immediately, and the hook converges on the first try:
git rm --cached graphify-out/manifest.json
# remove the "!graphify-out/manifest.json" allowlist line from .gitignore
Verified on two repos: after this, git push completes with zero trailing commits and a clean working tree.
Version: graphifyy 0.9.46 · Windows 11 · Python 3.12 (uv tool install)
Summary
On unchanged code,
graph.jsonis byte-identical across runs and graphify correctly reportsNo code-graph topology changes detected; outputs left untouched. Butmanifest.jsonis rewritten anyway, and the only thing that differs is the per-fileseentimestamp.Because the git hooks commit
graphify-out/wholesale,graphify-out/is never clean, and everygit pushleaves one trailing graph commit behind — permanently.Reproduction
On a clean working tree, with no source change between runs:
graph.jsonis identical all three times (same sha256), and runs 2 and 3 printNo code-graph topology changes detected; outputs left untouched.Now diff two consecutive graph commits made by the hooks:
graph.json,GRAPH_REPORT.mdand.graphify_labels.jsondo not appear in the diff. Every changed line is aseenfield — verified, zero changed lines are anything else:386 entries, one line changed each.
Impact
The
pre-pushhook seesgraphify-out/as dirty, commits, and reports:Two problems with that:
git pushjust produces another one. The repo sits permanently one graph commit ahead of origin._rewire_unique_stub_nodesandcluster()before diffing the manifest.Suggested fix
Any of these would do:
seenwhen no other field in the entry changed — or skip writingmanifest.jsonentirely on theoutputs left untouchedpath.manifest.jsonfrom the hook's change detection, since it's cache bookkeeping rather than graph content.!graphify-out/manifest.jsonfrom the.gitignoretemplate thatgraphify installwrites, so it isn't versioned in the first place.Workaround
Untracking it fixes it immediately, and the hook converges on the first try:
git rm --cached graphify-out/manifest.json # remove the "!graphify-out/manifest.json" allowlist line from .gitignoreVerified on two repos: after this,
git pushcompletes with zero trailing commits and a clean working tree.