Skip to content

Page descriptions and CI work.

Choose a tag to compare

@dankoverride dankoverride released this 31 Aug 02:18
· 22 commits to main since this release
feat(seo): derive a description for every page from its own opening

Closes the defect Dobri reported: every page on the site served the same
meta description, so a Slack unfurl of an installation guide and of the
release notes were indistinguishable. 11 pages were fixed by hand on
2026-08-30. This covers the other 108.

NOT BY HAND, AND THAT IS THE POINT. The Writing Standard (canon,
2026-07-31) already requires the first ~50 words of a page to stand alone as
a summary. Where a page complies, its opening paragraph IS its description;
the text existed and simply was not reaching the meta tag. Sampling eight
untouched pages, seven opened with a usable summary sentence. So the hook
derives rather than invents, and hand-authoring drops from 108 to 3.

hooks/meta_descriptions.py runs on_page_markdown and fills the gap only.
Explicit front matter always wins. It SKIPS rather than guesses when it
cannot produce something honest: an include directive, an admonition, a list
item, anything under 40 characters. A page falling back to a correct generic
string beats one carrying a derived sentence that misleads.

Trademark per Friday's ruling (#2223, clarified #2270): the mark once, on
first appearance, never on every appearance, because "DeepCube Web" and
"DeepCube Studio" are distinct product names and marking the family name
inside them asserts a claim that has not been filed. Written ™ to
match the © already in mkdocs.yml.

TWO BUGS FOUND AND FIXED BEFORE WIRING IT UP, both caught by reading the
generated output rather than trusting it:

1. Multi-line HTML comments were not tracked across lines, only skipped at
   the opener. Uninstallation/Windows and macOS open with an SP-074 note, so
   the hook would have published "Per R-DOCS-005, docs that quote a shipping
   string stay on the old" as those pages' descriptions. An internal rule ID
   and a rename instruction, to Google. Comment state is now tracked like
   fence state.

2. The character budget measured the SOURCE string. `™` is 7 source
   characters and 1 glyph, so a 159-character source is 153 to a reader. The
   ~155 budget belongs to the rendered snippet, not the markup producing it.
   Now measured with html.unescape, marking happens before truncation, and
   truncation never severs an entity.

THE CHECK NOW ASSERTS THE REAL INVARIANT. The compare pass only inspected
pages that DECLARE a description, so it could not see a page that has none
and silently inherits. That is precisely what shipped. A third pass now
fails any page serving site_description. Of 309 rendered pages, 0 inherit.

The allow-list is two entries and both are named. The homepage legitimately
carries the descriptor. Data-Residency is an EMPTY PAGE: 16 bytes, a heading
and nothing else, published under the legal section, linked from nowhere,
and returning 200 with only site chrome. It has no description because it
has no content, and writing one would describe a page that says nothing.
Tracked as DOC-SP-079, with the CI comment saying to delete the line when
the page gets content or is unpublished. That is a tracked defect, not an
exemption.

Verified: mkdocs --strict green, 41 front-matter blocks parse, 14 compared
and 0 mismatched, 309 checked for silent fallback and 0 inheriting, no
™ leaking as literal text, no internal markers in any rendered
description.

The hook produces __pycache__ at build time; .gitignore already covered it
at line 7, so nothing was needed there.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>