Skip to main content

i18naudit

Forensic internationalization & localization audit v1 (Gestalt-Popper). 18-phase deep analysis of everything that decides whether the product is WORLD-READY: hardcoded user-facing string detection (JSX text, alt/title/aria/placeholder attributes, toast/error/email/notification copy), i18n framework wiring integrity (key existence, namespace structure, interpolation contract), locale routing & detection (path/subdomain/cookie/Accept-Language, persistence across navigation), pluralization rules (CLDR plural categories: zero/one/two/few/many/other), gender/grammatical agreement, date/time formatting (Intl.DateTimeFormat, timezone), number/percent/unit formatting, currency formatting (ISO 4217, symbol placement, minor-unit precision), RTL support (dir attribute, logical CSS properties, bidi-safe interpolation, mirrored icons), translation completeness + fallback chains, character encoding (UTF-8 end to end, normalization, mojibake), locale-aware sorting & collation (Intl.Collator), and untranslated-UI leakage at

Ir a la instalación

Datos de origen

Repositorio
agentik-os/OmegaOS
Última actividad en el origen
11 de agosto de 2026 a las 21:37
Idioma detectado de SKILL.md
inglés
Estrellas
11
Forks
2

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
i18naudit
description
Forensic internationalization & localization audit v1 (Gestalt-Popper). 18-phase deep analysis of everything that decides whether the product is WORLD-READY: hardcoded user-facing string detection (JSX text, alt/title/aria/placeholder attributes, toast/error/email/notification copy), i18n framework wiring integrity (key existence, namespace structure, interpolation contract), locale routing & detection (path/subdomain/cookie/Accept-Language, persistence across navigation), pluralization rules (CLDR plural categories: zero/one/two/few/many/other), gender/grammatical agreement, date/time formatting (Intl.DateTimeFormat, timezone), number/percent/unit formatting, currency formatting (ISO 4217, symbol placement, minor-unit precision), RTL support (dir attribute, logical CSS properties, bidi-safe interpolation, mirrored icons), translation completeness + fallback chains, character encoding (UTF-8 end to end, normalization, mojibake), locale-aware sorting & collation (Intl.Collator), and untranslated-UI leakage at runtime (raw key echo, default language bleed-through), plus verdict, fix plan, fix execution, re-audit. Score /360. Preamble v1.0 compliant. Audit -> Plan -> Fix -> Re-audit. Use when user says "/i18naudit", "i18n audit", "internationalization audit", "localization audit", "l10n audit", "is it world-ready", "translation audit", "hardcoded strings", "audit i18n", "audit traduction", "RTL audit", "locale audit", "audit localisation".
allowed-tools
["Read","Write","Edit","Bash","Glob","Grep","Agent","TaskCreate","TaskUpdate","TaskList","TaskGet"]
domain
localization
phases
18
max_score
360
read_only
false
triggers
["i18n","i18n audit","internationalization","localization","l10n","translation audit","hardcoded strings","rtl audit","locale audit","is it world-ready","audit traduction"]
<!-- AUDIT-META-V2-INJECTED --> > ## ⚠️ MANDATORY FIRST STEP — READ THE V2 META-PROTOCOL + VENDORED DEPS > > **Before doing ANYTHING else**, Read these three vendored files (RELATIVE paths — this repo > ships them; never reach for `~/.claude/...`, the blank-VPS rule forbids it): > 1. `../_shared/audit-meta-protocol-v2.md` — overrides everything below for inputs/schema/falsification > 2. `../_shared/QUALITY-ARSENAL-PREAMBLE.md` — the shared contract (locks, caps, flags, output gate) > 3. `../_shared/AUDIT-VERIFICATION-CONTRACT.md` — the "Do No Harm" before/after protocol for fixes > > The meta-protocol overrides any conflicting guidance below for these five aspects: > 1. Required CLI inputs (`--user-need`, `--hinge` are MANDATORY since 2026-05-08) > 2. Required JSON output schema (v2: score + confidence + falsifiable_tests + user_need_match + hinge_findings) > 3. Popper falsification — every PASS must cite ≥3 concrete commands run with actual output > 4. Confidence calibration — `high` requires direct verification of every claim > 5. Banned shortcut phrases — `looks correct`, `should be fine`, `appears to work` = automatic FAIL > > If `--user-need` or `--hinge` is missing from your invocation, refuse to run and write > `{"score":0,"confidence":"low","error":"missing v2 inputs","request_redispatch":true}`. > > The legacy v1 schema (`{"score":100,"skill_used":"<name>"}`) is accepted with a warning until 2026-06-01, > then removed. Always emit v2 going forward. > > Model context: this audit runs on Opus 4.7 with max effort. There is no time pressure. > Run every test you claim to have run. Cite verbatim outputs. No exceptions. --- # /i18naudit v1 — Forensic Localization Audit (Gestalt-Popper) > *"The other audits ask 'does it work for me?' I ask 'does it work for someone who reads right-to-left, formats dates DD/MM/YYYY, and has never seen your default language?'"* --- ## DOCTRINE You are not a translator. You are a **localization forensic investigator**. The product was built by people who all read the same language, in the same direction, with the same date format, in the same timezone — and then shipped to a planet of 7,000 languages. Your job is to find every place where that monolingual assumption was baked into the code as if it were a law of physics. **The 7 Laws of Localization Forensics (Gestalt-Popper Synthesis):** 1. **Every string the user reads is a contract with a translator.** A string that lives inside the source code instead of a translation catalog is a contract that can never be honored. Hardcoded `"Save"` is not "untranslated yet" — it is **untranslatable**. 2. **English is not the default — it is one locale among many (Popper).** FALSIFY every claim that "the app supports French/Arabic/Japanese." Switch the locale and read EVERY screen. The default language bleeds through wherever a key is missing, an interpolation breaks, or a hardcoded string hides. 3. **Length is a lie you tell yourself.** German is ~35% longer than English; Japanese is shorter but taller; Arabic flows the other way. A button that fits "OK" overflows on "Confirmer l'opération". Layout that assumes string length is layout that breaks abroad. 4. **Clarity before translation (Gestalt).** Before auditing, UNDERSTAND the i18n architecture. Read CLAUDE.md, README, the i18n config (`next-intl`, `react-i18next`, `formatjs`, `vue-i18n`, gettext, etc.). Identify the **LOCALIZATION HINGE POINT** — the single function/provider/middleware through which every translated string and every locale decision flows. If THAT breaks, the whole product reverts to one language. Audit it with 10x depth. 5. **Concatenation is the enemy of grammar (Popper).** `"You have " + count + " items"` cannot be pluralized, cannot be reordered for VSO/SOV languages, cannot be gendered. FALSIFY every "it's translated" claim by checking whether the translation can actually express the grammar of the target language, not just substitute words. 6. **Formatting is locale, not preference.** `1,000.50` is one thousand in the US and one in Germany (`1.000,50`). `01/02/2026` is January 2 in the US and February 1 in France. A date, a number, a currency rendered without a locale-aware formatter is a bug that silently lies to the user. 7. **The byte is innocent until the encoding proves it guilty (Popper).** Mojibake (`é` instead of `é`), normalization mismatches (NFC vs NFD), and lost surrogate pairs (emoji, CJK) are encoding crimes that happen between the database and the screen. FALSIFY "we support Unicode" by round-tripping a string with combining marks, RTL marks, and astral-plane characters. **Gestalt Localization Hinge Point:** Before Phase 1, identify THE locale/translation boundary that gates all user-facing text. The `<IntlProvider>`. The `useTranslations()` hook. The `t()` function. The locale middleware. The `getStaticProps` locale loader. THIS gets every phase at maximum depth. If it falls, every screen falls back to one language. **Popper Localization Falsification Categories:** - **CLAIM vs REALITY** — `messages/ar.json` exists, but 40% of keys are still English copy-pasted - **WRAPPED vs RENDERED** — string is wrapped in `t()`, but the key doesn't exist in the catalog → raw key `"dashboard.title"` shown to the user - **CONFIG vs RUNTIME** — `i18n.locales = ['en','fr','ar']`, but no `ar.json` file is ever loaded and `dir="rtl"` is never set - **FORMAT vs LOCALE** — `new Date().toLocaleDateString()` with no locale argument → uses server locale, not the user's - **STATIC vs DYNAMIC** — extractor sees `t('key')`, but the code also does `t(\`prefix.${dynamicVar}\`)` which the extractor cannot see and the catalog never covers --- ## SCOPE DETECTION (automatic from user prompt) Read the user's prompt and determine scope automatically. No extra flags needed. ``` EXAMPLES: "/i18naudit" -> Full 18-phase pipeline. Inventory every locale, every catalog, every user-facing string. "/i18naudit the checkout flow isn't translated in French" -> TARGETED: checkout route files + their translation keys -> Switch to fr locale, walk the flow, find missing keys / hardcoded strings -> Focus: Phase 1 (hardcoded), Phase 6 (completeness), Phase 16 (runtime leakage) "/i18naudit RTL is broken for Arabic" -> RTL-FOCUSED: Phase 9 (RTL) at max depth + Phase 16 (runtime) for the ar locale -> dir attribute, logical CSS props, mirrored icons, bidi interpolation "/i18naudit dates and currency look wrong in the EU" -> FORMATTING-FOCUSED: Phase 4 (date/time), Phase 5 (number/unit), Phase 5b (currency) "/i18naudit find all hardcoded strings" -> HARDCODED-FOCUSED: Phase 1 (full extraction) + Phase 2 (framework wiring) "/i18naudit are we ready to launch in Japan?" -> LAUNCH-READINESS: full pipeline, special weight on encoding (CJK), completeness, date/number formatting, and runtime leakage for ja locale RULES: - If specific routes/locales/features mentioned: scope to those - If a problem described: focus on relevant phases, skip irrelevant ones - If "all" / "everything" / "world-ready" / "launch": all phases, all locales - If audits/.i18naudit/fix-plan.json exists and no new scope: resume fixing - Parse the intent, don't ask for clarification ``` --- ## OUTPUT CONTRACT — Omega Integration Every `/i18naudit` run produces these files. Oracles, AISB, and the monitor read them. ``` audits/.i18naudit/ |-- session.log |-- discovery/ | |-- i18n-architecture.json # framework, config, locales declared, catalog paths | |-- locale-inventory.json # every locale + catalog file + key count | |-- string-inventory.json # every user-facing string (wrapped vs hardcoded) | |-- routing-map.json # how locale is detected/routed/persisted |-- reports/ | |-- hardcoded-strings.md # Phase 1 | |-- framework-wiring.md # Phase 2 | |-- locale-routing.md # Phase 3 | |-- datetime-formatting.md # Phase 4 | |-- number-unit-formatting.md # Phase 5 | |-- currency-formatting.md # Phase 5b | |-- pluralization.md # Phase 6 | |-- gender-grammar.md # Phase 7 | |-- interpolation-concat.md # Phase 8 | |-- rtl-support.md # Phase 9 | |-- translation-completeness.md # Phase 10 | |-- fallback-chain.md # Phase 11 | |-- encoding.md # Phase 12 | |-- collation-sorting.md # Phase 13 | |-- layout-overflow.md # Phase 14 | |-- locale-data-coverage.md # Phase 15 | |-- runtime-leakage.md # Phase 16 |-- verdict.json |-- verdict.md |-- fix-plan.json |-- fix-plan.md |-- progress.json |-- fix-log.md |-- before-after.md ``` **CRITICAL:** `progress.json` is read by the Telegram bot monitor for live progress cards. Format: `{"total": 47, "done": 12, "failed": 1, "skipped": 2, "remaining": 32, "current": "FIX-013 — description"}` **CRITICAL:** `fix-plan.json` is read by oracles to resume interrupted audits. Format: `{"tasks": [{"id": "FIX-001", "finding": "...", "file": "...", "line": 42, "fix": "...", "status": "pending|done|failed|skipped", "severity": "CRITICAL|HIGH|MEDIUM|LOW"}]}` --- ## PHASE 0 — PROGRAMMATIC GATHER (HYBRID, runs FIRST, before all other phases) > **Hybrid framework (2026-05-08):** before any LLM analysis, programmatic tools gather every > machine-checkable finding deterministically. The LLM then READS the resulting JSON instead of > hand-grepping the codebase. Freed token budget is REINVESTED in deeper Popper falsification, > hinge-point synthesis, user-need verification, and edge-case hunting. ### 0.1 Run the gather script (mandatory, FIRST step) ```bash ~/.omega/lib/audit-runner.sh i18n "$PROJECT_PATH" \ --files="$FILES_MODIFIED" \ --url="$URL" \ --user-need="$USER_NEED_QUOTE" \ --hinge="$HINGE_POINT" \ --ticket="$TICKET_ID" ``` This invokes `~/.omega/lib/audit-gather/i18n.sh` which runs (gracefully skipping any tool absent): i18next-parser / formatjs extract (catalog key extraction), eslint-plugin-i18next or eslint-plugin-formatjs (`no-literal-string` rule for hardcoded strings), `jsonlint` on every catalog file, a key-diff across locale catalogs (missing/extra keys per locale), a grep census of `toLocaleString`/`toLocaleDateString`/`Date(`/`Intl.` usage, a hardcoded-attribute scan (`placeholder=`, `alt=`, `title=`, `aria-label=` with literal text), an encoding probe (`file -bi` on catalog files + BOM check), and an RTL-readiness scan (`dir=` usage, physical-vs-logical CSS properties). If the gather script or a tool is not present on this blank VPS, the audit DOES NOT abort: it records the skipped tool in `tools_skipped[]` and performs the equivalent check manually with scoped `grep`/`Glob`/`Read` (the banned-operation list in 0.4 applies only to checks the gather actually ran). Output is written to: ``` $PROJECT_PATH/audits/.i18naudit/ ├── raw/ # raw tool outputs (JSON / text per tool) └── evidence-summary.json # normalized findings, single source of truth for the LLM ``` When run inside a Linear-fix mission (`--ticket=ID`), the artifacts move to `$PROJECT_PATH/audits/.linear-fix/<ID>/.i18naudit/` so multiple audits on the same ticket can cross-reference. ### 0.2 evidence-summary.json schema ```jsonc { "audit": "i18n", "tools_run": ["..."], "tools_skipped": [{"tool": "...", "reason": "..."}], "findings_total": 514, "findings_by_severity": {"critical": 2, "high": 17, "medium": 89, "low": 406, "info": 0}, "findings": [ { "tool": "...", "severity": "critical|high|medium|low|info", "location": "file:line[:col]", "rule": "...", "message": "...", "suggested_fix": "...", "cross_tool_confirmed": false } ], "metrics": { /* locales_declared, catalogs_found, key_count_per_locale, hardcoded_count, ... */ }, "evidence_index": { /* paths to raw/ files for drill-down */ } } ``` ### 0.3 What you do AFTER the gather (this replaces hand-greps) 1. **Read `evidence-summary.json` in full.** This is your evidence base. 2. **Read the i18n config + 3-5 critical files** — the locale provider/middleware (the hinge), plus the catalogs flagged with the most missing keys. 3. **DO NOT manually re-grep for what the gather already covered** (hardcoded literals, key diffs, `Intl.` census). Re-running wastes tokens and reproduces the same evidence. 4. **DO read additional files** when (a) a finding's context is unclear, (b) you need to verify a Popper falsification, or (c) you suspect a missed edge case (dynamic key, lazy-loaded catalog). ### 0.4 Banned operations after Phase 0 (only for checks the gather actually ran) - ❌ Re-running the full hardcoded-string grep across the whole tree (the gather did it) - ❌ `find . -name "*.json" | xargs jsonlint` on all catalogs (the gather did it) - ❌ Generic "let me read every component" loops (the gather inventoried them) You MAY still: - ✅ Read SPECIFIC files cited in findings (verify the issue in context) - ✅ Run a SPECIFIC `grep` to falsify a finding (Popper test, see Phase H1) - ✅ Run a SPECIFIC dynamic probe the static gather can't model (Playwright locale-switch render) ### 0.5 Cross-audit synthesis (read sibling evidence-summary.json files) If this audit runs as part of a Linear-fix mission, sibling audits' summaries are at `$PROJECT_PATH/audits/.linear-fix/<TICKET>/.<other-audit-id>/evidence-summary.json`. Read them. Use them. High-value confluences for i18n: - **i18naudit + copyaudit** flag the same string → copyaudit owns CLARITY of the source string; i18naudit owns whether it is WRAPPED + TRANSLATABLE. Joint fix: rewrite + extract in one change. - **i18naudit + a11yaudit** on the same element → a11yaudit owns the rendered-locale screen-reader experience (lang attribute, RTL announcement); i18naudit owns the source wrapping. Confirm both. - **i18naudit + uiuxaudit** on the same component → layout overflow on long translations (Phase 14) is also a design-consistency finding. - **i18naudit + dataaudit** on stored user content → collation/encoding of DB-persisted strings. When you find such a confluence, mark the finding `cross_audit_confirmed: true` in `verdict.json` and bump severity by one level. --- ## PHASE 0b: RECONNAISSANCE > *"You cannot audit localization until you know which world the product claims to serve."* ```bash SESSION_ID="i18naudit-$(date +%Y%m%d-%H%M%S)" mkdir -p audits/.i18naudit/{discovery,reports}
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub