Files
ai-for-dummies/plans/astro-refactor/task-20-cutover.md
T
Marcos Paulo 48c31dc1b3 build: migrate from npm to pnpm
Ten git worktrees each carried their own 225 MB node_modules (1.1 GB across
five) and paid 11s per `npm ci`. pnpm hardlinks from a shared store: the same
five worktrees cost ~250 MB total, and a fresh install is 4s.

What changed beyond the mechanical rename:

- `overrides` moved to `pnpm-workspace.yaml`. pnpm 11 does not read the `pnpm`
  field in package.json *or* npm's top-level `overrides`, and it fails silently
  — the vite/defu/language-server pins would have quietly stopped applying.
- Build scripts are blocked by default in pnpm; esbuild and sharp are allowed
  explicitly via `allowBuilds` (renamed from `onlyBuiltDependencies` in 11).
- `packageManager` + `engines` pin the toolchain.
- gate.sh rejects a package-lock.json/yarn.lock/bun.lock outright, so an agent
  running `npm install` out of habit fails loudly instead of building a second,
  divergent dependency tree.
- CI bootstraps pnpm with `npm install --global pnpm@11.25.0` rather than
  corepack (unbundled as of Node 25) or pnpm/action-setup (this self-hosted
  act-runner has never run a job; fetching a third-party action is not
  something to discover on the first one).

Two pre-existing CI bugs fixed while in the file:

- the gate installed with `npm install --package-lock=false`, which discarded
  the lockfile the previous session had just fixed.
- the visual-regression step imported `playwright`, which is not a dependency,
  and `visual-regression.mjs` has no compare mode anyway — in CI it overwrote
  its own baselines and passed unconditionally. Removed with a comment; it
  comes back when it can diff.

The `publish` job is now manual (`workflow_dispatch`). During the migration
dist/ holds three HTML files against the live pages branch's ten, so publishing
on every push to main would take the site down to a stub. Restore at task 20.

HANDOVER.md's incident log still says npm where it describes what happened at
the time; that is history, not a missed rename.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 04:29:42 +00:00

2.4 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