docs: a link gate that reads what ships, and the last GCP project id - #125
Merged
Merged
Conversation
Four things, and the first is the one that matters. THE ARTIFACT GATE. Every link gate here read SOURCE MARKDOWN: the bundled links-check plugin filters candidates on /\.md(?:[?#]|$)/ and so sees about 861 of ~1331 internal links; base-prefix-check greps `](/…)`; lychee-source runs over docs/**.md. None can see the bytes that deploy. Measured on 92925e5: a one-character typo in the config.ts navbar (`/why` -> `/whyy`) leaves `npm run docs:build` exiting 0 while shipping 424 dead references across 212 of the 213 rendered pages. scripts/check-dist-links.mjs walks docs/.vuepress/dist/**.html instead — 219 pages, 107,738 absolute references, 474 distinct targets on this build, with the census printed, because "passed" with no numbers is indistinguishable from "inspected nothing". Its canaries run IN-PROCESS before every scan rather than as a separate step, a separate step being deletable while the gate keeps reporting green, and there are floors on pages, references and distinct targets. That machinery earned its keep immediately: the first version's fixture contained only `<a href>` elements, so dropping `src` from the extractor moved the counts by 219 of 107,738 — under every floor — and the gate printed "Clean" while no asset reference in dist was checked. Reproduced, then closed: the fixture now carries a resolving `<img src>` and a failing `<script src>`, and that mutant fails four separate assertions. The "ok" line now derives from the census too; it was a fixed sentence describing an earlier version of itself. The step's coverage map says which gate owns which class, so nobody deletes a sibling believing it redundant. One cell in it was wrong and is corrected: lychee DOES read raw HTML anchors in markdown, measured, not inferred. THE SECOND GCP PROJECT ID. `fluid-crypto-tracker` was mostly illustrative, but two sites were the same shape as the id removed earlier: project_id = os.getenv("GCP_PROJECT_ID", "fluid-crypto-tracker") feeding straight into bigquery.Client(project=project_id). A reader who copies the script and forgets the export writes to whoever owns that id, silently. The second one is a deployed Cloud Function on an hourly schedule. Both now fail loudly with a usage line; the function returns 500. 35 occurrences gone, the remaining placeholders follow the convention already used elsewhere in the same file. THE RELEASE BANNER was a single 266-word paragraph and led with `0.15.0` while the page's own version line said `0.15.1`. Now: the upgrade break first (a `0.14.1`-clean contract can fail), three scannable bullets, history collapsed with each version linking its own notes. It also credited the MCP output-port gateway to `0.8.7`; RELEASE_NOTES_0.8.6 headlines it and 0.8.7 says outright that it adds no features. Corrected to `0.8.6`. THE MONACO MECHANISM is recorded where someone will meet it. Monaco's CSS is 162,004 of the single 251,769-byte stylesheet — 64.3%, contiguous from `.monaco-aria-container` — on all 213 pages, because bundler-vite 2.0.0-rc.31 hard-sets `cssCodeSplit: false` at dist/index.js:108. Its JAVASCRIPT is split correctly: 13.1 MB in async chunks that no prerendered page references. The comment records that overriding the option is mechanically possible via viteOptions and that the fix is DECLINED rather than blocked, with the reason, plus the commands to re-verify every number. Comment only: +60/-0, and the built HTML is byte-identical across all 219 pages. Verified here, not taken on report: build 0 and gate 1 on the seeded typo (424 refs, 212 pages), both 0 restored; the src mutant caught; lychee reproducing the raw-anchor finding; zero `fluid-crypto-tracker` in tracked files; check_cli_docs green (1093 documented invocations, every version claim agreeing with the 0.15.1 pin); check_providers green.
…ent about it `docs/RELEASE_NOTES_0.7.11.md` linked `./.vuepress/cli-version.json`. `.vuepress/` is not copied into dist, so that resolved to nothing on the live site: 404 on the file while the page carrying it returned 200. The gate reported it warn-only and said why in its own header — a red gate nobody is permitted to fix is a gate that gets disabled — so the leniency was load-bearing on the defect existing. The link now points at the GitHub blob URL that `docs/contributing.md` already used for the same file, in the same sentence. That changes a destination, not a claim: the release note still says exactly what `0.7.11` did, which is the line between fixing a link in a frozen file and rewriting its history. New destination verified 200. With the exception gone, `--relative` defaults to `error` rather than `warn`, and the coverage map's relative row is a YES instead of a footnote. The flag still accepts `warn` for a local run. Verified: relative references fall 9 to 8 and scheme rises 970 to 971, which is the one link moving from one class to the other, and the "Broken RELATIVE references" section is gone. Then the tightening proved load-bearing rather than assumed — a raw `<a href="./no-such-relative-target.html">` appended to docs/why.md leaves `npm run docs:build` exiting 0 while the gate exits 1 and names `why.html -> ./no-such-relative-target.html`; the same run with `--relative=warn` exits 0. Seed removed, build and gate clean, self-test clean.
This branch was successfully deployed
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.
Four changes on disjoint files. The first is the one that matters.
1. A link gate that reads the artifact
Every link gate in this repo read source markdown:
links-checkplugin (build: 'error')/\.md(?:[?#]|$)/base-prefix-check](/…)indocs/**.mdlychee-sourcedocs/**.mdNone of them can see the bytes that deploy. Measured on
92925e5: a one-character typo in theconfig.tsnavbar (/why→/whyy) leavesnpm run docs:buildexiting 0 while shipping 424 dead references across 212 of the 213 rendered pages.scripts/check-dist-links.mjswalksdocs/.vuepress/dist/**.htmlinstead. On this build:It prints that census on every run, because "passed" with no numbers is indistinguishable from "inspected nothing". No dependency —
node:builtins only, 0.9s.The anti-blindness machinery earned its keep immediately
Canaries run in-process before every scan, not as a separate step — a separate step can be deleted while the gate keeps reporting green. There are floors on pages, references and distinct targets.
The first version's canary fixture contained only
<a href>elements and zerosrcattributes. So droppingsrcfrom the extractor moved the artifact counts by 219 of 107,738 — under every floor — and the gate printedCleanwhile no asset reference in dist was checked. That is this repo's signature defect reproduced inside the gate built to prevent it.Reproduced and closed. The fixture now carries a resolving
<img src>and a failing<script src>; the mutant fails four separate assertions:The
ok —summary now derives from the census as well. It was a fixed sentence reading "resolved 4 links … caught 1 missing file" for a fixture that resolved 5 and caught 2 — describing an earlier version of itself.The coverage map, with one cell corrected
The step carries a table of which gate owns which class, so nobody deletes a sibling believing it redundant. One row claimed only the new gate sees raw HTML anchors. That was wrong, and it is measured, not inferred — appending
<a href="/cli/init.html">to a page makes lychee reportFile not foundat3:10. Corrected toYES. An overstated new gate is the same category of misleading note this change set out to remove.2. The second GCP project id
fluid-crypto-trackerwas mostly illustrative — 33 of 35 sites were shell, YAML, SQL or expected output. Two were not:Both feed straight into
bigquery.Client(project=project_id). A reader who copies the script and forgets the export writes to whoever owns that id, with no error. The second is a deployed Cloud Function on an hourly Cloud Scheduler trigger.Both now fail loudly (usage line,
sys.exit(1); the function returns 500). All 35 occurrences gone; remaining placeholders use the convention already present elsewhere in the same file.3. The release banner
One 266-word paragraph that led with
0.15.0while the same page's version line said0.15.1. Now the upgrade break first (a0.14.1-clean contract can fail), three scannable bullets, history collapsed with each version linking its own notes.It also credited the MCP output-port gateway to
0.8.7.RELEASE_NOTES_0.8.6headlines it;0.8.7says outright it adds no commands, flags or schema features. Corrected to0.8.6.4. The Monaco mechanism, recorded in the code
Monaco's CSS is 162,004 of the single 251,769-byte stylesheet (64.3%), contiguous from
.monaco-aria-container, on all 213 pages — because@vuepress/bundler-vite2.0.0-rc.31 hard-setscssCodeSplit: falseatdist/index.js:108. Its JavaScript is split correctly: 13.1 MB in async chunks that no prerendered page references.The comment records that overriding the option is mechanically possible via
viteOptionsand that the fix is declined, not blocked, with the reason — a claim a maintainer could disprove in five minutes would poison the rest of it. Plus the commands to re-verify every number.Comment only: +60/−0, every added line a
//, and the built HTML byte-identical across all 219 pages.Verification
Done here, not taken on report:
npm run docs:buildexit 0srcmutantFile not foundat 3:10fluid-crypto-trackercheck_cli_docs.pycheck_providers.pyname,runonly — nocontinue-on-error, noif:Known, not fixed here
docs/RELEASE_NOTES_0.7.11.mdlinks./.vuepress/cli-version.json, which is a live 404 (.vuepress/is not copied into dist). The gate reports it warn-only and says why: RELEASE_NOTES files are frozen, and a red gate nobody may fix is a gate that gets disabled. Fix that link, then flip the step to--relative=error.deploy-docs.ymluploads to Pages with no link gate between build and upload. Two individually-green PRs can ship a broken artifact, and a direct push to main is ungated. Addingnode scripts/check-dist-links.mjsthere is the follow-up.examples/bitcoin-tracker/load_bitcoin_price_batch.py:70andruntime/ingest_bitcoin_prices.py:50still carryos.getenv("GCP_PROJECT_ID", "<<YOUR_PROJECT_HERE>>"). The placeholder is invalid so it cannot reach a real project, but it is the same shape and their sibling no longer has it.