From aa2653340adb19ab953b873c41fbf28fa81d10ea Mon Sep 17 00:00:00 2001 From: Marcos Paulo Date: Sat, 5 Sep 2026 17:35:58 +0000 Subject: [PATCH] docs: split task 15 into 15a-15e after two failed attempts --- plans/astro-refactor/MODEL-ROUTING.md | 65 +++++++------- plans/astro-refactor/README.md | 51 ++++++----- .../astro-refactor/task-15-page-full-guide.md | 78 ++++------------- .../astro-refactor/task-15a-guide-selector.md | 86 +++++++++++++++++++ plans/astro-refactor/task-15b-copy-prompt.md | 55 ++++++++++++ .../task-15c-language-toggle.md | 62 +++++++++++++ .../task-15d-page-full-guide.md | 58 +++++++++++++ .../astro-refactor/task-15e-responsive-css.md | 42 +++++++++ 8 files changed, 384 insertions(+), 113 deletions(-) create mode 100644 plans/astro-refactor/task-15a-guide-selector.md create mode 100644 plans/astro-refactor/task-15b-copy-prompt.md create mode 100644 plans/astro-refactor/task-15c-language-toggle.md create mode 100644 plans/astro-refactor/task-15d-page-full-guide.md create mode 100644 plans/astro-refactor/task-15e-responsive-css.md diff --git a/plans/astro-refactor/MODEL-ROUTING.md b/plans/astro-refactor/MODEL-ROUTING.md index 28f3f37..d0483ff 100644 --- a/plans/astro-refactor/MODEL-ROUTING.md +++ b/plans/astro-refactor/MODEL-ROUTING.md @@ -5,9 +5,9 @@ interchangeable here, and the split is not about which is "smartest" — it is about which failure mode each task punishes. **Honest caveat up front:** I have not benchmarked these three on this -repository. The routing below is reasoned from task shape and each model's -known strengths. Validate it cheaply on **task 07** (small, self-contained, -easy to judge) before fanning out across ten worktrees. +repository. The routing below is reasoned from task shape and each model's known +strengths. Validate it cheaply on **task 07** (small, self-contained, easy to +judge) before fanning out across ten worktrees. ## Short answer @@ -18,22 +18,27 @@ points where M3 is the wrong tool. ## Routing table -| Task | Model | Why this one | -| --- | --- | --- | -| 01 scaffold + gates | **Codex** | Config-heavy, many interacting tools (Astro + husky + lint-staged + CI), and success is binary — it builds and hooks fire, or not. Codex's long autonomous run-until-green loop suits it, and getting the foundation wrong is expensive later. | -| 02 design tokens | **Gemini** | Needs the whole CSS corpus in one context (8 stylesheets, ~90 KB) plus **visual judgement on screenshots**. Gemini's long context and multimodal comparison are the differentiator; the others would work file-by-file and miss cross-file drift. | -| 03 verification net | **Codex** | Writing test tooling with a tight feedback loop. Precision about what an assertion pins matters more than speed. | -| 04 content schema | **MiniMax-M3** | Small, well-specified, one file. | -| 05–06 content migration | **MiniMax-M3** | High-volume mechanical string moves with a `diff` as the oracle. Cheap, parallel, verifiable. Exactly M3's sweet spot. | -| 07 primitives | **MiniMax-M3** | Small components from templates. Use this task to calibrate the whole routing decision. | -| 08–11 component blocks | **MiniMax-M3 ×4 parallel** | Four bounded tasks, one template each, checklist-gated. Cost per task matters because there are many. | -| 12–14, 17 pages | **MiniMax-M3** | Bounded, snapshot-diff verified. | -| 15 full guide | **Codex** | The hard one: 50 KB `app.js`, 12 render functions, tab state, bilingual swap. Long sustained reasoning over interacting pieces; the task most likely to need many iterations against a failing check. | -| 16 review desk | **Codex** | Same shape and worse — search, filtering, file fetching, six query params, markdown rendering, client-side diff. Highest defect risk in the plan. | -| 18 motion | **Gemini** | Judging whether motion looks right is perceptual. Feed it before/after captures. | -| 19 contract re-point | **Codex** | 42 assertions to translate without losing coverage. Meticulous, mechanical, verifiable. | -| 20 cutover | **you, with M3 assisting** | Touches production publishing. A human should be watching. | -| review of every task | **Gemini** | Fresh eyes, whole-diff-in-context, and it did not write the code. Never review with the model that wrote it. | +| Task | Model | Why this one | +| ------------------------- | -------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| 01 scaffold + gates | **Codex** | Config-heavy, many interacting tools (Astro + husky + lint-staged + CI), and success is binary — it builds and hooks fire, or not. Codex's long autonomous run-until-green loop suits it, and getting the foundation wrong is expensive later. | +| 02 design tokens | **Gemini** | Needs the whole CSS corpus in one context (8 stylesheets, ~90 KB) plus **visual judgement on screenshots**. Gemini's long context and multimodal comparison are the differentiator; the others would work file-by-file and miss cross-file drift. | +| 03 verification net | **Codex** | Writing test tooling with a tight feedback loop. Precision about what an assertion pins matters more than speed. | +| 04 content schema | **MiniMax-M3** | Small, well-specified, one file. | +| 05–06 content migration | **MiniMax-M3** | High-volume mechanical string moves with a `diff` as the oracle. Cheap, parallel, verifiable. Exactly M3's sweet spot. | +| 07 primitives | **MiniMax-M3** | Small components from templates. Use this task to calibrate the whole routing decision. | +| 08–11 component blocks | **MiniMax-M3 ×4 parallel** | Four bounded tasks, one template each, checklist-gated. Cost per task matters because there are many. | +| 12–14, 17 pages | **MiniMax-M3** | Bounded, snapshot-diff verified. | +| 15 full guide | **split** | Ran twice on Codex, zero usable commits both times. This table's own swap rule applied: too big, so it became 15a–15e. | +| 15a guide selector | **Codex** | Collapsing nine near-identical render functions into one island is the reasoning-heavy part that remains. | +| 15b copy prompt | MiniMax-M3 | Small, mechanical, and has an exact oracle: the clipboard payload must be byte-identical. | +| 15c language toggle | **Codex** | Needs a design decision written down, not a port — the selector-map approach cannot survive. | +| 15d assemble full guide | **Codex** | Assembly, but wide: 22 KB of bilingual markup against three islands and task 10's blocks. | +| 15e retire responsive.css | `agy` | Screenshot-diff driven — needs vision. | +| 16 review desk | **Codex** | Same shape and worse — search, filtering, file fetching, six query params, markdown rendering, client-side diff. Highest defect risk in the plan. | +| 18 motion | **Gemini** | Judging whether motion looks right is perceptual. Feed it before/after captures. | +| 19 contract re-point | **Codex** | 42 assertions to translate without losing coverage. Meticulous, mechanical, verifiable. | +| 20 cutover | **you, with M3 assisting** | Touches production publishing. A human should be watching. | +| review of every task | **Gemini** | Fresh eyes, whole-diff-in-context, and it did not write the code. Never review with the model that wrote it. | ## The reasoning in one line each @@ -41,11 +46,11 @@ points where M3 is the wrong tool. Use it for volume: 13 of the 20 tasks. Its weakness is long multi-file reasoning where the spec is vague; every task above that it owns has a template and a mechanical oracle. -- **Codex** — best at "keep iterating until the check passes" over a - complicated existing codebase. Use it where the loop is long and the answer is - not obvious: scaffold, the two hard pages, verification. +- **Codex** — best at "keep iterating until the check passes" over a complicated + existing codebase. Use it where the loop is long and the answer is not + obvious: scaffold, the two hard pages, verification. - **Gemini** — biggest context and genuinely useful multimodal comparison. Use - it where the input is *everything at once* or where the judgement is + it where the input is _everything at once_ or where the judgement is **visual**: token consolidation, motion, screenshot diffing, and code review. ## Cross-checking rule @@ -56,13 +61,13 @@ reviews; Codex writes → Gemini reviews; Gemini writes → Codex reviews. The ## Swap the routing if you see this -| Symptom | Move the task to | -| --- | --- | -| M3 spends more than ~3 iterations failing the same gate | Codex | -| M3 edits files outside its task scope | Codex, and tighten the brief | -| Codex "fixes" a red suite by deleting assertions | anything — but re-read `context/verification.md` to it first; `gate.sh` blocks the merge either way | -| Gemini gives confident visual sign-off with no screenshots attached | require the artifacts; do not accept prose | -| A task needs more than two models' worth of hand-holding | the task is too big — split it | +| Symptom | Move the task to | +| ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- | +| M3 spends more than ~3 iterations failing the same gate | Codex | +| M3 edits files outside its task scope | Codex, and tighten the brief | +| Codex "fixes" a red suite by deleting assertions | anything — but re-read `context/verification.md` to it first; `gate.sh` blocks the merge either way | +| Gemini gives confident visual sign-off with no screenshots attached | require the artifacts; do not accept prose | +| A task needs more than two models' worth of hand-holding | the task is too big — split it | ## Cost shape diff --git a/plans/astro-refactor/README.md b/plans/astro-refactor/README.md index 319ad05..4ae45c1 100644 --- a/plans/astro-refactor/README.md +++ b/plans/astro-refactor/README.md @@ -37,32 +37,37 @@ on four branches; nothing is merged or pushed. Phase 0 foundation 01 → (02 ∥ 03 ∥ 04) Phase 1 content 05 ∥ 06 after 04 Phase 2 components 07 → (08 ∥ 09 ∥ 10 ∥ 11) after 02 -Phase 3 pages 12 ∥ 13 ∥ 14 ∥ 17, then 15 ∥ 16 +Phase 3 pages 12 ∥ 13 ∥ 14 ∥ 17, then 15a ∥ 15b ∥ 15c ∥ 16, then 15d, 15e Phase 4 polish 18 ∥ 19, then 20 ``` -| # | Task | Agent | Depends on | Parallel with | -| --- | ------------------------------------------------ | --------------------- | ---------- | ------------- | -| 01 | [scaffold + gates](task-01-scaffold.md) | astro-architect | — | — | -| 02 | [design tokens](task-02-tokens.md) | design-system-keeper | 01 | 03, 04 | -| 03 | [verification net](task-03-verification-net.md) | verification-engineer | 01 | 02, 04 | -| 04 | [content schema](task-04-content-schema.md) | content-i18n-migrator | 01 | 02, 03 | -| 05 | [guide content](task-05-content-guide.md) | content-i18n-migrator | 04 | 06 | -| 06 | [review-desk content](task-06-content-review.md) | content-i18n-migrator | 04 | 05 | -| 07 | [primitives](task-07-primitives.md) | component-builder | 02 | — | -| 08 | [route cards](task-08-route-cards.md) | component-builder | 07 | 09, 10, 11 | -| 09 | [chapter blocks](task-09-chapter-blocks.md) | component-builder | 07 | 08, 10, 11 | -| 10 | [guide blocks](task-10-guide-blocks.md) | component-builder | 07 | 08, 09, 11 | -| 11 | [review-desk blocks](task-11-review-blocks.md) | component-builder | 07 | 08, 09, 10 | -| 12 | [landing page](task-12-page-landing.md) | page-migrator | 03, 08 | 13, 14, 17 | -| 13 | [chapter pages ×4](task-13-page-chapters.md) | page-migrator | 03, 09 | 12, 14, 17 | -| 14 | [rules page](task-14-page-rules.md) | page-migrator | 03, 09 | 12, 13, 17 | -| 15 | [full guide](task-15-page-full-guide.md) | page-migrator | 05, 10, 13 | 16 | -| 16 | [review desk](task-16-page-review-desk.md) | page-migrator | 06, 11, 13 | 15 | -| 17 | [hands-on passthrough](task-17-hands-on.md) | astro-architect | 01 | 12, 13, 14 | -| 18 | [motion pass](task-18-motion.md) | motion-designer | 15, 16 | 19 | -| 19 | [contract re-point](task-19-verify-repoint.md) | verification-engineer | 15, 16 | 18 | -| 20 | [cutover + cleanup](task-20-cutover.md) | astro-architect | all | — | +| # | Task | Agent | Depends on | Parallel with | +| --- | ----------------------------------------------------------------- | --------------------- | ------------- | ------------- | +| 01 | [scaffold + gates](task-01-scaffold.md) | astro-architect | — | — | +| 02 | [design tokens](task-02-tokens.md) | design-system-keeper | 01 | 03, 04 | +| 03 | [verification net](task-03-verification-net.md) | verification-engineer | 01 | 02, 04 | +| 04 | [content schema](task-04-content-schema.md) | content-i18n-migrator | 01 | 02, 03 | +| 05 | [guide content](task-05-content-guide.md) | content-i18n-migrator | 04 | 06 | +| 06 | [review-desk content](task-06-content-review.md) | content-i18n-migrator | 04 | 05 | +| 07 | [primitives](task-07-primitives.md) | component-builder | 02 | — | +| 08 | [route cards](task-08-route-cards.md) | component-builder | 07 | 09, 10, 11 | +| 09 | [chapter blocks](task-09-chapter-blocks.md) | component-builder | 07 | 08, 10, 11 | +| 10 | [guide blocks](task-10-guide-blocks.md) | component-builder | 07 | 08, 09, 11 | +| 11 | [review-desk blocks](task-11-review-blocks.md) | component-builder | 07 | 08, 09, 10 | +| 12 | [landing page](task-12-page-landing.md) | page-migrator | 03, 08 | 13, 14, 17 | +| 13 | [chapter pages ×4](task-13-page-chapters.md) | page-migrator | 03, 09 | 12, 14, 17 | +| 14 | [rules page](task-14-page-rules.md) | page-migrator | 03, 09 | 12, 13, 17 | +| 15 | [full guide](task-15-page-full-guide.md) — **split into 15a–15e** | — | — | — | +| 15a | [guide selector](task-15a-guide-selector.md) | component-builder | 05, 10 | 15b, 15c | +| 15b | [copy prompt](task-15b-copy-prompt.md) | component-builder | 05 | 15a, 15c | +| 15c | [language toggle](task-15c-language-toggle.md) | content-i18n-migrator | 05 | 15a, 15b | +| 15d | [assemble full guide](task-15d-page-full-guide.md) | page-migrator | 10, 13, 15a–c | 16 | +| 15e | [retire responsive.css](task-15e-responsive-css.md) | design-system-keeper | 15d, 16 | — | +| 16 | [review desk](task-16-page-review-desk.md) | page-migrator | 06, 11, 13 | 15d | +| 17 | [hands-on passthrough](task-17-hands-on.md) | astro-architect | 01 | 12, 13, 14 | +| 18 | [motion pass](task-18-motion.md) | motion-designer | 15d, 16 | 19 | +| 19 | [contract re-point](task-19-verify-repoint.md) | verification-engineer | 15d, 16 | 18 | +| 20 | [cutover + cleanup](task-20-cutover.md) | astro-architect | all | — | Widest parallelism: **four agents** (tasks 08–11, then 12/13/14/17). More than that and they start contending on review capacity, not on files. diff --git a/plans/astro-refactor/task-15-page-full-guide.md b/plans/astro-refactor/task-15-page-full-guide.md index 0208bc1..c39ed95 100644 --- a/plans/astro-refactor/task-15-page-full-guide.md +++ b/plans/astro-refactor/task-15-page-full-guide.md @@ -1,64 +1,22 @@ -# Task 15 — Full guide +# Task 15 — Full guide — **SUPERSEDED, split into 15a–15e** -**Agent**: `page-migrator` · **Model**: **Codex** — hardest task in the plan -**Depends on**: 05, 10, 13 · **Parallel with**: 16 **Worktree**: -`.agents/scripts/worktree.sh start 15 page-full-guide` +Do not work this brief. It is kept because other documents link to it. -## Goal +Task 15 was attempted twice on Codex and produced no usable commit either time. +The second report's own words: _"this is an incomplete scaffold, not the real +migration requested."_ `MODEL-ROUTING.md` says a task needing more than two +models' worth of hand-holding is too big — split it. So it is split, along the +seams that made it hard: the nine-fold selector duplication, the clipboard +fallback, and the selector-map language toggle that cannot survive the port. -`/full-guide/` → Astro. 22 KB of HTML, a 50 KB script, 30 KB of CSS, twelve -render functions, bilingual throughout. +| Brief | What | Depends on | +| ---------------------------------- | ------------------------------------------- | --------------------- | +| [15a](task-15a-guide-selector.md) | one generic selector island for nine groups | 05, 10 | +| [15b](task-15b-copy-prompt.md) | copy-prompt buttons, reading progress | 05 | +| [15c](task-15c-language-toggle.md) | language toggle — needs a decision first | 05 | +| [15d](task-15d-page-full-guide.md) | assemble `/full-guide/` | 10, 13, 15a, 15b, 15c | +| [15e](task-15e-responsive-css.md) | prove `responsive.css` dead, delete it | 15d, 16 | -## What `app.js` actually is - -Not application code — a **bilingual content database** (task 05 already moved -it) plus ~12 `render*` functions that swap `innerHTML` on tab clicks. Once -content is a collection, the remaining JS is small: tab state and a language -toggle. - -## Islands - -Only these hydrate. Everything else is server-rendered. - -| Island | Directive | Why | -| -------------------------------------------------------- | ---------------- | -------------------------------------------------- | -| Phase tabs | `client:visible` | click-driven panel swap | -| Tree / worker / route / model / effort / skill selectors | `client:visible` | same pattern; consider one generic selector island | -| Language toggle | `client:idle` | page-wide, not urgent | -| Copy-prompt buttons | `client:visible` | clipboard | - -If you end up with 12 separate islands you have missed the pattern — they are -one selector component with different data. - -## Asserted by verify.mjs — all must survive - -`const phases`, `const handsOnPrompts`, `const modelGuide`, -`const skillSources`, `const skillInstallPrompts`, `render('plan')`, -`renderTree`, `renderWorker`, `renderRoute`, `renderModelProvider`, -`renderEffort`, `renderSkillFile`, `renderSkillWorkflow`, `renderCommonSkill`, -`renderHandsOn`, `copyPrompt`. - -These are **implementation-detail assertions** — they look deletable and are -not. Each pins a feature. Coordinate with task 19 to replace each with an -output-level assertion of the same behaviour. **Never delete one yourself.** - -Also: `data-copy-target="prompt-install-skills|prompt-basic|prompt-skills"`, -`hands-on/starter/`, `additional-reading.md`, `role="tablist"`, ``. - -## Watch for - -- `copyPrompt` uses `navigator.clipboard` with a `document.execCommand` - fallback. Keep both — the fallback exists for non-secure contexts. -- The hands-on prompt strings are copy-pasted by attendees into an agent. Exact - whitespace and line breaks matter. -- `responsive.css` (30 KB) mostly serves this page. Port what is needed, prove - the rest dead, delete it. Screenshots are the proof. - -## Done when - -- [ ] Snapshot diff empty -- [ ] Every interaction works: all tabs, both languages, all copy buttons -- [ ] Keyboard: arrow keys move between tabs; focus visible throughout -- [ ] JS payload **smaller** than today's 50 KB (content is now static) -- [ ] Screenshots match at four widths; checklist complete; `pnpm run gate` - green +15a, 15b and 15c run in parallel. 15d is assembly and must not invent islands. +Downstream tasks that said "depends on 15" now depend on **15d** (18, 19) or +**15e** (20). diff --git a/plans/astro-refactor/task-15a-guide-selector.md b/plans/astro-refactor/task-15a-guide-selector.md new file mode 100644 index 0000000..44ae48f --- /dev/null +++ b/plans/astro-refactor/task-15a-guide-selector.md @@ -0,0 +1,86 @@ +# Task 15a — The one guide selector island + +**Agent**: `component-builder` · **Model**: **Codex** **Depends on**: 05, 10 · +**Parallel with**: 15b · **Blocks**: 15d **Worktree**: +`.agents/scripts/worktree.sh start 15a guide-selector` + +## Why this task exists + +Task 15 was attempted twice on Codex and produced no usable commit either time. +Its own second report said "this is an incomplete scaffold, not the real +migration requested". `MODEL-ROUTING.md` says a task that needs more than two +models' worth of hand-holding is too big — so it is split. This is the first +piece: **the interactive machinery, with no page migration in it.** + +## Scope + +One new island under `src/components/islands/`. You import nothing into a page +and you migrate no page — tasks 07 through 11 shipped components ahead of their +pages the same way, and the gate is happy with an unimported component. + +## What you are replacing + +`app.js` has nine functions that are the same function nine times: + +| Function | Trigger attribute | Detail panel target | +| --------------------- | --------------------- | ---------------------- | +| `render` | `data-phase` | `#phase-panel` | +| `renderWorker` | `data-worker` | `#worker-detail` | +| `renderTree` | `data-tree` | `#tree-detail` | +| `renderRoute` | `data-route` | `#route-detail` | +| `renderModelProvider` | `data-model-provider` | `#provider-detail` | +| `renderEffort` | `data-effort` | `#effort-detail` | +| `renderSkillFile` | `data-skill-file` | `#skill-detail` | +| `renderSkillWorkflow` | `data-skill-step` | `#builder-detail` | +| `renderCommonSkill` | `data-common-skill` | `#common-skill-detail` | + +Each: click a button in a group, mark it active, swap the panel's `innerHTML` +from a content object. **Build one island, not nine.** If your diff has nine +components you have missed the point of the task. + +The panels' inner markup differs per group (`#route-detail` draws a `--score` +meter, `#tree-detail` draws owner/checkout/note/command). Take the shape from +the slot or from a per-group layout, not from nine islands. + +## The one coupling that is not uniform + +`data-model-provider` clicks also re-run `renderEffort` with the currently +active effort. Preserve that. Everything else is independent. + +## Asserted by verify.mjs — all nine names must survive + +`render('plan')`, `renderTree`, `renderWorker`, `renderRoute`, +`renderModelProvider`, `renderEffort`, `renderSkillFile`, `renderSkillWorkflow`, +`renderCommonSkill`. Also `role="tablist"`. + +These are implementation-detail assertions. They look deletable and are not — +each pins a feature. **Never delete one.** If a name genuinely cannot survive +the new shape, stop and report it; task 19 re-points assertions, you do not. + +## Also deliver + +- Keyboard: Arrow keys, Home and End move between buttons in a group; focus + visible throughout. `role="tablist"` groups follow the ARIA tabs pattern. +- Server-render the initially active panel. The panel must not be empty before + hydration. +- `client:visible`. + +## Do not + +- Migrate `/full-guide/` or create `src/pages/full-guide.astro`. That is 15d. +- Touch the language toggle or the copy buttons. Those are 15c and 15b. +- Touch `src/content/config.ts`, `verify.mjs`, `tokens.css`, `responsive.css`. +- Reformat `app.js`. It is in `.prettierignore`; keep it that way. +- Substitute a near-miss design token for a legacy value. Mark it: + `/* token-gap: ; owner design-system-keeper */`. See + `.agents/rules/gates.md`. + +## Done when + +- [ ] One island, driven by the collections task 05 filled +- [ ] All nine behaviours reachable through it, including the provider/effort + coupling +- [ ] Keyboard and focus complete +- [ ] `pnpm run gate` green — the **full** gate, not just `verify` + `audit-ui` +- [ ] 42 assertions intact +- [ ] Report names the island's props so 15d can wire it without guessing diff --git a/plans/astro-refactor/task-15b-copy-prompt.md b/plans/astro-refactor/task-15b-copy-prompt.md new file mode 100644 index 0000000..0110697 --- /dev/null +++ b/plans/astro-refactor/task-15b-copy-prompt.md @@ -0,0 +1,55 @@ +# Task 15b — Copy-prompt buttons and reading progress + +**Agent**: `component-builder` · **Model**: MiniMax-M3 **Depends on**: 05 · +**Parallel with**: 15a, 15c · **Blocks**: 15d **Worktree**: +`.agents/scripts/worktree.sh start 15b copy-prompt` + +## Scope + +Two small pieces of `app.js`, as islands. No page migration. + +### 1. `copyPrompt` + +Reads `#${button.dataset.copyTarget}`'s `textContent` and copies it. + +- Keeps `navigator.clipboard.writeText` **and** the `document.execCommand` + textarea fallback. The fallback exists because the site is served over plain + HTTP in workshop settings, where `navigator.clipboard` is undefined. Deleting + it silently breaks the lab for attendees. Keep both paths. +- Writes a bilingual result string into `#copy-status`. +- On success, swaps the button's `` to COPIED / COPIADO and back after + 1800 ms. + +Targets asserted by `verify.mjs`: +`data-copy-target="prompt-install-skills|prompt-basic|prompt-skills"`. + +The prompt bodies are copy-pasted by attendees straight into an agent. **Exact +whitespace and line breaks matter** — verify what lands on the clipboard is +byte-identical to today's, not merely visually similar. + +### 2. Reading progress + +The `scroll` listener that sets `.reading-progress span`'s width. It is +`{ passive: true }` today; keep it passive. + +## Language + +Both pieces read `currentLanguage`. Task 15c owns how language is held. Do not +invent a second mechanism — take the language as a prop or read the document's +`lang`, and say in your report which you chose so 15c and 15d can align. + +## Do not + +- Create `src/pages/full-guide.astro`. That is 15d. +- Touch `verify.mjs`, `tokens.css`, `src/content/config.ts`. +- Reformat `app.js`. +- Substitute a near-miss token; mark gaps with + `/* token-gap: ; owner design-system-keeper */`. + +## Done when + +- [ ] Both clipboard paths present and the fallback actually exercised +- [ ] `#copy-status` bilingual, and announced (it is a live region) +- [ ] Clipboard payload byte-identical to today's for all three targets +- [ ] `pnpm run gate` green — the full gate +- [ ] 42 assertions intact diff --git a/plans/astro-refactor/task-15c-language-toggle.md b/plans/astro-refactor/task-15c-language-toggle.md new file mode 100644 index 0000000..41f7373 --- /dev/null +++ b/plans/astro-refactor/task-15c-language-toggle.md @@ -0,0 +1,62 @@ +# Task 15c — The language toggle + +**Agent**: `content-i18n-migrator` · **Model**: **Codex** **Depends on**: 05 · +**Parallel with**: 15a, 15b · **Blocks**: 15d **Worktree**: +`.agents/scripts/worktree.sh start 15c language-toggle` + +## Why this is its own task + +This is the part of the full guide that does not survive a mechanical port, and +it is the most likely reason task 15 failed twice. + +Today `applyLanguage` walks a `translations.pt` map of **CSS selector → +Portuguese HTML** and overwrites `innerHTML` at each selector. It keeps an +`originals` Map to restore English. That design cannot survive the migration: +the selectors are page-structure coupling, and once the content is a collection +the Portuguese string already lives beside the English one. + +## Deliver a decision, then an implementation + +Write the approach down in `.agents/context/content-i18n.md` (or the rule file +it points at) **before** you build, because tasks 15d, 16, and 20 all depend on +it and there is currently no stated answer. + +The realistic options: + +1. **Server-render both locales, toggle visibility.** Simple, no hydration cost + for text, doubles the HTML. +2. **Server-render the saved locale, islands re-render on toggle.** Smaller + HTML; every island then needs both strings client-side anyway. +3. **Separate routes per locale.** Cleanest, but changes URLs, which touches + publishing and every internal link — out of scope unless you argue for it and + the report flags it as a plan change. + +Pick one, say why, and note what it costs. + +## Behaviour that must not regress + +- `localStorage` key `ai-for-dummies-language`, wrapped in try/catch — previews + disable storage and an unguarded read throws. +- `document.documentElement.lang` becomes `pt-BR` or `en`. +- `[data-lang]` buttons get `.active` and `aria-pressed`. +- Toggling language re-renders the active phase panel and every selector panel. + Coordinate with 15a: the island must expose a way to do this. +- `client:idle` — page-wide, not urgent. + +## Do not + +- Create `src/pages/full-guide.astro`. That is 15d. +- Edit `src/content/config.ts` schemas belonging to other collections beyond + what the toggle genuinely needs; if a schema is wrong, report it. +- Touch `verify.mjs`. +- Translate, rewrite, or "improve" any string. Both locales already exist in the + collections. This is plumbing, not copywriting. + +## Done when + +- [ ] Approach written down where 15d, 16 and 20 will find it +- [ ] Toggle island built, `client:idle`, storage guarded +- [ ] Both locales verified on a real rendered page, not just in theory +- [ ] `pnpm run gate` green — the full gate +- [ ] 42 assertions intact +- [ ] Report states the contract 15d must satisfy diff --git a/plans/astro-refactor/task-15d-page-full-guide.md b/plans/astro-refactor/task-15d-page-full-guide.md new file mode 100644 index 0000000..140d906 --- /dev/null +++ b/plans/astro-refactor/task-15d-page-full-guide.md @@ -0,0 +1,58 @@ +# Task 15d — Assemble /full-guide/ + +**Agent**: `page-migrator` · **Model**: **Codex** **Depends on**: 10, 13, 15a, +15b, 15c · **Parallel with**: 16 · **Blocks**: 15e, 18, 19 **Worktree**: +`.agents/scripts/worktree.sh start 15d page-full-guide` + +## Goal + +`src/pages/full-guide.astro`. 22 KB of HTML, bilingual throughout, everything +interactive already built by 15a/15b/15c and every block already built by +task 10. **This task is assembly.** If you find yourself writing a new island, +stop — it belongs to one of the earlier briefs and you should report the gap +instead. + +Read the reports from 15a, 15b and 15c first. They state their props and the +language contract. + +## Islands and nothing else + +| Island | Directive | From | +| ------------------------------- | ---------------- | ---- | +| Guide selector (one, ×9 groups) | `client:visible` | 15a | +| Copy-prompt buttons + progress | `client:visible` | 15b | +| Language toggle | `client:idle` | 15c | + +Everything else is server-rendered. + +## Asserted by verify.mjs — all must survive + +`const phases`, `const handsOnPrompts`, `const modelGuide`, +`const skillSources`, `const skillInstallPrompts`, `render('plan')`, +`renderTree`, `renderWorker`, `renderRoute`, `renderModelProvider`, +`renderEffort`, `renderSkillFile`, `renderSkillWorkflow`, `renderCommonSkill`, +`renderHandsOn`, `copyPrompt`, plus +`data-copy-target="prompt-install-skills|prompt-basic|prompt-skills"`, +`hands-on/starter/`, `additional-reading.md`, `role="tablist"`, `
`. + +Implementation-detail assertions, deliberately. **Never delete one.** Task 19 +re-points them to output-level checks; you do not. + +## Watch for + +- `hands-on/starter/` is a **lab fixture**. Link to it, ship it as a static + asset, do not componentize it. Same for `hands-on/rules/`. +- `renderHandsOn` takes no argument — it is not part of 15a's selector pattern. + Check whether 15a covered it; if not, it is yours, and say so in the report. +- Do not delete `responsive.css` here. That is 15e, and it needs screenshots. + +## Done when + +- [ ] Snapshot diff against `.agents/snapshots/` empty +- [ ] Every interaction works: all nine selector groups, both languages, all + three copy buttons +- [ ] Keyboard: arrows move between tabs; focus visible throughout +- [ ] JS payload **smaller** than today's 50 KB — content is static now +- [ ] Screenshots match at 560 / 800 / 1100 / 1600 px +- [ ] `pnpm run gate` green — the full gate, not `verify` + `audit-ui` alone +- [ ] 42 assertions intact diff --git a/plans/astro-refactor/task-15e-responsive-css.md b/plans/astro-refactor/task-15e-responsive-css.md new file mode 100644 index 0000000..fc69a5e --- /dev/null +++ b/plans/astro-refactor/task-15e-responsive-css.md @@ -0,0 +1,42 @@ +# Task 15e — Retire responsive.css + +**Agent**: `design-system-keeper` · **Model**: `agy` (Gemini 3.1 Pro — vision) +**Depends on**: 15d, 16 · **Blocks**: 20 **Worktree**: +`.agents/scripts/worktree.sh start 15e responsive-css` + +## Goal + +`responsive.css` is 30 KB and mostly served `/full-guide/`. Once 15d and 16 have +landed, port what the Astro pages still need into component styles or +`tokens.css`, prove the remainder dead, and delete it. + +**Proof is screenshots, not reading.** A rule that looks unused because no +selector matches at 1600 px may be the only thing holding the 560 px layout +together. + +## Method + +1. Build. Screenshot every migrated route at 560 / 800 / 1100 / 1600 px. +2. Remove `responsive.css` from the build entirely. +3. Screenshot again. Every diff is a rule you must port. +4. Port it into the owning component's `