Skip to content

Weakly-connected / "Knowledge Gaps" signal doesn't filter AST-origin declarations without a () suffix — false positives dominate #4205

Description

@rsaer

suggest_questions() and the GRAPH_REPORT.md "Knowledge Gaps" section both treat degree(n) <= 1 as "possible documentation gap," filtered only by _is_file_node, _is_concept_node, and file_type != "rationale" (analyze.py:549-563, report.py:327, shared via _real_node).

_is_file_node (analyze.py:65-90) only recognizes three shapes: a label matching its own filename, a .method() stub, or a bare function_name() stub. _is_concept_node (analyze.py:183-193) only excludes nodes with an empty or extension-less source_file.

Neither catches a plain AST declaration whose label has no trailing () — e.g. a TypeScript type/interface alias, an enum member, a local const, or a JSON config key — even when it has a real source_file and _origin == "ast", and even when its only edge is the contains edge from its own file.

Concrete repro: in a Next.js/Medusa monorepo, three file-local row-shape types declared back-to-back:

type TabRow = { id: string; ... };
type ContributionRow = { id: string; ... };
type TabRecognition = { vendor_id: string; ... };

(used only as manager.execute<ContributionRow[]>(...) generic parameters, never exported) — each got exactly one contains edge and were then surfaced by suggest_questions() as "What connects ContributionRow, TabRecognition, TabRow to the rest of the system? — 1,556 weakly-connected nodes found — possible documentation gaps." They are not a gap; they're working as designed.

This isn't a one-off: in a ~5,000-node graph of that repo, 1,718 of 2,033 weakly-connected nodes have _origin == "ast", vs. 260 _origin == "semantic" (docs/PRD-derived) and 55 untagged. Manually sampling 26 of the semantic ones found zero confirmed real gaps too (mostly risk-register table rows and section headings) — but the AST-origin majority is the larger, more mechanically-fixable false-positive source.

Suggested fix: have _is_file_node (or a sibling check) also exclude any node with _origin == "ast" whose only edge is a single contains edge from its declaring file — regardless of whether the label ends in (). That one change would remove the great majority of the 1,718 false positives in our graph without touching the semantic/doc side of gap detection.


(graphify version: graphifyy 0.9.79, installed via uv tool install)

No activity

Activity on this issue will appear here.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions