メインコンテンツへスキップ

言語カード仕様

唯一の信頼できる情報源。 このドキュメントは、すべての言語カードの標準的な形式を定義します。すべてのカードは、値が null または [] であっても、ここに記載されているすべてのトップレベルフィールドを含まなければなりません(MUST)。フィールドが欠けているカードは非準拠です。この統一性があるからこそ、自動化ツール、リンター、エンリッチメントスクリプト、および人間のレビュアーがカード構造を信頼できます。

設計原則

  1. 統一された形式。 8,000枚以上のカードすべてが同じトップレベルフィールドを持ちます。不明な値は null、空の配列は []、空のオブジェクトは null{}ではなく)です。 これにより、コードは「このフィールドは存在するか?」を確認する必要がなく、「値が入っているか?」だけを確認すれば済みます。

  2. すべてに出典を。 すべての事実的な主張は、名前と版が明記された一次資料に基づきます。出典のない主張は検証不可能な主張です。dataSources フィールド(およびサブオブジェクト内のフィールドごとの source アノテーション)によって出典が明示されます。

  3. 見解の相違を保持する。 権威ある情報源が一致しない場合(Wikidataが話者数50,000人、Ethnologueが20,000人と言う場合など)、出典の帰属とともに両方を保存します。平均を取ったり、解決したり、どちらかを選んだりしません。ユーザーが細かな違いを把握できるようにします。

  4. null は不明を意味し、非該当を意味しない。 フィールドが null の場合、「まだデータが見つかっていない」ことを意味します。フィールドが本当に該当しない場合(例:手話における grammatical gender)、値でそれを説明すべきです:{ "grammatical": false, "inclusiveGuidance": "Not applicable — ASL does not have grammatical gender." }

  5. マージのみ。 エンリッチメントスクリプトはデータを追加するだけで、上書きしません。人間が手動で設定した値は、自動化されたデータより優先されます。


三層アーキテクチャ

場所目的
言語カードshared/language-cards/<code>.json言語ごとの設定:識別情報、分類、リソース、その他すべて
属カードshared/language-cards/genera/<genus>.json関連言語の共有ランタイムプロパティ(手動でキュレーション、自動生成ではない)
言語ツリーshared/language-cards/language-tree.json完全な Glottolog 階層 — Lab UI と言語探索のための参照データ

継承モデル

カードが "extends": "family-dravidian" を設定すると、ランタイムは(lib/registers.js 内の)_deepMerge() を使用して親カードを子カードにマージします。これにより、属カードが共有のレジスター、丁寧さシステム、および性別ガイダンスを定義し、数百の個別カードにデータを複製することなく、すべてのメンバー言語に継承させることができます。

マージのセマンティクス

子の値動作理由
null親から継承null は「このフィールドを定義しない」を意味する — 親の値がそのまま使われる
null 以外親を上書き子のデータがより具体的 — 優先される
ネストされたオブジェクト再帰的マージ子のフィールドが上書き、親のフィールドは保持
配列完全に置き換え配列はアイテムごとにマージされない — 子の配列が優先

識別フィールド(継承されない)

一部のフィールドはカード自体に属するものであり、親から継承されてはなりません(MUST NOT):

code, extends, _migration, aliases, iso639_1, iso639_3

親カードが aliases: ["macro-code"] を定義していても、子カードはそのエイリアスを継承しません。これらのフィールドは常に子自身の値です(未設定の場合は null を含む)。

理由: このルールがなければ、すべての Cree 言語がマクロ言語の親から aliases: ["cre"] を継承し、すべての変種がマクロのエイリアスになってしまいます。

例:Cree カードの解決方法

┌───────────────────────┐
│ family-algic.json │ formality: null, registers: null
│ (no registers) │
└──────────┬────────────┘
│ extends
┌──────────┴────────────┐
│ genus-cree.json │ formality: { system: "obviative-animate", ... }
│ (sourced registers) │ registers: { formal: {...}, informal: {...} }
└──────────┬────────────┘
│ extends
┌──────────┴────────────┐
│ crk.json │ code: "crk", extends: "genus-cree"
│ (Plains Cree) │ formality: null → inherits from genus-cree
│ │ registers: null → inherits from genus-cree
│ │ script: "Cans" → own value, no inheritance
│ │ code: "crk" → identity field, never inherited
└───────────────────────┘

ランタイムでは、getLanguageCard("crk") は genus-cree のレジスター + family-algic のプロパティ(存在する場合)+ crk 自身の識別情報とメタデータをマージしたオブジェクトを返します。

属カードテンプレート

属カードは shared/language-cards/genera/ に置かれ、言語グループの共有プロパティを定義します。通常のカードと同じスキーマに従いますが、異なる規則があります:

{
// Identity — genus cards use a prefixed code, NOT an ISO 639-3 code
"code": "genus-cree", // "genus-", "family-", or "macrolanguage-" prefix
"name": "Cree Languages", // Human-readable group name
"extends": "family-algic", // Genus cards can extend family cards (chaining)

// Formality — shared across the group, sourced from typological databases
"formality": {
"system": "obviative-animate",
"description": "Cree languages use an obviative/proximate system...",
"default": "formal",
"source": "WALS 37A, 38A + Wolfart 1973"
},

// Registers — shared presets, if the group shares a formality system
"registers": {
"formal": {
"label": "Formal (Proximate)",
"description": "...",
"prompt": "...",
"isDefault": true
},
"informal": {
"label": "Informal",
"description": "...",
"prompt": "..."
}
},

// Gender — shared grammatical gender behavior
"gender": {
"grammatical": false, // Cree doesn't have grammatical gender
"inclusiveGuidance": null // so no inclusive guidance needed
},

// Everything else is null — individual cards provide their own
// classification, geography, resources, etc.
"classification": null,
"methodSupport": null,
// ...
}

重要なルール: 属カードには、グループ全体で真に共有されており、権威ある参照資料に基づいたデータのみを含めなければなりません(MUST)。丁寧さシステムがメンバー間で異なる場合は、属カードではなく個別カードに記載します。

