aae4d42229
Adds the agent-facing workspace and a 20-task plan for migrating the site to Astro. Nothing here implements the refactor; these are briefs, rules and templates that the task agents read. - .agents/ holds context, rules, checklists, skills, specialist agents, component/page/config templates and gate scripts. It is vendor-neutral so MiniMax, Gemini and Codex can all read it; CLAUDE.md just points at AGENTS.md. - .husky/ plus .lintstagedrc.json wire the three gate tiers. gate.sh locks on the shared git-common-dir so parallel worktrees serialise, and guards the assertion count in scripts/verify.mjs against a coverage drop. - plans/astro-refactor/ carries the phase graph, per-task briefs and the model-routing recommendation. These files must be tracked before fanning out: a worktree only checks out tracked files, so an untracked plan is invisible to every agent working in one. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
65 lines
2.4 KiB
Markdown
65 lines
2.4 KiB
Markdown
---
|
|
name: verify-contract
|
|
description: Evolve scripts/verify.mjs across the Astro migration without losing coverage. Use whenever a verify assertion fails because of a refactor, or when adding checks for new architecture.
|
|
---
|
|
|
|
# The verification contract
|
|
|
|
Read [`../../context/verification.md`](../../context/verification.md) first.
|
|
|
|
`verify.mjs` has 42 assertions pinning real content and interactions. They are
|
|
the only thing preventing silent content loss during this migration, and they
|
|
will all break, because they assert against files that stop existing.
|
|
|
|
## The rule
|
|
|
|
**A failing assertion is a question, not a bug to delete.**
|
|
|
|
```
|
|
assertion fails
|
|
↓
|
|
does the user-visible fact it pins still exist?
|
|
├── yes → re-point the assertion at the new location
|
|
└── no → you deleted content. Put it back, or get sign-off.
|
|
```
|
|
|
|
`grep -c 'throw new Error' scripts/verify.mjs` must not decrease. If it must,
|
|
the `verification-engineer` writes a one-line reason per removal in the task
|
|
report. Nobody else may reduce coverage.
|
|
|
|
## Translating assertions
|
|
|
|
| Kind | Old | New |
|
|
| --- | --- | --- |
|
|
| Content presence | `html.includes('data-phase="plan"')` | same token, read from `dist/full-guide/index.html` |
|
|
| Implementation detail | `js.includes('renderTree')` | assert the rendered output has the tree UI, not that a function is named that |
|
|
| Asset version | `'app.js?v=20260904-vote-widget'` | assert the built HTML references a hashed asset |
|
|
|
|
Implementation-detail assertions are the dangerous ones: they *look* deletable.
|
|
They are pinning a feature. Replace with an output-level assertion of the same
|
|
feature; never drop.
|
|
|
|
## Add the stronger check
|
|
|
|
Token matching cannot catch a dropped paragraph. Add rendered-text snapshots:
|
|
|
|
```bash
|
|
# before migrating
|
|
node .agents/scripts/snapshot-route.mjs http://localhost:4173/models/ > .agents/snapshots/models.txt
|
|
# after
|
|
node .agents/scripts/snapshot-route.mjs dist/models/index.html | diff .agents/snapshots/models.txt -
|
|
```
|
|
|
|
Commit the snapshots. They are the migration's regression net.
|
|
|
|
## Extend audit-ui.mjs
|
|
|
|
It rejects external `<script>`/`<link>` but **misses external URLs inside CSS** —
|
|
which is exactly how the broken Google Fonts `@font-face` in `styles.css:1` got
|
|
into a "dependency-free" site. Add:
|
|
|
|
```js
|
|
if (/@import|src:\s*url\(['"]?https?:|url\(['"]?https?:/i.test(css))
|
|
throw new Error(`${file} has an external CSS dependency`);
|
|
```
|