fix(reflect): resolve learning-sidecar source_file against the project root#1558
fix(reflect): resolve learning-sidecar source_file against the project root#1558TPAteeq wants to merge 1 commit into
Conversation
…t root
The work-memory sidecar's staleness check resolved each node's relative
`source_file` against graph.json's own directory (`graphify-out/`) instead of
the project root one level up. That path never exists, so every
`code_fingerprint` was written empty and `load_learning_overlay` flagged every
node stale — surfacing "[code changed — re-verify]" on a freshly built graph
with zero edits, across explain/query/report/html. The hint fired on
everything, always, so it carried no signal.
Add `_source_root()` and use it on both the write side (fingerprint) and the
read side (staleness): prefer the absolute path recorded in
`<output-dir>/.graphify_root` (the marker the git hooks already trust, and the
only correct answer when `GRAPHIFY_OUT` is an absolute/elsewhere override),
else the parent of the output dir, else graph.json's own directory.
The existing stale test passed only because it used an *absolute* `source_file`,
which skips the relative-path join real graphs always take ("no absolute paths
in output", Graphify-Labs#555/Graphify-Labs#932). Add two regression tests with a relative `source_file`:
one for the standard layout, one driven by the `.graphify_root` marker.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
|
Superseded by 00e00a0 on v8, which fixes the same work-memory staleness false-positive (relative |
…1558) Refines the staleness file resolution (00e00a0) by folding in the two genuine merits of @TPAteeq's parallel fix (#1558), which independently and correctly diagnosed the same root-mismatch bug: - Layout-ordered candidates: try the layout-appropriate root FIRST (the graphify-out parent for the standard layout, graph.json's own dir for a flat layout) before the other. The prior order tried the grandparent first unconditionally, which in a flat layout (graph.json at the project root) could fingerprint a same-named file one directory up. Existence checking is kept on top, so a defeated name heuristic or a stale .graphify_root marker still falls through to the real file. - Adds @TPAteeq's .graphify_root-marker-driven regression test, plus a flat-layout test that pins the ordering (editing the real file flips stale; editing the same-named decoy one dir up does not). Co-Authored-By: tpateeq <mohammedateequddin399@gmail.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thank you — and great catch. You independently diagnosed this exactly right: source_file is relative to the project root, both the write and read sides resolved it against graph.json's dir (graphify-out/), so the file was never found, the fingerprint stayed empty, and every node got the re-verify tag on a clean build. You even spotted the same reason the suite stayed green (the existing staleness test used an absolute source_file, which skips the relative join). The fix landed on
So the bug is fixed and your contribution is in the tree. This is the second time you've driven this overlay feature (the original idea in #1542, now this) — genuinely appreciated. Closing as landed. |
The
.graphify_learning.jsonwork-memory overlay (#1441,5779767) is great — but itsstaleness / "re-verify" hint is broken in the standard layout: it fires on every
annotated node, even on a freshly built graph with zero edits.
Symptom
On a clean AST build (no source edits since the build), every node shows the re-verify tag:
It surfaces the same way on all four read surfaces —
explain(__main__.py),graph.html(export.py),GRAPH_REPORT.md(report.py), andserve.py. A hint thatfires on everything, always, carries no signal.
Root cause
source_fileis stored relative to the project root ("no absolute paths in output",#555/#932). But
graph.jsonlives in the output dir (graphify-out/), one level belowthe project root, and both
_code_fingerprint(write) and_is_stale(read) resolved therelative
source_fileagainstgraph_path.parent(=graphify-out/):So
file_hashalways raised, the storedcode_fingerprintwas always"", and theread-side
_is_stalesaw the file as "vanished" → returnedTruefor every node.Fix
Add
_source_root(graph_path)and use it on both sides. It resolves the directory thatsource_fileis relative to, in order:<output-dir>/.graphify_root— the same marker thegit hooks already trust, and the only correct answer when
GRAPHIFY_OUTis anabsolute / elsewhere override (Support for working with worktrees #686/bug: validate_graph_path() fallback and callflow_html.py project-root check hardcode "graphify-out", ignoring GRAPHIFY_OUT #1423);
graph.jsonsits inside it;graph.json's own directory (flat layouts; an absolutesource_fileresolvesregardless of root).
graph.jsonitself is still never touched — this only changes which directory thefingerprint is computed against.
After the fix, same node, same clean build:
…and a real edit to
admin/blueprint.gocorrectly flips the node to stale.Why the suite was green
test_loader_marks_entry_stale_when_source_file_changessetsource_fileto anabsolute path (
str(tmp_path / "auth.py")), which skips the relative-path join — soit exercised a path real graphs never take. Added two regression tests using a relative
source_file(the real-world case): one for the standardgraphify-out/layout, onedriven by the
.graphify_rootmarker. Both fail onv8(assert ''— empty fingerprint)and pass with the fix.
Verification
tests/test_reflect.py— 58 passed (incl. the 2 new regression tests).test_reflect + test_export + test_report + test_serve + test_explain_cli— 186 passed.ruff check graphify/reflect.py— clean.re-verify tag is gone; an actual edit re-flags the node.
Scope
Touches only
graphify/reflect.py(one helper + two one-line call-site changes) andtests/test_reflect.py. No version bump, no CHANGELOG entry