feat(engine): fixture-path dead links are SKIP, not WARN

A file living under test/, tests/, fixtures/, or a *golden* path is
presumed to break its own links on purpose. nav-golden-escape/bundle/
index.md's deliberate `../../../../etc/passwd` escape pops the whole
base path instead of resolving to null, so it read as a genuine WARN
against three repos in the org — the check was at fault, not them.

The finding still fires, as LINK-INTERNAL-FIXTURE at SKIP with file
and line, so it is never silently dropped. Measured before shipping:
16 LINK-INTERNAL-* findings before, 16 after, across all 20 local
clones — every one converted 1:1, none disappeared.

135 tests (was 129).
This commit is contained in:
Kjell Tore Guttormsen 2026-08-09 14:31:18 +02:00
commit 9eb210bb01
4 changed files with 105 additions and 8 deletions

View file

@ -768,6 +768,20 @@ function linkLevelFor(path) {
return String(path).includes('/') ? 'WARN' : 'ERROR';
}
// A file living in a test/fixture path is presumed to break its own links on
// purpose — `nav-golden-escape/bundle/index.md` escapes with `../../../../etc/passwd`
// deliberately, and the deep `..` pops the whole base path rather than resolving
// to `null`, so it read as a genuine WARN. Third tool in the org to hit this
// exact pattern, which is the signal that the check was at fault, not the repos.
// Only `*golden*` is a substring glob; the other three are exact segment names,
// so `testing/` or `fixturesque/` — real directories — are not swept in.
function isFixturePath(path) {
return String(path)
.toLowerCase()
.split('/')
.some((seg) => seg === 'test' || seg === 'tests' || seg === 'fixtures' || seg.includes('golden'));
}
// Relative file links only. Anchor resolution depends on per-renderer heading
// slug rules and is a rabbit hole; external URLs need the network. Both are
// deliberately out — a check that is sometimes wrong teaches people to ignore it.
@ -804,12 +818,20 @@ export function checkInternalLinks({ files, present }) {
continue;
}
if (!have.has(resolved) && !haveDirs.has(resolved)) {
findings.push({
level: linkLevelFor(path),
code: 'LINK-INTERNAL-MISSING',
bucket: 'broken',
msg: `${path}:${i + 1} — link points at \`${clean}\` (${resolved}), which is not a tracked file`,
});
if (isFixturePath(path)) {
findings.push({
level: 'SKIP',
code: 'LINK-INTERNAL-FIXTURE',
msg: `${path}:${i + 1} — link points at \`${clean}\` (${resolved}), which is not a tracked file; ${path} is a test/fixture path, so this is presumed intentional and not judged`,
});
} else {
findings.push({
level: linkLevelFor(path),
code: 'LINK-INTERNAL-MISSING',
bucket: 'broken',
msg: `${path}:${i + 1} — link points at \`${clean}\` (${resolved}), which is not a tracked file`,
});
}
}
}
});