Skip to content

Resolve graph.json from an ancestor directory, plus two independent fixes - #3296

Open
bobthearsonist wants to merge 7 commits into
Graphify-Labs:v8from
bobthearsonist:fix/follow-symlinks-containment
Open

Resolve graph.json from an ancestor directory, plus two independent fixes#3296
bobthearsonist wants to merge 7 commits into
Graphify-Labs:v8from
bobthearsonist:fix/follow-symlinks-containment

fix(hook-guard): resolve the graph upward, not just in cwd

b4dbad0
Select commit
Loading
Failed to load commit list.
Graphify Labs / Graphify succeeded Sep 2, 2026 in 0s

Graphify — worth a look

Worth a look — the grounded gate found no coupling regressions or blocking issues, but 5 advisory finding(s) below merit a look before merge.

Details

Graphify reviewed this change.

Worth a look — the grounded gate found no coupling regressions or blocking issues, but 5 advisory finding(s) below merit a look before merge.


Graphify review — findings

Makes read commands (explain, affected, god-nodes, path) resolve a missing default graph by walking up to the nearest ancestor's graph.json, while an explicit --graph is always used verbatim even when absent. Extends the hook guards (search/read/gemini) to fire when a graph exists in an ancestor rather than only in cwd, so agents running from worktrees or subdirectories still get nudged. Disambiguates explain when several files define the same label by preferring the top-level directory the caller is standing in, falling back to a stderr warning plus the lowest-sorted source_file for a stable pick.

Worth a look

  • SSRF guard bypassed when follow_symlinks=True in collect_filesgraphify/extract.py:7080 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • collect_files no longer enforces root containment when following symlinksgraphify/extract.py:7081 · Escalate · high
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • Default graph lookup trusts attacker-controlled ancestor directoriesgraphify/cli.py:108 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • follow_symlinks bypasses root containment and includes files outside the scan rootgraphify/extract.py:7078 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
  • follow_symlinks=True disables containment, enabling path traversal outside rootgraphify/extract.py:7080 · Escalate · medium
    • agreed by 2 of 2 members but NOT verified (no proof, no reproducing execution) — consensus is not a verdict; needs human review
Analysis details — impact, health, verification

Impact & health

Graphify review

Impact — 3056 functions depend on the 739 functions this change touches.

Health — this change adds coupling hotspots:

  • new: extract() — 490 callers, 42 callees
  • new: _rebuild_code() — 98 callers, 50 callees
  • new: build_from_json() — 187 callers, 18 callees
  • new: build_merge() — 46 callers, 14 callees
  • new: to_obsidian() — 36 callers, 13 callees
  • new: save_manifest() — 40 callers, 11 callees
  • new: _extract_generic() — 18 callers, 24 callees
  • new: extract_bash() — 41 callers, 10 callees
  • …and 74 more — each is listed as a finding

Verification — 3056 functions in the blast radius were not formally verified this run (proofs are advisory here).

Gate & verification

graphify gate

PASS — objectively clean (no health regressions, tests not run — proofs not run this pass (advisory)). Grounded, not self-assessed.

Advisory (not blocking):

  • verification_scope: 2836 function(s) in the blast radius were not formally verified this run