標準テンプレート

すべてのカードはこの正確なトップレベルの形式を持たなければなりません(MUST)。サブオブジェクトのスキーマは以下のフィールドリファレンスに記載されています。

{
// ═══════════════════════════════════════════════════════════════════════
// § 1. IDENTITY
// Who is this language? What codes identify it?
// Sources: ISO 639-3 registry, ISO 639-1, BCP 47/IANA.
// ═══════════════════════════════════════════════════════════════════════

"code": "xxx", // REQUIRED. ISO 639-3 code. This IS the card ID and filename.
"name": "English Name", // REQUIRED. English reference name from ISO 639-3 registry.
"nativeName": null, // Endonym (name in the language itself). Source: Wikidata P1705.
// Examples: "nêhiyawêwin / ᓀᐦᐃᔭᐍᐏᐣ", "日本語", "Esperanto".
"alternateNames": [], // Other names this language is known by. Source: Glottolog, Ethnologue.
// Not aliases (those are code-level). These are name-level variants.
// Example: ["Qafar af", "Afaraf", "'Afar Af"] for Afar (aar).
"iso639_3": "xxx", // REQUIRED. Three-letter ISO 639-3 code. Same as `code`.
"iso639_1": null, // Two-letter ISO 639-1 code (e.g., "en", "fr"). null if none.
"bcp47": null, // IETF BCP 47 tag. Often same as iso639_1. Can include subtags
// (e.g., "iu-Cans-CA"). null if unknown.
"aliases": [], // Alternative code-level identifiers that resolve to this card.
// Example: ["fil"] for tl (Tagalog), ["iu"] for iku (Inuktitut).
// Used by code resolution: user types "fil", system loads tl.json.
"isoScope": "I", // REQUIRED. ISO 639-3 scope:
// "I" = Individual language
// "M" = Macrolanguage (e.g., Chinese, Arabic, Cree)
// "S" = Special (e.g., mis, mul, zxx)
"isoType": "L", // REQUIRED. ISO 639-3 type:
// "L" = Living "E" = Extinct "A" = Ancient
// "H" = Historical "C" = Constructed
"macrolanguage": null, // If this language is part of a macrolanguage, the macrolanguage
// ISO 639-3 code (e.g., "cre" for Plains Cree, "ara" for Arabic
// varieties). Source: ISO 639-3 macrolanguages.tab.
"extends": null, // Genus card key if shared properties are inherited from a genus
// card (e.g., "genus-cree", "genus-eskimo-aleut").
// null for most languages.

// ═══════════════════════════════════════════════════════════════════════
// § 2. CLASSIFICATION
// Where does this language sit in the family tree?
// Source: Glottolog. NEVER hand-build classifications.
// ═══════════════════════════════════════════════════════════════════════

"glottocode": null, // Glottolog identifier (e.g., "plai1258", "stan1293").
// null if the language is not in Glottolog.
"classification": null, // Genealogical classification from Glottolog. When populated:
// {
// "family": "Algic", // Top-level family. null for isolates.
// "familyGlottocode": "algi1248", // Glottocode of the family.
// "genus": "Plains Creeic", // WALS-style genus.
// "genusGlottocode": "plai1264", // Glottocode of the genus.
// "ancestry": ["Algic", "Algonquian-Blackfoot", "Algonquian",
// "Cree-Montagnais-Naskapi", "Cree", "Plains Creeic"]
// }
// For isolates: family = language name, genus = language name,
// ancestry = [language name].
"isIsolate": false, // true if a language isolate (no known genetic relatives).
// Source: Glottolog CLDF.

// ═══════════════════════════════════════════════════════════════════════
// § 3. GEOGRAPHY
// Where is this language spoken?
// Sources: Glottolog (coordinates, countries), census data, Ethnologue.
// ═══════════════════════════════════════════════════════════════════════

"macroarea": null, // Glottolog macroarea. One of: "Africa", "Australia",
// "Eurasia", "North America", "Papunesia", "South America".
// null if unknown. Source: Glottolog CLDF.
"coordinates": null, // Representative geographic point. When populated:
// { "lat": 52.1, "lng": -106.6, "source": "glottolog-5.3" }
// This is a representative point, not a boundary.
"countries": [], // ISO 3166-1 alpha-2 country codes where this language is spoken.
// Example: ["CA", "US"]. Source: Glottolog.
"regions": [], // Detailed regional breakdown with admin codes & speaker estimates.
// Each entry:
// {
// "country": "Canada",
// "countryCode": "CA",
// "officialStatus": "recognized", // official, co-official,
// // recognized, none
// "region": "Saskatchewan, Alberta, Manitoba",
// "speakerEstimate": "~20,000",
// "coordinates": [-106.6, 52.1], // [lng, lat]
// "admin1Codes": ["CA-SK", "CA-AB", "CA-MB"]
// }

"arealContext": null, // Linguistic area / Sprachbund membership. DISTINCT from
// contactInfluences (which is language-specific contact history).
// This field captures zone-level typological convergence patterns
// — i.e., what linguistic area the language exists within and
// what features are common across that area.
// {
// "zone": "Mainland Southeast Asian Sprachbund",
// "arealFeatures": "Tonal convergence, classifier systems,
// topic-prominence, monosyllabicity trend.",
// "typicalContacts": ["Classical Chinese", "Sanskrit/Pali"],
// "source": "areal-linguistics (Enfield 2005)"
// }
// NOT the same as contactInfluences. A language can exist within
// a convergence area without having specific contact history with
// any particular language in that area.

// ═══════════════════════════════════════════════════════════════════════
// § 4. WRITING SYSTEMS
// How is this language written?
// Sources: Wikidata P282, ISO 15924, manual research.
// Note: Some languages have NO standardized orthography. Some have
// competing orthographies. Some use multiple scripts routinely (e.g.,
// Serbian: Cyrillic + Latin; Japanese: Kanji + Hiragana + Katakana).
// Sign languages may use notation systems (SignWriting, HamNoSys) or
// none at all.
// ═══════════════════════════════════════════════════════════════════════

"script": null, // Primary ISO 15924 script code (e.g., "Latn", "Cyrl", "Cans",
// "Jpan"). null if no written form or unknown.
"scriptUnicodeName": null, // Unicode script block name derived from the script field.
// e.g., "Latin", "Cyrillic", "Canadian_Aboriginal", "CJK".
// Used by code_switching metric plugin. Auto-populated by
// enrich-script-unicode-names.mjs. null if script is null.
"scripts": [], // All writing systems with detail. Array of:
// {
// "code": "Cans",
// "name": "Unified Canadian Aboriginal Syllabics",
// "primary": true
// }
// A language with multiple scripts has multiple entries.
// A language with no written form has [].
"dir": null, // Writing direction: "ltr" (left-to-right) or "rtl" (right-to-left).
// null if no written form or unknown.
"scriptConverter": null, // Script converter key if we have a converter for this language
// (e.g., "crk" for SRO↔Syllabics). null for most languages.
"orthographicStatus": null, // Writing system standardization status. When populated:
// {
// "status": "standardized",
// // "standardized" — official/agreed orthography exists
// // "competing" — multiple orthographies in active use
// // "emerging" — orthography under development
// // "none" — primarily oral, no standard writing
// "notes": "Uses SIL-developed Latin orthography since 1960s.",
// "source": "ethnologue" // or "manual-curation"
// }
// Crucial for LRLs where orthographic variation directly impacts
// MT training data quality and evaluation consistency.

// ═══════════════════════════════════════════════════════════════════════
// § 5. DEMOGRAPHICS & VITALITY
// How many people speak this language? Is it endangered?
// Sources: Census, Ethnologue, UNESCO Atlas, Wikidata, Glottolog AES.
//
// CRITICAL: Store ALL estimates separately with source attribution.
// Never average or "resolve" conflicting data. Speaker counts are
// politically contested for many languages. Present the evidence,
// let the reader assess.
// ═══════════════════════════════════════════════════════════════════════

"speakerEstimates": [], // Array of speaker count estimates from different authorities.
// Each entry:
// {
// "source": "wikidata", // or "ethnologue-28",
// // "census-ph-2020", etc.
// "count": 20000, // Point estimate. null if range-only.
// "date": "2026-06-07", // When this data was retrieved.
// "countRange": { "min": 15000, "max": 25000 }, // Optional range.
// "note": "Wikidata has 2 estimates: 15,000 and 25,000"
// }
// Empty array means we have not yet found speaker count data.

"vitality": null, // Endangerment / vitality assessment. When populated:
// {
// "unescoStatus": "severely-endangered",
// // Enum: "safe", "vulnerable", "definitely-endangered",
// // "severely-endangered", "critically-endangered",
// // "extinct"
// "aesStatus": "shifting",
// // Glottolog AES label (free text from AES data).
// "egids": "6b",
// // Ethnologue Expanded Graded Intergenerational Disruption
// // Scale. Levels: 0 (international) to 10 (extinct).
// "trend": "declining",
// // Qualitative trend: "stable", "growing", "declining",
// // "shifting", "moribund", "awakening"
// "source": "glottolog-aes-5.3",
// "notes": "Intergenerational transmission breaking down."
// }

// ═══════════════════════════════════════════════════════════════════════
// § 5.5. DOCUMENTATION & DIGITAL PRESENCE
// How well-documented is this language? What digital footprint does it
// have? These fields answer the practical question: "What can I
// actually DO with this language?"
// Sources: Glottolog (references), Wikipedia, Common Voice, Tatoeba.
// ═══════════════════════════════════════════════════════════════════════

"documentationDepth": null, // How well-documented is this language in the literature?
// {
// "referenceCount": 42,
// // Number of published references in Glottolog.
// "med": "grammar",
// // Most Extensive Description type. One of:
// // "long_grammar", "grammar", "grammar_sketch",
// // "dictionary", "phonology", "text", "wordlist",
// // "comparative", "minimal", "unknown"
// "source": "glottolog-5.3"
// }

"digitalPresence": null, // Digital footprint across web platforms. When populated:
// {
// "wikipedia": {
// "edition": true, // Has its own Wikipedia edition?
// "articleCount": 75000, // Number of articles.
// "editionCode": "crk", // Wikipedia subdomain code.
// "source": "wikimedia-api-2026"
// },
// "commonVoice": {
// "validatedHours": 12.5,
// "totalHours": 25.0,
// "speakers": 45,
// "sentences": 1200,
// "source": "common-voice-20.0"
// },
// "tatoeba": {
// "sentenceCount": 342,
// "source": "tatoeba-2026"
// }
// }

"dialectCount": null, // Number of recognized dialects in Glottolog.
// Derived from child_dialect_count in languoid.csv.
// Simple integer. null if 0 or unknown.
// Source: glottolog-5.3.

// ═══════════════════════════════════════════════════════════════════════
// § 6. FORMALITY, REGISTERS & GENDER
// How does politeness work in this language? What translation registers
// do we offer? How should gender be handled?
//
// This section drives Champollion's register-preset system — the
// mechanism by which users select formal/informal/professional tone.
// These fields require genuine linguistic research, not automation.
// ═══════════════════════════════════════════════════════════════════════

"formality": null, // Formality system description. When populated:
// {
// "system": "T-V",
// // One of: "T-V", "speech-levels", "keigo", "particles",
// // "register-levels", "register-and-code-switching",
// // "code-switching", "none"
// "description": "French uses a vous/tu distinction...",
// "default": "formal-vous" // Key into the `registers` object.
// }

"registers": null, // Translation register presets. When populated, keyed by preset ID:
// {
// "formal-vous": {
// "label": "Formal (vouvoiement)",
// "description": "One sentence: when to use this preset.",
// "prompt": "The actual LLM system prompt instruction that
// steers translation tone. Must name specific
// linguistic features (pronouns, verb forms, particles).",
// "deeplFormality": "prefer_more"
// // Only if methodSupport.deepl.formality is true.
// // One of: "prefer_more", "prefer_less", "default".
// }
// }

"gender": null, // Grammatical gender and inclusive guidance. When populated:
// {
// "grammatical": true, // Does the language have gram. gender?
// "inclusiveGuidance": "Use gender-neutral forms when possible.
// Prefer 'iel' (neologism) or rephrase to
// avoid gendered agreement."
// }
// For languages without grammatical gender (Turkish, Finnish):
// { "grammatical": false, "inclusiveGuidance": null }

"codeSwitching": null, // Code-switching behavior (for languages where mixing with another
// language is the norm, not an error). When populated:
// {
// "contactLanguage": "Spanish",
// "contactIso639_3": "spa",
// "mixedVarietyName": "Jopará", // null if no named mixed variety
// "prevalence": "dominant", // "rare", "common", "dominant"
// "morphologicalIntegration": true,
// "pipelineStrategy": "hybrid-fst",
// "notes": "Jopará IS the everyday language of most Paraguayans..."
// }

// ═══════════════════════════════════════════════════════════════════════
// § 7. LINGUISTIC PROFILE
// What makes this language what it is? What are the specific challenges
// for machine translation? What rules govern its typography?
// What languages have shaped it through contact?
//
// These fields require genuine linguistic expertise. For many languages
// (especially low-resource), this section will remain null until a
// qualified researcher or community member contributes.
// ═══════════════════════════════════════════════════════════════════════

"linguisticChallenges": null, // MT-relevant challenges, keyed by challenge ID.
// When populated:
// {
// "polysynthesis": "Cree is highly polysynthetic. A single verb
// can incorporate subject, object, tense...",
// "animacy": "Verb conjugation changes based on whether the
// subject/object is animate or inanimate...",
// "neologisms": "Avoid literal translations of modern software
// concepts. Maintain Cree metaphorical logic..."
// }
// Aim for 3–6 challenges per language when researched.

"contactInfluences": [], // How other languages have shaped this one. Array of:
// {
// "source": "English",
// "sourceIso639_3": "eng", // null if proto-language/unknown
// "type": "superstrate",
// // Enum: "superstrate", "substrate", "adstrate",
// // "learned_borrowing", "lexical_borrowing",
// // "relexification"
// "domains": ["education", "government", "technology"],
// "depth": "deep",
// // Enum: "light", "moderate", "heavy", "structural",
// // "defining"
// "period": "1870–present",
// "notes": "Residential school era and ongoing...",
// "citation_needed": false
// // true if no published academic source found.
// // See language-card-citation-procedure.md.
// }

"rules": null, // Typography, plural, and capitalization rules. When populated:
// {
// "typography": {
// "quoteStart": "\u201c",
// "quoteEnd": "\u201d",
// "usesSpaces": true, // false for CJK, Thai, Lao, Khmer
// "punctuationSpacing": {
// "doublePunctuation": "none" // "thin-nbsp" for French
// }
// },
// "plurals": {
// "categories": ["one", "other"]
// // From CLDR. Possible values:
// // "zero", "one", "two", "few", "many", "other"
// },
// "capitalization": {
// "hasCase": true
// // true for Latin, Cyrillic, Greek, Armenian scripts.
// // false for CJK, Arabic, Devanagari, etc.
// }
// }
// Source: CLDR + ISO 15924 derivation.

"typologicalProfile": null, // Grambank typological features. When populated:
// {
// "featuresDocumented": 195,
// "featuresCoverage": 1, // 0.0–1.0 fraction of features
// "wordOrderDominant": "SVO",
// "hasDefiniteArticle": true,
// "hasIndefiniteArticle": true,
// "hasGenderSystem": true,
// "hasCaseMorphology": true,
// "hasEvidentiality": false,
// "hasToneSystem": false,
// "source": "grambank-1.0.3"
// }
// Auto-populated by enrich-grambank-typology.mjs.

"phonologicalInventory": null, // PHOIBLE phoneme inventory. When populated:
// {
// "consonants": 24,
// "vowels": 16,
// "tones": 0,
// "totalPhonemes": 40,
// "isTonal": false,
// "inventorySize": "moderately-large",
// // Enum: "small", "moderately-small", "average",
// // "moderately-large", "large"
// "source": "phoible-2.0"
// }
// Auto-populated by enrich-phoible-phonemes.mjs.

// ═══════════════════════════════════════════════════════════════════════
// § 8. ENCYCLOPEDIC
// General knowledge about the language for human context. History,
// dialect situation, institutional resources, representative sayings.
// This section is for understanding, not computation.
// ═══════════════════════════════════════════════════════════════════════

"encyclopedic": null, // General knowledge. When populated:
// {
// "family": "Algic", // Redundant with classification
// // but useful for human readers.
// "dialects": {
// "split": true, // Is there significant variation?
// "classification": "Plains Cree (y-dialect)",
// "variants": ["crk", "cwd", "csw"] // ISO codes of variants
// },
// "demographics": {
// "speakers": "Approx. 20,000 active speakers",
// "regions": ["Saskatchewan", "Alberta", "Manitoba"]
// },
// "history": "Plains Cree is the most widely spoken Algonquian
// language in western Canada...",
// "resources": {
// "wikipedia": "https://en.wikipedia.org/wiki/Plains_Cree",
// "foundations": [{ "name": "ALTLab", "url": "https://..." }],
// "dictionaries": [{ "name": "itwêwina", "url": "https://..." }]
// }
// }

"culturalAphorism": null, // A representative saying, proverb, or teaching in the language.
// When populated:
// {
// "text": "ê-wîcêhtonaniwahk kâ-kî-isi-wâpahtamâhk ôma pimâtisiwin",
// "transliteration": null, // Romanized form if non-Latin script.
// "translation": "Through helping each other we come to understand
// this life",
// "literal": "By-helping-one-another we-have-come-to-see this life",
// "source": "Cree teaching, documented in nêhiyawêwin educational
// resources"
// }
// Choose sayings that reveal something about the language's
// worldview or structure. Must be sourced.

"varieties": [], // For macrolanguages or languages with significant dialectal
// variation, the individual varieties with their own tool coverage.
// Each entry:
// {
// "name": "Cusco Quechua",
// "iso639_3": "quz",
// "region": "Cusco, Peru",
// "fstCoverage": true,
// "corpusCoverage": true,
// "nllbCoverage": false,
// "mutualIntelligibility": "Primary variety for this card",
// "notes": "SQUOIA FST was built for this variety."
// }

// ═══════════════════════════════════════════════════════════════════════
// § 9. DIGITAL RESOURCES & TOOLING
// What NLP tools, corpora, models, and datasets exist for this language?
// What translation APIs support it? What eval benchmarks are available?
//
// This is Champollion's operational core — these fields determine what
// we can actually DO with this language.
// ═══════════════════════════════════════════════════════════════════════

"resources": null, // NLP resources available for this language. When populated:
// {
// "fsts": [{ // Finite-state transducers
// "name": "GiellaLT Plains Cree FST (lang-crk)",
// "url": "https://github.com/giellalt/lang-crk/releases",
// "type": "morphological-analyzer"
// }],
// "corpora": [{ // Text corpora
// "name": "EDTeKLA Cree Language Textbook Corpus",
// "type": "parallel", // "parallel", "monolingual"
// "pairs": ["en-crk"],
// "url": "https://...",
// "exposure": "open-web" // "open-web", "restricted",
// // "holdout"
// }],
// "models": [{ // Pre-trained models
// "name": "NLLB-200 (crk_Cans)",
// "url": "https://...",
// "type": "nmt"
// }],
// "tools": [], // Other NLP tools
// "wordlists": [{ // Standardized wordlists
// "name": "Lexibank",
// "conceptCount": 200,
// "source": "lexibank"
// }],
// "treebanks": [{ // Syntactic treebanks
// "name": "UD_Korean-GSD",
// "tokens": 80000,
// "source": "universal-dependencies-2.14"
// }]
// }
// IMPORTANT: Only actual NLP/digital resources belong here.
// "This language has a WALS entry" is NOT a resource — that
// goes in databaseCoverage.

"databaseCoverage": null, // Which typological/reference databases cover this language.
// Separated from resources to avoid conflating "has a database
// entry" with "has usable NLP tooling."
// {
// "wals": true,
// "grambank": true,
// "phoible": true,
// "cldr": true,
// "lexibank": true,
// "commonVoice": true,
// "source": "derived"
// }

"corpusAvailability": null, // What text/parallel corpora exist for NLP use?
// {
// "bibleTranslation": {
// "textAvailable": true,
// "audioAvailable": true,
// "source": "bible-brain-api"
// },
// "opusCorpora": ["wikimedia", "ubuntu", "gnome"],
// "source": "multi-source"
// }

"keyboardSupport": null, // Input method / keyboard availability. When populated:
// {
// "keymanKeyboards": 3,
// // Number of Keyman keyboards available.
// "cldrKeyboard": true,
// // CLDR has keyboard layout data.
// "source": "keyman-api + cldr"
// }

"methodSupport": { // REQUIRED. Which Champollion translation methods support this
// language. Each method is an object with at minimum
// { "supported": boolean }.
"googleTranslate": { "supported": false },
"deepl": { "supported": false },
"microsoftTranslator": { "supported": false },
"libreTranslate": { "supported": false },
"nllb": { "supported": false },
// When NLLB is supported, include the code:
// { "supported": true, "code": "crk_Cans" }
"llm": { "supported": true }
// LLM is always true (quality varies by language).
// Optional: "verifiedDate": "2026-06-07" for audit trail.
},

"metricModelSupport": null, // Which MT evaluation models produce reliable scores.
// When populated:
// {
// "xlmr": "high", // "high", "medium", or "low"
// // XLM-R training representation tier.
// "africomet": false // true if AfriCOMET covers this language.
// }
// Drives automatic COMET model selection in metrics_comet.py.
// Auto-populated by enrich-metric-model-support.mjs.

"metricPlugins": null, // Which per-language metric plugin packs are available.
// When populated:
// {
// "formalityMarkers": true // Formality marker resource file exists
// // at plugins/resources/formality/{code}.json
// }
// Each key corresponds to a resource pack in
// arena/mt_eval_harness/plugins/resources/{packName}/.
// To add a new metric pack for a language, create the resource
// file and set the flag here. No code changes required.

"evalPack": null, // Evaluation dependency pack for language-specific metrics.
// When populated, declares the Python dependencies and
// post-install steps required by this language's eval standards.
// The harness uses this for dependency gating: if deps are
// missing, the harness warns the user and skips LYSS metrics
// (rather than crashing).
// When populated:
// {
// "pythonDeps": {
// "pyhfst": "pyhfst>=1.4", // PyPI package specs
// "requests": "requests>=2.28",
// "spacy": "spacy>=3.7"
// },
// "postInstall": [ // Commands to run after pip
// {
// "command": "spacy download en_core_web_md",
// "label": "spaCy English model (for LYSS-sem)"
// }
// ],
// "requiresFst": true, // true if GiellaLT FST needed
// "description": "LYSS equivalence linter + FST validation"
// }

"evalMetrics": null, // Language-specific evaluation metrics (LYSS standards).
// When populated, the harness dynamically imports these
// MetricPlugin classes from eval_standards/<lang>/ and applies
// them to every run targeting this language — regardless of
// which method (contestant) is being evaluated.
// Keyed by metric ID:
// {
// "lyss-eq": {
// "module": "eval_standards.crk.metrics",
// "class": "CrkLinterMetric",
// "description": "LYSS deterministic variant-class linter"
// },
// "lyss-sem": {
// "module": "eval_standards.crk.metrics",
// "class": "CrkSemanticMetric",
// "description": "LYSS FST-based semantic validator",
// "dependencies": ["spacy>=3.7"],
// "spacy_models": ["en_core_web_md"]
// }
// }
// Architecture: eval standards are referees, not contestants.
// They live in the harness (eval_standards/), not in method
// plugins. This ensures all methods are scored equally.
// Discovery: plugin_discovery.py reads this field via
// language_cards.get_eval_metrics() and instantiates metrics
// using importlib. Dependencies are checked against evalPack.

"omt1600": null, // Meta's OMT-1600 (One Model for Translation) coverage assessment.
// When populated:
// {
// "covered": true,
// "tier": "R1", // Meta's resource tier
// "evalMetrics": ["chrF++", "BLASER-3"],
// "notes": "Plains Cree: no web-crawled bitext..."
// }

"evalDatasets": [], // Evaluation dataset IDs available for this language.
// Example: ["flores-plus-devtest", "edtekla-dev-v1"].
// Empty means no standardized eval set exists.

"pipelineReadiness": null, // Assessment of readiness for Champollion's translation pipeline.
// When populated:
// {
// "tier": "tier-2-feasible",
// // "watch-list" — cataloged but no path to translation
// // "tier-3-cataloged" — basic metadata present
// // "tier-2-feasible" — tools exist, pipeline possible
// // "tier-1-ready" — pipeline operational
// "hasFST": true,
// "hasParallelCorpus": true,
// "hasEvalBenchmark": true,
// "blockers": ["Syllabics post-processing validation"],
// "notes": "FST-gated pipeline operational. EDTeKLA corpus..."
// }

// ═══════════════════════════════════════════════════════════════════════
// § 10. PROVENANCE & METADATA
// Where does this data come from? Who reviewed it? When was it
// generated? What's its overall quality level?
//
// This section exists to make the card auditable. Every automated
// enrichment, every human review, every source consulted should
// leave a trace here.
// ═══════════════════════════════════════════════════════════════════════

"dataSources": [], // REQUIRED. Sources consulted for this card's data.
// Can be a flat array (backwards-compatible):
// ["iso639-3-2024", "glottolog-5.3", "wikidata"]
//
// Or a structured per-field object (preferred for new cards):
// {
// "classification": ["glottolog-5.3"],
// "vitality": ["glottolog-aes-5.3", "unesco-atlas-2024"],
// "speakerEstimates": ["wikidata", "census-ca-2021"],
// "rules": ["cldr-48"],
// "methodSupport": ["google-translate-2026-06"]
// }

"supportTier": "cataloged", // Auto-derived tier summarizing the card's depth:
// "cataloged" — identity + classification only
// "emerging" — + vitality + speakerEstimates
// "developing" — + resources + methodSupport
// "supported" — full research: registers, challenges, etc.

"humanReviewed": null, // null until a qualified human reviews the card. When populated:
// {
// "reviewer": "Prof. Kenneth Jamandre",
// "affiliation": "University of the Philippines Diliman",
// "date": "2026-06-08",
// "scope": "full", // "full", "partial", "vitality-only"
// "notes": "Verified speaker count, vitality assessment,
// and contact influences for Tagalog."
// }

"notes": null, // Free-text notes about this language or this card's data quality.
// Example: "Low-resource language under active development.
// Translation pipeline uses FST-gated approach."

"firstDocumented": null, // Year of first known documentation. Negative for BCE.
// Example: -1500 (Sanskrit, ~1500 BCE), 1787 (some languages).
// Source: Glottolog CLDF.

"lastDocumented": null, // Year of last known documentation (relevant for extinct languages).
// Source: Glottolog CLDF.

"_generated": null // Auto-populated by enrichment scripts. When populated:
// {
// "by": "generate-all-cards.mjs",
// "at": "2026-06-07T12:34:56Z",
// "sources": ["iso639-3", "glottolog-5.3", "wikidata"],
// "completeness": "partial",
// // "partial" — has identity + classification + coords
// // "substantial" — + vitality + speakerEstimates + script
// // "complete" — all automatable fields populated
// "lastEnriched": "2026-06-07"
// }
}

