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

5.8 KiB

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.