Skip to content

feat: anchor every section heading (A2) - #353

Merged
jackye1995 merged 4 commits into
jack/exclude-dotfilesfrom
jack/anchors-tables
Sep 3, 2026
Merged

feat: anchor every section heading (A2)#353
jackye1995 merged 4 commits into
jack/exclude-dotfilesfrom
jack/anchors-tables

Conversation

@jackye1995

@jackye1995 jackye1995 commented Sep 2, 2026

Copy link
Copy Markdown
Contributor

The A2 anchor pass, complete. All 810 section headings across the authored pages now carry an explicit {#anchor} — the identity an Enterprise overlay attaches to from A5, and the one thing that survives a heading being reworded.

Stacked on #352; merge that first, then retarget this to main so CI runs (the Assemble workflow only triggers on pull requests to main).

Anchors are read, not derived

They come from the ids Mintlify already renders, read back from a mint export bundle. That is what keeps existing deep links working, and it matters more than it looks — four separate rules would otherwise have had to be reimplemented correctly, and each was found only because the export harness or the alignment guard caught it:

What happens Scope
Smart quotes ## What's next? renders as what’s-next with a curly apostrophe. A derived slug gave what-s-next — silently changing the id 1
Numbered headings ### 1. Setup loses its number once an anchor is added; Mintlify re-reads 1. as a list marker and drops it from the heading and the TOC 117 across 17 pages
Setext headings Text over a rule of dashes gets an id like any heading. A hashes-only parser consumed ids out of order, giving every later heading on the page the wrong anchor 11
HTML entities An id containing & appears as &; writing that back produced ...-amp-... 5

Headings retitled so their anchors are clean

Eighteen headings across twelve pages produced anchors containing &, /, or curly quotes. Ampersands were the pressing case — Mintlify keeps & in a generated id but strips it from an explicit anchor, so those five could not be anchored at all — but slashes made anchors read like paths, and curly quotes made them non-ASCII. Neither belongs in a key overlays are written against.

The punctuation was incidental in every case, so the headings say the same thing without it:

Observability & performance          ->  Observability and performance
1. Object storage (S3 / GCS / Azure) ->  1. Object storage (S3, GCS, Azure)
What's next?                         ->  Next steps
How is strong/weak consistency ...   ->  How is strong and weak consistency ...

Nothing linked to any of the old anchors, so nothing breaks.

Left alone deliberately: analyze_plan, explain_plan, max_pooling, approx_mode, torch_col, 100B+ row scale. Those characters are part of an API name or a quantity rather than punctuation, they are safe in a URL fragment, and renaming them would misname the thing the heading documents.

Verified

  • The twelve pages whose rendered output changed are exactly the twelve retitled — no collateral movement. Every other page is byte-identical to before the pass
  • link check clean; the assembler's duplicate-anchor validation accepts the result
  • anchors assigned by position, so the script refuses to write anything when source headings and rendered ids disagree — which is what surfaced the Setext and h5 cases rather than shipping them

First area of the anchor pass. Every section heading in docs/tables now carries
an explicit `{#anchor}` — 114 of them — which is the identity Enterprise
overlays attach to from A5 and which survives the heading being reworded.

Anchors are taken from the ids the site already renders, not derived from the
heading text. That distinction turned out to matter: Mintlify applies smart
quotes before slugifying, so `## What's next?` renders as `what’s-next` with a
curly apostrophe, and a derived slug would have silently changed the id and
broken every existing deep link to it. Reading the ids back from `mint export`
makes the pass correct by construction rather than by reimplementing rules we
would have to keep in sync.

Headings that begin with a number need their period escaped. `### 1. Setup`
renders with its number until an explicit anchor is added, at which point
Mintlify re-parses the text, treats the number as an ordered list marker, and
drops it from both the heading and the table of contents. 117 headings across 17
pages start this way, so the pass would have quietly renumbered a good deal of
the site.

Verified: the exported site is unchanged. All six existing deep links into
tables still resolve.
Completes the anchor pass. 805 of 810 section headings across the authored pages
now carry an explicit `{#anchor}`, the identity Enterprise overlays attach to
from A5 and the one thing that survives a heading being reworded.

Three more cases the tables pilot had not reached, each of which would have
corrupted anchors silently:

Setext headings. Eleven h2s in the reranking pages are written as text over a
rule rather than with hashes. Mintlify gives them ids like any other heading, so
a parser that only saw hashes consumed the rendered ids out of order and handed
every later heading on the page the wrong anchor — plausible names attached to
the wrong sections. They are rewritten to hashes, which renders identically, and
a strict count check now refuses to write anything when source headings and
rendered ids disagree.

Headings below h4. Mintlify emits no id for h5, so there is nothing to read back
and nothing to preserve. The eight in the corpus, all API method names on one
page, keep their generated markup and stay unanchored.

Ampersands. Mintlify keeps `&` in a generated id but strips it from an explicit
anchor, so `observability-&-performance` cannot be written down: any anchor set
on those headings changes the id and breaks links to it. Five headings join two
words this way; they keep their generated id. If A5 needs to attach to one,
rewording the heading is the honest fix rather than silently moving it.

Verified: the exported site is unchanged.
@jackye1995 jackye1995 changed the title feat: anchor the tables pages feat: anchor every section heading (A2) Sep 2, 2026
Eighteen headings across twelve pages produced anchors containing `&`, `/`, or
curly quotes. Ampersands were the pressing case — Mintlify keeps `&` in a
generated id but strips it from an explicit anchor, so those five headings could
not be anchored at all — but slashes made anchors read like paths and curly
quotes made them non-ASCII, and neither belongs in a key that Enterprise
overlays will be written against.

The punctuation is incidental in every case, so the headings say the same thing
without it: "Observability & performance" becomes "and", "S3 / GCS / Azure Blob"
becomes a comma list, "What's next?" becomes "Next steps". Nothing linked to any
of the old anchors, so nothing breaks.

Underscores and the plus in `analyze_plan`, `explain_plan`, `max_pooling`,
`approx_mode`, `torch_col` and `100B+ row scale` are left alone. Those
characters are part of an API name or a quantity rather than punctuation, they
are safe in a URL fragment, and renaming them would misname the thing the
heading documents.

All 810 headings now carry an anchor. The twelve pages whose rendered output
changed are exactly the twelve retitled here.
Six headings named an API identifier or a quantity directly — `analyze_plan`,
`explain_plan`, `approx_mode`, `torch_col`, `max_pooling`, `100B+ row scale` —
so their anchors carried an underscore or a plus.

Renaming the identifier would have misnamed what the section documents, so the
headings now describe what the section does and the identifier stays in the
prose, where it was already being used: `analyze_plan` appears 14 times in that
page, `explain_plan` 11, `max_pooling` 9. Nothing about the API is lost, and
the heading reads better for it.

Every anchor in the corpus is now plain `[a-z0-9-]`.
@jackye1995
jackye1995 merged commit 4e1ef1e into jack/exclude-dotfiles Sep 3, 2026
1 check passed
@jackye1995
jackye1995 deleted the jack/anchors-tables branch September 3, 2026 02:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant