mirror of
https://github.com/safishamsi/graphify.git
synced 2026-08-28 17:26:48 +00:00
fix(analyze): exclude rationale nodes from suggested-question gap count (#1768)
suggest_questions()'s "isolated/weakly-connected nodes" filter was missing the `file_type != "rationale"` exclusion that report.py's Knowledge Gaps section already applies, so the same GRAPH_REPORT.md reported two different counts for the same concept (757 vs 245 on a real graph) — an internal inconsistency that made a healthy graph look like a documentation problem. Add the same filter so both computations agree. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
committed by
safishamsi
co-authored by
Claude Opus 4.8
parent
a646d66a67
commit
15a86536c4
@@ -4,6 +4,8 @@ Full release notes with details on each version: [GitHub Releases](https://githu
|
||||
|
||||
## 0.9.13 (unreleased)
|
||||
|
||||
- Fix: the report's "Suggested Questions" weakly-connected-node count now matches its "Knowledge Gaps" count (#1768, thanks @balloon72). `suggest_questions()` omitted the `file_type != "rationale"` filter that `report.py`'s Knowledge Gaps section applies, so the same `GRAPH_REPORT.md` showed two different numbers for the same concept (e.g. 757 vs 245), making a healthy graph look like it had a major documentation gap. Both computations now use the same filter.
|
||||
|
||||
- Fix: Bash scripts that run each other by execution now get a cross-file edge (#1756, thanks @balloon72). `extract_bash` only linked `source x.sh` / `. x.sh`; the two most common forms — `bash x.sh` and `./x.sh` — produced no edge, so execution topology was missing. They now emit a `calls` edge (context `script_invocation`) to the invoked script's entry node when the target resolves to a real file on disk (script runners `bash`/`sh`/`zsh`/`ksh`/`dash` and bare `./x.sh`), skipping missing or shadowed targets.
|
||||
|
||||
- Fix: Ruby `.rake` files are now extracted and participate in Ruby cross-file resolution like `.rb` (#1784, thanks @krishnateja7). `.rake` is plain Ruby but the extension was gated out of seven places (classification, extractor dispatch, the language-name/family maps, the `ruby_member_calls` resolver's suffix set, both `.rb`-suffix filters in `ruby_resolution.py`, and the build repo-tag map), so every rake task was skipped and its calls were invisible. All seven now include `.rake`; `Widget.tally` from a `.rake` task resolves to its `.rb` definition.
|
||||
|
||||
+4
-1
@@ -504,7 +504,10 @@ def suggest_questions(
|
||||
# 4. Isolated or weakly-connected nodes → exploration questions
|
||||
isolated = [
|
||||
n for n in G.nodes()
|
||||
if G.degree(n) <= 1 and not _is_file_node(G, n) and not _is_concept_node(G, n)
|
||||
if G.degree(n) <= 1
|
||||
and not _is_file_node(G, n)
|
||||
and not _is_concept_node(G, n)
|
||||
and G.nodes[n].get("file_type") != "rationale"
|
||||
]
|
||||
if isolated:
|
||||
labels = [G.nodes[n].get("label", n) for n in isolated[:3]]
|
||||
|
||||
+14
-1
@@ -5,7 +5,7 @@ import pytest
|
||||
from pathlib import Path
|
||||
from graphify.build import build_from_json
|
||||
from graphify.cluster import cluster
|
||||
from graphify.analyze import god_nodes, surprising_connections, _is_concept_node, graph_diff, _surprise_score, _file_category, _is_json_key_node, find_import_cycles
|
||||
from graphify.analyze import god_nodes, surprising_connections, _is_concept_node, graph_diff, _surprise_score, _file_category, _is_json_key_node, find_import_cycles, suggest_questions
|
||||
from graphify.extract import _make_id
|
||||
|
||||
FIXTURES = Path(__file__).parent / "fixtures"
|
||||
@@ -603,6 +603,19 @@ def test_god_nodes_filter_is_case_insensitive():
|
||||
assert variant not in labels, f"`{variant}` should be filtered as JSON-key noise"
|
||||
|
||||
|
||||
def test_suggest_questions_excludes_rationale_nodes_from_isolated_count():
|
||||
G = nx.Graph()
|
||||
G.add_node("service", label="Service", file_type="code", source_file="service.py")
|
||||
G.add_node("reason", label="Explains service", file_type="rationale", source_file="service.py")
|
||||
|
||||
questions = suggest_questions(G, communities={}, community_labels={}, top_n=10)
|
||||
isolated = next(question for question in questions if question["type"] == "isolated_nodes")
|
||||
|
||||
assert isolated["why"].startswith("1 weakly-connected node")
|
||||
assert "`Service`" in isolated["question"]
|
||||
assert "Explains service" not in isolated["question"]
|
||||
|
||||
|
||||
# ── find_import_cycles tests ──────────────────────────────────────────────────
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user