ab2308441c
The repository had two skill directories. `skills/` held the four written for this project; `.agents/skills/` held the ones the agent context refers to. Nothing said which an agent should read, and `.agents/ORCHESTRATOR.md` only ever pointed at the second. Move the first four into `.agents/skills/` so there is one location, and add the vendored packages this chapter work used: `animation-vocabulary` and `improve-animations` (emilkowalski/skills), `teach` (mattpocock/skills), plus a local `translation` skill and `audit-translations.mjs` for the EN/PT pairs. `skills-lock.json` pins the vendored three by source and content hash, so a later re-vendor is a diff rather than a guess. `.claude/skills/` is symlinks into `.agents/skills/`, which is what makes them loadable here without a second copy on disk. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
117 lines
4.6 KiB
Markdown
117 lines
4.6 KiB
Markdown
---
|
|
name: translation
|
|
description:
|
|
Translate site copy to Brazilian Portuguese in a register and vocabulary that
|
|
match the existing translated collections. Use when adding a new localized
|
|
field, auditing a chapter for missing or identical en/pt pairs, or proposing
|
|
translation candidates for review. Always pair with
|
|
[`../../rules/content-i18n.md`](../../rules/content-i18n.md).
|
|
---
|
|
|
|
# Translation
|
|
|
|
This site is bilingual EN/PT-BR. The English is editorial; the Portuguese has to
|
|
read like a native technical writer, not like a machine. The glossary
|
|
([`references/glossary.md`](references/glossary.md)) and tone notes
|
|
([`references/tone.md`](references/tone.md)) pin the conventions so any agent —
|
|
me, a different LLM, a future you — produces Portuguese that matches what is
|
|
already there.
|
|
|
|
## Before anything
|
|
|
|
Read [`../../rules/content-i18n.md`](../../rules/content-i18n.md) and
|
|
[`../../context/content-i18n.md`](../../context/content-i18n.md). Both are
|
|
binding. In particular:
|
|
|
|
- Both `en` and `pt` are required on every `localized` field. A missing `pt`
|
|
must fail the build.
|
|
- These are hand-written translations with deliberate tone. **Copy, do not
|
|
retype.** Retyping introduces drift.
|
|
- The site's bilingual contract is client-side: both languages ship in the
|
|
payload, the toggle swaps visibility. Do not propose `/en/` `/pt/` routing
|
|
without a separate decision.
|
|
|
|
## Audit before you propose
|
|
|
|
Run the audit script first. It walks `src/content/**` and reports every
|
|
`localized` field where `en === pt`:
|
|
|
|
```bash
|
|
node .agents/scripts/audit-translations.mjs
|
|
```
|
|
|
|
The script exits non-zero on any identical pair. That is the list you work from
|
|
— chapter, file, field. Touch only what's flagged, and only after a human has
|
|
reviewed your proposal for the first chapter (the tone is contagious: if the
|
|
first chapter is right, the rest fall into the same voice).
|
|
|
|
## Propose, do not commit
|
|
|
|
This skill is **review-first**. The workflow is:
|
|
|
|
1. Pick the smallest chapter (today: `landing.json`, 30 fields). Read the
|
|
English, read the existing translations in the other collections to absorb
|
|
the voice, then write candidates.
|
|
2. Show the diff to a human reviewer. They sign off on tone, terminology, and
|
|
register before you proceed to the next chapter.
|
|
3. Only after the reviewer agrees, write the JSON. Re-run the audit; it must
|
|
pass.
|
|
4. Repeat for the next chapter.
|
|
|
|
Auto-committing a translation in bulk is the same failure mode as a content
|
|
migration that "passes" by deleting assertions: silent monolingualism. The
|
|
review step is the whole point.
|
|
|
|
## What stays in English
|
|
|
|
Some terms are kept in English by deliberate convention. Do not translate:
|
|
|
|
- Code identifiers, file paths, command names, product names (`SKILL.md`,
|
|
`AGENTS.md`, `.agents/skills/`, `git`, `pnpm`, `claude`, `opus`, `sonnet`,
|
|
`haiku`, `gpt-5.6`, `sol`, `terra`, `luna`)
|
|
- Product surface nouns that the team has decided to keep: `skill`, `worktree`,
|
|
`worker`, `branch`, `merge`, `commit`, `diff`, `brief`, `gate`, `pipeline`,
|
|
`recall`, `prompt`
|
|
- The `<i></i>` and `<b></b>` glyphs that ship in copy — they are decorative and
|
|
the stylesheet depends on them
|
|
- Arrows used as connectors (`→`, `↗`) — keep them, the spacing is intentional
|
|
|
|
The full list is in the glossary.
|
|
|
|
## What to translate
|
|
|
|
Everything else, including:
|
|
|
|
- Section titles, ledes, eyebrows
|
|
- Card titles, body copy, call-to-action labels
|
|
- Stage / phase labels in prose ("PLAN", "BUILD", "REVIEW" stay uppercase
|
|
English because they are acronyms in the design system; the prose around them
|
|
translates)
|
|
- Inline `<em>` emphasis and `<br>` line breaks — the structure is shared, the
|
|
words differ
|
|
|
|
## Verification
|
|
|
|
After writing, before committing:
|
|
|
|
```bash
|
|
pnpm run build # schema check (both locales present)
|
|
node .agents/scripts/audit-translations.mjs # en !== pt everywhere
|
|
pnpm run verify # full gate, includes rendered snapshots
|
|
```
|
|
|
|
A rendered snapshot diff in `verify.mjs` catching a new Portuguese string is
|
|
expected. Update `.agents/snapshots/*.txt` if the prose really did change and
|
|
the snapshot was a stale capture. Do not delete assertions to make it pass.
|
|
|
|
## What this skill does NOT do
|
|
|
|
- Migrate content out of legacy `app.js` (that's `content-migration`)
|
|
- Wire `lang` state into chapter pages (that's tasks 12 / 13 / 15)
|
|
- Edit `src/content/config.ts` (the schema is `verification-engineer`'s scope)
|
|
- Touch components, layouts, styles, or the legacy tree
|
|
- Translate code, comments inside code blocks, command output, or paths
|
|
|
|
The chapter's review-desk body (`src/content/reviews/*.md`) is intentionally not
|
|
localized — the review desk is an English-only editor by design.
|