# 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 spins up — 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 && npm ci --prefer-offline && npm 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: ```bash .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, 08–11 run four at a time. ## Running an agent `.agents/scripts/launch.sh [--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.