フィールドリファレンス

§ 1. 識別フィールド

フィールド必須自動化可能出典
codestringISO 639-3 レジストリ
namestringISO 639-3 レジストリ
nativeNamestring | nullWikidata P1705
alternateNamesstring[]Glottolog、Ethnologue
iso639_3stringISO 639-3 レジストリ
iso639_1string | nullISO 639-1
bcp47string | null部分的IANA サブタグレジストリ
aliasesstring[]手動キュレーション
isoScopestringISO 639-3 レジストリ
isoTypestringISO 639-3 レジストリ
macrolanguagestring | nullISO 639-3 macrolanguages.tab
extendsstring | null手動キュレーション

§ 2. 分類フィールド

フィールド必須自動化可能出典
glottocodestring | nullGlottolog
classificationobject | nullGlottolog
isIsolatebooleanGlottolog CLDF

§ 3. 地理フィールド

フィールド必須自動化可能出典
macroareastring | nullGlottolog CLDF
coordinatesobject | nullGlottolog
countriesstring[]Glottolog
regionsobject[]国勢調査、Ethnologue、手動
arealContextobject | null座標 + 言語地域ゾーン

§ 4. 文字体系フィールド

フィールド必須自動化可能出典
scriptstring | nullWikidata P282
scriptUnicodeNamestring | nullscript から ISO 15924 → Unicode マッピングで導出
scriptsobject[]部分的Wikidata、手動
dirstring | nullスクリプトから導出可能
scriptConverterstring | null手動
orthographicStatusobject | null部分的Ethnologue、手動

