Files
ai-for-dummies/plans/astro-refactor/HANDOVER.md
Marcos Paulo f241c5581a
verify-and-publish / gate (push) Successful in 6m21s
verify-and-publish / publish (push) Has been skipped
docs: verify the base path on the real host
The real-host smoke test was the migration's #1 production-only failure mode and
had never run. It has now run, without taking the site down: the Astro dist was
published to `pages` additively under two previously-unused paths (`_astro/` and
`_verify/summary/`), so all ten live pages stayed up, then force-pushed away.

Astro's base-prefixed absolute asset URLs resolve on the Pages Server — that was
the actual risk, and it is now proven rather than assumed. Trailing-slash
redirects match `trailingSlash: 'always'`.

Also corrects two things the guide got wrong:

- a `?v=$(git rev-parse --short HEAD)` cache-busting idiom. The Pages Server
  caches for ten minutes keyed on path, so a query string never busted it; the
  guide was telling operators to trust a check that could not work. A file you
  just deleted keeps serving 200 until the cache expires.
- the claim that a push to `main` publishes. It no longer does, and must not
  until cutover.

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

166 lines
8.8 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Handover — Astro refactor, session of 2026-09-05
Phase 0 is done, merged, and green. Tasks 0104 are all in `main`. The project
now runs on **pnpm**, not npm. Nothing has been pushed: `main` is **23 commits
ahead of `origin/main`**.
## Where the work is
| Branch | Head | State |
| ----------------------------------- | ------------- | ----------------------------------- |
| `main` | see `git log` | 0104 merged, gate green under pnpm |
| `refactor/task-01-scaffold` | `71021e6` | merged |
| `refactor/task-02-tokens` | `c9ec9e3` | merged |
| `refactor/task-03-verification-net` | `2e79aac` | merged |
| `refactor/task-04-content-schema` | `b554f87` | merged (gate verified before merge) |
All four merged with `--no-ff` and **zero conflicts**. The four worktrees in
`~/Projects/af-task-0*` still exist and still hold npm-era `node_modules`; they
are stale. `~/Projects/af-task-02/before/` still holds 29 MB of misplaced
untracked screenshots — delete or move them before removing that worktree.
## 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/`~~ — **done**, see
"Resolved: the base path serves correctly on the real host" above.
- No Playwright locally, so screenshot comparison still cannot run anywhere.
`visual-regression.mjs` also has no compare mode, so it is out of CI until it
grows one. See `.agents/rules/gates.md`.
## 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. **Decide the font question** (see below). It blocks task 19 and it is now the
only thing here that needs a human.
2. 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
```
All three are unblocked now that 02 and 04 are in `main`. After 07 lands,
08-11 run four at a time. **Task 07 is the routing calibration point** -
judge it before committing to MiniMax for the other twelve.
3. Clean up the four merged worktrees and branches in `~/Projects/af-task-0*`.
`~/Projects/af-task-02/before/` holds 29 MB of misplaced untracked
screenshots; delete or move them first.
## Resolved: the base path serves correctly on the real host
This was the #1 production-only failure mode and it is now **verified against
the live Pages Server**, not just `pnpm run preview`.
Method, which is reusable and costs no downtime: the Astro `dist/` was published
to the `pages` branch **additively** — `_astro/` plus a single page at
`_verify/summary/`, both paths previously unused, so no existing file was
touched and all ten live pages stayed up throughout. Results:
- `/ai-for-dummies/_verify/summary/` → 200, and it really is the Astro page
(`<title>AI For Dummies — Route map</title>`), not a 200-ing error page.
- `/ai-for-dummies/_astro/chapters.PwjFDHFw.css` → 200 `text/css`. **This is the
actual base-path proof**: Astro emits base-prefixed _absolute_ asset URLs, and
the server resolves them.
- `/ai-for-dummies/_verify/summary` (no trailing slash) → 307 to the slashed
form, which matches `trailingSlash: 'always'`.
The probe was force-pushed away immediately; `pages` is back at `37a1e48`.
Note for whoever publishes next: **the Pages Server caches for ten minutes**,
keyed on path. A deleted file keeps serving 200 until the cache expires, and a
`?v=<sha>` query does not bust it. See `docs/operations-guide.md` step 6.
## Carried over from the phase 0 review
Found while reviewing the four diffs, none of it blocking, none of it fixed:
- **`public/hands-on/` is a byte-identical copy of `hands-on/`** with no sync
mechanism. Two trees will drift. Symlink, or copy as a build step.
- **`--bp-*` tokens cannot work.** CSS custom properties do not resolve inside
`@media` queries. The real enforcement is `check-tokens.mjs`'s
`ALLOWED_BREAKPOINTS` allowlist; the variables are decoration and will mislead
whoever writes the first responsive component.
- **`tokens.css` has no font tokens at all**, and the scale skips `--step-2` and
`--step-3`. Downstream of the font decision.
- **`visual-regression.mjs` has no compare mode.** It only captures. It is out
of CI for that reason — see `.agents/rules/gates.md`.
- `src/content/config.ts` uses the legacy `type: 'data'` API. Astro 5
auto-converts it to a glob loader and it works; prefer explicit
`file()`/`glob()` loaders in `src/content.config.ts` when 05/06 touch it.
## 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.