fix(readme): the four dead TOC anchors, and a guard that reads the renderer instead of modelling it

Ordre 39's TOC was built from a model of Forgejo's slugger ("each space becomes
one hyphen"). Measured against the published page, the renderer COLLAPSES each
run of [space|hyphen] into one — so the four headings carrying an em-dash between
spaces got two hyphens in the anchor and none in the id. Four of eleven links
were dead on the open mirror while every local check said green.

The anchors lose the extra hyphen; no heading text changes.

test_readme_anchors_loadbearing.py makes the check load-bearing (spec §11). It
pins the 14 heading ids Forgejo actually emitted on 2026-08-17, so the rule is
checked against the EMISSION rather than against itself — the failure mode that
let three known-negative controls agree with the wrong model. Known-negative
fixtures cover a broken anchor and a "## Phantom Heading" inside a fence (with a
positive control, so the fence test cannot pass by finding nothing), and the
naive space-rule is asserted to miss exactly the four ids that shipped dead.

Value-proved green-before/red-after on four mutations, including one that stays
green for the right reason and is recorded as a limit. Offline; no network.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QwphwRfCBaDDCzeYghKuoM
This commit is contained in:
Kjell Tore Guttormsen 2026-08-17 11:28:46 +02:00
commit 3793466521
2 changed files with 268 additions and 4 deletions

View file

@ -0,0 +1,264 @@
"""Every ``](#anchor)`` in the README must hit a heading Forgejo actually emits (§11).
Ordre 39 shipped a Table of Contents whose anchors were built from a MODEL of the
slugger: "lowercase, drop punctuation, turn each space into one hyphen". The model was
never compared against the renderer. Four of the eleven anchors were dead on the
published surface every one of them a heading with an em-dash surrounded by spaces,
where the model wrote two hyphens and Forgejo emits one.
The rule below is MEASURED, not assumed. On 2026-08-17 the published README was fetched
from the open mirror and its emitted heading ids were read out of the HTML::
curl -sS https://git.fromaitochitta.com/open/portfolio-optimiser-claude \\
| grep -oE '<h[1-6][^>]* id="[^"]+"'
Forgejo emits each id with a ``user-content-`` prefix; ``_MEASURED_HEADING_IDS`` below is
that emission with the prefix stripped, in document order, all 14 of them. The rule in
``forgejo_slug`` reproduces 14/14. The naive space-rule reproduces 10/14 and its four
misses are exactly the four anchors that were dead. That contrast is a test here, so the
COLLAPSING half of the rule is load-bearing rather than decorative: swap in the model
Ordre 39 used and this guard goes red.
What is measured and what is not:
- Measured: the four ASCII classes this document exercises letters, digits, spaces, and
hyphens plus removal of ````, ``,``, ``(``, ``)`` and ``§``, and the collapsing of any
run of [space|hyphen] into ONE hyphen.
- NOT measured: non-ASCII letters in a heading, leading/trailing separators, and duplicate
headings (goldmark suffixes those ``-1``, ``-2``). No heading here exercises them, so
the rule makes no claim about them.
That gap is why ``test_rule_still_reproduces_the_measured_emission`` compares against the
dated fixture rather than merely checking anchors against slugs. A model checked only
against itself is green-but-dead by construction the failure this file exists to prevent
happened precisely because three known-negative controls all agreed with the wrong model.
Editing a heading so its SLUG moves reds that test on purpose: the new ids must then be
re-measured against the published surface, never re-derived from this file.
Value-proved 2026-08-17, green BEFORE / red AFTER, same mutation:
- reinstating one double-hyphen anchor 3 red (the gate, the emission cross-check, and
the naive-model contrast).
- ``## Architecture — the seams`` → ``… and wires`` (slug moves) → 3 red, the ratchet first.
- swapping ``forgejo_slug``'s collapse for the naive replace → 3 red, including the broken-
anchor fixture, which is what proves the collapse is what the fixture detects.
- ``## Architecture — the seams`` → ``## Architecture / the seams`` → GREEN, and correctly
so: ``/`` collapses to the same single hyphen, so the emitted id does not move. Recorded
because a control that passes for the right reason still has to be stated as a limit
this file guards ids, not heading prose.
"""
from __future__ import annotations
import re
from pathlib import Path
import pytest
README = Path(__file__).resolve().parents[1] / "README.md"
# Emitted by Forgejo for the published README, ``user-content-`` prefix stripped, in
# document order. Measured 2026-08-17 against open/portfolio-optimiser-claude (see module
# docstring for the command). NOT derived from forgejo_slug -- this is the ground truth
# forgejo_slug is checked against.
_MEASURED_HEADING_IDS: tuple[str, ...] = (
"portfolio-optimiser-claude",
"table-of-contents",
"install",
"non-goals",
"built-from-the-spec-and-since-2026-08-09-in-the-open-against-the-sibling",
"architecture-the-seams",
"the-operator-cli",
"setting-up-a-knowledge-base",
"load-bearing-tests-11",
"the-ingest-layer-csv-and-sql-in-front-of-the-loop",
"the-live-run-s10-executed-and-validated",
"stack",
"development",
"changelog",
)
_FENCE = re.compile(r"^ {0,3}(`{3,}|~{3,})(.*)$")
_ATX = re.compile(r"^ {0,3}#{1,6}\s+(.*)$")
_ANCHOR = re.compile(r"\]\(#([^)]*)\)")
def strip_fenced_code(text: str) -> str:
"""Blank every line inside a fenced code block, keeping line numbering intact.
A ``## Phantom Heading`` inside a fence is code, not a heading; counting it would let
a sample in the README mint anchors that no rendered page carries.
"""
out: list[str] = []
open_fence: str | None = None
for line in text.split("\n"):
match = _FENCE.match(line)
if open_fence is None:
if match:
open_fence = match.group(1)
out.append("")
continue
out.append(line)
continue
# inside a fence: only the same marker, at least as long, with no info string closes it
if (
match
and match.group(1)[0] == open_fence[0]
and len(match.group(1)) >= len(open_fence)
and not match.group(2).strip()
):
open_fence = None
out.append("")
return "\n".join(out)
def heading_texts(text: str) -> list[str]:
"""ATX heading titles in document order, closing ``#`` sequence removed."""
titles = []
for line in strip_fenced_code(text).split("\n"):
match = _ATX.match(line)
if match:
titles.append(re.sub(r"\s+#+\s*$", "", match.group(1).rstrip()).strip())
return titles
def anchor_targets(text: str) -> list[str]:
"""Every in-document link target ``](#...)``, outside fenced code."""
return _ANCHOR.findall(strip_fenced_code(text))
def forgejo_slug(title: str) -> str:
"""The MEASURED slug rule: drop, then COLLAPSE.
Lowercase; drop every character outside [alphanumeric | space | hyphen] without
replacement; collapse each run of [space | hyphen] into exactly ONE hyphen.
"""
kept = "".join(c for c in title.lower() if c.isalnum() or c in " -")
return re.sub(r"[ -]+", "-", kept)
def naive_slug(title: str) -> str:
"""The rule Ordre 39 assumed: each space becomes one hyphen, runs are NOT collapsed.
Kept only so the difference can be asserted -- never used to validate anything.
"""
kept = "".join(c for c in title.lower() if c.isalnum() or c in " -")
return kept.replace(" ", "-")
def dead_anchors(text: str, slug=forgejo_slug) -> list[str]:
"""Anchors in ``text`` that no heading in ``text`` produces under ``slug``."""
valid = {slug(t) for t in heading_texts(text)}
return [a for a in anchor_targets(text) if a not in valid]
@pytest.fixture(scope="module")
def readme() -> str:
return README.read_text(encoding="utf-8")
def test_the_denominator_is_not_empty(readme: str) -> None:
"""A guard that measured nothing would report zero dead anchors forever."""
assert len(heading_texts(readme)) == len(_MEASURED_HEADING_IDS)
assert len(anchor_targets(readme)) >= 11
def test_rule_still_reproduces_the_measured_emission(readme: str) -> None:
"""forgejo_slug must reproduce Forgejo's OWN output, in order, for every heading.
RED here means a heading changed. Do NOT re-derive the expected ids from this rule --
re-measure them against the published page (module docstring carries the command).
"""
assert [forgejo_slug(t) for t in heading_texts(readme)] == list(_MEASURED_HEADING_IDS)
def test_every_toc_anchor_resolves_to_a_heading(readme: str) -> None:
"""The gate itself: no link in the README may point at an id the renderer never emits."""
assert dead_anchors(readme) == []
def test_anchors_are_checked_against_the_measured_ids_too(readme: str) -> None:
"""Belt to the rule's braces: resolve anchors against the EMISSION, not only the model."""
assert [a for a in anchor_targets(readme) if a not in set(_MEASURED_HEADING_IDS)] == []
def test_the_naive_space_rule_does_not_reproduce_the_emission(readme: str) -> None:
"""Known-negative on the RULE: the collapsing half is what makes the guard true.
Ordre 39's model agrees with Forgejo on 10 of 14 headings. The four it misses are the
four anchors that shipped dead -- every one an em-dash between spaces.
"""
misses = [
naive_slug(t)
for t, measured in zip(heading_texts(readme), _MEASURED_HEADING_IDS)
if naive_slug(t) != measured
]
assert len(misses) == 4
assert all("--" in m for m in misses)
# The corrected TOC depends on the collapsing half: read through the naive model, the
# README's own four fixed anchors stop resolving. The fix is not a coincidence.
assert len(dead_anchors(readme, slug=naive_slug)) == 4
assert set(misses) == {
"built-from-the-spec--and-since-2026-08-09-in-the-open-against-the-sibling",
"architecture--the-seams",
"the-ingest-layer--csv-and-sql-in-front-of-the-loop",
"the-live-run--s10-executed-and-validated",
}
_BROKEN_FIXTURE = """# Title
- [Architecture the seams](#architecture--the-seams)
## Architecture — the seams
body
"""
_FENCE_FIXTURE = """# Title
- [Phantom Heading](#phantom-heading)
## Real Heading
```markdown
## Phantom Heading
```
body
"""
_FENCE_POSITIVE_CONTROL = """# Title
- [Phantom Heading](#phantom-heading)
## Real Heading
## Phantom Heading
body
"""
def test_a_broken_anchor_is_reported_dead() -> None:
"""Known-negative fixture: the shape of the bug that shipped must fail this check."""
assert dead_anchors(_BROKEN_FIXTURE) == ["architecture--the-seams"]
def test_a_heading_inside_a_fence_does_not_mint_an_anchor() -> None:
"""A ``## Phantom Heading`` in a code sample is code -- an anchor to it is dead."""
assert heading_texts(_FENCE_FIXTURE) == ["Title", "Real Heading"]
assert dead_anchors(_FENCE_FIXTURE) == ["phantom-heading"]
def test_fence_control_the_same_heading_outside_a_fence_is_real() -> None:
"""Positive control: without the fence the extractor DOES find it.
Without this, the test above would pass just as well if the extractor found nothing.
"""
assert heading_texts(_FENCE_POSITIVE_CONTROL) == [
"Title",
"Real Heading",
"Phantom Heading",
]
assert dead_anchors(_FENCE_POSITIVE_CONTROL) == []