From 12bc1dc067be8dc85a92a27d7b79f7ff7ef1c454 Mon Sep 17 00:00:00 2001 From: Marcos Paulo Date: Sat, 5 Sep 2026 23:03:55 +0000 Subject: [PATCH] docs: tell 19 what the gate missed and which checks caught it --- .../astro-refactor/task-19-verify-repoint.md | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/plans/astro-refactor/task-19-verify-repoint.md b/plans/astro-refactor/task-19-verify-repoint.md index b19cc9c..b8d36b3 100644 --- a/plans/astro-refactor/task-19-verify-repoint.md +++ b/plans/astro-refactor/task-19-verify-repoint.md @@ -43,3 +43,68 @@ a written reason. Do not weaken an assertion to make it pass. If it cannot pass, something is broken — that is the assertion doing its job. + +## Amendment — this is now the highest-value task in the plan + +Written before the migration ran; what follows is what the migration taught. + +Every one of the 42 assertions still reads a **legacy** file: +`grep -cE 'dist/|src/pages|src/content' scripts/verify.mjs` returns 0. Nothing +in the gate looks at what the Astro pages render. Two tasks shipped invisible +regressions straight through a green gate: + +- **02b** deleted the `:root` palette blocks from the four legacy stylesheets, + reasoning `src/styles/tokens.css` is the single source of truth. It is — for + Astro pages. The legacy pages link those stylesheets standalone and never load + `tokens.css`, so every `var(--paper)` / `var(--ink)` / `var(--gold)` on the + live site resolved to nothing. Eight pages, colourless. Gate green. +- **15d attempt 1** built `/full-guide/` by importing + `full-guide/index.html?raw` and `set:html`-ing the `
` out of it. Zero + `data-language-content` attributes, zero `.pt` reads: Portuguese gone from the + largest page on a bilingual site. Gate green. Tagged `rejected/15d-attempt-1`. + +The gate is doing its job — it is a legacy-content contract. Your job is to make +it an output contract too. Until you land, "gate green" means nothing about the +new site. + +### Three checks to build in, each of which caught a real regression + +1. **Bilingual coverage of the built HTML.** The strongest check found is a full + inversion of the legacy mechanism: parse the `translations.pt` object out of + `app.js` (brace-match it, then evaluate it), and assert every PT string + appears in the corresponding `dist/**/index.html`. Flatten tags and collapse + whitespace on **both** sides before comparing — a needle stripped of `
` + will not match a haystack that still has it, and that false negative cost an + afternoon. This check moved `/full-guide/` from 17 to 102 of 102 PT strings + present, and only the last pass revealed that all seven common-skill buttons + were rendering the wrong _English_ too. `translations.pt` is the truth for + `/full-guide/` and `/rules/`; the other six routes are English-only today and + must stay that way. + +2. **Every `var()` resolves.** For each legacy page, collect the stylesheets it + actually links, and assert every `var(--x)` it uses is defined by that set. + `--score` is the only legitimate miss — `app.js:289` sets it inline. This is + the check that would have caught 02b in seconds. + +3. **Built-CSS diff against `main`.** Build, then enumerate every colour and + size declaration in `dist/_astro/*.css` that exists on `main` and not on the + branch. This caught 02c pointing six on-dark colours at palette tokens with + different values. Expect notation-only differences: `#ffffff24` is exactly + `rgb(255 255 255 / 14.1176%)`, and `32px`/`48px` now resolve through + `--step-32`/`--step-48`. + +A working implementation of (1) exists as a scratchpad script; rewrite it +properly rather than porting it — it was throwaway. + +### On the assertion count + +Baseline is 42 and the gate enforces it. Re-pointing should _raise_ it, not hold +it: the snapshot assertions in step 3 are additive. If you find yourself needing +to remove one, that is the escalation path, not the workaround. + +### Screenshots + +`playwright` is now a devDependency (`c2a046d`) and +`.agents/scripts/visual-regression.mjs` runs. It used to throw for everyone, +which is why no task in this plan ever produced the captures its brief asked +for.