feat(i18n): wire audit-translations into pnpm run verify
Wires the .agents/scripts/audit-translations.mjs script into the
existing pnpm run verify chain as the first gate. A `pt` field
identical to its `en` counterpart is how a bilingual site quietly
becomes monolingual — this script catches that before any other
check runs.
Added an allowlist mechanism: the script now reads a sibling
`.agents/scripts/audit-translations.allowlist.json` file. Entries
in the allowlist are listed in the output under "ALLOWED" and do
not fail the gate. Currently 18 entries: numeric card labels
("01"–"06") in chapters/landing.json and chapters/summary.json, the
"Skills" product noun on both, the "Brief" handoff step label in
chapters/agents.json, and the three model-tier series names in
providers/{claude,gemini,openai}.json.
Adding to the allowlist requires a deliberate edit + commit; future
translators can see the allowlist and understand which identicals
are intentional.
The verify chain order is now:
1. audit-translations.mjs — fail-fast on translation regressions
2. verify.mjs — content + interaction contracts
3. audit-ui.mjs — responsive / no-external-dep audit
4. check-tokens.mjs — design-token enforcement
Ownership notes:
- package.json is owned by the astro-architect agent per
.agents/rules/git-worktrees.md. The wiring in this commit is the
change the user explicitly asked for; the architect should review
the format on merge.
- scripts/verify.mjs is owned by the verification-engineer agent
per the same table. The pre-existing assertion that `package.json`
contains the literal verify-script string no longer matches once
`audit-translations.mjs &&` is prepended. This commit updates the
assertion from a strict `.includes()` substring check to a regex
that allows the optional translation-audit prefix while still
requiring the three core scripts (verify.mjs, audit-ui.mjs,
check-tokens.mjs) to run in order. The regex still rejects any
chain that drops one of them.
Verified by running pnpm run verify from the worktree — all four
checks pass with the translations from the prior five commits.
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
{
|
||||
"entries": [
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "agents.json",
|
||||
"field": "sections.1.steps.0.label",
|
||||
"reason": "Handoff step label (\"Brief\"); kept English by glossary convention."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "landing.json",
|
||||
"field": "cards.0.label",
|
||||
"reason": "Numeric card label (\"01\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "landing.json",
|
||||
"field": "cards.1.label",
|
||||
"reason": "Numeric card label (\"02\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "landing.json",
|
||||
"field": "cards.2.label",
|
||||
"reason": "Numeric card label (\"03\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "landing.json",
|
||||
"field": "cards.2.title",
|
||||
"reason": "Product noun (\"Skills\"); kept English by glossary convention."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "landing.json",
|
||||
"field": "cards.3.label",
|
||||
"reason": "Numeric card label (\"04\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "landing.json",
|
||||
"field": "cards.4.label",
|
||||
"reason": "Numeric card label (\"05\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "landing.json",
|
||||
"field": "cards.5.label",
|
||||
"reason": "Numeric card label (\"06\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "summary.json",
|
||||
"field": "cards.0.label",
|
||||
"reason": "Numeric card label (\"01\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "summary.json",
|
||||
"field": "cards.1.label",
|
||||
"reason": "Numeric card label (\"02\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "summary.json",
|
||||
"field": "cards.2.label",
|
||||
"reason": "Numeric card label (\"03\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "summary.json",
|
||||
"field": "cards.2.title",
|
||||
"reason": "Product noun (\"Skills\"); kept English by glossary convention."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "summary.json",
|
||||
"field": "cards.3.label",
|
||||
"reason": "Numeric card label (\"04\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "summary.json",
|
||||
"field": "cards.4.label",
|
||||
"reason": "Numeric card label (\"05\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "chapters",
|
||||
"file": "summary.json",
|
||||
"field": "cards.5.label",
|
||||
"reason": "Numeric card label (\"06\"); identical across locales by design."
|
||||
},
|
||||
{
|
||||
"collection": "providers",
|
||||
"file": "claude.json",
|
||||
"field": "title",
|
||||
"reason": "Model-tier series name (\"Opus · Sonnet · Haiku\"); kept English as product name."
|
||||
},
|
||||
{
|
||||
"collection": "providers",
|
||||
"file": "gemini.json",
|
||||
"field": "title",
|
||||
"reason": "Model-tier series name (\"Pro · Flash · Flash-Lite\"); kept English as product name."
|
||||
},
|
||||
{
|
||||
"collection": "providers",
|
||||
"file": "openai.json",
|
||||
"field": "title",
|
||||
"reason": "Model-tier series name (\"Sol · Terra · Luna\"); kept English as product name."
|
||||
}
|
||||
]
|
||||
}
|
||||
Reference in New Issue
Block a user