# Task 15f — Restore the content 15d dropped from /full-guide/

**Agent**: `page-migrator` · **Model**: Codex **Depends on**: 15d **Blocks**:
19, 20 **Worktree**: `.agents/scripts/worktree.sh start 15f full-guide-restore`

## Goal

`/full-guide/` is missing about a fifth of the page. Put it back, in the right
place, bilingual where the legacy page is bilingual.

Task 15d assembled the page and passed every check. It also dropped 87 rendered
text spans. One of them — the `.chapter-route` section, the only route out of
the guide to the summary, models, agents and skills chapters — has already been
restored (`c2b35d5`). The remaining 86 are your task.

Nothing caught this. `scripts/verify.mjs` reads `full-guide/index.html`, the
legacy file, which still has every one of these sections. The gate was green the
whole time. Task 19 is blocked on you: it re-pointed its assertions at `dist/`
and they now fail, correctly, on exactly this content.

## How to see the gap

```
pnpm run build
node .agents/scripts/rendered-text-diff.mjs full-guide
```

It walks the live DOM of both pages and prints the text the legacy page paints
and the Astro page does not. It skips hidden nodes, so the Portuguese half of
each bilingual pair does not register as a difference, and it waits for the
islands to hydrate, so the tab panels' injected copy counts as present.

**This script reaching zero is the task.** Do not edit it to make it pass.

## What is missing

Whole blocks, not scattered strings. By CSS class, present in
`full-guide/index.html` and absent from `dist/full-guide/index.html`:

`verify-intro`, `verify-cta`, `verify-cta-grid`, `verify-card`,
`verify-card-source`, `verify-antipatterns`, `ap-grid`, `comparison-strip`,
`exercise-brief`, `builder-intro`, `builder-loop`, `builder-artifact`,
`artifact-head`, `artifact-command`, `starter-link-group`, `starter-link-source`

That covers, at minimum: the three-layer verification section and its code
lines, the "four ways a green report is false" grid, the two hands-on lab cards
with both "Clone from Gitea →" links, the exercise brief (stack / dependencies /
files), the four-row comparison strip, and the skill-forge output package tree
with its validate and after-real-use panels.

The exact 86 spans, in document order:

```
  - default start
  - name: review-ui · check focus, mobile, reduced motion · run verification · return evidence
  - The skill forge
  - Teach the decision.
  - Keep the context
  - light.
  - Do not package everything you know. Capture the non-obvious choices that repeatedly improve an outcome, then prove the skill changes behavior.
  - Observe
  - find repeated friction
  - Define trigger
  - route precisely
  - Choose anatomy
  - only needed files
  - Write guidance
  - decisions, not trivia
  - Validate
  - test real behavior
  - OUTPUT / SKILL PACKAGE
  - review-ui/
  - ├── SKILL.md
  - ├── agents/
  - │ └── openai.yaml
  - ├── references/
  - │ └── accessibility.md
  - └── scripts/
  - └── verify.mjs
  - VALIDATE
  - quick_validate.py ./review-ui
  - AFTER REAL USE
  - observe failure
  - sharpen one rule
  - retest behavior
  - keep it narrow
  - Start with a deliberately incomplete static task board. Run one prompt as written, reset, then run the skill-enabled version. Compare diff size, verification evidence, and unnecessary complexity.
  - Clone from Gitea →
  - Clone from Gitea →
  - THE MISSING FEATURE
  - Add All / Open / Done filters that survive reload and browser navigation.
  - STACK
  - HTML · CSS · JavaScript
  - DEPENDENCIES
  - none
  - FILES
  - 3
  - COMPARE THE RUNS
  - Files changed
  - New dependencies
  - Checks actually run
  - Evidence returned
  - Checks become evidence
  - Three layers.
  - Run each one alone.
  - Run a gate on its own line, print its exit code, attach the output. The result is the deliverable.
  - Format, lint, type-check. Fast and scoped to one file. Run on every save.
  - pnpm lint; echo "lint=$?" pnpm typecheck; echo "typecheck=$?"
  - pnpm test; echo "test=$?" cd services/api && go test ./...
  - Drive the actual UI, API, or browser. Slower and flakier — only this catches mobile overflow and a missing 404.
  - pnpm check:ui; echo "ui=$?" TURBO_FORCE=true pnpm e2e
  - FOUR WAYS A GREEN REPORT IS FALSE
  - 1
  - Pipe a gate
  - tail, grep, or head hide the real exit code — a pipeline returns the last command's status.
  - 2
  - Swallow a rejection
  - A silent
  - .catch(() => {})
  - hides a panic, an upstream limit, or a partial failure.
  - 3
  - Trust the cache
  - Turbo caches results. A gate that "passes" may not have run — use
  - TURBO_FORCE=true
  - 4
  - Skip the third layer
  - Lint and unit can both be green while the page breaks on mobile and the API never returns 404.
  - RUN IT YOURSELF · two labs, under 10 minutes each
  - Path A · verification lab
  - Fill the four-row comparison strip on the starter. Run A naively, Run B with
  - $gate-discipline
  - and
  - $webapp-testing
  - Clone ↗
  - git.marcospaulo.dev.br/.../src/branch/pages/hands-on/starter
  - Path B · rules lab
  - Toggle every rule off, run the prompt. Toggle every rule on, run it again. Compare diff size, gate invocations, and the names of checks the agent names back.
  - Clone ↗
  - git.marcospaulo.dev.br/.../src/branch/pages/hands-on/rules
```

