Generator × Asset × Locale × Repo Matrix
This is the combination contract: every generator type, every data-source (asset) kind, their locale behaviour, their tier, the cross-cutting features they support, and every way they can be split across repositories. If a combination appears here, the architecture commits to supporting it.
Status: this documents the target design surface — the contract the engine and the OSS runtimes implement against. Build progress lives in the repo's
BUILD-LOG.md, not here.
The unified model in one breath
- Everything is a generator. The "seven types" are first-party generators, not a closed enum — the set is open (see Generator Types).
- Data is an asset, not code. Lists are JSON, models are the portable
.ngrambinary. A generator references an asset; it never embeds language data. - Locale is a resolution axis, not an identity. An asset has one scoped name (
@phony/person:first_names);tr_TR/en_US/de_DEare contributions to it, resolved through thedomain > locale > basechain. - Three tiers preserve cross-runtime determinism. Tier 0 primitive kernel (native in every runtime), Tier 1 composition (pure data + PEL), Tier 2 WASM (rare imperative escape hatch).
- Distribution is open. Any package can contribute generators, assets, or locale data; the main generator stays fixed while third parties add locales in separate data-only repos.
Legend: 🌍 multilingual (locale-bound asset) · ⚪ universal (locale-independent) · ➖ no data source
1. Generator catalog (all types, all variants)
| Type | Variants / algorithms / modes | Data binding | Locale | Tier |
|---|---|---|---|---|
| Logic | uuid_v4 uuid_v7 ulid nanoid int_between float_between boolean datetime_between date_between time_between timestamp sequence gaussian exponential | ➖ algorithm | ⚪ | 0 |
| List | simple · weighted · object-with-metadata | asset or inline | 🌍 or ⚪ | 0 + asset |
| Model (N-gram) | word sentence text paragraph poem acrostic real_word | .ngram asset | 🌍 | 0 + asset |
| Template | single pattern · weighted variants · operations | references + own variant patterns | 🌍 when refs/patterns are | 1 |
| Statistical | categorical continuous algebraic multivariate; distributions normal lognormal exponential uniform poisson beta gamma; differential_privacy (laplace/gaussian/exponential) | inline params; categorical weights may be locale/domain | ⚪ mostly; weights may be 🌍 | 0 distributions · 1 algebraic/multivariate |
| Linked | geo · person · financial · product | linked multi-column asset or rules | geo/person 🌍 · financial ⚪ | 1 + asset |
| Event Sequence | base after delay probability distribution condition | ➖ chronology | ⚪ | 1 |
Key invariant: locale-dependence is a property of the asset a generator binds to, not of the generator type. The same list generator is 🌍 with cities and ⚪ with http_methods. For template, the "data source" is its locale-scoped variant patterns (Turkish address format ≠ French), not a file.
2. Cross-cutting feature matrix (all features)
Which feature applies to which generator type.
| Feature | Logic | List | Model | Template | Statistical | Linked | Event Seq |
|---|---|---|---|---|---|---|---|
| Weighted selection | – | ✓ | – | variant weights | ✓ categorical | – | – |
| Constraints (min/max length, prefix) | range | – | ✓ | – | min/max | – | – |
unique modifier | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | – |
nullable modifier | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ (optional events) |
transform (PEL post-op) | ✓ | ✓ | ✓ | ✓ (operations) | ✓ | ✓ | ✓ |
| Consistency (table/entity/global) | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| FPE for PK/FK | ✓ (keys) | ✓ | ✓ | ✓ | – | – | – |
| Linking participation | – | ✓ | – | ✓ | – | ✓ (is) | – |
| Differential privacy | – | – | – | – | ✓ | – | – |
locale_independent opt-out | ✓ | ✓ | (rarely) | depends | ✓ | financial | ✓ |
All generators flow through the same uniform envelope
{use, params, constraints, modifiers}, so the modifier pipeline (unique/nullable/transform) is available to every type without each reinventing it.
3. Data source (asset) catalog
🌍 Multilingual assets — one scoped name, many locale contributions
| Asset kind | Examples (logical names) | Format |
|---|---|---|
Model (.ngram) | person.first_names person.last_names person.full_names business.company_names address.street_names usernames product_names slogans | portable binary |
| List | geo.cities geo.districts geo.neighborhoods geo.regions person.titles person.suffixes address.street_suffixes address.building_types commerce.* | JSON array |
| Template (patterns) | person.full_name address.street_address address.full_address contact.phone contact.email | pattern set |
| Linked (multi-column) | geo.locations (city+district+country+postal+coords+phone_prefix+currency) person.names_with_gender | JSON records |
⚪ Universal assets — never multilingual
| Asset kind | Examples |
|---|---|
| List (standards) | internet.http_methods http_status_codes mime_types tlds · standards.iso_countries iso_currencies iso_languages timezones · tech.file_extensions protocols |
| None | all Logic, all Event Sequence, Statistical distributions, Linked.financial (pure math) |
Combination space: every 🌍 asset × {tr_TR, en_US, de_DE, fr_FR, az_AZ, …}. The asset is one extension point; each locale is an independent contribution to it.
4. Master combination matrix
For each generator, which data-binding modes it allows, its locale behaviour, its tier, and which repo-distribution patterns (§5) can carry it.
| Generator | Inline | Asset | Refs | None | Locale | Tier | Repo patterns |
|---|---|---|---|---|---|---|---|
| Logic | – | – | – | ✓ | ⚪ | 0 | A, C |
| List (universal) | ✓ | ✓ | – | – | ⚪ | 0 | A, C, D |
| List (multilingual) | ✓ | ✓ | – | – | 🌍 | 0 | B, D, E, F, G, H |
| Model | – | ✓ | – | – | 🌍 | 0 | B, D, E, F, G, H |
| Template | ✓ (patterns) | – | ✓ | – | 🌍/⚪ | 1 | B, C, D, F, H |
| Statistical (dist) | ✓ | – | – | – | ⚪ | 0 | A, C |
| Statistical (categorical) | ✓ | ✓ (weights) | – | – | ⚪/🌍 | 0 | A, C, E, H |
| Statistical (algebraic/mv) | ✓ | – | ✓ | – | ⚪ | 1 | A, C |
| Linked (geo/person) | – | ✓ | ✓ | – | 🌍 | 1 | B, D, E, F, G, H |
| Linked (financial) | ✓ (rules) | – | ✓ | – | ⚪ | 1 | A, C |
| Event Sequence | ✓ | – | ✓ | – | ⚪ | 1 | A, C |
5. Repo-distribution patterns
Every legitimate way generators and assets split across repositories.
| # | Pattern | Holds | Repos | Example |
|---|---|---|---|---|
| A | Base package | locale-independent generators + universal lists | 1 (no locale variants) | @phony/base |
| B | Monolithic locale package | one language's models + lists + templates + defs | 1 per locale | @phony/tr_TR |
| C | Dataless generator package | pure logic / event / statistical / algorithmic defs — no assets, works in every locale | 1, any author | @x/isbn @x/tckn @x/event-seq |
| D | Generator + bundled default assets | declares an asset extension point + ships some locales | 1 | @phony/coin (def + de/en) |
| E | Data-only contribution package | only assets; adds locale data to an asset defined elsewhere; no code | 1 | @alice/coin-trnl → @phony/coin:coin.flip (tr/nl) |
| F | Concept split within a locale | parts of one language in separate repos | N per locale | @phony/tr_TR-names -geo -address |
| G | Locale split for one concept | a concept's languages in separate repos (contributors) | N per concept | @phony/coin + @x/coin-de + @y/coin-tr + @z/coin-nl |
| H | Domain override | inherits a locale, overrides/adds, usually private | 1 | @company/internal ⟵ @phony/tr_TR |
Distribution form by tier (orthogonal to the above):
- Tier 1 (data / PEL) — composition generators + assets. Run natively in every runtime, no engine. This is the default for third-party generators.
- Tier 2 (WASM) — genuinely imperative generators. Authored in any WASM-targeting language; the artifact is
.wasm, not source. Runs anywhere a WASM engine is present (PHP is the weak runtime — see Execution Model). - Language-native (Rust-only) artifacts are not a distribution form — they would only run in one runtime, breaking portability.
6. Worked example — person.first_name across locales and repos
Generator definition: first_name = { use: model, source: @phony/person:first_names }
→ defined once, never changes, blind to the locale axis
Asset extension point: @phony/person:first_names (scoped, locale-polymorphic)
Locale contributions (may live in different repos):
├─ @phony/tr_TR → first_names.ngram (tr) [pattern B or F]
├─ @phony/en_US → first_names.ngram (en)
├─ @phony/de_DE → first_names.ngram (de)
└─ @aziz/az-names → first_names.ngram (az) [pattern E: 3rd-party, data-only]
Resolution (locale = az): domain > locale > base chain → @aziz/az-names contribution
Determinism: each (asset, locale) is independent → adding az never
changes tr / en / de outputThis single example exercises all four axes at once: generator (fixed) × asset (scoped) × locale (resolution axis) × repo (open contribution).
7. Invariants the matrix guarantees
- Portability — any supported combination produces byte-identical output in Rust, PHP, JS, Python, and Go, given the same seed (SplitMix64 +
derive_seed- portable
.ngram+ JSON assets).
- portable
- Open locales — any 🌍 asset can gain a new locale from a separate data-only repo, without touching the generator that consumes it.
- Determinism isolation — each
(asset, locale)and each cell(seed, field_path, row)is independent; adding generators, assets, or locales never perturbs existing output. - Uniform features — the modifier pipeline and consistency/FPE apply across types through the one envelope; no feature is locked to a single generator.
- Safe by construction — Tier 1 contributions are pure data; Tier 2 is sandboxed WASM. Installing a community generator cannot run code on your machine.