§ 5. 人口統計・活力フィールド

フィールド必須自動化可能出典
speakerEstimatesobject[]Wikidata、Ethnologue、国勢調査
vitalityobject | nullGlottolog AES、UNESCO

§ 5.5 ドキュメンテーション・デジタルプレゼンスフィールド

フィールド必須自動化可能出典
documentationDepthobject | nullGlottolog 参照資料
digitalPresenceobject | nullWikipedia、Common Voice、Tatoeba
dialectCountnumber | nullGlottolog

§ 6. 丁寧さ・レジスター・性別フィールド

フィールド必須自動化可能出典
formalityobject | null言語学的研究
registersobject | null言語学的研究
genderobject | null言語学的研究
codeSwitchingobject | null言語学的研究

§ 7. 言語プロファイルフィールド

フィールド必須自動化可能出典
linguisticChallengesobject | null言語学的研究
contactInfluencesobject[]出版された言語学文献
rulesobject | nullCLDR
typologicalProfileobject | nullGrambank 1.0.3 — enrich-grambank-typology.mjs によって自動入力
phonologicalInventoryobject | nullPHOIBLE 2.0 — enrich-phoible-phonemes.mjs によって自動入力

§ 8. 百科事典的フィールド

フィールド必須自動化可能出典
encyclopedicobject | null手動調査
culturalAphorismobject | nullコミュニティからの貢献
varietiesobject[]手動調査

