Skip to content

.graphifyinclude is dead code: loaded on every detect() run but never consumed #2112

Description

@safishamsi

Summary

.graphifyinclude is dead code. The file is read from disk on every detect() run and its patterns are parsed, but the result is assigned to a local variable that is never read again. A user who creates a .graphifyinclude file gets a silent no-op: no effect on which files are indexed, no warning, and no field in the result dict.

How it got here

.graphifyinclude was added in v0.6.6 (#583, CHANGELOG.md:1084) as a hidden-path allowlist ("opt specific hidden dirs into traversal, e.g. .hermes/plans/**/*.md"). It was wired into the detect() walk via two call sites:

if (not d.startswith(".") or _could_contain_included_path(dp / d, root, include_patterns))
...
if p.name.startswith(".") and not _is_included(p, root, include_patterns):

Commit df40e4d (#873, "index dot dirs") removed the blanket dot-prefix exclusion and, with it, both of those consumer lines. It left the loader, both matcher helpers, and the assignment in place. Since then the chain is: file read, patterns parsed, local variable, discarded.

Evidence (all references, repo-wide)

  • graphify/detect.py:1140 _load_graphifyinclude(root) — working loader (walks root to VCS-root, reads .graphifyinclude, parses via _parse_gitignore_line). Dead.
  • graphify/detect.py:1170 _is_included(path, root, patterns) — full gitignore-style matcher. Zero callers.
  • graphify/detect.py:1219 _could_contain_included_path(...) — directory-prefix matcher. Zero callers.
  • graphify/detect.py:1315 include_patterns = _load_graphifyinclude(root) — the only call site; value never read again (confirmed: include_patterns matches only this line plus the dead defs).
  • CHANGELOG.md:1084 — the v0.6.6 feature entry (the only user-facing promise).
  • CHANGELOG.md:664 — a v0.8.26 ([BUG] anchored gitignore pattern (/dir/) matches basename anywhere in tree, not just at root #1087) anchored-pattern bugfix that was applied to _is_included while it was already dead.
  • Tests: none on mainline. The original PR's tests and a graphifyinclude_patterns result key only exist on the old origin/v5 branch; the v0.6.6 mainline squash landed the detect.py code without them, so nothing failed when the feature was later severed.

No references in README, cli.py, extract.py, watch.py, skill files, or tools. Even when live, the feature only ever affected detect(), never extract.py collect_files.

Contrast: .graphifyignore is fully wired

Load at detect.py:1306, consumed for dir pruning (1385) and file filtering (1418), surfaced as graphifyignore_patterns in the result dict (1504), and mirrored in extract.py collect_files (5306+). That is the pattern an include feature would need to follow.

User impact

Low severity but real: ~110 lines of maintained-but-dead code (it even received a bugfix while dead), real I/O on every scan, and a silent no-op for anyone who trusts the loader or the CHANGELOG entry. Minor wart: .graphifyinclude is not in _SKIP_FILES (detect.py:796), so the allowlist file itself shows up in the unclassified output.

Proposed fix

Two coherent directions:

Option A (preferred): remove the dead code. Delete _load_graphifyinclude, _is_included, _could_contain_included_path, and detect.py:1315. Add a CHANGELOG erratum noting .graphifyinclude has been non-functional since #873. Optionally emit a one-line stderr note when a .graphifyinclude file is present, pointing users to ! negations in .graphifyignore (which already provide re-include via last-match-wins) now that dot dirs are indexed by default. This removes the original motivation cleanly.

Option B: re-implement as an ignore-override. Make .graphifyinclude a re-include that can rescue paths excluded by .gitignore/.graphifyignore: check _is_included before recording ignored for dirs (1385) and files (1418), use _could_contain_included_path to exempt matching dirs from pruning, mirror in extract.py collect_files, add graphifyinclude_patterns to the result dict, and restore tests. Decisions to settle first: precedence vs CLI --exclude (currently wins over all ignore files, #947); whether include can rescue _SKIP_DIRS noise and _is_sensitive files (#583 said no, keep that); the gitignore parent-exclusion rule (a negation cannot rescue files under an excluded dir); and the --code-only and watch.py re-scan paths.

Given #873 already made the original hidden-dir use case moot and ! in .graphifyignore covers the common "re-include" need, Option A is the lower-risk resolution unless there is demand for a distinct allowlist file.

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