<!-- llms-explorer twin of https://llms-explorer.com/reference/passes/ · generated 2026-08-31 -->

# The passes

What the optimizer runs, in order, and how each pass is judged and fixed.

<!-- llms-deep-optimizer · references/passes.md · 2026-08-30 -->

Each pass names the attributes it judges (ids from `attributes.md`), whether it is
**deterministic** (`scripts/llms_lint.py`), **model** (an LLM reads and decides),
or **live** (an agent or an HTTP call is exercised), and for every pass: how it is used,
how a finding is judged, how the file is updated, what tools it leans on, and which sibling
skills it hands to. Passes are grouped into bundles that run concurrently; findings are
collected before any write (the family rule, `convergence-and-severity.md` § Convergence loop).

**Contents**
- Bundle map and dispatch rules
- P0 Detect kind and grammar
- P1 Structure
- P2 Links and reachability
- P3 Descriptions
- P4 Navigation design
- P5 Size ladder and budgets
- P6 Full-file fidelity
- P7 Facts-file shape
- P8 Facts truthfulness
- P9 Provenance, rights and steering
- P10 Family and nesting
- P11 Retrieval readiness (keyword + vector)
- P12 Agent usability test
- P13 Serving and headers
- P14 Hygiene
- P15 Regeneration parity
- Severity resolution across passes
- N/A rules

## Bundle map and dispatch rules

| Bundle | Passes | Kind | Runs as |
|---|---|---|---|
| B0 | P0 | deterministic | inline, first — every other pass keys off the detected kind |
| B1 | P1 P2 P3 P5 P14 | deterministic | one `llms_lint.py` invocation, JSON findings |
| B2 | P4 P9 | model | one subagent reading the index (+ sample pages) |
| B3 | P6 P7 | deterministic | `llms_lint.py --full` / `--facts` (same invocation as B1 when the kind is full/facts) |
| B4 | P8 | model, sampled | one subagent, 20 units re-read against source spans |
| B5 | P10 | deterministic + model | only when kind = family or `--family` |
| B6 | P11 | live | `docset_indexer.py keyword` + `query --layer facts` probes |
| B7 | P12 | live agent | one fresh-context subagent given ONLY the file; opt-in `--agent-test`, default on for new files |
| B8 | P13 | live HTTP | only when a URL is given or `--serve-check` |
| B9 | P15 | deterministic | only when the export directory has a source mirror |

Dispatch: B1 and B3 in one tool call; B2, B4, B7 as three concurrent subagents when the Agent
tool exists (sequential otherwise); B5/B6/B8/B9 inline. Small profile (index < 4 KB, no full,
no facts): B3, B4, B6 are `N/A (no layer)`, B7 shrinks to 5 questions.

---

## P0 — Detect kind and grammar (deterministic)

**Judges** I6. **Used** first, always. Reads the first 4 KB and the file name and returns one of
`index | family | full | small | facts | unknown`, plus for full files the page grammar
(`mintlify | anthropic-yaml | cloudflare-frontmatter | firecrawl | none`).

**Judged:** `unknown` → High (the file cannot be optimized without knowing what it is; report
and stop unless `--kind` is passed). Two grammars in one full file → High (C1). A file named
`llms.txt` that parses as full → High (I6; it will be served as an index and blow every budget).

**Updated:** never rewrites; it sets the profile. `--kind` overrides.

**Tools:** `llms_lint.py detect`; `llms_acquire.split_llms_full` for grammar probing.
**Relations:** `document-formats/references/llms-txt.md` § grammars is the authority on what
counts as a grammar; this pass never invents a fourth.

## P1 — Structure (deterministic)

**Judges** I1 I2 I4 I5 N4. Parses the index as spec v2: one H1, optional blockquote, optional
free text, H2 sections of `- [name](url): notes` lines, `## Optional` last.

**Judged:** missing/multiple H1 → High. Blockquote missing → Medium; blockquote present but > 3
sentences or restating the H1 → Medium (model confirms in P4). H3+ headings or paragraphs after
the first H2 → Medium. List line not matching the link grammar → per-line finding, High if
< 90% of lines match. `## Optional` not last → Medium.