§ 9. デジタルリソースフィールド

フィールド必須自動化可能出典
resourcesobject | null部分的手動 + 自動
databaseCoverageobject | nullエンリッチメントから導出
corpusAvailabilityobject | nullBible Brain、OPUS、Lexibank
keyboardSupportobject | nullKeyman API、CLDR
methodSupportobject部分的API 検証
metricModelSupportobject | nullXLM-R 論文、AfriCOMET 論文
metricPluginsobject | nullカードエンリッチメント — どのメトリクスプラグインパックが適用されるかを宣言(例:{ formalityMarkers: true }
omt1600object | nullメタ評価
evalDatasetsstring[]データセットレジストリ
pipelineReadinessobject | null部分的導出 + 手動

resources.fsts[].installresources オブジェクト内の FST エントリには、フィールド reporeleaseTagassetPatternformatmaturity、およびオプションで bundlePattern を持つ install サブオブジェクトを含めることができます。これは以前の GIELLALT_FST_REGISTRY ハードコードされた辞書を置き換えます。language_cards.py 内の get_fst_install_info() を参照してください。

§ 10. 出典フィールド

フィールド必須自動化可能出典
dataSourcesarray | object自動 + 手動
supportTierstringカードの完成度から導出
humanReviewedobject | null人間のレビュアー
notesstring | null手動
firstDocumentednumber | nullGlottolog CLDF
lastDocumentednumber | nullGlottolog CLDF
_generatedobject | nullエンリッチメントスクリプト

言語コードポリシー

Champollion は ISO 639-3 を標準識別子として使用します。その他の標準コードはエイリアスとして登録され、ランタイムで ISO 639-3 コードに解決されます。

優先度標準フィールド用途
1(標準)ISO 639-3crkcodeカードファイル名、設定キー、API パラメータ
2(エイリアス)ISO 639-1iualiases[]CLI で受け付け、ISO 639-3 に解決
3(エイリアス)BCP 47filaliases[]CLI で受け付け、ISO 639-3 に解決
参照Glottocodeplai1258glottocode分類のみ、ランタイムには使用しない

解決順序: ユーザーがコードを指定した場合:

  1. card.code で直接一致 → 見つかった
  2. card.aliases[] で一致 → 見つかった、標準カードを返す
  3. card.iso639_1 で一致 → 見つかった(フォールバック)
  4. 見つからない → エラー

移行履歴:ISO 639-1 → ISO 639-3

v8 以前は、カードファイル名に ISO 639-1 コードが利用可能な場合はそれを使用していました(fr.jsonde.jsonja.json)。639-3 への移行で、すべてのカードが ISO 639-3 相当のファイル名に変更されました:

変更前変更後理由
fr.jsonfra.json639-3 が標準
de.jsondeu.json639-3 が標準
zh.jsoncmn.jsonマクロ言語 → デフォルト個別言語
ar.jsonarb.jsonマクロ言語 → 現代標準アラビア語
ms.jsonzsm.jsonマクロ言語 → 標準マレー語

旧コードはどうなったか?

  • 旧 639-1 コードは card.iso639_1 に記載
  • 旧 639-1 コードは card.aliases[] に記載
  • resolveCode("fr") はランタイムで "fra" を返す — 後方互換性あり
  • ユーザーは引き続き設定に "fr" と記述できる — 透過的に解決される

アーキテクチャ上の変更点:

  • _deepMerge()null の値をスキップするようになった(親から継承)
  • _deepMerge() は識別フィールドセットを持つようになった(コード、extends、エイリアスは継承されない)
  • formality.default はレジスター isDefault: true フラグから導出されるようになった
  • 205 枚の Grambank 由来カードが構造的な formality.default 修正を受けた
  • 38 枚の属・語族・マクロ言語カードが継承ターゲットを提供する

エッジケース

手話

手話(例:ASE — アメリカ手話)は ISO 639-3 コードを持つ正当な言語です。地理情報と話者数を持ちますが:

  • script は通常 null(標準的な書記形式がない)
  • scripts には、表記システムが使用されている場合 "Sgnw"(SignWriting)が含まれることがある
  • dirnull
  • linguisticChallenges は空間文法、分類詞などを扱うべき
  • gender.grammatical は通常 false

古代語・歴史的言語

ラテン語(lat、isoType H)やサンスクリット語(san、isoType H)などの言語は、特定の文脈(典礼、学術)で今も使用されていますが、母語話者はいません:

  • vitality は「母語話者なし」と "trend": "stable" を記載することがある(衰退ではない — 使用するコミュニティは安定しているが、規模が小さい)
  • speakerEstimates はこれらが L1 ではなく L2 話者であることを記載すべき
  • firstDocumented / lastDocumented は時代的な位置づけを示す

人工言語

エスペラント(epo、isoType C)、Lojban など:

  • classification は「constructed」ファミリーを指すか、null になることがある
  • contactInfluences は元となった素材を反映する(例:エスペラントはロマンス語、ゲルマン語、スラブ語を基にしている)
  • vitality は特殊 — 話者コミュニティは成長しているが、母語の故郷はない

マクロ言語

アラビア語(ara)、中国語(zho)、Cree 語(cre)、ケチュア語(que)は複数の個別言語を包含するマクロ言語です:

  • isoScope: "M"
  • varieties には ISO コードとともに個別言語を列挙すべき
  • methodSupportマクロ言語カードがサポートするもの(通常は標準化された変種)を反映すべき
  • 個別の変種もそれぞれ独自のカードを持つべき

標準化された正書法を持たない言語

多くの言語(特に口承伝統の言語)には標準化された文字体系がなく、または競合する正書法が存在します:

  • scriptnull
  • scripts[]
  • dirnull
  • notes は正書法の状況を説明すべき
  • linguisticChallenges はこれが機械翻訳に与える影響を記載すべき(例:訓練データがない)

ダイグロシア

アラビア語(現代標準アラビア語 vs. 方言)やグアラニー語(Jopará vs. 純粋なグアラニー語)などの言語:

  • codeSwitching は混合変種の状況を捉える
  • registers は異なるレベルのプリセットを提供できる
  • varieties はダイグロシアのペアを列挙できる

言語接触の影響タイプ

タイプ意味
superstrateコミュニティに押し付けられた支配的言語フランス語 → 英語(1066年以降)
substrate押し付けられた言語に影響を与える母語ケルト語 → 英語
adstrate相互影響を持つ隣接言語古ノルド語 → 英語
learned_borrowing教育・学術を通じた借用ラテン語 → 英語
lexical_borrowing接触による直接的な語彙借用スペイン語 → フィリピン語
relexification語彙の全面的な置き換えポルトガル語 → パピアメント語

言語接触の影響の深さ

深さ意味
light少数の借用語、構造的影響は最小限
moderate特定の領域で大量の語彙
heavy語彙全体に広がり、一部の構造的特徴も
structural文法、統語、音韻に影響
defining接触によってコアアイデンティティが形成された(クレオール語、混合言語)

良いレジスタープリセットの書き方

良いプリセットプロンプトの条件:

  • 丁寧さの特徴を明示的に名指しする(例:「해요체」、「vous 形」、「siz 形」)
  • 使用する具体的な代名詞や動詞形を説明する
  • このレジスターが適切な場面の文脈を示す
  • 該当する場合は文字体系に関する考慮事項を記載する

禁止事項: プリセットプロンプトに性別包括的なガイダンスを含めないでください。性別ガイダンスは card.gender.inclusiveGuidance に属します — 別途注入されます。

❌ Bad: "Standard Thai. Professional register."
✔ Good: "Professional Thai. Use คุณ (khun) for second person, เรา (rao)
for first person when needed. Clear, concise phrasing
appropriate for digital interfaces."

プリセット命名規則

プリセットキーは説明的で、小文字ハイフン区切りにすべきです:

  • T-V 言語:formal-vousinformal-tuformal-Siecasual-du
  • 話し言葉レベル:polite-haeyoformal-hapsyocasual-hae
  • 中立:professionalneutral-professional
  • コードスイッチング:taglish-professionalpure-filipino

エンリッチメント手順

カードごとの処理順序

カードをエンリッチする際は、この順序で情報源を参照してください。データが得られなかった場合も含め、参照したすべての情報源を記録してください。

  1. ISO 639-3 レジストリcodenameisoScopeisoType
  2. ISO 639-3 macrolanguages.tabmacrolanguage
  3. Glottolog languoid.csvglottocodeclassificationcoordinatescountries
  4. Glottolog CLDFmacroareaisIsolatefirstDocumentedlastDocumented
  5. Glottolog AESvitality(危機度ステータス)
  6. Wikidata SPARQLnativeNamespeakerEstimatesscriptscriptsdir
  7. CLDRrules(タイポグラフィ、複数形規則、大文字化)
  8. NLLB-200 / FLORES+methodSupport.nllbevalDatasets
  9. API 検証 → 残りの methodSupport エントリ
  10. ML モデル論文metricModelSupport(XLM-R 訓練データ、AfriCOMET カバレッジ) スクリプト:node scripts/enrich-metric-model-support.mjs

競合の処理

情報源が一致しない場合:

  1. 出典の帰属とともに両方を保存する
  2. 平均を取ったり、どちらかを選んだりしない(禁止
  3. 関連する note フィールドに不一致を記録する
  4. 計算に単一の値が必要な場合のみ、最新の一次資料を優先する

バリデーション

エンリッチメントまたは手動編集の後、リンターを実行してください:

node scripts/lint-language-cards.mjs # all cards
node scripts/lint-language-cards.mjs --lang crk # single card

PR チェックリスト

新規または変更された言語カードを提出する際:

  • shared/language-cards/ 内でファイル名が <code>.json になっている
  • 標準テンプレートのすべてのトップレベルフィールドが存在する
  • classification が Glottolog から入力されている(手動で構築されていない)
  • dataSources に参照したすべての情報源が列挙されている
  • methodSupport エントリが実際の API 言語リストに対して検証されている
  • contactInfluences エントリに出版された情報源または citation_needed: true がある
  • linguisticChallenges に MT に関連する課題が 3〜6 件記載されている(調査済みの場合)
  • rules が CLDR から入力されている(ロケールデータが存在する場合)
  • リンターがエラーなしで通過する

専門的参照資料

標準管理機関当プロジェクトでの用途
ISO 639-3SIL International標準言語コード、マクロ言語の関係
GlottologMax Planck Institute分類、座標、AES 危機度
WALSMax Planck Institute属の定義、類型論的特徴
ISO 15924Unicode/ISOスクリプトコード
CLDRUnicode Consortiumロケールデータ、複数形規則、タイポグラフィ
WikidataWikimedia Foundation話者数、自称名、スクリプトデータ
EthnologueSIL InternationalEGIDS、話者数推定、DLS
UNESCO AtlasUNESCO危機度分類
Katig CollectiveUP Dilimanフィリピン言語カプセル

詳細な情報源ごとのガイダンスについては、言語カード引用手順も参照してください。