Catch a doc page whose source moved on without it #69

Merged
paulhitt merged 1 commits from 7-doc-page-drift-guard into main 2026-08-31 17:04:29 +00:00
paulhitt commented 2026-08-31 16:27:13 +00:00 (Migrated from gitlab.com)

Closes #7

Every generated page warns that edits made there are deleted on the next run.
Nothing guarded the other direction — and that is the one that hurts.

direction how it fails
edit the generated page loud — your words vanish on the next run
edit the source, never regenerate silent — the stale page stays served

/self-hosting was live for a day telling self-hosters to run
docker compose up -d without the docker network create web that the fix a day
earlier had added. The published instructions still produced the exact error that
fix removed.

How it works

The banner records a hash of the source it was built from:

<!-- GENERATED by Scripts/build-doc-pages.sh from flamenet-e2e/docs/SPEC.md.
     Edits made HERE are deleted the next time that script runs.
     Change the markdown source and re-run it.
     source-sha256: 41002a1ef1cc4ff5 -->

Scripts/check-doc-pages.py compares that against the source as it stands.

Hashes, not a re-render — the one real design decision

The obvious check is to run pandoc in CI and diff the output. That makes the job
hostage to the pandoc version: a different release emits different HTML, so it
fails where nothing is wrong, and the tempting "fix" is to commit whatever the CI
image produced.

A hash answers the question actually being asked — was this page built from the
current source?
— and needs no pandoc. The job is alpine:3.20 + python3 + a
shallow clone.

A page generated before the hash existed is reported stale, not skipped.
"We cannot tell" must not read as "it is fine" — that is the failure being fixed.

Verified by breaking it

$ printf "\n<!-- probe -->\n" >> ../flamenet-e2e/docs/SPEC.md
  spec.leaf   from flamenet-e2e/docs/SPEC.md  (41002a1ef1cc4ff5 != 779f735fc11d2b42)   exit=1

$ printf "\n<!-- probe -->\n" >> docs/API.md
  api.leaf    from docs/API.md  (81839b97940fe782 != 026e436bbb31de22)                 exit=1

$ check-doc-pages.py --engine /nonexistent
  cannot find the source for spec.leaf …  exit=2   # not a silent pass

Both source locations are covered, and the job body was run in alpine:3.20
exactly as CI will:

python3: Python 3.12.13
9 generated pages match their sources

Page diffs

Banner line only — no content changed (3 lines per file, all banner).

Closes #7 Every generated page warns that edits made **there** are deleted on the next run. Nothing guarded the other direction — and that is the one that hurts. | direction | how it fails | |---|---| | edit the generated page | **loud** — your words vanish on the next run | | edit the source, never regenerate | **silent** — the stale page stays served | `/self-hosting` was live for a day telling self-hosters to run `docker compose up -d` without the `docker network create web` that the fix a day earlier had added. The published instructions still produced the exact error that fix removed. ### How it works The banner records a hash of the source it was built from: ``` <!-- GENERATED by Scripts/build-doc-pages.sh from flamenet-e2e/docs/SPEC.md. Edits made HERE are deleted the next time that script runs. Change the markdown source and re-run it. source-sha256: 41002a1ef1cc4ff5 --> ``` `Scripts/check-doc-pages.py` compares that against the source as it stands. ### Hashes, not a re-render — the one real design decision The obvious check is to run pandoc in CI and diff the output. That makes the job hostage to the **pandoc version**: a different release emits different HTML, so it fails where nothing is wrong, and the tempting "fix" is to commit whatever the CI image produced. A hash answers the question actually being asked — *was this page built from the current source?* — and needs no pandoc. The job is `alpine:3.20` + `python3` + a shallow clone. A page generated before the hash existed is reported **stale**, not skipped. "We cannot tell" must not read as "it is fine" — that is the failure being fixed. ### Verified by breaking it ``` $ printf "\n<!-- probe -->\n" >> ../flamenet-e2e/docs/SPEC.md spec.leaf from flamenet-e2e/docs/SPEC.md (41002a1ef1cc4ff5 != 779f735fc11d2b42) exit=1 $ printf "\n<!-- probe -->\n" >> docs/API.md api.leaf from docs/API.md (81839b97940fe782 != 026e436bbb31de22) exit=1 $ check-doc-pages.py --engine /nonexistent cannot find the source for spec.leaf … exit=2 # not a silent pass ``` Both source locations are covered, and the job body was run in `alpine:3.20` exactly as CI will: ``` python3: Python 3.12.13 9 generated pages match their sources ``` ### Page diffs Banner line only — no content changed (3 lines per file, all banner).
paulhitt commented 2026-08-31 17:04:30 +00:00 (Migrated from gitlab.com)

mentioned in commit ada0de3529

mentioned in commit ada0de3529206aa264ed7b95852abd458702248d
paulhitt (Migrated from gitlab.com) merged commit ada0de3529 into main 2026-08-31 17:04:30 +00:00
paulhitt commented 2026-09-09 18:59:25 +00:00 (Migrated from gitlab.com)

changed the description

changed the description
Sign in to join this conversation.