- Fix: a node whose
source_fileis a URL/virtual scheme (gdoc://,s3://,http://, ...) is no longer evicted on the secondgraphify update(follow-up to #2051). The #2051 disk-absence sweep guarded such sources with a literal"://"check, but write-side path normalization collapses the double slash (gdoc://xbecomesgdoc:/x), so the guard missed the node on the next run and dropped it into the disk-absence eviction branch. The scheme is now matched tolerantly (and a Windows drive letter likeC:/is not misread as remote). - Fix: a real source directory named
env/.env/*_envis no longer silently pruned as a false-positive Python virtualenv (#2058).detect's directory-noise heuristic matched those names before.graphifyignorenegation and with no trace in any output bucket, so codebases using them as source dirs (common in UVM/ASIC verification) lost large subtrees undetectably. The venv heuristic for those names is now gated on an actual marker (pyvenv.cfg, anactivatescript,lib/python*, orconda-meta/);venv/.venv/*_venvstay name-only, and every pruned-as-noise directory is now recorded in apruned_noise_dirsbucket for traceability. - Fix: Office (
.docx/.xlsx) and Google-Workspace sidecars are now named from the scan-root-relative path, not the absolute path (#2059). The absolute-path hash salted the sidecar name with the checkout location, so committinggraphify-out/(a supported workflow) produced a new duplicate.mdper clone/worktree, each ingested as a distinct source document. The relative hash is stable across checkouts while still disambiguating same-stem files; the Google-Workspace sidecar path additionally gains the NFC normalization it was missing. - Fix:
serve.py's "graph.json is corrupted" recovery message is now reachable (#2005, thanks @kimdzhekhon).json.JSONDecodeErrorsubclassesValueError, and the broadexcept (ValueError, FileNotFoundError)clause was ordered first, so a truncated graph printed the bareExpecting value...instead of the documented rebuild hint. TheJSONDecodeErrorclause now comes first. - Fix:
graphify god-nodes/god_nodesis now a real CLI subcommand, andgraphify extract --output DIRis honored as an alias of--out(#2004).god_nodeswas an analyzer, an MCP tool, and a documented capability but had no CLI command;--outputwas silently dropped onextracteven thoughgraphify treedocuments it. (Theaffected/reverse-dep import-id mismatch from the same report is tracked separately.) - Fix: a nested class/object/trait now gets its
containsedge from the enclosing type instead of the file node (#2040). Across ~19 languages the edge was hard-coded to source from the file, so the containment tree was flat (file -> Inner) rather than nested (file -> Outer -> Inner); it now sources from the enclosing type when present, with top-level types still contained by the file. - Fix: file nodes that share a basename now get a directory-qualified label so
explain/discovery can tell them apart (#2032). In directory-per-entrypoint repos (Supabase Edge Functions, Next.jspage.tsx, Rustmod.rs, Python__init__.py) dozens of files named e.g.index.tscollided under one label, breaking free-text discovery for exactly those files. Colliding file nodes are relabelled to the shortest unique path suffix (process-order/index.ts); unique basenames stay bare, and node ids/edges are unchanged.