champollion 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (170) hide show
  1. package/LICENSE +133 -0
  2. package/README.md +387 -0
  3. package/bin/cli.js +278 -0
  4. package/index.js +135 -0
  5. package/lib/api-key.js +127 -0
  6. package/lib/autofix.js +432 -0
  7. package/lib/bridge/method_bridge.py +430 -0
  8. package/lib/card-source-resolution.mjs +284 -0
  9. package/lib/cards/cache.js +169 -0
  10. package/lib/cards/env.js +82 -0
  11. package/lib/cards/fetch-card-child.js +38 -0
  12. package/lib/cards/reader.js +435 -0
  13. package/lib/cards/refresh.js +111 -0
  14. package/lib/cards/remote.js +387 -0
  15. package/lib/cldf-export.mjs +540 -0
  16. package/lib/cldf-terms.mjs +62 -0
  17. package/lib/command-help.js +790 -0
  18. package/lib/commands/audit.js +49 -0
  19. package/lib/commands/card.js +454 -0
  20. package/lib/commands/doctor.js +559 -0
  21. package/lib/commands/fonts.js +489 -0
  22. package/lib/commands/help.js +91 -0
  23. package/lib/commands/init.js +1259 -0
  24. package/lib/commands/integrity.js +148 -0
  25. package/lib/commands/leaderboard.js +478 -0
  26. package/lib/commands/lint.js +30 -0
  27. package/lib/commands/models.js +177 -0
  28. package/lib/commands/plugin.js +103 -0
  29. package/lib/commands/provenance.js +45 -0
  30. package/lib/commands/recommend.js +75 -0
  31. package/lib/commands/register-corpus.js +678 -0
  32. package/lib/commands/repair-script.js +42 -0
  33. package/lib/commands/seal-corpus.js +355 -0
  34. package/lib/commands/seo.js +72 -0
  35. package/lib/commands/serve.js +147 -0
  36. package/lib/commands/status.js +265 -0
  37. package/lib/commands/submit.js +332 -0
  38. package/lib/commands/sync.js +89 -0
  39. package/lib/commands/tm.js +573 -0
  40. package/lib/commands/verify.js +39 -0
  41. package/lib/commands/watch.js +20 -0
  42. package/lib/commands/wrap.js +138 -0
  43. package/lib/commands/xliff.js +327 -0
  44. package/lib/commercial-eligibility.js +235 -0
  45. package/lib/concurrent.js +87 -0
  46. package/lib/config.js +523 -0
  47. package/lib/contamination-lane.js +76 -0
  48. package/lib/content-sync.js +731 -0
  49. package/lib/content.js +733 -0
  50. package/lib/corpus-registration.mjs +608 -0
  51. package/lib/cost-report.js +346 -0
  52. package/lib/diff.js +155 -0
  53. package/lib/docusaurus-sync.js +1256 -0
  54. package/lib/flatten.js +55 -0
  55. package/lib/format.js +954 -0
  56. package/lib/hash.js +159 -0
  57. package/lib/icu.js +473 -0
  58. package/lib/integrity.js +689 -0
  59. package/lib/license-gate.mjs +478 -0
  60. package/lib/license-identify.mjs +229 -0
  61. package/lib/lint.js +629 -0
  62. package/lib/method-manifest.js +60 -0
  63. package/lib/methods/anthropic.js +140 -0
  64. package/lib/methods/apertium.js +163 -0
  65. package/lib/methods/api.js +316 -0
  66. package/lib/methods/base.js +184 -0
  67. package/lib/methods/content-separator.js +45 -0
  68. package/lib/methods/deepl.js +426 -0
  69. package/lib/methods/direct-llm.js +586 -0
  70. package/lib/methods/external.js +332 -0
  71. package/lib/methods/fetch-with-retry.js +124 -0
  72. package/lib/methods/gemini.js +147 -0
  73. package/lib/methods/google-translate.js +402 -0
  74. package/lib/methods/http-utils.js +122 -0
  75. package/lib/methods/libretranslate.js +314 -0
  76. package/lib/methods/llm-coached.js +670 -0
  77. package/lib/methods/llm.js +592 -0
  78. package/lib/methods/local.js +76 -0
  79. package/lib/methods/microsoft-translator.js +331 -0
  80. package/lib/methods/openai.js +131 -0
  81. package/lib/methods/openrouter-client.js +327 -0
  82. package/lib/methods/openrouter-pricing.js +156 -0
  83. package/lib/methods/provider-env.js +115 -0
  84. package/lib/methods/provider-pricing.js +310 -0
  85. package/lib/methods/tilde.js +150 -0
  86. package/lib/methods/translated.js +229 -0
  87. package/lib/methods/translation-error.js +80 -0
  88. package/lib/models.js +258 -0
  89. package/lib/no-translate.js +233 -0
  90. package/lib/output.js +238 -0
  91. package/lib/pairs.js +547 -0
  92. package/lib/plugins.js +447 -0
  93. package/lib/provenance.js +323 -0
  94. package/lib/recommend.js +648 -0
  95. package/lib/registers.js +1185 -0
  96. package/lib/repair-script.js +266 -0
  97. package/lib/scripts.js +994 -0
  98. package/lib/seal.mjs +464 -0
  99. package/lib/sealed-qualifier.mjs +211 -0
  100. package/lib/security.js +59 -0
  101. package/lib/segment.js +369 -0
  102. package/lib/seo.js +275 -0
  103. package/lib/serve.js +854 -0
  104. package/lib/string-classify.js +85 -0
  105. package/lib/submit.mjs +344 -0
  106. package/lib/sync.js +969 -0
  107. package/lib/tags/bcp47.js +202 -0
  108. package/lib/tags/resolve.js +314 -0
  109. package/lib/terminology.js +111 -0
  110. package/lib/tm-seed.js +294 -0
  111. package/lib/tm.js +515 -0
  112. package/lib/translate-pair.js +197 -0
  113. package/lib/translate.js +203 -0
  114. package/lib/types.js +230 -0
  115. package/lib/validate.js +510 -0
  116. package/lib/verify.js +451 -0
  117. package/lib/watch.js +145 -0
  118. package/lib/xliff.js +184 -0
  119. package/package.json +93 -0
  120. package/shared/ATTRIBUTION.md +145 -0
  121. package/shared/CORPORA-CARDS.md +288 -0
  122. package/shared/DATA-SOVEREIGNTY.md +500 -0
  123. package/shared/LANGUAGE-CARD-FIELDS.md +532 -0
  124. package/shared/card-lint-baseline.json +3189 -0
  125. package/shared/cards-fallback.json +1 -0
  126. package/shared/catalogue/card-config.json +6091 -0
  127. package/shared/catalogue/external-results.json +3888 -0
  128. package/shared/catalogue/gender-guidance.json +1038 -0
  129. package/shared/catalogue/method-coverage.json +1751 -0
  130. package/shared/catalogue/metric-coverage.json +170 -0
  131. package/shared/catalogue/metric-reliability.json +1 -0
  132. package/shared/catalogue/register-presets.json +3180 -0
  133. package/shared/catalogue/vitality-scales.json +55 -0
  134. package/shared/cldr-index.json +1115 -0
  135. package/shared/code-bridge.json +253 -0
  136. package/shared/corpora-cards-v1-reference.md +281 -0
  137. package/shared/curated-dictionary-flags.json +35 -0
  138. package/shared/curated-endonyms.json +35 -0
  139. package/shared/curated-fsts.json +51 -0
  140. package/shared/curated-orthography-conventions.json +26 -0
  141. package/shared/curated-sil-resources.json +374 -0
  142. package/shared/curated-tools.json +41 -0
  143. package/shared/docent/corpus.json +11333 -0
  144. package/shared/docent/faq.en.json +564 -0
  145. package/shared/docent/register-blocks.json +60 -0
  146. package/shared/docent/system-prompt.md +144 -0
  147. package/shared/domain-taxonomy.json +35 -0
  148. package/shared/explainers/glossary.json +2975 -0
  149. package/shared/explainers/tc-features.json +20112 -0
  150. package/shared/explainers/term-watchlist.json +147 -0
  151. package/shared/human-services.json +59 -0
  152. package/shared/license-corrections.json +261 -0
  153. package/shared/license-evidence.json +13452 -0
  154. package/shared/licenses.json +6781 -0
  155. package/shared/method-registry.json +236 -0
  156. package/shared/metric-registry.json +620 -0
  157. package/shared/model-aliases.json +7 -0
  158. package/shared/schemas/champollion-plugin.schema.json +206 -0
  159. package/shared/schemas/corpora-card.schema.json +957 -0
  160. package/shared/schemas/domain-taxonomy.schema.json +64 -0
  161. package/shared/schemas/external-results.schema.json +314 -0
  162. package/shared/schemas/human-services.schema.json +90 -0
  163. package/shared/schemas/language-card.schema.json +1308 -0
  164. package/shared/schemas/licenses.schema.json +155 -0
  165. package/shared/schemas/method-card.schema.json +412 -0
  166. package/shared/schemas/method-registry.schema.json +85 -0
  167. package/shared/schemas/metric-registry.schema.json +96 -0
  168. package/shared/schemas/metric-reliability.schema.json +178 -0
  169. package/shared/schemas/model-aliases.schema.json +27 -0
  170. package/shared/schemas/source-snapshot.schema.json +96 -0