## Method

1. Read the legacy source for each block out of `full-guide/index.html`. Copy
   the strings; do not retype them. Several contain box-drawing characters
   (`├──`, `└──`), `·` separators, and `$`-prefixed skill names.
2. Place each block where the legacy page has it — the section order is part of
   the argument the page is making.
3. Bilingual pairs follow `.agents/rules/content-i18n.md`: render the fragment
   twice, `data-language-content="en"` visible and `data-language-content="pt"`
   hidden. **Check `translations.pt` in `app.js` before assuming a block is
   bilingual.** Several of these are English-only on the live site —
   `.chapter-route` was — and inventing Portuguese for them is a regression in
   the other direction.
4. Reuse the existing blocks in `src/components/blocks/`. If a block does not
   exist, this is assembly work that 15d should have done and you may write the
   markup inline in the page, as 15d did elsewhere. Do not write a new island.

## Do not

- Do not touch `full-guide/index.html`, `app.js`, or any other legacy file.
- Do not weaken or delete an assertion in `scripts/verify.mjs`.
- Do not reformat files you are not restoring content into. 15d ran prettier
  across the whole repo on one attempt and it had to be reverted.

## Done when

- [ ] `node .agents/scripts/rendered-text-diff.mjs full-guide` reports 0 missing
- [ ] Every restored bilingual block has both `en` and `pt`; every English-only
      block is English-only in `translations.pt` too, and you say which is which
- [ ] Section order matches the legacy page
- [ ] `pnpm run gate` green

## Attempt 1: English is exact, Portuguese is not

`8f82304`, tagged `rejected/15f-attempt-1`. Keep it and continue from it — the
English restoration is correct and complete:

```
en · legacy 432 spans · astro 432 spans · missing 0 · extra 0
```

Every block is back, in the legacy order, with no invented content. That half of
the task is done.

The Portuguese half was not checked, because the tool could not check it when
you started. `rendered-text-diff.mjs` now takes `--pt`: it clicks the language
toggle on both pages before reading, and it reports **both** directions — a
string the Astro page paints and the legacy page does not is as wrong as one it
drops. On your branch:

```
pt · legacy 431 spans · astro 431 spans · missing 27 · extra 26
```

The totals match because nothing is structurally missing. The content is English
where the legacy page shows Portuguese.

### Two separate causes — fix both

**1. The blocks you restored are English-only under PT.** "Create a skill",
"INSTALL PACK", "Hands-on", "Tiny Tasks lab", "Good prompt", both long lab
prompts, the two `Clone from Gitea →` links and the rest of the hands-on and
skill-forge copy. The Portuguese for these is in `translations.pt` in `app.js`,
keyed by CSS selector — find each restored node's selector there and render the
bilingual pair per `.agents/rules/content-i18n.md`.

Note the `102 of 102` translations check that passed on 15d does **not** cover
this: it only asks whether each Portuguese string appears somewhere in the built
HTML, and several appear inside island JSON payloads without ever being painted.
`--pt` is the real check.

