Skip to content

fix: context-drift-check false positives for generated-bridge, renamed, and external-repo path references #31

Description

Summary

context-drift-check.sh's broken-path check reports false positives for backtick-quoted references that legitimately do not exist in the local repo. Found by dogfooding on ContextDocs' own repo: a trivial commit (a .gitignore change) triggered five "AI CONTEXT DRIFT DETECTED … not found" warnings, all of which are false positives.

Reproduction

On the ContextDocs repo itself, commit any change. The PostToolUse drift hook emits:

AI CONTEXT DRIFT DETECTED:
  - CLAUDE.md references `GEMINI.md` (not found)
  - CLAUDE.md references `index.md` (not found)
  - AGENTS.md references `GEMINI.md` (not found)
  - AGENTS.md references `scripts/docs-sync.config.ts` (not found)
  - llms.txt references `GEMINI.md` (not found)

None of these are stale/broken references — see triage below.

Root cause

.claude/hooks/context-drift-check.sh lines 63–74 extract every backtick-quoted `…​.(ts|js|py|go|rs|md|json|toml|yaml|yml|sh)` token and flag it unless the path exists locally or its basename is found anywhere in the repo. That heuristic assumes every backtick-quoted path is a claim that the file exists in this repo. Three legitimate reference categories break that assumption:

  1. Generated-bridge filenames — files the plugin emits into other projects, not files that exist here. GEMINI.md, .windsurfrules, .clinerules/agents.md, .cursor/rules/agents.mdc, .github/copilot-instructions.md, etc. ContextDocs' own context files describe these as generated output ("Compatibility bridges: .windsurfrules and GEMINI.md remain generated for now").
  2. Historical / rename mentions — e.g. CLAUDE.md's docs/faq/faq.md row says "renamed from index.md per docs(faq): rename docs/faq/index.md → docs/faq/faq.md for cleaner site URL #29". The old name is intentional context; the real file (docs/faq/faq.md) exists.
  3. External-repo paths — e.g. AGENTS.md references "the marketing-site scripts/docs-sync.config.ts mapping", a file in the littlebearapps.com repo, not this one.

Triage of the five current false positives

Reference Category Correct?
GEMINI.md (×3) Generated-bridge filename ✅ legit — plugin output, not a local file
index.md Historical rename mention (→ faq.md, which exists) ✅ legit
scripts/docs-sync.config.ts External-repo path (marketing site) ✅ legit

Suggested fixes (any combination)

  • Allowlist the generated-bridge filenames ContextDocs emits, and skip them in the broken-path check. The list is already known to the generator (CLAUDE.md, AGENTS.md, GEMINI.md, .windsurfrules, .clinerules/agents.md, .cursor/rules/agents.mdc, .github/copilot-instructions.md, .cursorrules, .clinerules).
  • Skip references with contextual cue words on the same line — renamed from, formerly, was, marketing-site, external, generated, generates, emits.
  • Support an inline ignore / allowlist file (e.g. a .context-guard-ignore glob list, or a <!-- drift-ignore --> line marker) so maintainers can suppress known-good references explicitly.
  • Bias toward repo-relative paths — only hard-flag references containing a / that resolve against a real top-level directory, and downgrade bare capitalised doc filenames to a softer notice.

Impact

Low severity (advisory hook, never blocks work) but high noise: it cries wolf on every commit to this repo, which trains maintainers to ignore the warning — defeating the hook's purpose. Since this ships as a ContextDocs product feature, the same false positives will hit any downstream project whose context files describe generated bridges or external paths.

Notes

  • Hook: .claude/hooks/context-drift-check.sh (broken-path check: lines 63–74).
  • Installed by /contextdocs:context-guard install; Claude Code only.
  • The staleness check (source-commits-since-context-update, lines 44–61) is unaffected — this is only about the broken-path heuristic.

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions