Files
ai-for-dummies/plans/astro-refactor/task-20-cutover.md
T
Marcos Paulo 580293867d refactor: retire the hand-written site
Deletes the pre-Astro pages, scripts, and stylesheets that the migration
replaced, and moves the ones it did not replace out of the way.

Deleted (32 files): app.js, responsive.css, landing.css, rules/app.js,
rules/styles.css, skills/app.js, the ten route index.html files, and the
root hands-on/ copy, which is byte-identical to public/hands-on/ -- the
one the build actually ships.

Moved to legacy/ (12 files): styles.css, full-guide/audit.css,
chapters.css, skills/styles.css, skills-review/styles.css,
skills-review/change-lens.css, and the skills-review/app.js module graph.
These are not dead. The Astro pages import them and the build fails
without them, which the plan had not accounted for. They go to legacy/
rather than src/ because check-tokens.mjs sweeps src, and these files are
full of raw hex and unnamed breakpoints: moving one into src/ should mean
migrating it to tokens in the same change, not adding a scan exclusion.
The prettier, stylelint, and eslint ignore lists that already named these
files at their old paths now name legacy/ instead.

verify.mjs no longer reads app.js. The 102 Portuguese strings were
extracted from its translations.pt object before deletion into
.agents/snapshots/full-guide-pt.json -- a legacy capture, not a snapshot
of the Astro build, so the assertion still compares against an
independent source. The brace-matching helper's assertion is replaced by
one that rejects an empty snapshot entry, without which trimming the
snapshot would make the presence check pass vacuously. Count stays at 84.

audit-ui.mjs reads the ten pages from dist/ and resolves Astro's
base-absolute hrefs against it.

Before deleting anything, rendered-text-diff was run across all ten
routes plus both Portuguese pages: every one at parity, 0 missing and 0
extra. That comparison is not repeatable once the legacy files are gone.
computed-style-diff on /full-guide/ stays at 32 differences, so the moves
are style-neutral.

Docs updated to match: README, AGENTS.md, GATES.md, the architecture
context, the operations guide's lab instructions, and the three skills
that told you to serve the vanilla site.

Publishing is not part of this commit.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-06 08:30:27 +00:00

6.3 KiB

Task 20 — Cutover and cleanup

Agent: astro-architect, with a human watching · Model: MiniMax-M3 assisting Depends on: all · Worktree: .agents/scripts/worktree.sh start 20 cutover

This task touches production publishing. Do not run it unattended.

Goal

The Astro build is what the world sees, the old files are gone, and the docs describe reality.

Steps

  1. Full verification on the built site: all 10 routes, all 6 query params, both languages, vote widget against the live API, screenshots at four widths.
  2. Delete the superseded files — only after their replacements are proven: app.js, styles.css, responsive.css, chapters.css, landing.css, rules/app.js, rules/styles.css, skills/app.js, skills/styles.css, skills-review/*.js, skills-review/*.css, and the ten old index.html files. git rm, one commit, reviewable. Keep: hands-on/** (now under public/), submitted-skills/**, skill-reviews/**, docs/**, vote-service/**.
  3. Publish via the mechanism chosen in task 01.
  4. Verify on the real host with a cache-buster:
    for r in "" full-guide summary models agents skills rules skills-review \
             hands-on/starter hands-on/rules; do
      curl -sS -o /dev/null -w "%{http_code} $r\n" \
        "https://netcracker.pages.marcospaulo.dev.br/ai-for-dummies/$r/?v=$(git rev-parse --short HEAD)"
    done
    
    All ten must be 200. A stale cached 200 looks identical to success — the ?v= is what distinguishes them.
  5. Update the docs: README.md, docs/operations-guide.md (build + publish path, and it must stop claiming pages is "the exact published source" if that is no longer true), GATES.md, and AGENTS.md (stack is no longer "migration in progress").
  6. Fast-forward pages per the procedure in docs/operations-guide.md.

Rollback

pages still holds the working vanilla site until you overwrite it. If cutover fails, reset pages to its previous commit — the old site returns immediately. Note the SHA before you start:

git rev-parse origin/pages   # write it down

Done when

  • Ten routes 200 on the real host with a fresh cache-buster
  • Vote widget works end-to-end from the published origin (CORS is origin-sensitive — ALLOWED_ORIGIN must still match)
  • Old files deleted; pnpm run gate green
  • Docs match reality
  • Previous pages SHA recorded for rollback

Cutover record

origin/pages before cutover: 37a1e480c6bffb0bff77ad3854ec068688c17d7b ("Merge branch 'main' into pages"). Reset pages to this SHA to roll back.

Step 1 — verification before deletion

rendered-text-diff.mjs compares the rendered DOM of each legacy page against its Astro replacement. Deleting the legacy files makes that comparison impossible, so the full sweep was taken first, against the post-cutover build:

Route Legacy spans Astro spans Missing Extra
/ 36 36 0 0
/full-guide/ 432 432 0 0
/summary/ 34 34 0 0
/models/ 36 36 0 0
/agents/ 39 39 0 0
/skills/ 48 48 0 0
/rules/ 119 119 0 0
/skills-review/ 178 178 0 0
/full-guide/ pt 431 431 0 0
/rules/ pt 119 119 0 0

computed-style-diff.mjs full-guide --widths 880,1050 → 32 differences, unchanged from the task 15e result, so the file moves below are style-neutral.

Step 2 — what could not be deleted

The brief assumed every legacy file had been superseded. Seven had not: the Astro build still imports them, and astro build fails outright without them.

File Imported by
styles.css src/pages/full-guide.astro
full-guide/audit.css src/pages/full-guide.astro
chapters.css src/layouts/ChapterLayout.astro
skills/styles.css src/pages/skills.astro
skills-review/styles.css src/pages/skills-review.astro
skills-review/change-lens.css src/pages/skills-review.astro
skills-review/app.js src/pages/skills-review.astro

app.js pulls in catalog.js, files.js, and vote.js, which pull in submitted-catalog.js and submitted-files.js — twelve files in all.

They were moved to legacy/, not into src/. check-tokens.mjs sweeps src, and these files are full of raw hex and unnamed breakpoints; moving one into src/ should mean migrating it to tokens in the same change, never adding a scan exclusion. legacy/ keeps the checker's scope honest and stops the files sitting at route-shaped paths next to the routes they no longer serve.

Deleted outright (32 files): app.js, responsive.css, landing.css, rules/app.js, rules/styles.css, skills/app.js, all ten index.html files, and the root hands-on/ copy — byte-identical to public/hands-on/, which is what the build ships.

Step 3 — verify.mjs off the legacy source

Two assertions read app.js to parse translations.pt. The 102 strings were extracted verbatim before deletion into .agents/snapshots/full-guide-pt.json — a legacy capture, not a snapshot of the Astro build, so the check still asserts against an independent source.

The brace-matching helper went with the file, taking one assertion. It was replaced by a check that no snapshot entry is empty: without it, trimming the snapshot would make the "every string is present" assertion pass vacuously. Count stays at 84.

audit-ui.mjs now reads the ten pages from dist/, resolving Astro's base-absolute /ai-for-dummies/... hrefs against dist/.

Not done here

Steps 3, 4, and 6 — publish, verify on the real host, fast-forward pages — are untouched. They need a human present.