Files
ai-for-dummies/plans/astro-refactor/task-19-verify-repoint.md
T
Marcos Paulo 12bc1dc067
verify-and-publish / gate (push) Successful in 33m45s
verify-and-publish / publish (push) Has been skipped
docs: tell 19 what the gate missed and which checks caught it
2026-09-05 23:03:55 +00:00

111 lines
5.8 KiB
Markdown

# Task 19 — Re-point the verification contract
**Agent**: `verification-engineer` · **Model**: Codex **Depends on**: 15, 16 ·
**Parallel with**: 18 **Worktree**:
`.agents/scripts/worktree.sh start 19 verify-repoint`
## Goal
All 42 assertions pin the same user-visible facts against the new architecture.
Coverage does not fall.
You are the only role permitted to remove an assertion, and every removal needs
a written reason.
## The three kinds
| Kind | Example | What to do |
| --------------------- | --------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------- |
| Content presence | `data-phase="plan"` | re-point at `dist/full-guide/index.html`; the token should survive rendering. If it does not, a component dropped content — **stop and report** |
| Implementation detail | `const phases`, `renderTree`, `from './catalog.js'` | obsolete as written, but each pins a **feature**. Replace with an output-level assertion of that feature. Never drop |
| Asset version | `app.js?v=20260904-vote-widget` | Astro hashes assets — assert the built HTML references a hashed asset |
## Steps
1. `pnpm run build`, then re-point `read()` calls at `dist/`.
2. Work through all 42 in order. For each: does the fact it pins still exist?
Yes → re-point. No → content was lost; escalate.
3. Add rendered-text snapshot assertions for all ten routes so this class of
regression is caught structurally, not by string luck.
4. Confirm `check-tokens.mjs` and the extended `audit-ui.mjs` are in
`pnpm run verify`.
## Done when
- [ ] `grep -c 'throw new Error' scripts/verify.mjs` ≥ the `origin/main`
baseline
- [ ] Every removal has a one-line reason in this file
- [ ] Snapshot assertions cover all ten routes
- [ ] `pnpm run gate` green, and it **fails** when you deliberately delete a
paragraph from a component (prove the net works, then revert)
## Do not
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 `<main>` 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 `<br />`
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.