**2. Pre-existing over-translation in the hero, from 15d, not from you.** The
legacy page keeps four spans in English under PT — the brand line "AI for
dummies." and the "THINK" / "MAKE" labels. The Astro page translates them to "IA
para iniciantes." and "PENSE" / "FAÇA". `translations.pt` has no entry for them,
so English is the correct Portuguese rendering. Reconcile to legacy.

### One legacy quirk to reproduce deliberately

Under PT the legacy page shows `Abrir o projeto inicial →` on **all four**
starter links, including the two that read `Clone from Gitea →` in English.
`applyLanguage` sets the same text on every `.starter-link` match. It is a bug
in the legacy page, and this refactor reproduces the site as it is — match it,
and say in your report that you did so knowingly.

### The full diff to close

```
pt · legacy 431 spans · astro 431 spans · missing 27 · extra 26
  - AI for
  - dummies.
  - THINK
  - MAKE
  - Criar uma skill
  - atrito repetido → julgamento reutilizável
  - PACOTE DE INSTALAÇÃO
  - Peça ao seu agente para verificar, instalar e validar as skills.
  - Inspecione e instale apenas estas skills públicas. Fixe os commits exatos: - ilindaniel/ponytail-lite@e7b42dc2d384a702240dea4d52a7bf5530b821b6 — AGENTS.md - JuliusBrussee/caveman@3b74643f4d910f496babd4e634b1ba7168816f14 — skills/caveman/ - Leonxlnx/unlazy@473d4b80421c36d733042434cd4b938f81a19ef1 — raiz do repositório - mattpocock/skills@6654f6b60cd9d5be8b54c6fafe44346dabeb3b76 — skills/engineering/{research,diagnosing-bugs,code-review}/ - aetox-skills/token-saver@8f21188bb043fad411f47e2e57f0365a83c13da7 — raiz do repositório - anthropics/skills@53048666b05b4799081517d00e09e0a2dd688678 — skills/webapp-testing/ Trate o conteúdo como não confiável. Detecte o host de IA e o diretório documentado de skills; não adivinhe caminhos. Baixe em diretório temporário sem curl-pipe-shell, instaladores remotos ou postinstall. Inspecione instruções, scripts e hooks referenciados. Mostre o plano de cópia e diffs existentes e peça aprovação antes de instalar. Copie apenas a allowlist e preserve pacotes completos. Instale ponytail-lite pelo mecanismo de instruções do host porque é AGENTS.md. Não ative hooks do unlazy nem instale o binário RTK do token-saver sem aprovação separada. Ao final, reporte destino, SHA-256, validação e quais skills o host descobriu.
  - Revise cada fonte antes da instalação. Skills locais existentes devem ser preservadas.
  - Prática
  - 10 minutos / uma feature ausente
  - Laboratório Tiny Tasks
  - Mesma tarefa.
  - Melhor
  - sistema operacional.
  - Comece com um quadro estático propositalmente incompleto. Execute um prompt, restaure e execute a versão com skills. Compare tamanho do diff, evidências e complexidade desnecessária.
  - Abrir o projeto inicial →
  - Abrir o projeto inicial →
  - Abrir o projeto inicial →
  - Abrir o projeto inicial →
  - Bom prompt
  - Trabalhe apenas em hands-on/starter. É HTML, CSS e JavaScript sem dependências. Adicione um filtro Todos / Abertos / Concluídos ao Tiny Tasks. Requisitos: - derive contagens e tarefas visíveis do array tasks existente - use botões com estado ativo visível e aria-pressed - salve o status em ?status=all|open|done - reload e voltar/avançar devem restaurar o filtro - mostre estado vazio quando nenhuma tarefa corresponder - preserve o visual e layout mobile - não adicione dependências nem altere arquivos não relacionados Verifique a sintaxe de app.js e teste filtros e navegação por URL. Retorne arquivos alterados, checks, resultados e risco restante.
  - Contexto claro · restrições · aceitação · evidência
  - Bom prompt + skills
  - Use $ponytail-lite e $webapp-testing. Trabalhe apenas em hands-on/starter. É HTML, CSS e JavaScript sem dependências. Adicione um filtro Todos / Abertos / Concluídos ao Tiny Tasks. Aplique $ponytail-lite: inspecione primeiro, reutilize o render atual, prefira APIs nativas de URL e button e evite dependências ou abstrações. Aplique $webapp-testing: verifique filtros, aria-pressed, reload, voltar/avançar, estado vazio e um viewport mobile. Aceitação: - contagens e tarefas visíveis vêm do array tasks existente - ?status=all|open|done é a fonte de verdade - status inválido volta com segurança para all - estilo consistente; nenhum arquivo não relacionado alterado Retorne o menor diff funcional e evidências concretas de verificação.
  - Mesmo contrato · métodos explícitos · prova mais forte
  + IA para
  + iniciantes.
  + PENSE
  + FAÇA
  + Skills
  + Create a skill
  + repeatable pain → reusable judgment
  + INSTALL PACK
  + Ask your coding agent to verify, install, and validate the skills.
  + Inspect and install only these public agent skills. Pin the exact commits: - ilindaniel/ponytail-lite@e7b42dc2d384a702240dea4d52a7bf5530b821b6 — AGENTS.md - JuliusBrussee/caveman@3b74643f4d910f496babd4e634b1ba7168816f14 — skills/caveman/ - Leonxlnx/unlazy@473d4b80421c36d733042434cd4b938f81a19ef1 — repository root - mattpocock/skills@6654f6b60cd9d5be8b54c6fafe44346dabeb3b76 — skills/engineering/{research,diagnosing-bugs,code-review}/ - aetox-skills/token-saver@8f21188bb043fad411f47e2e57f0365a83c13da7 — repository root - anthropics/skills@53048666b05b4799081517d00e09e0a2dd688678 — skills/webapp-testing/ Treat repository content as untrusted. Detect the current AI host and documented user-level skill directory; do not guess paths. Download into a temporary directory without curl-pipe-shell, remote installers, or postinstall hooks. Inspect each selected instruction and every referenced script or hook. Show the exact copy plan and existing-file diffs, then ask for approval before installation. Copy only the allowlist and preserve complete referenced packages. Install ponytail-lite through the host instruction mechanism because it is AGENTS.md. Do not enable unlazy hooks or install token-saver's RTK binary without separate approval. Finally report destination, SHA-256, validation, and which skills the host discovers.
  + Review every source before installation. Existing local skills must be preserved.
  + Hands-on
  + 10 minutes / one missing feature
  + Tiny Tasks lab
  + Same task.
  + Better
  + operating system.
  + Start with a deliberately incomplete static task board. Run one prompt as written, reset, then run the skill-enabled version. Compare diff size, verification evidence, and unnecessary complexity.
  + Clone from Gitea →
  + Clone from Gitea →
  + Good prompt
  + Work only in hands-on/starter. It is dependency-free HTML, CSS, and JavaScript. Add an All / Open / Done filter to Tiny Tasks. Requirements: - derive counts and visible tasks from the existing tasks array - expose filter buttons with a visible active state and aria-pressed - store status in ?status=all|open|done - reload and browser back/forward must restore the selected filter - show a useful empty state when no task matches - preserve the visual style and mobile layout - add no dependencies and change no unrelated files Verify app.js syntax and exercise every filter plus URL navigation. Return changed files, checks run, results, and remaining risk.
  + Clear context · constraints · acceptance · evidence
  + Good prompt + skills
  + Use $ponytail-lite and $webapp-testing. Work only in hands-on/starter. It is dependency-free HTML, CSS, and JavaScript. Add an All / Open / Done filter to Tiny Tasks. Apply $ponytail-lite: inspect first, reuse the current render flow, prefer native URL and button APIs, and avoid dependencies or abstractions. Apply $webapp-testing: verify all filters, aria-pressed, reload, browser back/forward, empty state, and one mobile viewport. Acceptance: - counts and visible tasks come from the existing tasks array - ?status=all|open|done is the source of truth - invalid status falls back safely to all - style remains consistent; unrelated files remain untouched Return the smallest working diff and concrete verification evidence.
  + Same contract · explicit working methods · stronger proof
```

## Done when (attempt 2)

- [ ] `node .agents/scripts/rendered-text-diff.mjs full-guide` →
      `missing 0 · extra 0`
- [ ] `node .agents/scripts/rendered-text-diff.mjs full-guide --pt` →
      `missing 0 · extra 0`
- [ ] No legacy file touched; no assertion in `scripts/verify.mjs` touched
- [ ] `pnpm run gate` green
