name: 407-sf-audit-translate description: "Audit translation quality, i18n sync, and missing strings." disable-model-invocation: true argument-hint: '[file-path | "global" | "sync" | "apply"] (omit for full project audit)'
Canonical Paths
Before resolving any ShipFlow-owned file, load $SHIPFLOW_ROOT/skills/references/canonical-paths.md ($SHIPFLOW_ROOT defaults to $HOME/shipflow). ShipFlow tools, shared references, skill-local references/*, templates, workflow docs, and internal scripts must resolve from $SHIPFLOW_ROOT, not from the project repo where the skill is running. Project artifacts and source files still resolve from the current project root unless explicitly stated otherwise.
Chantier Tracking
Trace category: conditionnel.
Process role: source-de-chantier.
Before producing the final report, load $SHIPFLOW_ROOT/skills/references/chantier-tracking.md when this run is attached to a spec-first chantier. If exactly one active specs/*.md chantier is identified, append the current run to Skill Run History, update Current Chantier Flow when the run changes the chantier state, and include a final Chantier block. If no unique chantier is identified, do not write to any spec; report Chantier: non applicable or Chantier: non trace with the reason.
Chantier Potential Intake
Because this skill has process role source-de-chantier, evaluate the standard threshold from $SHIPFLOW_ROOT/skills/references/chantier-tracking.md before the final report. If the findings reveal non-trivial future work and no unique chantier owns it, do not write to an existing spec; add a Chantier potentiel block with oui, non, or incertain, a proposed title, reason, severity, scope, evidence, recommended /100-sf-spec ... command, and next step. If the work is only a direct local fix or already belongs to the current chantier, state Chantier potentiel: non with the concrete reason.
Report Modes
Before producing the final report, load $SHIPFLOW_ROOT/skills/references/reporting-contract.md.
Default to report=user: concise, findings-first, and focused on top issues, proof gaps, chantier potential, and the next real action. Use report=agent, handoff, verbose, or full-report for the detailed audit matrix, domain checklist output, command evidence, assumptions, confidence limits, and handoff notes.
Context
- Current directory: !
pwd - Project CLAUDE.md: !
head -100 CLAUDE.md 2>/dev/null || echo "no CLAUDE.md" - Default locale: !
grep -ri "defaultLocale\|default_locale\|i18n" astro.config.* next.config.* src/i18n/* 2>/dev/null | head -10 || echo "unknown" - i18n files: !
find src -path "*/i18n/*" -o -path "*/locales/*" -o -path "*/messages/*" -o -path "*/translations/*" -o -path "*/lang/*" 2>/dev/null | sort - Locale directories: !
find src/pages -mindepth 1 -maxdepth 1 -type d 2>/dev/null | sort || echo "no locale dirs" - Content collections: !
find src/content -type d -mindepth 1 -maxdepth 2 2>/dev/null | sort || echo "none" - All pages: !
find src/pages src/app -name "*.astro" -o -name "*.tsx" -o -name "*.vue" 2>/dev/null | grep -v node_modules | sort - Hardcoded strings: !
grep -rn --include="*.{astro,tsx,jsx,vue}" -E '>(["'"'"'])[A-ZÀ-Ÿ][^<]{5,}\1|>\s*[A-ZÀ-Ÿ][a-zà-ÿ]{3,}[^<]*<' src/components/ src/layouts/ 2>/dev/null | head -20 || echo "none found"
Mode detection
$ARGUMENTSis "global" → GLOBAL MODE: audit ALL multilingual projects in the workspace.$ARGUMENTSis a file path → PAGE MODE: check translations for that specific page.$ARGUMENTSis empty → PROJECT MODE: full i18n audit of the entire project.$ARGUMENTSis "sync" or "apply" → SYNC MODE: fill missing translations from default/source locale to target locales.$ARGUMENTSstarts withsyncorapply→ SYNC MODE (scoped): same operation, limited to the provided path/scope.
SYNC MODE (translation ops)
Use this mode when the goal is operational throughput, not only audit visibility.
Examples:
/407-sf-audit-translate sync/407-sf-audit-translate apply/407-sf-audit-translate sync src/i18n/407-sf-audit-translate apply src/content/blog
Step 1: Scope and source locale
- Detect the scope:
- no extra argument → whole project
- path provided after
sync/apply→ only that folder/file/surface
- Detect locales and choose source locale:
- use configured default locale when available
- otherwise use the locale with the highest key/content coverage
- Build a locale matrix for the scoped area:
- message keys, content files, and translatable frontmatter fields
Step 2: Fill missing translations safely
For each target locale, only apply low-risk changes by default:
- add missing keys/entries
- add missing localized content counterparts when mapping is clear
- preserve placeholders/tokens exactly (
{name},%s, ICU fragments, markdown links) - preserve HTML tags and component placeholders
Do not do these unless explicitly requested:
- rewriting existing non-empty translations for style
- changing established terminology without project glossary alignment
- changing URL slug strategy across locales
Step 3: Guardrails
- Keep brand/product names unchanged.
- Keep technical nouns in English when this is project convention.
- Maintain tone consistency defined in
CLAUDE.md/ project docs. - For French, enforce accents and typographic spacing rules.
- If a translation is ambiguous or business-sensitive, propose 2 options and ask before changing.
Step 4: Verify after sync
Run a quick post-sync check in scope:
- missing keys count before/after by locale
- placeholder/token integrity checks
- obvious truncation risk notes (long labels/buttons)
- technical i18n invariants (
lang, locale routes,hreflangwhen relevant to the scope)
Step 5: Report
TRANSLATION SYNC: [project/scope]
═══════════════════════════════════════
Source locale: [xx]
Target locales: [yy, zz]
Scope: [full project | path]
Missing keys before: [per locale]
Missing keys after: [per locale]
Entries added: X
Files touched: Y
Ambiguous items: Z (needs review)
Safety checks
Placeholder integrity: [ok/issues]
Terminology drift: [none/suspected]
Technical i18n risk: [none/list]
═══════════════════════════════════════
GLOBAL MODE
Audit ALL multilingual projects in the workspace for translation completeness and i18n quality.
Read discovered project-local corpora (
shipflow_data/markers) — check the Domain Applicability table. Identify projects with ✓ in the Translate column.Use the runtime's structured question tool when available to let the user choose:
- Question: "Which projects should I audit for translations?"
multiSelect: true- One option per applicable project: label = project name, description = stack inferred from project-local markers
- All applicable projects pre-listed as options
Use available parallel agent/tooling to launch one bounded worker per selected project in a single parallel batch when supported. If unavailable, run the selected projects sequentially.
Agent prompt must include:
cd [path]then readCLAUDE.mdfor project context- The absolute date, exact project path, and the i18n context already surfaced by this skill (default locale, locale dirs, translation files, content collections)
- The complete PROJECT MODE section from this skill (all 7 phases: i18n Architecture Review → Translation Completeness Matrix → Consistency Audit → Hardcoded String Detection → Technical SEO for i18n → Fix → Report)
- The Tracking section from this skill
- Rule: read-only analysis — no code fixes, only update AUDIT_LOG.md and TASKS.md
- Rule: before scoring, identify locale links, routing/SEO consequences, and UI surfaces affected by translation drift
- Rule: do not ask follow-up questions; if context is missing, state assumptions / confidence limits and continue
- Required sub-report sections:
Scope understood,Context read,Linked systems & consequences,Findings,Confidence / missing context
After all agents return, compile a cross-project translation report:
GLOBAL TRANSLATION AUDIT — [date] ═══════════════════════════════════════ PROJECT SCORES [project] [A/B/C/D] — summary ... CROSS-PROJECT PATTERNS [Shared terminology inconsistencies, common i18n gaps] ALL ISSUES BY SEVERITY 🔴 [project] file:line — description 🟠 [project] file:line — description 🟡 [project] file:line — description Total: X critical, Y high, Z medium across N projects ═══════════════════════════════════════Update project-local
shipflow_data/workflow/AUDIT_LOG.md(one traffic-first audit record per project, Translate column) and project-localshipflow_data/workflow/TASKS.md(each project's### Audit: Translatesubsection).Ask: "Which projects should I fix?" — list projects with scores. Fix only approved projects, one at a time.
PAGE MODE
Step 1: Identify the translation setup
- Read the target file (
$ARGUMENTS). - Determine the i18n approach:
- File-based routing:
/pages/en/about.astro+/pages/fr/about.astro(Astro) - JSON/YAML translation files:
locales/en.json+locales/fr.json - Content collections:
content/blog/en/+content/blog/fr/ - Inline i18n:
t('key')function calls - Hybrid: Combination of the above
- File-based routing:
- Read all locale versions of this page/content.
- Read the translation files used by this page.
Step 2: Audit
1. Completeness
- All translatable strings exist in every locale
- No missing keys in any language file
- No untranslated content (strings left in the source language)
- Dynamic content (dates, numbers, currencies) uses locale-aware formatting
- Pluralization rules are handled correctly per locale
- Alt text on images is translated
2. Quality
- Translations are natural, not machine-translated gibberish
- Technical terms are translated consistently (same term → same translation everywhere)
- Brand names and product names are NOT translated (kept as-is)
- Cultural adaptation: idioms, date formats, number formats match the locale
- Tone and formality match the locale convention (tu/vous in FR, Sie/du in DE, etc.)
- French typographic rules: espaces insécables before : ; ! ? « »
- No truncation issues (translated text fits the UI — FR is ~15% longer than EN, DE ~30% longer)
3. Technical Correctness
- No hardcoded strings in components (everything goes through i18n)
-
<html lang="xx">matches the current locale -
hreflangtags present for all locale variants - Canonical URL and
og:urlare locale-specific - URL slugs are translated (or intentionally kept in source language)
- Meta title and description are translated
-
<link rel="alternate">points to other locale versions
Step 3: Fix
For each issue found:
- Add missing translations directly (translate them naturally).
- Fix technical i18n issues (hreflang, lang attribute, canonical).
- Extract hardcoded strings to the i18n system.
- For ambiguous translations or cultural choices, propose 2 options and ask.
Step 4: Report
TRANSLATION REVIEW: [page name]
─────────────────────────────────────
Locales checked: [fr, en, ...]
Completeness [A/B/C/D] — X/Y keys translated
Quality [A/B/C/D] — one-line summary
Technical i18n [A/B/C/D] — hreflang, lang, canonical
─────────────────────────────────────
OVERALL [A/B/C/D]
Missing translations added: X
Hardcoded strings extracted: Y
Technical fixes: Z
PROJECT MODE
Workspace root detection
If the current directory has no project markers (no package.json, no src/ dir) BUT contains multiple project subdirectories — you are at the workspace root, not inside a project.
Use the runtime's structured question tool when available, or a concise plain-text question:
- Question: "You're at the workspace root. Which project(s) should I audit for translations?"
multiSelect: true- Options:
- All projects — "Run translation audit across every multilingual project" (Recommended)
- One option per multilingual project from discovered project-local corpora (
shipflow_data/markers): label = project name, description = stack
Then proceed to GLOBAL MODE with the selected projects.
Phase 1: i18n Architecture Review
- Identify the i18n framework/approach used.
- List all supported locales.
- Identify the default locale and fallback behavior.
- Check the routing strategy (prefix-based, domain-based, etc.).
Architecture checks
- i18n setup is documented or clear from config
- Default locale has a consistent URL strategy (with or without prefix, but consistent)
- Language switcher exists and works
- Language preference is persisted (cookie, URL, browser preference)
- SEO: each locale has unique URLs (not just client-side switching)
Phase 2: Translation Completeness Matrix
Build a matrix of all translation keys across all locales:
KEY FR EN [other]
─────────────────────────────────────────────────
nav.home ✓ ✓
nav.about ✓ ✗ ← MISSING
hero.title ✓ ✓
hero.subtitle ✓ ✗ ← MISSING
...
─────────────────────────────────────────────────
TOTAL X/Y X/Y
For content collections (blog posts, docs), check:
- Every piece of content exists in all locales
- Slugs are consistent across locales (same content linked by slug or ID)
- Frontmatter fields (title, description, date, tags) are translated
Phase 3: Consistency Audit
Terminology Consistency
Build a glossary of key terms and verify they're translated the same way everywhere:
| Source (EN) | FR Translation | Consistent? | Files |
|---|---|---|---|
| Dashboard | Tableau de bord | ✓ / ✗ | [list] |
| Settings | Paramètres | ✓ / ✗ | [list] |
| ... | ... | ... | ... |
Flag: same source term translated differently across files.
UI String Audit
- Button labels are consistent across pages (same action = same label)
- Error messages are consistent in style and tone
- Date/time/number formatting uses
IntlAPIs (not hardcoded formats) - Currency formatting matches locale
Phase 4: Hardcoded String Detection
Search all components, layouts, and pages for hardcoded user-facing strings:
- Text between HTML tags that isn't using
t()or translation function aria-label,placeholder,title,altattributes with hardcoded text- Strings in JavaScript/TypeScript that appear in the UI
For each: extract to the i18n system and translate.
Phase 5: Technical SEO for i18n
-
<html lang="xx">dynamically set per locale -
<link rel="alternate" hreflang="xx">on all pages for all locales -
<link rel="alternate" hreflang="x-default">points to default locale - Sitemap includes all locale URLs
-
og:localeset correctly per page - Canonical URLs are locale-specific (not all pointing to default)
- Meta title and description translated in every locale
Phase 6: Fix
Fix all issues in code. Priority:
- Missing translations — translate and add them
- Hardcoded strings — extract to i18n system
- Inconsistent terminology — standardize across all files
- Technical SEO — hreflang, lang, canonical, sitemap
- Formatting — dates, numbers, currencies using
Intl - French typography — espaces insécables
Phase 7: Report
TRANSLATION AUDIT: [project name]
═══════════════════════════════════════
I18N ARCHITECTURE
Framework: [approach used]
Locales: [fr, en, ...]
Default locale: [xx]
Routing: [prefix / domain / hybrid]
Language switcher: [present / missing]
COMPLETENESS (by locale)
FR: X/Y keys (Z missing)
EN: X/Y keys (Z missing)
...
CONTENT COLLECTIONS
Blog: X/Y articles in all locales
Docs: X/Y pages in all locales
...
CONSISTENCY
Terminology: X inconsistencies across Y terms
UI strings: [consistent / mixed]
Formatting: [Intl APIs / hardcoded / mixed]
HARDCODED STRINGS
Components: X strings to extract
Layouts: X strings to extract
Pages: X strings to extract
TECHNICAL SEO
hreflang: [complete / partial / missing]
Sitemap: [all locales / default only]
Meta tags: X/Y pages fully translated
PAGE-BY-PAGE
/ FR [A/B/C/D] EN [A/B/C/D]
/about FR [A/B/C/D] EN [A/B/C/D]
...
═══════════════════════════════════════
OVERALL [A/B/C/D]
Missing translations added: X
Hardcoded strings extracted: Y
Terminology standardized: Z terms
Technical fixes: W
Tracking (all modes)
Shared file write protocol for AUDIT_LOG.md and TASKS.md:
- First load
$SHIPFLOW_ROOT/skills/references/operational-record-format.md; new audit and task records must use that traffic-first operational format. - Treat the snapshots loaded at skill start as informational only.
- Right before each write, re-read the target file from disk and use that version as authoritative.
- Append or replace only the intended row or subsection; never rewrite the whole file from stale context.
- If the expected anchor moved or changed, re-read once and recompute.
- If it is still ambiguous after the second read, stop and ask the user instead of forcing the write.
After generating the report and applying fixes:
Log the audit
Create or update traffic-first audit operational records in the target audit logs:
- Project-local
shipflow_data/workflow/AUDIT_LOG.md: create or update a traffic-firstaudit:record for the Translate audit. - Project-local
./AUDIT_LOG.md: same project-explicit traffic-first record; keep the required[project]token.
Create either file if missing.
Update TASKS.md
- Local TASKS.md (project root): create or update traffic-first task records for the Translate audit findings.
- Project-local
shipflow_data/workflow/TASKS.md: find the project section and mirror the same traffic-first task records.
Important (all modes)
- Translate naturally. No Google Translate quality. Write like a native speaker of each locale.
- For French: tutoiement/vouvoiement per project CLAUDE.md, espaces insécables before : ; ! ? and around « », no unnecessary anglicisms.
- Brand names, product names, and technical terms that are universally known (API, URL, JavaScript, etc.) stay in English.
- When a project uses bilingual message templates (e.g.,
titleFr/titleEn), check BOTH fields for every entry. - For Astro content collections: check that the slug/ID linking between locales is correct — a French article must map to its English counterpart.
- Don't just flag missing translations — actually write the translation and add it.
- If you're unsure about a translation, propose 2 options and ask.
- Accents français obligatoires. Lors de toute création ou modification de contenu en français, vérifier systématiquement que TOUS les accents sont présents et corrects (é, è, ê, à, â, ù, û, ô, î, ï, ç, œ, æ). Les accents manquants sont une faute d'orthographe. Relire chaque texte produit pour s'assurer qu'aucun accent n'a été oublié — c'est une erreur très fréquente à corriger impérativement.