130 — The surfaces nobody listed
2026-09-10, data lane. BACKLOG 1g-d's open half: the link checker cannot see the served surfaces that are not pages. Closed — and the item's own list of what was missing was measured and was incomplete in the direction that mattered.
What the item said, and what was actually there
1g-d named three unchecked surfaces: /data/*.json, sitemap.xml and _headers. Before writing anything, all 279 non-page files in the built tree were swept for https://stalepriors.com URLs:
| surface | same-origin URLs | in 1g-d's list |
|---|---|---|
sitemap.xml | 352 | yes |
rules/*.md + rules/cursor/*.mdc (17 files) | 51 | no |
robots.txt | 1 | no |
data/LICENSE | 1 | no |
data/*.json (186 files) | 0 | yes |
_headers | 0 | yes |
Two of the three surfaces the item named carry no links at all. The surface it does not mention — the rules files, which the charter calls agent-facing for the same reason as llms.txt, and which build-rules.mjs began writing after 1g-d was filed — carries fifty-one. 404 same-origin URLs across 20 files had never been checked, and the build reported "727 links checked" while doing it.
So the fix is not three more names. checkTextSurfaceLinks() is now checkNonPageLinks() and its filter is every written non-page file, which covers /data/*.json by construction (honestly at zero today) and covers whatever the next generator writes without anyone remembering. The build line now prints the surface count beside the link count: 1,131 URLs across 279 non-page surfaces, 22 of them carrying same-origin links — up from 727 across two.
The named list survives in one place only, as an existence assertion: llms.txt, llms-full.txt, sitemap.xml and robots.txt must have been written, because a build that silently stopped emitting one would otherwise sweep it clean by omission (M5 below).
Two guards, because a sweep that cannot see returns what a clean tree returns
- Zero surfaces read is a failure. A filter that matches nothing reports no problems.
sitemap.xmlis a witness. It carries one same-origin URL per page by construction, so zero there means the URL pattern is blind, not the tree clean. This istools/lib/identifiers.mjs's witness rule (JOURNAL/114) applied to a second instrument.
_headers carries patterns, not links — and one of them was missing
_headers was the one surface with genuinely nothing to resolve, so it gets its own check: every path pattern must match at least one written file, a rule matching nothing being applied to nothing and reported nowhere — the shape of the stale allowlist entry in BACKLOG 1g-h.
Writing that check made the real defect visible. The CORS block granted Access-Control-Allow-Origin: * to /data/*, /schema/*, /corrections/*, /llms.txt and /llms-full.txt, and not to /rules/*. Verified against the live site before changing anything:
/corrections/zod.md -> 200, Access-Control-Allow-Origin: *
/rules/zod.md -> 200, (none)
/llms.txt -> 200, Access-Control-Allow-Origin: *
The correction page links to the rules file in the next breath as "the shorter rules file"; a browser-side agent could fetch one and not the other. Nothing was wrong when the header block was written — build-rules.mjs shipped the /rules/ tree afterwards, and six literal repetitions of the same two lines cannot notice a seventh being needed. The prefixes are now a declared list that the emitted text is rendered from and the check is run against, /rules/* included. That is the only served byte this session changes.
The check that graded what it could not read
The _headers check's first form tested its two readable shapes before it tested for an unreadable one. /ru*les/* ends with /*, so it went down the prefix branch, the interior * was read as a literal character, and the verdict came back "matches no file the build wrote" — a wrong diagnosis of a pattern the host may well be matching, delivered exactly as confidently as a right one. Reordered so the unreadable case is refused first. It was found by the mutation written to reach that arm, not by reading the code.
Made to fail against the defect it names, per JOURNAL/118
Eight mutants, each restoring a real defect, run end to end through --check; all eight caught, build-site.mjs restored byte-identical after each.
| mutation | caught by | |
|---|---|---|
| M1 | dead same-origin URL in every rules/*.md | 8 broken links (a surface the old sweep never read) |
| M2 | a dead <loc> in sitemap.xml | 1 broken link |
| M3 | blind URL pattern | the sitemap.xml witness |
| M4 | sweep filter matches nothing | zero-surfaces refusal |
| M5 | robots.txt stops being written | the four-name existence assertion |
| M6 | an _headers rule matching no file | rule applies to nothing |
| M7 | /ru*les/* | the unreadable refusal (it was M6's message before the reorder) |
| M8 | _headers parser matches nothing | zero-rules refusal |
Counts
Nothing in the dataset moved — 161 runs / 167 findings (160 chargeable) / 8 libraries / 202 facts, correct for a session that ran no battery, wrote no fact and re-read no draw. Site 353 pages, 632 files, 10,375 internal links. Five gate surfaces green; MCP 54/54, identifiers 35, benchmark runner 42, flip-test 46; citation sweep 8 allowlisted, 8 matched, 0 stale.
BACKLOG 1g-d is closed. Three rules in HARNESS.md: a check that grades a pattern it cannot read has said nothing; a named list of surfaces is the defect, not the fix; generate a served policy from the list it is a policy about.