Files
zernie__vigiles/docs/rules/spec-refs.md
zernie 85c54e7e78 fix(lint)!: make the lint report complete, tierable and machine-readable (#187)
Closes #181, closes #182, closes #183, closes #184, closes #185, and the
residual half of #173.

#185 — every per-surface check read ONE root, so a monorepo with `skills/` plus
`plugins/*/skills/` scored only the first: 4 skills over budget, 2 reported,
exit 0. The default now NAMES the bundles it did not score; `--bundles=all`
scores them in one pass with one exit code. Root-only stays the default so a
vendored third-party corpus is not scored as if it were yours.

#181 — `orphan-docs` had a documented severity nothing read, and the
duplicate-rules check had no id at all, so neither could be tiered. Both are
real rules now and the exit code respects their severity.

#183 — the log and `--json` disagreed (21 lines against 88 findings) because
some checks print per finding and others per group. One computed total, printed
and carried in `--json`.

#182 — `--json-out=<file>` writes the JSON while stdout stays human-readable,
so a CI job stops scanning twice.

#184 — `vigiles test` resolves a harness's bare `vigiles` import from the CLI's
own install, so `npx vigiles@<version> test` needs nothing in the project.
NODE_PATH was measured, not assumed: Node ignores it for ESM.

#173 residual — `lint` verified the integrity HASH, which says nothing about
whether the things a file NAMES still exist, so an artifact committed while its
refs were live stayed green after the target was deleted. The new `spec-refs`
rule re-derives them. It immediately found four dead references in this repo's
own `examples/CLAUDE.md.spec.ts`, left behind by the hexagonal refactor.

BREAKING CHANGE: `orphan-docs` and `duplicate-rules` now default to "warn" — a
repo relying on either to fail CI must set "error" explicitly. Registering them
surfaced that both are heuristic proxies, and this repo's calibration rule is
that a heuristic never defaults to error.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-01 19:51:21 +05:00

2.1 KiB

spec-refs

A compiled instruction file whose .spec.ts references a file, script or symbol that no longer exists.

{ "rules": { "spec-refs": "error" } }
Default error
Surface instruction files compiled from a spec
Bucket external-decidable
Detector compileClaude

What it checks

For every <file>.spec.ts whose compiled <file> exists, the spec's references are re-derived and validated exactly as compile validates them: file() paths against the filesystem, cmd() against package.json scripts, enforce() against the real linter catalogs.

Why the integrity hash is not enough

They answer different questions, and reading them as one is what hid this:

check answers
integrity is this file still what the spec compiled to?
spec-refs do the things it NAMES still exist?

An artifact committed while its references were live stays hash-valid forever. Delete the referenced file afterwards and compile errors while lint reports ✓ hash valid — All compiled files intact and exits 0 — over a file that names a path the agent will not find.

Severity

  • "error" (default) — matches compile. A dead reference is decidable from the filesystem, not a proxy, so it sits in the hard tier.
  • "warn" — reported, exit code untouched.
  • false / "off" — skipped.

Cost

Only specs whose compiled output already exists are loaded, so a repo with no specs does no extra work. A spec that fails to LOAD is not reported here — that is compile's finding, and reporting it twice would blame the wrong command.

See also