Locales & the contribution model
A Turkish name should sound Turkish; a German address should follow German format. But you don't want a separate "Turkish name generator" and "German name generator" — you want one name generator whose data changes by locale.
Data is separate from the generator
Generators never embed data. They reference an asset by a logical name (person.first_names, coin.flip). A resolver maps (asset, locale) → data. The generator is locale-agnostic; the locale picks the data.
generator first_name → model, source "person.first_names" ← one definition
asset person.first_names
├─ tr_TR → models/tr/first_names.ngram
├─ en_US → models/en/first_names.ngram
└─ de_DE → models/de/first_names.ngramLocales are contributed, not owned
Crucially, the generator does not own a list of locales. Any package can contribute (asset, locale) data — so a generator that shipped with only German and English data can gain Turkish and Dutch from a completely separate, data-only package, without anyone editing the generator.
@phony/coin provides coin.flip for de, en
@alice/coin-trnl contributes coin.flip for tr, nl ← separate repo, generator untouchedThis is the opposite of hard-coding a { locale → data } map inside the generator (which is what the old approach did, and why it couldn't be extended).
Resolution: a chain, most-specific first
The active locale is really a chain walked top to bottom, with a locale-independent (*) fallback:
["@yourco/internal", "tr_TR", "base"]
│ │ └─ universal defaults (uuid, http, iso codes)
│ └─ Turkish names, cities, address formats
└─ your company's overridesSo you inherit Turkish data, override only what you need, and fall back to base for anything universal.
Three layers
Locale packages stack in three layers — base (universal) → locale (language-specific) → domain (your overrides) — each adding or replacing what the one below provides. The full design, including the locale_independent flag, is in the Locale System spec.
To wire locale data in code, see The engine → phony-pdl: Assets & locales.