Skip to content

Audit: Plan references in source

What we check

Every reference to a plan file (PLAN-*.md) written into source code or configuration must resolve in the repository it is written in, or else be an absolute URL.

Since 2026-09-24 the plan-references-in-code shared block (see the push-audit audit) says what code may cite at all: the reasoning behind a line belongs in its comment, not behind a pointer to the plan that produced it, and a plan link survives only for work that is not built yet -- "deferred; see docs/plans/PLAN-session-001-feedback.md". This audit is the mechanical half for the links that remain: whatever a comment still points at has to be there when a reader follows it.

Nothing renders these pointers. A markdown link in docs/ breaks visibly and docs-external-links audits it; a path inside a // comment or a YAML key is inert text no renderer resolves. So a renamed or archived plan rots the pointer silently, and the first person to notice is someone who went looking for the plan and did not find it -- at which point the comment is worse than none, because it asserts a record exists.

The check runs git ls-files, skips markdown files (they are docs-external-links' scope), files under a plans directory in docs/, and files over 2 MB, and resolves each PLAN-<name>.md it finds in what remains:

  • Path-qualified references (docs/plans/PLAN-foo.md) resolve as written, from the repository root and then from docs/. The second position exists for mkdocs navigation, which addresses pages relative to the documentation root.
  • Bare filenames (PLAN-foo.md) match any markdown file under docs/plans/ at any depth, so a plan archived into docs/plans/completed/ still resolves. A bare filename names no directory, so there is no path for it to be wrong about.

Three shapes are not flagged:

  • Absolute URLs. Text matching a scheme:// URL is removed before scanning. A plan in another repository cannot resolve locally and should be written as https://github.com/<org>/<repo>/blob/<default-branch>/docs/plans/PLAN-foo.md -- the same rule docs-external-links and readme-absolute-links apply, for the same reason: a reference read somewhere other than where it lives has to be absolute.
  • PLAN-TEMPLATE.md. Not a plan but the template plans are written from, living at the repository root and held there by the plan-template audit.
  • Lines carrying audit-ok: plan-reference, for the rare line where a PLAN-*.md string is not a pointer -- a filename pattern in a linter config, a fixture naming a plan that deliberately does not exist.

A plans directory is skipped because it is the record of how the software was built, and citing plans is its job. The case that forced the rule was client-python-k3s, whose push-audit phase keeps the diffs it reviewed in docs/plans/audit/diffs/: those diffs quote every plan path they touched, including plans renamed since and plans in other repositories, and rewriting them so the pointers resolve would falsify the record. The scope is the one plan-phase-references exempts -- a plans/ directory under docs/ at any depth -- so the two agree on what a plans directory is. A plans/ directory elsewhere, such as a package in the code, is source and is scanned.

Test suites are scanned like any other source: a test file carries prose pointers too and they rot the same way -- instar's tests/test_adversarial.py cites a plan that no longer exists, in its module docstring -- so skipping files for having "test" in the name would hide exactly the finding this audit is for. A suite whose plan paths genuinely are all fixtures carries audit-ok: plan-reference-file once near the top with a sentence saying why. That exempts the whole file, prose included, so prefer the per-line form.

A repository with no plan references outside markdown is N/A.

This audit composes with plan-phase-references, which governs what documentation prose may cite, plan-history-in-source, which reads the same files for the phase, decision and step numbers code should not cite at all, and plan-index, which governs whether a plan is registered. This one governs only whether a pointer written in code still lands on a file.

Template

No template. Fix each reference at its source:

  • the plan moved to docs/plans/completed/ -- update the path, or drop to the bare filename, which resolves either way;
  • the plan was renamed -- update the name;
  • the plan lives in another repository -- rewrite it as an absolute https://github.com/... URL;
  • the plan never existed, or the reference is not a pointer -- delete it, or mark the line audit-ok: plan-reference;
  • the whole file is fixtures rather than pointers -- mark it once with audit-ok: plan-reference-file, and say why.

Deleting a pointer is not a fix on its own where the comment leaned on it: write the reasoning the plan held into the comment, then drop the pointer. That is also the right fix for a pointer that does resolve but cites work already built -- plan-references-in-code asks for it, though this audit does not flag it.

Projects

Per-project compliance for this criterion is regenerated on every run of the consistency audit: see the compliance page.

📝 Report an issue with this page