fix(links): point the "verify this" links at the release they ask you to verify (#91) - #96
Merged
Merged
Conversation
… to verify (#91) Closes #91. #85 pinned the docs pipeline to the latest published release tag. Hand-written links kept pointing at `main`, which is 17+ commits ahead of the newest tag. The serious half is `features.ts`. Each feature carries a "Verify in the repository" link — the mechanism by which this site asks to be checked rather than believed — and those landed on `keel/compliance/screen.py`, `keel/execution/guards.py` and `keel/agent.py` at `main`. A reader who takes the invitation was reading code that may not be in the release they run. That is worse than a broken link: a broken link announces itself, while a verification link that verifies the wrong thing does not. Not hypothetical for these exact files. `docs/operator-runbook.md` gained packaged-install text in keel `1d1799e`, on `main`, unreleased — so a v0.11.2 operator clicking "verify" read behaviour their build does not have. ### The scope was wider than the issue said Issue #91 listed the five component call sites and `features.ts`. It missed `compliance.ts`, which carries four links in each of three locales — twelve more, including `docs/fiqh-basis.md#scholarly-review-status`. That fragment is load-bearing: a helper that appended a path to a base URL would silently drop it and land the reader at the top of the document. ### One place the ref lives `src/lib/engine-url.ts` builds every engine URL from the ref in `data/docs-meta.json` — the one `scripts/fetch-engine-docs.mjs` resolved. Copy files carry a repo-relative `path` (plus optional `hash`), and the component builds the href, matching the convention `community.ts`, `compliance.ts`'s `links.items` and #94's `FaqItem.link` already follow. `grep -rn "blob/main" src/ | grep -v "src/content/"` returning nothing is now the lint that keeps it true. ### It fails the build rather than guessing `nav.ts`'s `FALLBACK_META` sets `ref: ""` — #92 made it empty precisely so a hard-coded branch could not become a false claim. `engineSourceUrl` throws when the ref is empty rather than emitting `blob//docs/...` or falling back to `main`, because a silent fallback restores exactly the skew this removes. Proven, not asserted: blanking `ref` in `data/docs-meta.json` makes `astro build` exit **1** with the message naming the path and the fix; restoring it exits **0**. ### FR-8: revs deliberately not bumped No translated prose changed — every `label` and `note` string is byte-identical, and only the href construction moved. #94's reviewer settled the same question for an `id` attribute: markup is not copy. The diff is 35 `href:` lines removed (33 links plus two type declarations) against 33 `path:` and 3 `hash:` lines added. ### Out of scope, deliberately `src/content/changelog/*.md` still contains `blob/main` links. That directory is gitignored and rewritten by `fetch-release.mjs` — those links are quotes from release notes as published, and the site must not rewrite what a release said. `docs/desktop-install.md` is pinned like the rest, but still walks a reader through downloading a `.dmg` v0.11.2 does not carry. That is #87. ### Verification - `npm run check` — 0 errors, 0 warnings - `npm run build` — `docs ref: v0.11.2`, 56 pages - `grep blob/main` in `src/` excluding `src/content/` — 0 - No `blob/main` in any built page outside the changelog - `#scholarly-review-status` resolves at `blob/v0.11.2/` - Verify links pinned in en, ar and fr - Empty ref → build exit 1; real ref → exit 0 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015cBJ2syTN4VoE73F9sBNGW
Independent review returned MERGE and confirmed the substance: all eleven pinned paths exist at v0.11.2, both fragments resolve to real headings, and a dist-vs-dist diff against main is exactly 154 hrefs removed and 154 added, 1:1, with the compliance and features pages byte-identical once the ref is substituted. Two findings were worth acting on. ### The PR claimed an enforcement that did not exist Both the PR body and `engine-url.ts`'s header said `grep blob/main` "is the lint that keeps it that way". It was not wired to CI, `npm run check`, or any script — it was a sentence. On a site with FR-9, claiming a guard that does not run is the wrong kind of wrong. Worse, the named pattern would not have caught two shapes this repo already contained before #91: `tree/main/packages` and `raw.githubusercontent.../keel/main/...`. So the sentence is now a program. `scripts/check-engine-refs.mjs` fails on any engine URL naming `main`, `master` or `HEAD` across `blob/`, `tree/`, `raw/` and raw.githubusercontent.com, run by `npm run check` and as its own CI step so the failure is legible in Checks. Proven by injecting all three shapes into `Footer.astro`: exit 1, all three reported by file and line; removed, exit 0. Two exceptions are allowlisted in the script with their reasons, not silently skipped: - `scripts/install.sh` — does not exist at v0.11.2 (`git cat-file -e` fails). It lives on the default branch only, so pinning it would turn the install page's primary command into a 404. - `src/content/` — fetched release-note prose whose links are quotes; rewriting them would edit what a release said. ### A whitespace ref shipped a malformed URL on a green build `if (!ref || !repo)` tested falsiness. A ref of `" "` passed it and produced `blob/ /keel/compliance/screen.py`. Reachable: `fetch-engine-docs.mjs:46` short-circuits on a hand-set manifest ref (`if (manifest.ref !== LATEST_RELEASE) return manifest.ref;`), returning it verbatim without `release-tag.mjs`'s `TAG_PATTERN` validation. Both values are trimmed before the guard now — a whitespace ref exits 1 like an empty one. ### Two corrections to the record `main` is 25 commits ahead of v0.11.2, not the "17+" the previous message said. `docs/desktop-install.md` is pinned like the rest, but the section containing it does not currently render at all — `InstallPage.astro:216` gates it behind `hasPlatformBundle`, and v0.11.2 ships none, so `grep -c desktop-install dist/en/install/index.html` is 0. The earlier note read as though that link were live to a reader today. It is not, which makes #87 the only thing standing between it and a reader. ### Verification - `npm run check` — 0 errors, 0 warnings (now runs the guard first) - `npm run build` — `docs ref: v0.11.2`, 56 pages - Guard: clean on HEAD; exit 1 on each injected shape - Empty ref exit 1, whitespace ref exit 1, real ref exit 0 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015cBJ2syTN4VoE73F9sBNGW
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.



Closes #91.
#85 pinned the docs pipeline to the latest published release tag. Hand-written links kept pointing at
main, which is 25 commits ahead of the newest tag.Why the
features.tshalf is the serious oneEach feature carries a "Verify in the repository" link — the mechanism by which this site asks to be checked rather than believed. Those landed on
keel/compliance/screen.py,keel/execution/guards.pyandkeel/agent.pyatmain.A reader who takes that invitation was reading code that may not be in the release they run. Worse than a broken link: a broken link announces itself; a verification link that verifies the wrong thing does not.
Not hypothetical for these exact files —
docs/operator-runbook.mdgained packaged-install text in keel1d1799e, onmain, unreleased. A v0.11.2 operator clicking "verify" read behaviour their build does not have.The scope was wider than the issue said
#91 listed five component call sites plus
features.ts. It missedcompliance.ts— four links × three locales, twelve more, including:That fragment is load-bearing. A helper that appended a path to a base URL would silently drop it and land the reader at the top of the document instead of the scholarly-review section. Issue updated with the corrected surface.
One place the ref lives
src/lib/engine-url.tsbuilds every engine URL from the ref indata/docs-meta.json— the onescripts/fetch-engine-docs.mjsalready resolved. Copy files carry a repo-relativepath(plus optionalhash); the component builds the href, matching the conventioncommunity.ts,compliance.ts'slinks.itemsand #94'sFaqItem.linkalready follow.scripts/check-engine-refs.mjsis the lint that keeps it true — run bynpm run checkand as its own CI step. It fails on any engine URL namingmain/master/HEADacrossblob/,tree/,raw/and raw.githubusercontent.com, withscripts/install.shandsrc/content/allowlisted for documented reasons.Correction: an earlier revision of this body claimed a bare
grep blob/mainwas already the lint. It was a sentence, wired to nothing — and it would not have caughttree/main/packagesorraw.githubusercontent.../main/, two shapes this repo already contained. It is now a program, added in response to review.It fails the build rather than guessing
nav.ts'sFALLBACK_METAsetsref: ""— #92 made it empty precisely so a hard-coded branch could not become a false claim.engineSourceUrlthrows on an empty ref rather than emittingblob//docs/...or falling back tomain, because a silent fallback restores exactly the skew this removes.Proven, not asserted:
data/docs-meta.jsonastro buildref: ""ref: "v0.11.2"FR-8: revs deliberately not bumped
No translated prose changed — every
labelandnoteis byte-identical, only href construction moved. #94's reviewer settled the same question for anidattribute: markup is not copy.Diff accounting: 35
href:lines removed (33 links + 2 type declarations) against 33path:+ 3hash:lines added.Out of scope, deliberately
src/content/changelog/*.mdstill containsblob/main. That directory is gitignored and rewritten byfetch-release.mjs— those links are quotes from release notes as published, and the site must not rewrite what a release said.docs/desktop-install.mdis pinned like the rest, but still walks a reader through downloading a.dmgv0.11.2 does not carry. That is #87.Verification
npm run check— 0 errors, 0 warningsnpm run build—docs ref: v0.11.2, 56 pagesgrep blob/maininsrc/excludingsrc/content/— 0blob/mainin any built page outside the changelog#scholarly-review-statusresolves atblob/v0.11.2/Reviewer attention
docs/glossary.md,docs/fiqh-basis.mdand the experiment record all render at/en/docs/{slug}/. Sending a reader to GitHub for a page we publish is arguably the wrong destination independent of the ref. Not changed here; noted on The "Verify in the repository" links point at main, not the release they ask you to verify #91 as a candidate follow-up.🤖 Generated with Claude Code
https://claude.ai/code/session_015cBJ2syTN4VoE73F9sBNGW