docs: split task 15 into 15a-15e after two failed attempts
This commit is contained in:
@@ -5,9 +5,9 @@ interchangeable here, and the split is not about which is "smartest" — it is
|
|||||||
about which failure mode each task punishes.
|
about which failure mode each task punishes.
|
||||||
|
|
||||||
**Honest caveat up front:** I have not benchmarked these three on this
|
**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
|
repository. The routing below is reasoned from task shape and each model's known
|
||||||
known strengths. Validate it cheaply on **task 07** (small, self-contained,
|
strengths. Validate it cheaply on **task 07** (small, self-contained, easy to
|
||||||
easy to judge) before fanning out across ten worktrees.
|
judge) before fanning out across ten worktrees.
|
||||||
|
|
||||||
## Short answer
|
## Short answer
|
||||||
|
|
||||||
@@ -19,7 +19,7 @@ points where M3 is the wrong tool.
|
|||||||
## Routing table
|
## Routing table
|
||||||
|
|
||||||
| Task | Model | Why this one |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 03 verification net | **Codex** | Writing test tooling with a tight feedback loop. Precision about what an assertion pins matters more than speed. |
|
||||||
@@ -28,7 +28,12 @@ points where M3 is the wrong tool.
|
|||||||
| 07 primitives | **MiniMax-M3** | Small components from templates. Use this task to calibrate the whole routing decision. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 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. |
|
| 19 contract re-point | **Codex** | 42 assertions to translate without losing coverage. Meticulous, mechanical, verifiable. |
|
||||||
@@ -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
|
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
|
reasoning where the spec is vague; every task above that it owns has a
|
||||||
template and a mechanical oracle.
|
template and a mechanical oracle.
|
||||||
- **Codex** — best at "keep iterating until the check passes" over a
|
- **Codex** — best at "keep iterating until the check passes" over a complicated
|
||||||
complicated existing codebase. Use it where the loop is long and the answer is
|
existing codebase. Use it where the loop is long and the answer is not
|
||||||
not obvious: scaffold, the two hard pages, verification.
|
obvious: scaffold, the two hard pages, verification.
|
||||||
- **Gemini** — biggest context and genuinely useful multimodal comparison. Use
|
- **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.
|
**visual**: token consolidation, motion, screenshot diffing, and code review.
|
||||||
|
|
||||||
## Cross-checking rule
|
## Cross-checking rule
|
||||||
@@ -57,7 +62,7 @@ reviews; Codex writes → Gemini reviews; Gemini writes → Codex reviews. The
|
|||||||
## Swap the routing if you see this
|
## Swap the routing if you see this
|
||||||
|
|
||||||
| Symptom | Move the task to |
|
| Symptom | Move the task to |
|
||||||
| --- | --- |
|
| ------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------- |
|
||||||
| M3 spends more than ~3 iterations failing the same gate | Codex |
|
| M3 spends more than ~3 iterations failing the same gate | Codex |
|
||||||
| M3 edits files outside its task scope | Codex, and tighten the brief |
|
| 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 |
|
| 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 |
|
||||||
|
|||||||
@@ -37,12 +37,12 @@ on four branches; nothing is merged or pushed.
|
|||||||
Phase 0 foundation 01 → (02 ∥ 03 ∥ 04)
|
Phase 0 foundation 01 → (02 ∥ 03 ∥ 04)
|
||||||
Phase 1 content 05 ∥ 06 after 04
|
Phase 1 content 05 ∥ 06 after 04
|
||||||
Phase 2 components 07 → (08 ∥ 09 ∥ 10 ∥ 11) after 02
|
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
|
Phase 4 polish 18 ∥ 19, then 20
|
||||||
```
|
```
|
||||||
|
|
||||||
| # | Task | Agent | Depends on | Parallel with |
|
| # | Task | Agent | Depends on | Parallel with |
|
||||||
| --- | ------------------------------------------------ | --------------------- | ---------- | ------------- |
|
| --- | ----------------------------------------------------------------- | --------------------- | ------------- | ------------- |
|
||||||
| 01 | [scaffold + gates](task-01-scaffold.md) | astro-architect | — | — |
|
| 01 | [scaffold + gates](task-01-scaffold.md) | astro-architect | — | — |
|
||||||
| 02 | [design tokens](task-02-tokens.md) | design-system-keeper | 01 | 03, 04 |
|
| 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 |
|
| 03 | [verification net](task-03-verification-net.md) | verification-engineer | 01 | 02, 04 |
|
||||||
@@ -57,11 +57,16 @@ Phase 4 polish 18 ∥ 19, then 20
|
|||||||
| 12 | [landing page](task-12-page-landing.md) | page-migrator | 03, 08 | 13, 14, 17 |
|
| 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 |
|
| 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 |
|
| 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 |
|
| 15 | [full guide](task-15-page-full-guide.md) — **split into 15a–15e** | — | — | — |
|
||||||
| 16 | [review desk](task-16-page-review-desk.md) | page-migrator | 06, 11, 13 | 15 |
|
| 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 |
|
| 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 |
|
| 18 | [motion pass](task-18-motion.md) | motion-designer | 15d, 16 | 19 |
|
||||||
| 19 | [contract re-point](task-19-verify-repoint.md) | verification-engineer | 15, 16 | 18 |
|
| 19 | [contract re-point](task-19-verify-repoint.md) | verification-engineer | 15d, 16 | 18 |
|
||||||
| 20 | [cutover + cleanup](task-20-cutover.md) | astro-architect | all | — |
|
| 20 | [cutover + cleanup](task-20-cutover.md) | astro-architect | all | — |
|
||||||
|
|
||||||
Widest parallelism: **four agents** (tasks 08–11, then 12/13/14/17). More than
|
Widest parallelism: **four agents** (tasks 08–11, then 12/13/14/17). More than
|
||||||
|
|||||||
@@ -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
|
Do not work this brief. It is kept because other documents link to it.
|
||||||
**Depends on**: 05, 10, 13 · **Parallel with**: 16 **Worktree**:
|
|
||||||
`.agents/scripts/worktree.sh start 15 page-full-guide`
|
|
||||||
|
|
||||||
## 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
|
| Brief | What | Depends on |
|
||||||
render functions, bilingual throughout.
|
| ---------------------------------- | ------------------------------------------- | --------------------- |
|
||||||
|
| [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
|
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
|
||||||
Not application code — a **bilingual content database** (task 05 already moved
|
**15e** (20).
|
||||||
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"`, `<table>`.
|
|
||||||
|
|
||||||
## 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
|
|
||||||
|
|||||||
@@ -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: <reason>; 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
|
||||||
@@ -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 `<span>` 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: <reason>; 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
|
||||||
@@ -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
|
||||||
@@ -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"`, `<table>`.
|
||||||
|
|
||||||
|
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
|
||||||
@@ -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 `<style>`, or — if it is a real token —
|
||||||
|
into `tokens.css`, which **you own**. No other agent may add tokens.
|
||||||
|
5. Repeat until the diffs are empty.
|
||||||
|
|
||||||
|
## Constraints
|
||||||
|
|
||||||
|
- Allowed breakpoints are 560 / 800 / 1100 / 1600 / 2200 px.
|
||||||
|
`.agents/scripts/check-tokens.mjs` rejects others.
|
||||||
|
- Do not delete the file while any legacy page still loads it. Check which
|
||||||
|
routes have actually been migrated at the time you run; 20 is the cutover.
|
||||||
|
- No raw hex, no `font-size: Npx` outside `tokens.css`.
|
||||||
|
- You are also the owner of the ~190 accumulated `/* token-gap: ... */` markers.
|
||||||
|
Resolving them is **not** in this brief — do not start. Report the count so it
|
||||||
|
can be scheduled.
|
||||||
|
|
||||||
|
## Done when
|
||||||
|
|
||||||
|
- [ ] Screenshot diffs empty at all four widths without `responsive.css`
|
||||||
|
- [ ] Ported rules live with the component that needs them, or in `tokens.css`
|
||||||
|
- [ ] `responsive.css` deleted, and nothing references it
|
||||||
|
- [ ] `pnpm run gate` green; 42 assertions intact
|
||||||
Reference in New Issue
Block a user