**Updated (`--fix` safe):** demote H3 to a flat list under the nearest H2; move `## Optional` to
the end; wrap a bare URL line into `- [<last path segment>](url)`; strip prose after the first
H2 into a `<!-- moved -->` comment for the model pass to place. Never invents a blockquote —
that is P3/P4 model work.

**Tools:** `llms_lint.py structure`. **Relations:** the community validators' strict rules
(`llms-txt-validator`, `llmstxt-validator`) are folded in where they agree with the spec; where
they demand more than the spec (e.g. "blockquote required") the finding is Low, tagged
`validator-only`.

## P2 — Links and reachability (deterministic, optionally live)

**Judges** N1 N6 N7 P2 F1. Resolves each link: relative → against the base URL or the export
directory; absolute → HEAD when `--check-links` (rate-limited, 8 concurrent, 10 s timeout,
one retry). Counts hops for family files.

**Judged:** 4xx/5xx or HTML-app-shell response (content-type text/html with no `.md` twin
probe success) → High per link, capped at one High finding listing all. Redirect chain > 2 →
Medium. Duplicate target across sections → Low (N7). Family file linking a page rather than an
`llms.txt` → High (F1). Link to a private mirror path (`file://`, `127.0.0.1`, `text-mirror/`)
in a file not marked internal → High (P2).

**Updated (`--fix` safe):** rewrite `page.html` → `page.md` when the twin probe succeeded;
collapse redirect chains to the final URL; drop exact duplicate targets keeping the first. Dead
links are never deleted silently — they become BLOCKED rows unless the source mirror still has
the page (then P15 regenerates).

**Tools:** `llms_lint.py links [--check-links]`; `llms_serve.py` routes for hub-served files;
`hub_llms_full_read` to confirm a page exists in the mirror. **Relations:** `web-text-mirror`
owns re-crawling a page that has genuinely moved.

## P3 — Descriptions (deterministic + model)

**Judges** D1 D3 D4 D5 D6. Deterministic part: missing notes, word-count band, duplicates,
truncation ellipsis, family-line counts. Model part: for each description, is it a restated
title, and does it name what the reader finds (exact tokens)?

**Judged:** no notes on a link → Medium (High if > 40% of links). Duplicate notes → Medium.
Restated-title notes (model verdict on the sampled 30 worst) → Medium. Family line without
counts → Medium. A model-written description whose claims are not on the page (P8-style spot
check on 10) → High.

**Updated:** descriptions come from the `definition` unit of the page when a facts layer exists
(extractive, cheap, correct); else from the page's H1 + first sentence via the mirror; the model
polishes ONLY entries still under 40 chars or flagged restated-title, and every polished entry is
re-verified against the page before write. Counts on family lines are recomputed from the
manifests.

**Tools:** `llms_lint.py descriptions`; `docset_refine/export_llms.py` `_describe()`;
`hub_query_docset(layer="facts")` to fetch a page's definition unit; local LLM
(`HUB_REFINE_LLM_URLS`, `qwen3.5:35b`) for bulk polish, `claude -p` for the final 10%.
**Relations:** `document-formats/references/llms-txt-generation-tooling.md` § descriptions
(why extractive beats generated); `prompt-deep-optimizer` owns the polish prompt if it drifts.

## P4 — Navigation design (model)