@@ -0,0 +1,288 @@
1
+ # Corpora Cards
2
+
3
+ > **Corpora cards are the single source of truth (SSOT) for all dataset metadata in Champollion.** They describe evaluation sets and reference corpora in a structured, fact-checked format that all components (arena, harness, website) load from.
4
+
5
+ ## Architecture
6
+
7
+ ```
8
+ cli/shared/corpora-cards/ ← SSOT: metadata about datasets
9
+ arena/datasets/curated/ ← DATA: actual sentence pairs
10
+ arena/datasets/registry.json ← GENERATED: index for harness resolver
11
+ ```
12
+
13
+ | Layer | Contains | Role | Edited by |
14
+ |-------|----------|------|-----------|
15
+ | **Corpora cards** | License, provenance, contamination, stewardship | Truth about what a dataset IS | Humans (fact-checked) |
16
+ | **Curated data** | `{entries: [{id, source, reference}]}` | The actual sentences | Scripts + community |
17
+ | **Registry** | Paths, IDs, sizes | What the harness loads | `build_registry.py` only |
18
+
19
+ > [!CAUTION]
20
+ > **Never edit `registry.json` directly.** Edit the corpora card, then run `python arena/scripts/build_registry.py` to regenerate the registry.
21
+
22
+ ---
23
+
24
+ ## Two Types of Cards
25
+
26
+ ### Reference Corpus (`ref-*.json`)
27
+
28
+ Catalogues an external dataset that exists in the world. These are for development and practice — **NOT used for official Champollion evaluation**.
29
+
30
+ Examples: FLORES+, NTREX-128, Tatoeba Challenge, AmericasNLP shared task data.
31
+
32
+ **Use reference cards when:** You want to document a dataset that users can download for development, note its contamination risk, or track its license terms.
33
+
34
+ ### Champollion Eval Set (`eval-*.json`)
35
+
36
+ A pair-specific, community-curated dataset used for official Champollion evaluation. These are the real benchmarks.
37
+
38
+ **Key properties:**
39
+ - **Pair-specific**: One source language → one target language
40
+ - **Directional**: `eng→crk` is a different eval set from `crk→eng`
41
+ - **Community-created**: Quality-controlled by language community members
42
+ - **May have a secret test split**: Created by and controlled by the community
43
+
44
+ **Use eval cards when:** A dataset has been curated for evaluating MT quality on a specific language pair.
45
+
46
+ ---
47
+
48
+ ## Naming Convention
49
+
50
+ | Type | Pattern | Example |
51
+ |------|---------|---------|
52
+ | Reference | `ref-{name}.json` | `ref-flores-plus.json` |
53
+ | Eval set | `eval-{src}-{tgt}-{source}-{segment}-v{N}.json` | `eval-eng-crk-edtekla-dev-v1.json` |
54
+
55
+ The `eval-` prefix makes it instantly clear this is a benchmark, not just a dataset catalogue entry.
56
+
57
+ ---
58
+
59
+ ## Official Champollion Evaluation
60
+
61
+ Official eval sets have three components:
62
+
63
+ | Split | Location | Access | Purpose |
64
+ |-------|----------|--------|---------|
65
+ | **Dev** | `curated/` (distributed) | Everyone | Local testing, prompt tuning |
66
+ | **Test** | `curated/` (distributed) | Everyone | Self-scoring, debugging |
67
+ | **Secret** | Server-side only | Server process only | Official leaderboard scoring |
68
+
69
+ ### Secret Test Sets
70
+
71
+ Secret test sets are **created by the language community, not held-out splits from public data**. They are:
72
+
73
+ - Never distributed with the package
74
+ - Never visible to method authors
75
+ - Cryptographically hashed (SHA-256 published in the card for integrity verification)
76
+ - Only unlocked by steward authorization
77
+
78
+ ### Multi-Signature Stewardship
79
+
80
+ Each official eval set has a stewardship council:
81
+
82
+ - **5 stewards** appointed by the language community
83
+ - **3 of 5 approvals** needed to authorize a secret test run
84
+ - Stewards receive push notifications via app
85
+ - **Consent is per-submission** — no blanket authorization
86
+ - Each authorization is logged and auditable
87
+
88
+ ### Method Submission Flow
89
+
90
+ ```
91
+ Method author submits to arena
92
+ │
93
+ ├─→ PUBLIC EVAL (dev set)
94
+ │ Results displayed immediately
95
+ │
96
+ └─→ SECRET EVAL REQUEST
97
+ Status: "Pending Steward Authorization"
98
+ │
99
+ ├─→ 5 stewards notified via app
100
+ │ 3/5 push "Authorize"
101
+ │ Keys unlock secret test set
102
+ │
103
+ ├─→ Method runs in sandbox against secret test
104
+ │ Scores computed server-side
105
+ │ Results posted to arena
106
+ │
107
+ └─→ IF scores ≥ acceptance threshold:
108
+ Status: "Under Community Review for Prize"
109
+ IP transfer agreement activated
110
+ ```
111
+
112
+ ### IP Transfer on Success
113
+
114
+ By submitting a method for secret evaluation, the author agrees to transfer all rights to the technology and intellectual property to the evaluation stewards if the method passes the community's acceptance threshold.
115
+
116
+ > [!WARNING]
117
+ > **Infrastructure status**: The steward app, multi-sig key management, server-side sandbox, and eval API are **not yet built**. The corpora card schema accommodates them via `secretTest`, `stewardship`, and `submission` fields, but these contain placeholder values until the infrastructure exists.
118
+
119
+ ---
120
+
121
+ ## Schema Reference
122
+
123
+ ### Core Fields (all cards)
124
+
125
+ | Field | Type | Required | Description |
126
+ |-------|------|----------|-------------|
127
+ | `id` | string | ✅ | Unique ID. Must match filename. Pattern: `ref-*` or `eval-*`. |
128
+ | `type` | enum | ✅ | `"reference"` or `"eval"` |
129
+ | `name` | string | ✅ | Human-readable name |
130
+ | `version` | string | ✅ | Corpus version (semver recommended) |
131
+ | `description` | string | ✅ | What it is and why it matters |
132
+ | `source` | object | ✅ | Publisher, URL, paper, citation |
133
+ | `license` | object | ✅ | SPDX, commercial use, redistribution, AI training terms |
134
+ | `contamination` | object | ✅ | Risk level + evidence-based reasoning |
135
+ | `_provenance` | object | ✅ | When added + what sources were consulted |
136
+
137
+ ### Eval-Only Fields
138
+
139
+ | Field | Type | Required | Description |
140
+ |-------|------|----------|-------------|
141
+ | `pair` | object | ✅ | Source/target ISO 639-3 codes + direction |
142
+ | `dev` | object | ✅ | Dev split metadata: size, domain, data file path |
143
+ | `doNotTrain` | boolean | ✅ | Must be explicitly set for eval data |
144
+ | `quality` | object | — | Human-translated? Translator qualifications? Review process? |
145
+ | `secretTest` | object | — | Secret test set hash, status, server endpoint |
146
+ | `stewardship` | object | — | Steward list, threshold, authorization model |
147
+ | `submission` | object | — | IP transfer terms, acceptance threshold |
148
+
149
+ ### Reference-Only Fields
150
+
151
+ | Field | Type | Required | Description |
152
+ |-------|------|----------|-------------|
153
+ | `languages` | string[] | ✅ | ISO 639-3 codes of all languages covered |
154
+ | `download` | object | ✅ | Method, URL, instructions |
155
+ | `segments` | object[] | — | Available data splits (dev, devtest, test) |
156
+
157
+ ---
158
+
159
+ ## Building the Registry
160
+
161
+ After editing corpora cards, regenerate `registry.json`:
162
+
163
+ ```bash
164
+ # Preview what would be generated
165
+ python arena/scripts/build_registry.py --dry-run
166
+
167
+ # Show diff against current registry
168
+ python arena/scripts/build_registry.py --diff
169
+
170
+ # Build
171
+ python arena/scripts/build_registry.py
172
+ ```
173
+
174
+ ---
175
+
176
+ ## Registering a Corpus: License + Exposure
177
+
178
+ The fastest, safest way to author an eval card is the guided command — it puts
179
+ **you** in control of the license and how far the corpus travels, and it
180
+ **never reads, uploads, or hosts your corpus text** (in any tier):
181
+
182
+ ```bash
183
+ champollion register-corpus # interactive wizard
184
+ champollion register-corpus --list # show licenses + exposure tiers
185
+ champollion register-corpus --help # all flags (scriptable for agents)
186
+ ```
187
+
188
+ ### License (plain language)
189
+
190
+ Pick what others may do with your set. The choice fills in `license.spdx` plus
191
+ the `commercial` / `redistribution` booleans on the card:
192
+
193
+ | Option | Means |
194
+ |--------|-------|
195
+ | **CC-BY-4.0** | Use and share freely, even commercially, with credit. |
196
+ | **CC-BY-SA-4.0** | Like CC-BY, but derivatives must share alike. |
197
+ | **CC0 / public domain** | No rights reserved; anyone may do anything. |
198
+ | **CC-BY-NC-4.0** | Non-commercial use only — **blocked from public/ranked lanes**. |
199
+ | **Proprietary / all rights reserved** | You keep full control; not publicly redistributable. |
200
+ | **Other / custom** | Unconfirmed — treated as not-redistributable until verified. |
201
+
202
+ You may also pass any SPDX id to `--license`; it is classified through
203
+ [`cli/lib/license-gate.mjs`](lib/license-gate.mjs).
204
+
205
+ ### Exposure tiers (default: the most private)
206
+
207
+ Chosen explicitly with `--tier`. Champollion never hosts content in **any** of them:
208
+
209
+ | Tier | What happens | Card lands in |
210
+ |------|--------------|---------------|
211
+ | **local-only** *(default)* | Never registered, never uploaded. Card + text stay on your machine. | your working dir (`--out`), **not** the tracked SSOT |
212
+ | **private** | Register **metadata only** — a WMT-style sovereign/held-out set. Text never uploaded or hosted; you keep custody. The card is `quarantine: true` (catalogued, not publicly runnable). | `corpora-cards/` |
213
+ | **public** | Publish a metadata card **+ a fetch-from-source pointer** (`source.repo_url` + `builder`). Text is fetched from source on demand — never hosted here. **Gated**: NC / no-redistribute / unconfirmed licenses are rejected; use private/local-only instead. | `corpora-cards/` |
214
+
215
+ The tier is recorded on the card as `exposureTier`. Consumer-report metadata
216
+ (license, contamination risk, size/length, domain) is collected at registration
217
+ so every new set is properly marked.
218
+
219
+ > [!NOTE]
220
+ > **We never store your text.** `register-corpus` writes a *metadata card*, not
221
+ > your sentences. For `public`, the data is fetched from `source.repo_url` by the
222
+ > declared builder at run time; for `private`/`local-only`, it never leaves your
223
+ > machine. The CI quarantine gate (`scripts/quarantine_gate.sh`) enforces this.
224
+
225
+ ---
226
+
227
+ ## Adding a New Dataset
228
+
229
+ ### Adding a Reference Corpus
230
+
231
+ 1. Create `cli/shared/corpora-cards/ref-{name}.json`
232
+ 2. Fill in ALL required fields from the dataset's official documentation
233
+ 3. Set `contamination.risk` with evidence-based reasoning
234
+ 4. Set `_provenance.populatedFrom` to the exact documents you consulted
235
+ 5. Verify: `source.url` must resolve, `license.spdx` must match actual license
236
+
237
+ ### Adding an Eval Set
238
+
239
+ **Recommended:** run `champollion register-corpus` (see
240
+ [Registering a Corpus](#registering-a-corpus-license--exposure) above) — it
241
+ writes a schema-valid card with the license + exposure tier you choose, and
242
+ never touches your text. Then rebuild the registry. To author by hand instead:
243
+
244
+ 1. Create `cli/shared/corpora-cards/eval-{src}-{tgt}-{name}-{segment}-v{N}.json`
245
+ 2. Add the actual data file to `arena/datasets/curated/` **only** for permissive,
246
+ redistribution-cleared corpora — never for private/NC/no-redistribute content
247
+ (those stay fetch-from-source or local; see exposure tiers above)
248
+ 3. Verify `dev.size` matches `jq '.entries | length'` on the data file
249
+ 4. Run `python arena/scripts/build_registry.py` to update the registry
250
+ 5. Run `npm test` in `cli/` to verify nothing is broken
251
+
252
+ ### Population Rules
253
+
254
+ - **Every field must come from a verifiable source.** No guesses, no "seems reasonable."
255
+ - If you can't verify a field, set it to `null`.
256
+ - `_provenance.populatedFrom` must cite the specific document/URL consulted.
257
+ - `contamination.reasoning` must cite evidence for the risk rating.
258
+ - `quality.translatorQualifications` stays `null` unless the paper describes who translated.
259
+
260
+ ---
261
+
262
+ ## Cross-References
263
+
264
+ ### Language Cards → Corpora Cards
265
+
266
+ Language cards reference eval sets via the `evalDatasets` field:
267
+
268
+ ```json
269
+ // In cli/shared/language-cards/crk.json:
270
+ "evalDatasets": ["eval-eng-crk-edtekla-dev-v1"]
271
+ ```
272
+
273
+ The string is the corpora card ID. It resolves to `cli/shared/corpora-cards/eval-eng-crk-edtekla-dev-v1.json`.
274
+
275
+ Reference corpora (FLORES+, etc.) are **NOT** listed in `evalDatasets`. They belong in `corpusAvailability` — they are development resources, not evaluation benchmarks.
276
+
277
+ ### Harness → Corpora Cards
278
+
279
+ The harness resolver (`config.py:resolve_dataset()`) loads datasets via registry.json, which is generated from the cards. The flow:
280
+
281
+ ```
282
+ User runs: mt-eval run --corpus eval-eng-crk-edtekla-dev-v1
283
+ → resolve_dataset() checks local path (not found)
284
+ → loads registry.json
285
+ → finds entry with matching ID
286
+ → loads curated/eng-crk-dev-v1.json
287
+ → runs evaluation
288
+ ```