Localization: wire AI plural translation into the GlotPress reverse fold#25710
Draft
jkmassel wants to merge 2 commits into
Draft
Localization: wire AI plural translation into the GlotPress reverse fold#25710jkmassel wants to merge 2 commits into
jkmassel wants to merge 2 commits into
Conversation
Collaborator
Generated by 🚫 Danger |
a65c33b to
fd62b7f
Compare
Replace the ai_translate_plural -> nil stub with the AI tier. download_localized_plurals now builds AITranslator.with_anthropic once (gated on ANTHROPIC_API_KEY; absent => the prior English-fallback behavior, unchanged) and PluralStrings.fold_translations! invokes it once per (key, locale) with the whole form-set via translate_plural — keeping one consistent stem across forms — passing the human-translated forms as anchors. The fold's ai_translator contract changes from per-cell to per-form-set; a per-set API failure degrades to English (needs_review) instead of aborting the fold. Adds plural_strings_helper_test.rb covering provenance and the form-set/anchors contract; the nokogiri require is made lazy so that pure suite needs no gems (matches the no-bundle CI job).
Adds docs/localization-pipeline.md: the GlotPress + AI round trip, the human ?? AI ?? English floor, the AI tier (gating, placeholder gate, form-set plurals), and why regular-string MT is deferred to the String Catalog cutover — machine translations only ship from a state-bearing store (the catalog's needs_review), never from the live legacy .strings. Linked from AGENTS.md.
fd62b7f to
068fe82
Compare
4 tasks
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Wires the AI translation primitives from #25705 into the plural reverse fold — the live tier behind the
human ?? AI ?? Englishfloor — filling theai_translate_pluralstub #25688 left open.Stacked on #25705 (its primitives aren't on
trunkyet); the diff here is wiring + tests + docs only, and the base retargets totrunkonce #25705 merges. Draft to match #25705 and because the live fold wants a real download run to validate.Scope: plurals only
Plurals fold into
Plurals.xcstrings— a String Catalog with aneeds_reviewstate — which is built into the app but not consumed at runtime yet (no code reads it; plurals still render the legacy way). So the AI tier pre-populates the catalog for the plural cutover without shipping any machine-translated copy today.Regular strings are deliberately out of scope: they still ship from the legacy
Localizable.strings, where a machine translation would go live immediately — and we don't want machine-translated copy shipping before the catalog cutover. Regular-string MT waits for a catalog reverse-fold (same shape as plurals), where it can stage asneeds_reviewuntil cutover. The rationale is captured indocs/localization-pipeline.mdso it doesn't need re-explaining.Summary
download_localized_pluralsnow drivesAITranslatorinstead of thenilstub — gated onANTHROPIC_API_KEY(absent ⇒ unchanged English-fallback behavior) and run as a non-fatal step, so the AI tier can never break a release.translate_plural), with the human-translated forms as anchors — one consistent stem across the forms, not per-cell drift.plural_strings_helper_test.rb(picked up by Localization: AI translation primitives #25705's existingLocalization Tooling Unit TestsCI job);nokogirimade lazy so the suite needs no gems.docs/localization-pipeline.mddocuments the GlotPress + AI round trip end to end and why regular-string MT waits for the catalog.Form-set, not per-cell
PluralStrings.fold_translations!'sai_translatorcontract changed from per-cell to a per-(key, locale) form-set callable:AITranslator#translate_pluralimplements it directly —ai_translator: translator.method(:translate_plural). This is deliberately not the per-cellfor_pluraladapter #25705's notes floated: translating the whole set in one request is the fix for the synonym drift a per-category call structurally can't prevent (Polishsłowo→wyrazy→słów). A per-set API failure degrades to English (needs_review) rather than aborting the fold.Test plan
ruby fastlane/lanes/plural_strings_helper_test.rb— 10 (fold provenance + the form-set/anchors contract)fastlane/lanes/*_test.rbsuite green — 60 runsrubocopclean on all changed filesANTHROPIC_API_KEY+bundle install) on a real download — confirm quality before the plural cutoverRelated
ai_translate_pluralstub this fills)