3.9 KiB
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 createsrc/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 gategreen — the full gate, not justverify+audit-ui- 42 assertions intact
- Report names the island's props so 15d can wire it without guessing