Skip to content

History / Adding a Language Developer Guide

Revisions

  • Adding a language: what Bahasa Melayu taught, and who the script is actually for Four additions, all from doing ms (24th locale) rather than from theory. WHO THE SCRIPT IS FOR. The page reproduced a Claude Code workflow as though it were the process. It is not: Workflow/agent/pipeline are harness APIs, so a contributor without Claude Code could not run a line of it, and it carried the maintainer's own machine path. Now split explicitly -- the PROMPT and the VERIFICATION are the reusable artefacts and work for a human translator, another tool or an agency; the orchestration is one maintainer's tooling. Paths generalised. MODEL GUIDANCE. Run the agents on Sonnet, not Opus: the failure modes that matter are instruction-following, and step 3 catches every one mechanically, so the larger model buys quality where it cannot show. ms was done this way with zero structural faults. And use ONE model for the whole locale -- mixing them risks an inconsistent register within a single language, which is worse than either alone. TICKETS IS TOO BIG FOR ONE AGENT. At ~1,550 keys a single agent spent twenty minutes WITHOUT EVER ATTEMPTING A WRITE -- it read the source, then went grepping its sibling locale files to see how "Save" and "Delete" had already been translated, then started a task list about terminology. Not a crash, not a hang, not a truncated file: the transcript kept growing, and the tell was writes=0 after twenty minutes while its siblings finished in two. The fix is three changes, all needed: split by top-level section into six chunks that write fragments; HAND the agent lang/<code>/common.php as the only consistency reference so there is nothing to go looking for; and tell it plainly not to research, naming the failure. CHECK 5 — SIBLING-LANGUAGE DRIFT. New, and no structural check can ever catch it: a translator drifts between closely related languages while the file parses, every key is present and every placeholder survives. Applies to ms/id, nb/nn, and any Iberian or Serbo-Croatian variants added later. The defence is a word list used twice -- as a "use this NOT that" table in the prompt, and as a grep afterwards. For ms/id the decisive marker is bisa vs boleh: ms came out 432 boleh, zero bisa. Also records banning false friends outright -- "kereta" is car in Malay and train in Indonesian, the class of error that produces confident nonsense. Plus two smaller ones in step 4: update the README language count (a number in prose, so nothing reports it stale), and register the locale LAST on a live install, because a file mid-write is unparseable and a registered locale with an unparseable file is a fatal rather than a fallback.

    @edmozley edmozley committed Aug 8, 2026
  • Add the 'Adding a Language' developer guide, and refresh the locale list The workflow script that translated all 23 modules into pt-BR lived in a session temp directory and was deleted with that session, so the next language had to start by rewriting it from memory. The script is now reproduced in full, along with the two non-obvious decisions in it (no StructuredOutput, because it failed silently on files over ~350 keys; pt-BR as a structural template only) and the four verification checks — the placeholder one especially, since a key can pass both the count and the set check and still be broken. Internationalisation: the locale table said 20 and had never listed uk. Now 23, with nb and nn added.

    @edmozley edmozley committed Aug 7, 2026