Commit Graph

6 Commits

Author SHA1 Message Date
Marcos Paulo 3daad86db8 feat(i18n): wire audit-translations into pnpm run verify
Wires the .agents/scripts/audit-translations.mjs script into the
existing pnpm run verify chain as the first gate. A `pt` field
identical to its `en` counterpart is how a bilingual site quietly
becomes monolingual — this script catches that before any other
check runs.

Added an allowlist mechanism: the script now reads a sibling
`.agents/scripts/audit-translations.allowlist.json` file. Entries
in the allowlist are listed in the output under "ALLOWED" and do
not fail the gate. Currently 18 entries: numeric card labels
("01"–"06") in chapters/landing.json and chapters/summary.json, the
"Skills" product noun on both, the "Brief" handoff step label in
chapters/agents.json, and the three model-tier series names in
providers/{claude,gemini,openai}.json.

Adding to the allowlist requires a deliberate edit + commit; future
translators can see the allowlist and understand which identicals
are intentional.

The verify chain order is now:

  1. audit-translations.mjs  — fail-fast on translation regressions
  2. verify.mjs              — content + interaction contracts
  3. audit-ui.mjs            — responsive / no-external-dep audit
  4. check-tokens.mjs        — design-token enforcement

Ownership notes:

  - package.json is owned by the astro-architect agent per
    .agents/rules/git-worktrees.md. The wiring in this commit is the
    change the user explicitly asked for; the architect should review
    the format on merge.

  - scripts/verify.mjs is owned by the verification-engineer agent
    per the same table. The pre-existing assertion that `package.json`
    contains the literal verify-script string no longer matches once
    `audit-translations.mjs &&` is prepended. This commit updates the
    assertion from a strict `.includes()` substring check to a regex
    that allows the optional translation-audit prefix while still
    requiring the three core scripts (verify.mjs, audit-ui.mjs,
    check-tokens.mjs) to run in order. The regex still rejects any
    chain that drops one of them.

Verified by running pnpm run verify from the worktree — all four
checks pass with the translations from the prior five commits.
2026-09-06 21:18:48 -03:00
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
Marcos Paulo c2a046d6f7 chore: install Playwright so the visual checks can actually run
`.agents/scripts/visual-regression.mjs` has always imported Playwright
dynamically and thrown "install its project dependency" when it was
missing, which it always was. The consequence was quiet: every brief with
a "screenshots match at 560 / 800 / 1100 / 1600 px" box -- tasks 15d, 15e
and 18 -- had no way to tick it, and agents reported the box unticked
with "Playwright unavailable" rather than doing the comparison.

The browsers were already cached in ~/.cache/ms-playwright; only the node
package was absent. Verified a headless screenshot works after install.

pnpm-lock.yaml changes here as a side effect of `pnpm add -D`, never by
hand. No package-lock.json, yarn.lock or bun.lock.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-05 22:44:53 +00:00
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
Marcos Paulo 33df09f541 feat: scaffold astro publishing pipeline 2026-09-05 01:39:47 +00:00
Marcos Paulo 9557cae6b6 feat: add AI For Dummies presentation 2026-09-02 00:33:49 +00:00