fix(report): complete empty-community fix — hubs, summary count, thin-community gaps; add graph-query CLI rules to install sections

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
Safi
2026-04-21 22:42:53 +01:00
co-authored by Claude Sonnet 4.6
parent 39bf0a3f80
commit 7cb639ae5d
3 changed files with 14 additions and 6 deletions
+4
View File
@@ -191,6 +191,7 @@ This project has a graphify knowledge graph at graphify-out/.
Rules:
- Before answering architecture or codebase questions, read graphify-out/GRAPH_REPORT.md for god nodes and community structure
- If graphify-out/wiki/index.md exists, navigate it instead of reading raw files
- For cross-module "how does X relate to Y" questions, prefer `graphify query "<question>"`, `graphify path "<A>" "<B>"`, or `graphify explain "<concept>"` over grep — these traverse the graph's EXTRACTED + INFERRED edges instead of scanning files
- After modifying code files in this session, run `graphify update .` to keep the graph current (AST-only, no API cost)
"""
@@ -206,6 +207,7 @@ This project has a graphify knowledge graph at graphify-out/.
Rules:
- Before answering architecture or codebase questions, read graphify-out/GRAPH_REPORT.md for god nodes and community structure
- If graphify-out/wiki/index.md exists, navigate it instead of reading raw files
- For cross-module "how does X relate to Y" questions, prefer `graphify query "<question>"`, `graphify path "<A>" "<B>"`, or `graphify explain "<concept>"` over grep — these traverse the graph's EXTRACTED + INFERRED edges instead of scanning files
- After modifying code files in this session, run `graphify update .` to keep the graph current (AST-only, no API cost)
"""
@@ -219,6 +221,7 @@ This project has a graphify knowledge graph at graphify-out/.
Rules:
- Before answering architecture or codebase questions, read graphify-out/GRAPH_REPORT.md for god nodes and community structure
- If graphify-out/wiki/index.md exists, navigate it instead of reading raw files
- For cross-module "how does X relate to Y" questions, prefer `graphify query "<question>"`, `graphify path "<A>" "<B>"`, or `graphify explain "<concept>"` over grep — these traverse the graph's EXTRACTED + INFERRED edges instead of scanning files
- After modifying code files in this session, run `graphify update .` to keep the graph current (AST-only, no API cost)
"""
@@ -421,6 +424,7 @@ Rules:
- Before answering architecture or codebase questions, read graphify-out/GRAPH_REPORT.md for god nodes and community structure
- If graphify-out/wiki/index.md exists, navigate it instead of reading raw files
- If the graphify MCP server is active, utilize tools like `query_graph`, `get_node`, and `shortest_path` for precise architecture navigation instead of falling back to `grep`
- If the MCP server is not active, the CLI equivalents are `graphify query "<question>"`, `graphify path "<A>" "<B>"`, and `graphify explain "<concept>"` — prefer these over grep for cross-module questions
- After modifying code files in this session, run `graphify update .` to keep the graph current (AST-only, no API cost)
"""
+9 -5
View File
@@ -49,10 +49,14 @@ def generate(
"- Verdict: corpus is large enough that graph structure adds value.",
]
from .analyze import _is_file_node as _ifn
non_empty = {cid: nodes for cid, nodes in communities.items()
if any(not _ifn(G, n) for n in nodes)}
lines += [
"",
"## Summary",
f"- {G.number_of_nodes()} nodes · {G.number_of_edges()} edges · {len(communities)} communities detected",
f"- {G.number_of_nodes()} nodes · {G.number_of_edges()} edges · {len(non_empty)} communities detected",
f"- Extraction: {ext_pct}% EXTRACTED · {inf_pct}% INFERRED · {amb_pct}% AMBIGUOUS"
+ (f" · INFERRED: {len(inf_edges)} edges (avg confidence: {inf_avg})" if inf_avg is not None else ""),
f"- Token cost: {token_cost.get('input', 0):,} input · {token_cost.get('output', 0):,} output",
@@ -60,9 +64,9 @@ def generate(
# Community hub navigation - links to _COMMUNITY_*.md files in the Obsidian vault.
# Without these, GRAPH_REPORT.md is a dead-end and the vault splits into disconnected components.
if communities:
if non_empty:
lines += ["", "## Community Hubs (Navigation)"]
for cid in communities:
for cid in non_empty:
label = community_labels.get(cid, f"Community {cid}")
safe = _safe_community_name(label)
lines.append(f"- [[_COMMUNITY_{safe}|{label}]]")
@@ -105,7 +109,6 @@ def generate(
lines.append(f"- **{h.get('label', h.get('id', ''))}** — {node_labels} [{conf_tag}]")
lines += ["", "## Communities"]
from .analyze import _is_file_node as _ifn
for cid, nodes in communities.items():
label = community_labels.get(cid, f"Community {cid}")
score = cohesion_scores.get(cid, 0.0)
@@ -141,7 +144,8 @@ def generate(
if G.degree(n) <= 1 and not _is_file_node(G, n) and not _is_concept_node(G, n)
]
thin_communities = {
cid: nodes for cid, nodes in communities.items() if len(nodes) < 3
cid: nodes for cid, nodes in communities.items()
if 0 < sum(1 for n in nodes if not _is_file_node(G, n)) < 3
}
gap_count = len(isolated) + len(thin_communities)
+1 -1
View File
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "graphifyy"
version = "0.4.24"
version = "0.4.25"
description = "AI coding assistant skill (Claude Code, Codex, OpenCode, Cursor, Gemini CLI, Aider, OpenClaw, Factory Droid, Trae, Hermes, Kiro, Google Antigravity) - turn any folder of code, docs, papers, images, or videos into a queryable knowledge graph"
readme = "README.md"
license = { file = "LICENSE" }