Files
ai-for-dummies/plans/astro-refactor/HANDOVER.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

6.3 KiB
Raw Blame History

Handover — Astro refactor, session of 2026-09-05

Phase 0 is done and green. Phase 1 has not started. Nothing has been pushed; main is 6 commits ahead of origin/main, and no task branch has been merged into anything.

Where the work is

Branch Head Worktree Gate
main a45aa84 ~/Projects/ai-for-dummies n/a
refactor/task-01-scaffold 71021e6 ~/Projects/af-task-01 passed
refactor/task-02-tokens c9ec9e3 ~/Projects/af-task-02 passed
refactor/task-03-verification-net 2e79aac ~/Projects/af-task-03 passed
refactor/task-04-content-schema b554f87 ~/Projects/af-task-04 not run

02, 03 and 04 all branch from refactor/task-01-scaffold, not from main. Task 01 must merge to main first, then the other three.

What each task actually produced

01 — scaffold (Codex). Astro 5.5 with base: '/ai-for-dummies', strict TS, BaseLayout.astro, summary.astro as the single smoke page, lint/format/husky configs, .gitea/workflows/, rewritten publishing section in docs/operations-guide.md, hands-on/ copied verbatim into public/. Build passes, gate passes, hooks verified live, 42/42 assertions intact.

02 — tokens (Gemini). src/styles/tokens.css and src/styles/base.css only — 43 lines. It did not touch the legacy CSS, deliberately: rewriting styles.css would break verify.mjs's exact-string assertions. So the three drifting palettes are now resolved in the new token layer, while the live site still runs on the old values. That is the correct scope, but it means the consolidation is not proven visually yet.

03 — verification net (Codex). .agents/scripts/visual-regression.mjs, rendered-text snapshots for all 10 routes, and PNG baselines at 4 widths in .agents/snapshots/before/ and before-reduced-motion/ (~8 MB, committed on purpose — they are the regression baseline).

04 — content schema (MiniMax). src/content/config.ts with eight empty collections and a strict localized({en, pt}) helper. No content moved; that is tasks 05 and 06.

Things I fixed that the plan got wrong

  • AGENTS.md listed package-lock.json under Never touch, meaning never hand-edit. Task 01 read it as never create and shipped with --package-lock=false. npm ci — which is how every worktree spun up at the time — cannot work without it. Wording corrected; lockfile committed.
  • The first lockfile was reconstructed from a node_modules installed without one, so its entries had no resolved/integrity and npm ci failed with ETARGET tinyglobby@0.2.17. Regenerated from a clean install.
  • .husky/commit-msg rejected build: and revert:. Both are standard conventional types. Added.
  • launch.sh read the agent name with [a-z-]*, which cannot match content-i18n-migrator. Tasks 04/05/06 silently fell back to astro-architect. Fixed to [a-z0-9-]* and made it fail loudly instead of guessing. Task 04 was relaunched under the right agent.

Things the agents got wrong, and what I did

  • Task 03 went outside its brief. It rewrote scripts/audit-ui.mjs to ban external CSS dependencies — a sound check that the pre-existing malformed @font-face in styles.css violates, so it left the gate red for every downstream task. Reverted in 2e79aac; the snapshot net was kept. The check should come back once the font decision is made.
  • Task 03 rebased instead of branching, flattening task 01's merge into four duplicate commits with new SHAs — the same divergent-history trap that broke the pages branch. Replayed onto the proper base; task 01 is an ancestor again. Worth adding to .agents/rules/git-worktrees.md: never rebase a task branch onto anything.
  • Task 02 left 29 MB of screenshots in ~/Projects/af-task-02/before/ — untracked, and in the wrong place (.agents/snapshots/ is the right one). Its report claims the screenshot box is unticked while the files exist. Delete them or move them; do not commit them where they are.

Still open from task 01's own report

  • Real-host smoke test of /ai-for-dummies/summary/ never ran — the branch is not merged and CI has not published. This is the #1 production-only failure mode in the whole migration. Do it before trusting any page work.
  • No Playwright locally, so screenshot comparison could not run in CI.

The decision that is still yours

styles.css:1 has an @font-face whose src: points at a Google Fonts stylesheet, not a font file. Manrope and DM Mono have therefore never rendered; the site has always been Arial and generic monospace. Self-hosting them during the migration would silently redesign the site. Task 02 defaulted to matching what renders today. Decide explicitly, then task 19 can restore the external-CSS assertion. See .agents/context/design-system.md.

Next steps, in order

  1. Verify task 04: cd ~/Projects/af-task-04 && pnpm install --frozen-lockfile && pnpm run gate
  2. Review the four diffs against .agents/checklists/before-merge.md. Use a different model than the one that wrote each — MODEL-ROUTING.md says never review with the author.
  3. Merge refactor/task-01-scaffold into main, then 02, 03, 04.
  4. Push main — nothing has left this machine yet.
  5. Fan out phase 1 and 2:
    .agents/scripts/launch.sh 05 content-guide   --base main
    .agents/scripts/launch.sh 06 content-review  --base main
    .agents/scripts/launch.sh 07 primitives      --base main
    
    05 and 06 need 04 merged; 07 needs 02 merged. After 07 lands, 0811 run four at a time.

Running an agent

.agents/scripts/launch.sh <nn> <slug> [--base ref] [--cli codex|agy|mm] [--fg]

Routing is automatic: Codex for 01/03/15/16/19, agy (Gemini 3.1 Pro) for 02/18, mm (Claude Code against MiniMax-M3) for the rest. All three launch with permission prompts disabled, because a blocked edit in an unattended run just hangs. Logs land in .agents/logs/ (gitignored).

Task 07 is the routing calibration point. It is small and easy to judge. Check it before committing to MiniMax for the other twelve.