The lint that gates the estate

Problem

Fifteen docsets, each a family of index, spokes, full, small and facts files, regenerated whenever a mirror is refreshed. Nobody reads 652 files. The V1 pipeline had shown what happens without a gate: three green stages and an output consumed by nothing. The estate needed a check that is cheap enough to run on every regeneration, strict enough to stop a broken export from being served, and honest enough that its Highs are real.

The /ldo skill defines sixteen passes over an llms file. Some need a model (does this description say what the reader finds there?) or a live network (does this link resolve? does an agent answer the question in two hops?). The rest are deterministic, and those are the gate: llms_lint.py implements the deterministic passes — P0, P1, P2, P3, P5, P6, P7, P9 and P14 — emits findings as {pass, attr, severity, line, msg, fixable}, and exits 1 when any High remains. Pass ids and attribute ids collide (pass P5 is the size ladder; attribute P5 is the secrets row inside pass P9), so this post always says “pass P9” or “attribute P5”.

Inputs

Commands

# cwd: ~/.global-ai-hub
.venv/bin/python scripts/llms_lint.py detect text-mirror/mongodb.com.llms/llms.txt          # kind + grammar
.venv/bin/python scripts/llms_lint.py check  text-mirror/mongodb.com.llms/ --mirror text-mirror/mongodb.com.md --json
.venv/bin/python scripts/llms_lint.py check  text-mirror/mongodb.com.llms/llms.txt --check-links   # P2 live, main only in CI
.venv/bin/python scripts/llms_lint.py hygiene text-mirror/mongodb.com.llms/llms.txt --fix           # P14 only

# the estate gate: every export dir, exit 1 on any High
.venv/bin/python scripts/docset_rollout.py cleanup --dry-run

--fix applies only the fixes the passes reference marks safe: byte hygiene (BOM, smart quotes in URLs), ## Optional last, bare-URL wrapping, residue stripping in full files. It never rewrites a description or a unit — those are generator inputs.

Outputs

docset_rollout.py cleanup --dry-run on 2026-08-31: 0 High across 15 docsets / 652 files. Mediums remain and are listed, not hidden: spoke indexes between 10 and 17 KB (attribute S1), a facts file whose compression ratio to its source is above 0.30 (attribute S4; above 0.15 it is only a Low), and a few D2/D4 descriptions that restate a title or repeat a sibling.

What the gate checks, per file kind:

PassKindWhat fails High
P0 detectallnone — reports kind and grammar so the right passes run
P1 structureindex, familyno H1; more than one H1
P2 linksindex, familya relative target that does not exist (spoke split), a link with no target
P3 descriptionsindex— (Medium: empty, duplicate, restated title)
P5 size ladderallan index over 100,000 bytes — a full file wearing the wrong name
P6 full-file fidelityfulla grammar detected but zero page blocks parsed
P7 facts shapefactsa line with no source URL; a type outside the twelve; no unit lines at all
P9 provenance, rights and steeringalla real credential or PEM key body in copied text (attribute P5); third-party full text with no <!-- internal --> marker (attribute P3). A suspected instruction to the reading model is attribute P4 and only a Medium — the model pass confirms it
P14 hygieneallnever High (excluded from Medium+ credit)

Two generator changes came out of the first estate run rather than lint changes. Pages with fewer than 40 characters of text were being exported and linked — a dead end for any agent that follows the link — so the export now drops them and records the count:

48 on antigravity.google and 5 on platform.openai.com (whose JS-rendered site left 1 real page). And `_mirror_headings` gained an `lru_cache`, because

the gate re-parsed a 20 MB mirror once per spoke file.

What the lint found

Calibration is the part worth writing down. A lint that fires on real docs is worse than none, because people learn to ignore it.

Lessons

Reproduce

hub/scripts/llms_lint.py and hub/tests/test_llms_lint.py are vendored here; the pass and attribute references are skills/llms-deep-optimizer/references/{passes,attributes}.md and are rendered as tables under the site’s reference section. This site runs the same gate on its own llms family in CI; the workflow is .github/workflows/site.yml, and recipe 08 in the examples cookbook is the GitHub Action in isolation.