Skip to content

chore(content): clear the rot — dead links, held drafts, orphan sections - #169

Open
avrabe wants to merge 2 commits into
mainfrom
content/prune-rot
Open

chore(content): clear the rot — dead links, held drafts, orphan sections#169
avrabe wants to merge 2 commits into
mainfrom
content/prune-rot

Conversation

@avrabe

@avrabe avrabe commented Aug 20, 2026

Copy link
Copy Markdown
Contributor

Walked the content tree after noticing duplicates and unpublished material sitting there. Four separate kinds of rot, one of them breaking the local build.

The build was broken locally

content/preprints/ was an untracked leftover from the preprints → publications rename. The surviving content/publications/oracle-gated-agent-loops.md differs from it by exactly one line — the aliases = ["/preprints/oracle-gated-agent-loops/"] added to keep the old URL alive. zola build failed with a path collision on any tree that had it. Removed (it was never committed, so it is not in this diff — noted for the record).

Six dead internal links, CI green over all of them

link from why
/docs/guide/architecture/ /docs/ (in the nav) never written
/docs/guide/verify/ /docs/ never written
/docs/guide/trace/ /docs/ never written
/docs/guide/compliance/ /docs/ never written
/blog/rivet-v0.1.0/ 2 posts slugifies to rivet-v0-1-0
/blog/2026-05-01-cross-language-lto-…/ 1 post URLs are date-free

Four of the five bullets under The Guide on the Documentation page were 404s.

CI runs zola build, which does not validate links.

The gate that would have caught it is vacuous here

zola check --skip-external-links looks like the obvious fix. It isn't — measured with a deliberately dead /docs/guide/compliance/ in the tree:

$ zola check --skip-external-links ; echo $?
0

It only understands Zola's @/path.md internal-link syntax; our content uses raw absolute hrefs, which it treats as unchecked.

So this adds scripts/check-internal-links.py instead, verified red-first:

clean tree          -> 94 links, 0 dead, exit 0
+1 dead link        -> 95 links, 1 dead, exit 1     <- the control
reverted            -> 94 links, 0 dead, exit 0

It also fails if it matched zero links — Zola minifies output and emits unquoted attributes (href=/docs/), so the naive href="([^"]+)" pattern matches nothing and reports a triumphant zero. That is how the first version of this check fooled me.

Two drafts that rotted for 112 and 101 days

Deleted witness-wasm-mcdc and attestation-chains-trustmee-to-cerisier.

The interesting part is why the second one rotted. blog-autopublish runs daily and is 40/40 success, and reported both identically:

Held (2):
- ∞ · attestation-chains-trustmee-to-cerisier
- ∞ · witness-wasm-mcdc

But they were held for different reasons: witness-wasm-mcdc carried an explicit hold = true — a decision. attestation-chains had no hold and no ready — an omission. One glyph for both, so the only surface anyone would check made a forgotten flag look like a deliberate park.

Fixed two ways:

  • the report splits the bucket into held on purpose (hold = true) and not yet marked ready = true, the latter with a note saying it will never publish until someone acts. Verified with a fixture in each bucket.
  • the workflow header no longer documents a contract the script does not implement. It said draft = true + no hold was enough; scripts/blog-autopublish.py requires ready = true. The opt-in design is right — the stale comment was not.

Three empty sections in the sitemap

/gale/, /rivet/, /spar/ — each an _index.md reading "Artifacts from the X project, exported by rivet" with zero pages. Nothing populates them; /reports/ (#59) is what ships project evidence now. Unlinked from nav and from every page body, yet all three were in sitemap.xml.

Smaller

  • Filename dates now match frontmatter on three posts (overdoing-… 22→29 Apr, variant-pruning 24→30 Apr, verified-os-on-silicon 15→18 Jul). URLs are date-free, so nothing moved and no alias is needed.
  • /guides/verification-guide/ — a 16 KB reference reachable only from a footnote in the March 15 post — is now linked from the Documentation page.

Verification

zola build   -> 39 pages (0 orphan), 14 sections -> 11 sections
link check   -> 75 pages, 94 internal links, 0 dead

Still open, not touched here: content/talks/ is a leftover from the same talks → publications rename — no _index.md, holding one draft (speaker notes, 14 days old, not yet rotting).

🤖 Generated with Claude Code

https://claude.ai/code/session_01G5qpB7zvxLvdrvn5YRyj4R

avrabe and others added 2 commits August 20, 2026 07:58
…par)

Each was an `_index.md` reading "Artifacts from the <project> project,
exported by rivet" with zero pages beneath it. Nothing populates them —
no workflow, no script — and the reports section (#59, `load_data` over
`static/reports/index.json`) is what actually ships project evidence now.

They were unreachable from the nav and from any page body, yet all three
were in the sitemap: three URLs submitted to search engines rendering a
title and one sentence.

zola build: 39 pages (0 orphan), 14 sections -> 11 sections. No page lost.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G5qpB7zvxLvdrvn5YRyj4R
…ates

Six internal links were dead on the live site, four of them on the
nav-linked /docs/ page: `/docs/guide/{architecture,verify,trace,compliance}/`
were never written, `/blog/rivet-v0.1.0/` slugifies to `rivet-v0-1-0`, and
`/blog/2026-05-01-cross-language-lto-…/` carried a date the URL does not.
CI ran `zola build`, which does not validate links, so all six were green.

Adds `scripts/check-internal-links.py` and runs it in CI. Deliberately NOT
`zola check --skip-external-links`: measured, it exits 0 with a dead
`/docs/guide/compliance/` link in the tree, because it only understands
Zola's `@/path.md` syntax and our content uses raw absolute hrefs. The new
checker was verified red-first — green, red on one reintroduced dead link,
green again — and refuses to pass if it matched zero links at all.

The "The Guide" list on /docs/ drops the four pages that do not exist and
now surfaces `/guides/verification-guide/` — a 16 KB reference that was
reachable only from a footnote in the March 15 post.

Deletes two drafts that had been held 112 and 101 days
(`witness-wasm-mcdc`, `attestation-chains-trustmee-to-cerisier`).

The reason the second one rotted is fixed too. blog-autopublish runs daily
and is 40/40 green, and reported both as `∞ Held` — but one carried an
explicit `hold = true` (a decision) and the other was simply missing
`ready = true` (an omission). The report now separates them, and the
workflow header no longer documents a contract the script does not
implement (it said `draft = true` + no `hold` was enough; the script
requires `ready = true`). Verified with a fixture in each bucket.

Filename dates now match frontmatter dates on three posts. URLs are
date-free, so no page moved and no alias is needed.

zola build: 39 pages (0 orphan), 11 sections. Internal links: 94 checked, 0 dead.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01G5qpB7zvxLvdrvn5YRyj4R
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