**Judges** I2 I3 N2 N3 N4 N7. The subagent reads the whole index and the section names against
the question list (seeded from P12's question bank, or from `hub_ask` logs for hub docsets).

**Judged:** sections mirror the URL tree or the alphabet rather than tasks/topics → Medium.
Hot pages (quickstart, auth, reference root, errors, pricing) not in the first section →
Medium. Reference/pricing under `## Optional` → Medium. Blockquote that does not say what the
thing is and who it is for → Medium. Free text before the first H2 that a reader does not need
→ Low.

**Updated:** propose a section plan (name → links) as a diff; apply only when every link is
preserved (the demotion guard — a reorganisation that drops a link is a High finding on
itself). Section names are taken from the source nav when the mirror carries it
(`llms_acquire` keeps the source index order), else from the concept-tree children of the
docset's concept.

**Tools:** subagent (model per SKILL.md frontmatter), `hub_concept_lookup` for topic names,
`hub_docset_index` to read the current index. **Relations:** `concept-family-explorer` for a
topical file's section skeleton; `dfo` (document-deep-optimizer) for prose quality of the
blockquote when it exceeds two sentences.

## P5 — Size ladder and budgets (deterministic)

**Judges** S1 S2 S3 S4 S5 S6. Reads `manifest.json` when present, else measures.

**Judged:** index > 10 KB → Medium; > 100 KB → High (it is a full file wearing the wrong name).
Full file with no small variant beside it → Medium. Small > 50k tokens → Medium. Facts/prose
ratio > 0.30 → Medium. Manifest missing or inconsistent with the files (± 2%) → Medium (H8). A
page block > 200 KB → Low.

**Updated (`--fix` safe):** regenerate `manifest.json`; rebuild `llms-small.txt` with
`export_llms.build_small`; for an oversize index, propose hub-and-spoke split by section
(each section → `<section>/llms.txt`, root keeps one line per section) — applied only with
`--split`, since it changes URLs.

**Tools:** `llms_lint.py size`; `export_llms.py`. **Relations:** the 50k figure is the Cursor
stability ceiling from `llms-txt-ecosystem-evidence.md`; recalibrate there, not here.

## P6 — Full-file fidelity (deterministic)

**Judges** C1 C2 C3 C4 C5. Splits with the detected grammar; per block checks title, source
URL, residue patterns, fence balance, table separators; hashes bodies for exact dups;
`units.dedup`-style embedding pass for near-dups when `--near-dups`.

**Judged:** block fails to parse → High (C1). Missing title/URL → High per block, one finding.
Residue → Medium with line refs. Unbalanced fences → Medium (they poison every downstream
chunker). Exact duplicate page → Medium; near-dup ≥ 0.95 cosine → Low with the pair.

**Updated (`--fix` safe):** strip known residue (`Documentation Index` blockquote,
`[Skip to content]`, `theme={null}`, MDX import lines); close a dangling fence at the block end;
drop exact duplicates keeping the first occurrence; rewrite blocks into the declared grammar
(normalisation, lossless). Near-dups are reported, never removed (localised copies may be
wanted).

**Tools:** `llms_lint.py full`; `llms_acquire.split_llms_full`; `docset_refine.clean`;
`semantic_ops.vecstore` for near-dup embeddings. **Relations:** `docset_refine clean` is the
production version of the residue strip — the lint uses the same pattern table
(`docset_refine/clean.py`), never a second copy.

## P7 — Facts-file shape (deterministic)

**Judges** C6 R3 R4 R7 P6. Parses each unit line as `build_facts` emits it:
`- [type] text — <url>#<anchor>` under a `## <page title>` / `<url>` heading pair (optional
trailing ` · keywords: a, b` and ` · verified-as-of: YYYY-MM-DD` fields are accepted). Checks
type ∈ `docset_refine.UNIT_TYPES` (concept, fact, actionable, question, problem, statement,
quote, idea, snippet, parameter, definition, change), anchor resolves to a heading in the
mirror page, unit ≤ 2 sentences / 400 chars, code tokens present in the unit's `keywords`
(from `units.jsonl`, the source of truth the facts file is rendered from), every indexed page
has ≥ 1 unit.

**Judged:** unit without source → High. Anchor not resolvable → Medium (High if > 20%).
Untyped or unknown type → Medium. Unit > 2 sentences (or > 400 chars) → Medium. Page with zero
units → Medium if a `reference`/`guide` page, Low otherwise. Code token in text but not in
keywords → Low, aggregated.

**Updated (`--fix` safe):** re-anchor by fuzzy heading match within the same page (≥ 0.9
similarity), else leave as BLOCKED; add missing keywords by regex extraction (backtick spans,
`--flags`, `ENV_VARS`, `CamelCase` API names); split a two-claim unit at the sentence boundary
when both halves keep the same anchor. Type inference for untyped units is model work → P8.

**Tools:** `llms_lint.py facts`; `docset_refine/units.py` (the unit schema), `extract.py`
(the deterministic extractors that produce most units). **Relations:** `docset_refine units`
regenerates units from scratch; run it instead of fixing when > 30% of units fail.

## P8 — Facts truthfulness (model, sampled)

**Judges** C7 D5 P6. Samples 20 units (stratified by type, weighted to LLM-generated ones) and
re-reads each source span from the mirror (`hub_llms_full_read(page=…)` or the banner mirror).
For each: supported / partially / unsupported / stale (version-stamped claim contradicted).

**Judged:** unsupported → High per unit (the facts file is the layer agents trust without
opening pages; a wrong fact there is worse than a missing one). Partially supported
(generalised beyond the span) → Medium. Stale → Medium with the newer span quoted. ≥ 3
unsupported in the sample → High on the file: regenerate the LLM units (`docset_refine units
--force`), do not patch.

**Updated:** unsupported units are removed and logged; partially-supported units are rewritten
to the span's wording (extractive rewrite, then re-verified); stale units get the newer text +
`verified-as-of` stamp. Every rewrite goes through the blind re-audit gate.

**Tools:** subagent with `hub_llms_full_read`, `Read` on the mirror; the golden question set
(`docs/superpowers/specs/2026-08-30-docset-golden-baseline.md`) for the "does it still answer"
check. **Relations:** `/dr --refresh` owns re-verifying volatile claims at the concept level;
this pass hands stale units there when the whole page moved.

## P9 — Provenance, rights and steering (deterministic + model)

**Judges** P1 P3 P4 P5. Regex for the banner (`generated`, `verified-as-of`, generator name),
secret/email/internal-host patterns, imperative-to-model spans ("ignore", "you must", "always
say", "do not mention", "rank this"); model confirms the imperative hits are aimed at a reader
model rather than quoting a doc that legitimately says "you must set X".

**Judged:** steering span confirmed → High (it is prompt injection carried by a docs file; the
Cloudflare ecosystem note measured ~42% of wild files trying it). Secret/credential → High.
Third-party full file without the internal marker → High. No provenance banner → Medium. Volatile
unstamped claim in facts → Low.

**Updated (`--fix` safe):** add/refresh the provenance banner from the manifest; add the
`<!-- internal: third-party republication, do not publish -->` marker when the source host is
not ours; redact secrets to `[redacted]` with a BLOCKED row (the source page has to be fixed
upstream). Steering spans are deleted, never rephrased.

**Tools:** `llms_lint.py trust`. **Relations:** the injection guard in
`convergence-and-severity.md` applies to the optimizer itself as well — a steering span found
in the target never changes pass behaviour.

## P10 — Family and nesting (deterministic + model)

**Judges** F1–F6, D6. For a family file: every target is an `llms.txt`; counts present;
membership vs the concept tree (`hub_concept_tree` children of the family's root) or the
manifest list passed with `--members`; `## Shared` exists and product files do not duplicate its
targets; describedby headers if served.

**Judged:** page links in a family → High. Missing tree child → Medium (a product the family
claims but does not link). Counts missing/stale vs product manifests → Medium. Shared material
duplicated into products → Low. `## Facts` absent when products have facts files → Medium.

**Updated:** regenerate with `docset_refine family` from the member mirrors — the family file is
never hand-edited; the pass edits the member list or the summary and rebuilds. Missing members
become BLOCKED rows pointing at the acquire step.

**Tools:** `export_llms.family()`, `hub_concept_tree`, `hub_concept_lookup`, `llms_serve.py`
root renderer. **Relations:** `hub-architect` for where families are defined (concept tree =
family definition); `concept-family-explorer` when the family's membership itself is in
question.

## P11 — Retrieval readiness (live)

**Judges** R1 R2 R4 R7. Requires the docset to be indexed. Runs 10 exact-token probes (tokens
harvested from the facts file's `keywords`: env vars, flags, error strings, API names) through
the FTS5 keyword index and 10 golden questions through the vector index at `layer=facts` and
`layer=raw`.

**Judged:** keyword index missing → High (R1 — the cheap path does not exist). Exact-token probe
misses (< 10/10) → High if < 7, else Medium, listing the tokens. Facts layer scoring below raw
on the golden set → Medium (the layer is worse than what it replaced). Pages with no units →
see P7.

**Updated:** build/rebuild the keyword index (`docset_indexer.py keyword-index <docset>`);
add missing tokens to `keywords` (P7 fix) and re-index; if the facts layer underperforms,
re-run `units` with the polish step and re-index — never lower the golden bar.

**Tools:** `docset_indexer.py keyword <docset> "q"` (FTS5, BM25), `query --layer facts|raw`,
`hub_query_docset`, golden set from the baseline spec. **Relations:** `semantic_ops.fuse`
(RRF) is what `hub_ask` uses to combine both; this pass proves each leg works alone.

## P12 — Agent usability test (live agent)

**Judges** R5 R6 N3. A fresh-context subagent receives ONLY the index (or ONLY the facts file)
and 10 questions from the bank (`references/facts-to-llms-howto.md` § question bank shape). It
must answer by following ≤ 2 links (index) or from the file alone (facts), and report per
question: answered / partial / not found, links followed, time.

**Judged:** index < 8/10 → Medium; < 6/10 → High. Facts < 7/10 → Medium. A question answered
only after > 2 hops → Medium on the section that hid the page (feeds P4). A confident wrong
answer → High, traced to the description or unit that misled (feeds P3/P8).

**Updated:** no direct edits — the transcript is evidence for P3/P4/P8 rewrites. The questions
and verdicts persist to `~/.claude/skill-consolidation/evals/llms/<key>.eval.jsonl` so the
next run replays them (the family's eval-corpus pattern).

**Tools:** Agent tool (fresh context), `hub_docset_index`, `hub_llms_full_read` for link
following inside the hub. **Relations:** `skill-optimizer` Pass H is the same idea applied to
skill descriptions; the eval file shape is shared.

## P13 — Serving and headers (live HTTP)

**Judges** H2 H3 H4 H7. HEAD + GET on the served URL(s): status, content-type, redirects,
`Link` headers, `X-Markdown-Tokens`, auth challenge; for HTML pages of the same site, probe
`Accept: text/markdown` and the `.md` twin.

**Judged:** non-200, redirect to HTML, auth challenge → High. Content-type not markdown/plain →
Medium. Missing `describedby`/`alternate` → Low. Tokens header missing → Low.

**Updated:** for hub-served files, fix in `llms_serve.py` (headers are code, not content) and
restart `com.global-ai-hub.llms-serve`; for third-party sites, report only.

**Tools:** `curl -I`, `llms_serve.py /health`, `launchctl kickstart`. **Relations:** the
`document-formats/references/llms-txt.md` § discovery section defines which headers matter.

## P14 — Hygiene (deterministic, excluded from Medium+ credit)

**Judges** H1. Encoding, line endings, tabs in list lines, trailing whitespace, BOM, single
trailing newline, smart quotes inside URLs.

**Judged:** Hygiene row; always fixed, never counted toward convergence. Exception: a smart
quote or zero-width char inside a URL → High (dead link in disguise).

**Updated (`--fix` safe):** byte-level normalisation.

**Tools:** `llms_lint.py hygiene`. **Relations:** `skill-optimizer` Pass L is the same class.

## P15 — Regeneration parity (deterministic)

**Judges** H5 H8 R7. When the export directory sits beside its source mirror: does
`docset_refine export` reproduce the current files (modulo timestamps)? If not, the file was
hand-edited or the mirror moved on.

**Judged:** hand edits that the generator would drop → Medium (they will be lost on the next
refine; either fold them into the generator's inputs — nav order, summary, title flags — or
mark the file `hand-maintained` in the manifest). Mirror newer than the export → Medium
(stale). Manifest counts diverge → Medium.

**Updated:** regenerate when the mirror is newer; when hand edits exist, write them into the
manifest's `overrides` (title, summary, section order) so the generator reproduces them, then
regenerate.

**Tools:** `docset_refine export`, `diff`. **Relations:** `pipeline_manager.py` refine stage is
what will overwrite the file; this pass makes the overwrite safe.

---

## Severity resolution across passes

Same span flagged by several passes: take the highest severity; tie → lower pass number wins
(P0 > P1 > …); tie → the more conservative fix (report over rewrite). BLOCKED rows (dead links
with no mirror page, secrets that must be fixed upstream, members not yet acquired) are
reported but never count toward convergence, per the contract. The full ladder and the exits
live in `~/.claude/skill-consolidation/convergence-and-severity.md`.

## N/A rules

A pass reports `N/A (<reason>)` — never silently skips — when: the kind excludes it (P6 on an
index), the layer is absent (P11 without an indexed docset), the input is missing (P13 without a
URL, P15 without a mirror), or the flag is off (P12 without `--agent-test` on a refresh run).
An N/A that is caused by something the run could create (no keyword index, no small variant)
is also a Medium finding on the missing thing.
