Fix release for 1.1.1: the minimal path end to end, engine commands that run on Godot, Unity and Unreal, hook warnings you can see, and verdicts that say when they could not check. Details in CHANGELOG.md; upgrade steps in UPGRADING.md (v1.1.1 → v1.1.2). Fixes #67 Fixes #131 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01WuJn2FdynEybfL5KC697nJ
10 KiB
Skill Test Spec: /localize
Skill Summary
/localize runs the localization pipeline through one required subcommand:
scan, extract, validate, status, brief, cultural-review,
vo-pipeline, rtl-check, freeze or qa. It works on a single source string
table under assets/data/strings/ (strings-en.json is the English source; the
other locales sit beside it) and writes reports under production/localization/.
scan, validate and status are read-only. extract shows a diff of new
keyed entries and asks "May I write these new entries to
assets/data/strings/strings-en.json?" before appending only the diff; its
verdict is COMPLETE. With no subcommand the skill prints usage and stops with
verdict FAIL — missing required subcommand. A scan whose code root cannot be
resolved reports NOT ASSESSED — code root unresolved; a status run with no
string table reports NOT ASSESSED — no string table found. cultural-review
and qa spawn localization-lead; qa issues a per-locale
PASS / PASS WITH CONDITIONS / NOT ASSESSED / FAIL verdict, first match FAIL →
NOT ASSESSED → PASS WITH CONDITIONS → PASS. Its checks are playthrough-based, so a
locale nobody has played is NOT ASSESSED, and the release gate does not count it
as passed. No director gates apply.
Static Assertions (Structural)
Checked against the SKILL.md by /skill-test spec — no fixture needed.
- Has required frontmatter fields:
name,description,argument-hint,user-invocable,allowed-tools - Has ≥2 phase headings
- Contains verdict keywords: COMPLETE, FAIL, NOT ASSESSED, PASS WITH CONDITIONS
- Contains "May I write" collaborative protocol language before writing the string table or a report
- Has a next-step handoff (the Recommended Workflow chain ending in
/gate-check release) - The QA gate note is tiered: at
workflow: fullthe Polish → Release gate requires PASS or PASS WITH CONDITIONS for every translated locale being shipped (recommended atstandard, dropped atminimal) - The
freezequestion names the file it writes — "This writesproduction/localization/freeze-status.md" — before the user answers
Director Gate Checks
None. /localize is a pipeline utility and spawns no director. The only agent
it spawns is localization-lead (an operations-tier agent), and only in the
cultural-review and qa modes.
Test Cases
Case 1: Extract — New Strings Keyed and Appended After Approval
Fixture:
project.yamlhasengine.name: Godot, so the code root issrc/src/ui/hud.gdwraps three strings intr()that have no entry inassets/data/strings/strings-en.json- No
production/localization/freeze-status.mdexists
Input: /localize extract
Expected behavior:
- Skill scans source files for localized string references and compares them
against the table in
assets/data/strings/ - Skill proposes one new entry per unkeyed string, with a key in the form
[category].[subcategory].[description](e.g.ui.hud.health_label) - Each new entry carries a
contextfield: where it appears, maximum length, placeholder meaning - Skill presents the diff and asks "May I write these new entries to
assets/data/strings/strings-en.json?" - On approval it writes only the new entries (not a full replacement); verdict is COMPLETE
Assertions:
- Proposed keys follow
[category].[subcategory].[description] - Every new entry includes a
contextfield - The diff is shown and "May I write" names
assets/data/strings/strings-en.jsonbefore any write - Only the three new entries are written — existing entries are not rewritten
- Verdict is COMPLETE
Case 2: No Subcommand — Usage and FAIL
Fixture:
- Any project state
Input: /localize
Expected behavior:
- Skill finds no subcommand in the argument
- Skill outputs usage (the ten modes) and stops
- Verdict is FAIL — missing required subcommand
Assertions:
- Usage listing the available modes is printed
- Verdict is FAIL with the reason "missing required subcommand"
- No scan, extract or validation work is performed
- No file is written and no "May I write" ask appears
Case 3: Validate — Gaps Reported by Locale, Nothing Written
Fixture:
assets/data/strings/holdsstrings-en.json,strings-fr.jsonandstrings-de.jsonstrings-de.jsonlacks 4 keys present in the English source- One French entry omits the
{playerName}placeholder its English source has
Input: /localize validate
Expected behavior:
- Skill reads every string table file in
assets/data/strings/ - For
deit reports the 4 keys as Completeness gaps - For
frit reports a Placeholder mismatch on the affected key - Results are grouped by locale and severity
- Skill writes nothing — validate is read-only
Assertions:
- The 4 missing keys are named and attributed to the
delocale - The placeholder mismatch is reported against the
frlocale and its key - Output is grouped by locale and severity
- No file is written or modified, and no "May I write" ask appears
Case 4: Status With No String Table — NOT ASSESSED
Fixture:
assets/data/strings/does not exist
Input: /localize status
Expected behavior:
- Skill looks for the source string table and finds none
- The whole status output is
NOT ASSESSED — no string table found - Skill does not produce a coverage matrix of zeros, and does not pre-fill the
source row as
100%
Assertions:
- Output is
NOT ASSESSED — no string table found - No coverage matrix with zero counts is produced
- The source locale is not reported as
100%coverage - No file is written (status is read-only)
Case 5: Director Gate Check — None; Cultural Review Uses localization-lead
Fixture:
assets/data/strings/strings-en.jsonexists with player-facing strings- Any review mode
Input: /localize cultural-review
Expected behavior:
- Skill spawns
localization-leadto audit strings and assets for cultural sensitivity - Findings are presented as a table with a severity of BLOCKING, ADVISORY or NOTE per finding
- Skill asks "May I write this cultural review report to
production/localization/cultural-review-[date].md?" - No director agent is spawned and no gate ID appears in output
Assertions:
localization-leadis the only agent spawned- No director gate (creative, technical, producer, art) is invoked and no gate skip message appears
- Each finding carries BLOCKING, ADVISORY or NOTE severity
- "May I write" names
production/localization/cultural-review-[date].mdbefore the report is written
Case 6: Scan With an Unresolved Code Root — NOT ASSESSED, never "no hardcoded strings"
Fixture:
project.yamlhas noengine.name;.claude/docs/technical-preferences.mdreads[TO BE CONFIGURED]- Both
src/andAssets/exist and hold UI code with hardcoded strings (ambiguous tree)
Input: /localize scan
Expected behavior:
- Skill tries to resolve the code root and cannot (no engine, two candidate roots)
- It reports
NOT ASSESSED — code root unresolvedfor the hardcoded-string search and says which checks did not run - It does not guess
src/, and does not report zero hits or "no hardcoded strings found" — that would read as "nothing to localize" - Nothing is written — scan is read-only
Assertions:
- Output reads
NOT ASSESSED — code root unresolvedfor the code search - No "no hardcoded strings" or zero-hit result is reported
- The code root is not assumed to be
src/ - No file is written and no "May I write" ask appears
Case 7: QA on a Locale Nobody Has Played — NOT ASSESSED
Fixture:
assets/data/strings/strings-en.jsonandstrings-fr.jsonexist and validate cleanly- No one has played the French build: there are no in-game observations for the functional, overflow, contextual-accuracy or VO checks
Input: /localize qa
Expected behavior:
- Skill spawns
localization-leadfor the QA plan - The playthrough-based checks have no results, and no BLOCKING finding is open, so the French verdict is NOT ASSESSED, naming each check that did not run
- The verdict is not PASS or PASS WITH CONDITIONS on the strength of the string tables alone
- Skill asks "May I write this localization QA report to
production/localization/loc-qa-fr-[date].md?"; the report says the locale has not passed QA for the release gate
Assertions:
- The French Status is NOT ASSESSED, with the unrun checks named
- No PASS or PASS WITH CONDITIONS is issued for an unplayed locale
- "May I write" names the loc-qa report path before it is written
- The report does not present the locale as cleared for the Polish → Release gate
Protocol Compliance
- Stops with usage and verdict FAIL when no subcommand is given
scan,validateandstatuswrite no files- Asks "May I write" with the target path before writing the string table (extract) or any report (brief, cultural-review, vo-pipeline script, rtl-check, qa)
- Extract writes only the diff of new entries, never a full replacement of the table
- Reports NOT ASSESSED instead of zero results when the code root or the string table is missing
qaissues PASS, PASS WITH CONDITIONS, NOT ASSESSED or FAIL per locale, first match FAIL → NOT ASSESSED → PASS WITH CONDITIONS → PASS- Ends with the Recommended Workflow chain /
/gate-check releasehandoff
Coverage Notes
scanwith a resolved code root (findings with file paths and line numbers) is not separately tested; Case 6 covers the unresolved root.extractwhilefreeze-status.mdshows Status: ACTIVE (new keys appended to## Post-Freeze Changeswith a freeze-violation warning) is not tested.freeze(pre-freeze checklist andAskUserQuestion[A]/[B]),brief,vo-pipelineandrtl-checkare not exercised by a dedicated case;qais covered only for its NOT ASSESSED branch (Case 7).- The
qagate note — a FAIL blocks release for that locale only — needs a live run with multiple locales to verify.