Skip to content

Release 7.51.1a1 - #778

Open
github-actions[bot] wants to merge 199 commits into
masterfrom
release-7.51.1a1
Open

Release 7.51.1a1#778
github-actions[bot] wants to merge 199 commits into
masterfrom
release-7.51.1a1

Conversation

@github-actions

@github-actions github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown

Human review requested!

JarbasAl and others added 30 commits July 16, 2026 23:20
* Update kab.json

Add post-sonorant occlusivization blocking rules for /k/ and /ɡ/

* kab: rework k/ɡ spirantization, fix Bedar et al. citation

kab: rework k/ɡ spirantization, fix Bedar et al. citation

- Remove KAB_SPIRANT_K_ALT and the [ʃ] allophone of /k/: the k→ʃ
  value is Riffian-only in Kossmann & Stroomer (1997) p.469 and never
  occurs in Kabyle (native-speaker verified).
- Replace the 7 sonorant-specific blocking rules (K/G_AFTER_R/L/N/M)
  with generalized KAB_BLOCK_SPIRANT_K_AFTER_CONSONANT and
  KAB_BLOCK_SPIRANT_G_AFTER_CONSONANT: /k/→[ç] and /ɡ/→[ʝ] only
  post-vocalically and word-initially; stops after any consonant.
  Exception kept: /ɡ/ stays [ʝ] after /m/ (/mʝ/→[mʝ], Bedar, Quellec
  & Tifrit 2022). Contexts cover all singleton + geminate consonants.

* kab: drop t-before-i block, restore anta example, add 6 sources

kab: drop t-before-i block, restore anta example, add 6 sources

- Remove KAB_BLOCK_SPIRANT_T_BEFORE_I: speaker re-verification
  (2026-07-17) confirms word-initial /t/ is always [θ] before /i/
  (tifinaɣ, tilufa, tilelli, tikwal) — the 2026-07-16 table stands.
  24 → 23 allophone rules.
- Restore anta as the T_AFTER_N example with corrected gloss: native
  Kabyle 'which one (f.)' (feminine of anwa), not the Arabic pronoun —
  only the old gloss was wrong.
- Sources 6 → 12: add Chaker 1996 (INALCO notation), Mammeri 1976,
  Souag 2019, Wang 2020 (McGill Working Papers — corrects a
  miscitation), the 2026-07 native-speaker verification record, and
  the 2026-07-17 corpus audit. Notes now list the pending speaker
  checks (intervocalic -ti-; askar/sk schwa question).

Engine-verified on orthography2ipa 7.30.0a3 (fork): all outputs match
predictions.

* kab: realize /ɣ/ as uvular [ʁ] by default

kab: realize /ɣ/ as uvular [ʁ] by default

Source check (Kabyle consonant chart: ɣ in the uvular column as [ʁ];
IPA [ʁ] article's word-final Kabyle example bbeɣ → [bːəʁ]; no
word-final devoicing documented for Kabyle): add
KAB_GH_UVULAR_REALIZATION and its geminate counterpart so /ɣ/ surfaces
as [ʁ] in all positions. Underlying phoneme and rule contexts
unchanged; broad [ɣ] retained as documented variant. 23 → 25 rules.

* Improving kabyle

* Improving kabyle specs

* Improved kabyle specs

* Improved kabyle specs - json format
…greement boards (#636)

The scoreboard now carries 553 rows across every gold set the engine
ships, up from 467: the languages added since the last regeneration are
scored, cmudict and the Arabic diacritized set included. The espeak
board gains en-US and splits the single pt row into the five Portuguese
lects.
…d a stale regression baseline (#637)

* fix(kab): validate against the schema, and re-pin the gold to the sourced rules

The Kabyle spec carried a 'type' key on seven sources[] entries. The
schema's SourceModel is strict and has no such field, so every spec
validation failed; the provenance claim now opens each source's notes,
which the model does define.

The spec's rules are better sourced than the expectations they broke:
/ʝ/ occlusivizes after r, l, n but not after m (bedar_quellec_tifrit_2022
on Chemini Kabyle), so argaz keeps its stop; the /k/ -> [ʃ] rule was
Kossmann & Stroomer's RIFFIAN illustration and its removal makes amek
agree with its own cited note ([ç]); and /ɣ/ is the uvular [ʁ] in every
position. The tests now assert the sourced behaviour on both sides of
the blocking context, the twenty gold rows are re-pinned, and the notes
that still described the old realizations are corrected.

The velar_fricative tag accepts either realization of the one phoneme,
and kab-004 drops a spirantization tag its transcription no longer earns
(fourteen other rows carry the feature).

* fix(ci): install the Portuguese syllabifier in the test environment

The gold sets and benchmark baselines pin engine output produced with
the silabificador plugin loaded, but the plugin lived only in the
'portuguese' extra while build-tests, coverage and the benchmark gate
all install '.[test]'. Without it the syllabifier falls back and stress
lands elsewhere, so twenty Portuguese gold rows across fourteen lects
failed in CI while passing locally for anyone who had the plugin
installed.

* fix(ci): refresh the benchmark regression baseline

The sample baseline had not been refreshed since #361, so it covered 206
of the 551 rows the engine now scores and measured dev's whole
accumulated drift rather than a PR's own effect. Every PR since — #614
among them — met a red gate and merged through it, which is what a
baseline this old makes inevitable.

Rescored at the same uniform limit: 56 rows improve beyond epsilon
(ms/ipadict 0.5509 -> 0.0751, kab/vox_communis 0.3711 -> 0.2242,
eu/wikipron 0.0640 -> 0.0227) and 8 worsen. The 8 are listed in the PR
so they stay visible rather than folding silently into a new baseline;
ca-x-balear/4catac and pt-PT-x-porto/ep_dialects are the two worth a
look, both expert-human golds moved by the Iberian vocalism work.
Expose the prosodic-clitic test as module-level orthography2ipa.stress
functions so the engine and any downstream assembler place word stress
from one shared definition of stress.cliticless_words. G2P._is_cliticless
delegates to them; behaviour is unchanged.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
A bare region tag whose specs are all sub-regional had no exact match, so
nearest-language fallback picked whichever private-use sibling sorted
first: ar-SA resolved to ar-SA-x-dawasir. A dialect named in a private-use
subtag was invisible to tag distance, so ar-x-najdi fell through to ar.

Add a curated region-default table (ar-SA -> ar-SA-x-najd) alongside the
bare-primary defaults, and private-use dialect aliases (ar-x-najdi ->
ar-SA-x-najd, ar-x-hejazi -> ar-SA-x-hejaz). The Saudi default is an
explicit editorial convention — Najdi is the capital region's variety and
the most widely spoken (Ingham 1994) — not a claim in the spec data that
Saudi Arabic is Najdi. Unmatched Arabic tags still fall back to the ar
(MSA) leaf.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
The grapheme→IPA front-end runs once per utterance before synthesis, so
per-sentence latency is what matters. Profiling the transcribe path showed
two pure redundancies over immutable spec data:

- transcribe_word ran the pronunciation beam, then rebuilt a nearly
  identical rules-only lattice via ipa_lattice purely to read the
  confidence score.
- syllabification (the silabificador plugin) was recomputed several times
  per word — stress detection and the lattice each asked for it — and again
  for every repeat of a function word.

Memoize both per engine, keyed only on the word and this engine's fixed
stress spec. Neither consults the runtime-mutable lexicon, so a fresh
engine gets fresh caches and results are byte-identical. Real speech
repeats function words heavily, so the hit rate is high.

Steady-state per-utterance latency drops ~2-2.6x across en-GB, pt-PT,
es-ES and ar (pt-PT p99 7.2ms -> 3.4ms). Output — IPA and confidence,
greedy and beam — is byte-identical across an 8-language differential, and
the full suite passes unchanged. benchmarks/latency.py is the repro.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…#654)

* feat: add gaa, ada, gen, aja language specs

Ga, Dangme/Adangme, Gen (Mina) and Aja — Ghana/Togo Kwa and Gbe
languages. Research-tier grapheme/allophone inventories cited to
Wikipedia and published phonological descriptions (Kropp Dakubu 1999,
Apronti 1967); gen/aja pull their allophone stratum from the closely
related Ewe (`ee`) spec via allophones_base.

* feat: add tw, fat Akan-variety language specs

Twi and Fante as individual-language codes inheriting the shared
Akan (`ak`) grapheme table via graphemes_base/allophones_base; fat
overrides Fante's distinguishing affricate contrast (ts/dz/z) and
labial-palatalised digraphs (tw/dw/hw). Pins the two individual
codes in registry.py's alias table (same fix already applied to
bxr/diq) since langcodes' macro=True standardisation otherwise
collapses them into the ak macrolanguage. Refreshes the Glottolog
level snapshot for the five new glottolog_code values and adds
cited family-level test cases for all six new specs.
…ulde specs (#655)

* feat: add Serer (srr) language spec

Northern Atlantic (Senegambian) branch of Atlantic-Congo. Cited to
Wikipedia and McLaughlin (2000); quality: research.

* feat: add Soninke (snk) language spec

Soninke-Bozo branch of Mande. Cited to Wikipedia and Creissels (2016);
quality: research.

* feat: add Susu (sus) language spec

Susu-Yalunka branch of Central Mande. Cited to Wikipedia and Houis
(1963); quality: research.

* feat: add Mende (men) language spec

Southwestern Mande. Cited to Wikipedia and Innes (1969); quality:
research.

* feat: add Temne (tem) language spec

Mel branch of Atlantic-Congo. Cited to Wikipedia and Wilson (1961);
quality: research.

* feat: add Pular (fuf) and Nigerian Fulfulde (fuv) language specs

Both wired as parent_dialect children of ff via graphemes_base/parent,
since neither source consulted documents a Fula-variety-specific
grapheme or allophone divergence. Cited to Wikipedia and Arnott
(1970); quality: research.

* test: add cited-rule tests for the new Atlantic and Mande specs

One test per key cited claim (srr vowel length + implosives, snk vowel
length + affricate, sus/men labiovelars, men affricate vs. sus glide,
tem dental/alveolar contrast, fuf/fuv ff inheritance) on real words.

* fix(data): correct citation-validation findings for sus and tem specs

- sus.json: Wikipedia's Susu phoneme table (fetched) explicitly states
  nasal vowels are spelled as vowel+n digraphs (in/un/en/on/ɛn/ɔn/an);
  the previous notes claimed this was unconfirmed and omitted the
  graphemes. Add the seven nasal-vowel graphemes/allophones and fix the
  notes to cite the confirmed spelling convention.
- tem.json: add Kanu & Tucker (2010) JIPA "Illustrations of the IPA"
  as the primary fetched source, confirming the 9-vowel inventory and
  the dental/alveolar ⟨th⟩=/t̪/ vs ⟨t⟩=/t/ contrast, and clarifying that
  /tʃ/, /ʃ/, /w/ are dialectal variants rather than independently
  spelled phonemes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
The README and several docs quoted a fixed 676 languages / 749 spec
files figure. Running available_codes() against the current data now
gives 820 languages and 909 entries including classification-only
clade nodes, and that count changes as specs are added.

Rather than hardcode a new snapshot that will drift the same way,
each mention now points at the one-line command a reader can run to
get the live count: available_codes() and
available_codes(include_clades=True).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* feat: add Sasak, Rejang, Pijin language specs

Research-grounded Latin-orthography specs for Sasak (sas, Lombok),
Rejang (rej, Sumatra) and Pijin (pis, Solomon Islands), each cited
against Wikipedia and published grammars/phonology sources.

* feat: add Avestan spec and Sogdian/Khotanese/Parthian stubs

Avestan (ae) is scored in the standard Hoffmann scholarly
transliteration of the native Avestan script, following the akk.json/
pal.json precedent for ancient languages with non-Latin scripts.

Sogdian (sog), Khotanese (kho) and Parthian (xpr) are added as honest
stubs with full metadata and empty graphemes: each survives in
multiple divergent script/transliteration traditions with no single
citable letter-to-IPA table, so no inventory is asserted.

* fix(data): validate sas/rej/pis/ae specs against fetched primary sources

- sas.json: add Archangeli/Tanashur/Yip (2020) JIPA Illustration of the
  Meno-Mene dialect as primary source; model word-final <q> = /ʔ/ as a
  positional_graphemes rule (directly attested in the JIPA word list);
  clarify the 6-vowel (JIPA fieldwork) vs 8-vowel (Wikipedia, other
  dialects) vowel-count discrepancy in notes.
- rej.json: add fetched Omniglot citation; model word-final <k> = [ʔ]
  as a positional_graphemes rule ("K is pronounced [ʔ] at the end of
  words" - Omniglot); leave <q> unmodelled since no IPA value is
  confidently sourced for it.
- pis.json: remove unsupported <y> = /j/ grapheme (Wikipedia's Pijin
  alphabet excludes y; search evidence points to <i> being used
  instead, e.g. "iu" for "you"); fix notes claim that both voiceless
  and voiced English th merge with /t/ - fetched Wikipedia source shows
  voiceless th merges with /s/ (maos "mouth"), only voiced th merges
  with /t/ (brata "brother"); add sh/z merger details.
- ae.json: add Skjaervo (2007) "Old Iranian" chapter (fetched directly,
  PDF) as the actually-verified primary source after the Encyclopaedia
  Iranica articles by the same author returned HTTP 403 on every fetch
  attempt; cross-checked the full Hoffmann transliteration letter set
  against Skjaervo's own alphabet/vowel/consonant tables - no mapping
  corrections were needed, all graphemes confirmed.

All four specs pass the full test suite (1208 passed, 2 pre-existing
xfails unrelated to these files) and the derivable-key/positional-key
audits from SKILLS.md.
…drift (#670)

The CUNY-CL/wikipron Welsh scrape changed upstream (897 -> 894 entries),
shifting the sampled gold set and its PER (0.2175 -> 0.2297) with no code
or spec change in this repo — verified by bisecting dev back past all of
today's data merges and the #645 caching merge, which all score
identically. Rebuild the single (cy, wikipron) row with the same
build_scoreboard code path (bootstrap CI included), following the stale
baseline precedent of #637.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
JarbasAl and others added 30 commits August 3, 2026 19:51
Citation-verifies 6 more skeleton-tier specs from the fresh 37-candidate
pool (skeleton + non-empty graphemes + registered gold, per
docs/quality_tiers.md's research-tier criteria): kru, bbl, kwk, srs,
kld, bdq. Each already had a real Wikipedia orthography source; the gap
was a primary reference grammar/dictionary and a cited stress
block/exemption.

- kru (Kurukh): added Winfield 1928 (A Grammar of the Kurux Language).
  Grapheme table (Devanagari retroflex/aspirate/nasal series, nuqta
  letters) checked: no discrepancy found. Descriptive phonological work
  reports Kurukh word accent as weak and variable across syllables
  rather than a fixed positional rule, so no `stress` block is added
  (documented exemption) rather than encoding a guess.
- bbl (Bats/Tsova-Tush): added Holisky & Gagua 1994 (Tsova-Tush
  (Batsbi), in Smeets ed., Indigenous Languages of the Caucasus vol.
  4). Grapheme table (Georgian ejective series, added letters) checked:
  no discrepancy found. Added a cited stress rule (default_position=1)
  approximating the documented initial-syllable tendency;
  morphologically-conditioned shifts are a documented gap.
- kwk (Kwak'wala): added Boas 1947 (Kwakiutl Grammar, Transactions of
  the American Philosophical Society 37(3)). Grapheme table
  (labialized/lateral/affricate series) checked: no discrepancy found.
  Stress is quantity-sensitive and, in current analyses, phrasal rather
  than a fixed word position (Boas 1947; Elfner 2024), which this
  project's positional `stress` schema cannot express without a
  syllable-weight primitive, so no `stress` block is added (documented
  exemption).
- srs (Sarsi/Tsuut'ina): added Cook 1984 (A Sarcee Grammar). Grapheme
  table (lateral/ejective/affricate series) checked: no discrepancy
  found. Tsuut'ina is a tone language (Cook 1984; reported as a
  three-way H/M/L system in later work), not a stress language, and
  tone is not consistently marked in the mapped orthography, so no
  `stress` block is added (documented exemption).
- kld (Gamilaraay): added Austin 1993 (A Reference Grammar of
  Gamilaraay, Northern New South Wales). Grapheme table (stop series,
  retroflex r, digraph values) checked: no discrepancy found. Added a
  cited stress rule (default_position=1): word-initial primary stress,
  the typologically regular Pama-Nyungan pattern.
- bdq (Bahnar): added Banker & Banker 1979 (Bahnar Dictionary,
  Bahnar-Vietnamese-English, SIL). Grapheme table (Vietnamese-style
  digraphs, implosives, vowel letters) checked: no discrepancy found.
  Added a cited stress rule (default_position=-1): Bahnaric
  sesquisyllabic words carry stress on the word-final main syllable;
  non-native disyllabic loans are a documented gap.

None of the six required a grapheme-table fix, so no PER numbers
changed; only each spec's `quality_tier` was hand-updated in
benchmarks/results.json and docs/scoreboard.md (not regenerated via
--scoreboard/--ci-sample), per wave-2 precedent. No CI-sample epsilon
concerns are expected since no PER value moved.

31 candidates remain in the fresh audit pool (skeleton + non-empty
graphemes + registered gold, missing a real source or stress
block/exemption) after this wave's 6 promotions, left for a future
wave. `tn` and `ale` were left untouched: `tn`'s only registered gold
row is a 0-entry stub-tier placeholder (no usable PER to certify a
promotion against), and `ale` carries a prior deliberate skeleton
decision (documented gold mismatch) that this wave respects rather
than re-litigating.

Authorship: Claude Sonnet, orchestrated by Fable, per repo AGENTS.md.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
Gold-hunting wave 1: audited all 41 WOLD (World Loanword Database)
languages against the o2i spec registry. Gawwada, Iraqw, Seychelles
Creole and Tarifiyt Berber each have a non-empty grapheme table and no
existing gold anywhere in the registry; all four smoke-checked at
~100% non-empty engine coverage on a 150-row sample. Rows recorded in
benchmarks/results.json and docs/scoreboard.md, with the full audit
(what was already covered, what has no spec, what is stub-empty)
documented in docs/benchmarks.md.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* data: orthography wave 6 -- 10 registry stubs upgraded with cited orthographies

Cantonese (yue, Jyutping), Saraiki (skr, Shahmukhi) promoted to research tier
and wired to WikiPron gold (yue_latn_standard_broad, skr_arab_broad). Southern
Min (nan, POJ), Hakka (hak, Phåk-fa-sṳ), Wu (wuu, Wugniu), Eastern Min
(cdo, Bàng-uâ-cê), Gan (gan, Gan Wikipedia romanisation), Northern
Hindko (hno, Shahmukhi), Rohingya (rhg, RLC Latin alphabet) and Chittagonian
(ctg, Bengali script with cited divergent values) promoted to skeleton tier
with cited grapheme maps and documented tone/stress exemptions.

Co-Authored-By: Claude Sonnet 5 (Fable orchestration) <noreply@anthropic.com>

* fix: drop Sinitic base-spec romanization graphemes and the loanword yue gold

The five Han-script base specs (yue/nan/hak/wuu/cdo) must stay grapheme-
empty per the zh-Hani principle: a Han character encodes no sound, and
their romanizations already live in the dedicated -Latn-* script-variant
specs (which these divergent duplicate tables contradicted). gan's 'Gan
Wikipedia romanisation' is a wiki convention, not a citable standard.
The yue wikipron file was previously audited and rejected as English
loanword entries (PER 0.71 confirms); registration and rows removed.
Wave 6 keeps its four legitimate native-script languages: skr Saraiki
(Shahmukhi, wikipron research), hno Hindko, rhg Rohingya, ctg
Chittagonian.

---------

Co-authored-by: Claude Sonnet 5 (Fable orchestration) <noreply@anthropic.com>
Wires udm, ady, av, lbe, dar, lez, lv, smn, vep into
_NORTHEURALEX_LANGS: each had zero gold anywhere and a non-empty
grapheme table. Language-ID mappings were verified against NEL's own
cldf/languages.csv (not a naive ISO 639-3 lookup) -- av -> ava and
lv -> lav needed an explicit code translation, and dar was checked
against its glottocode (darg1241, "North-Central Dargwa") to confirm
it is the same Akusha-based literary standard the o2i dar spec
targets. All 9 passed a 100-sample smoke gate (100% non-empty output,
real per-language orthography in Value) before full-dataset scoring.

dar is promoted skeleton -> research: it already had sources and a
documented stress exemption, and now has a registered gold row
(1056 entries, PER 0.0833) to complete the tier's criteria. The other
8 languages were already labeled research pending exactly this gold
registration.

benchmarks/results.json and docs/scoreboard.md are hand-updated with
the new rows (full-dataset PER, no --scoreboard/--ci-sample rerun).

Authorship: Claude Sonnet, orchestrated by Fable (Anthropic).

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
…ve-speaker spot-checked (#767)

Registers Salesteq/arabic-dialects-gold20 (public HF dataset) at the
llm-generated provenance tier: semi-synthetic, authored by the same
Claude lineage that wrote o2i's Arabic dialect specs (near-circular —
the dataset carries an ipa_o2i draft column), spot-checked by a native
Arabic speaker, registered on explicit maintainer instruction because
for most of these 33 dialects no other gold exists. PERs 0.002-0.05 =
self-agreement, documented as such; no quality-tier promotion may rest
on these rows. Runtime fetch only, nothing vendored.
* feat: gold-hunting wave 2 -- register kaikki.org Wiktextract gold for 4 zero-gold languages

Wires a new generic kaikki.org (Wiktextract) loader and registers gold for
jv (Javanese), su (Sundanese), lo (Lao) and xh (Xhosa) -- all zero-gold
skeleton specs with a non-empty grapheme table, cross-referenced against
the full o2i registry before selection. Each language was downloaded,
filtered to sounds[].ipa entries, hand-sampled, and smoke-checked for
>=70% non-empty engine coverage; jv needed a Latin-script filter since
kaikki's Javanese dump is majority Aksara Jawa. Tigrinya was rejected
(only 28/933 entries carry ipa). Findings on lo/xh spec gaps recorded in
docs/benchmarks.md for a future (non-gold) wave. No promotions: all four
lack a stress block/exemption required for the research tier.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>

* chore: record the four kaikki rows in results.json + scoreboard

---------

Co-authored-by: Claude Sonnet 5 <noreply@anthropic.com>
…771)

Promote 6 empty REGISTRY STUB specs (ckt Chukchi, itl Itelmen, ket Ket,
gld Nanai, ddo Tsez, ess Central Siberian Yupik) from stub to research
tier with cited Cyrillic grapheme tables, NorthEuraLex gold registered
and PER recorded after one error-analysis iteration each.

mnc (Manchu) is promoted using the Moellendorff Latin romanization,
verified as the actual orthographic convention NorthEuraLex's Value
column uses (not the vertical Manchu script), cited to Moellendorff
1892 / Gorelova 2002.

bsk (Burushaski) is evaluated and deliberately NOT promoted: its NEL
gold is Berger (1998) scholarly transcription, not a community
orthography, so no graphemes or gold registration are added -- the
verdict is documented in the spec's notes.

Authorship note: drafted by Claude (Sonnet) under Fable orchestration.
* data: NEL convention fixes — fold ASCII/IPA g confusable in the harness

The 9 newly-measured NorthEuraLex languages from #765 (udm, ady, av, lbe,
dar, lez, lv, smn, vep) all showed a `g -> ɡ` confusion in
scripts/error_analysis.py: NEL's CLDF Segments column keys the voiced
velar plosive with ASCII "g" (U+0067) while every o2i spec correctly
emits the IPA symbol ɡ (U+0261, LATIN SMALL LETTER SCRIPT G). No
registered spec's own phonemes list contrasts the two (checked against
every data/*.json), so this is a Unicode-confusable typographic accident
in the gold data, not a phonemic distinction — folded unconditionally in
scripts/benchmark.py's normalize().

PER before -> after (northeuralex, full dataset):
  udm 0.2287 -> 0.2110
  ady 0.1745 -> 0.1684
  av  0.1115 -> 0.0990
  lbe 0.0443 -> 0.0387
  dar 0.0833 -> 0.0691
  lez 0.1513 -> 0.1329
  lv  0.2046 -> 0.1901
  smn 0.1755 -> 0.1600
  vep 0.2276 -> 0.2065

Other seeded udm confusions (gold ɑ vs spec a, gold l vs spec ɫ, gold
sʲ/zʲ/lʲ vs spec ɕ/ʑ/ʎ palatalization notation) were investigated and
NOT changed: several other registered specs contrast both members of
each pair in their own phoneme inventories (e.g. tyv/mzn contrast ɑ/a,
sjt/enf contrast sʲ/ɕ, diq/kdr contrast ɫ/l), so a normalizer fold is
not linguistically defensible for ALL languages — these are legitimate
per-language transcription-convention differences, not spec bugs, and
are left alone per the "don't chase" guidance.

Because the fold lives in the shared harness (normalize()), it also
shifts PER for the co-registered NEL Siberian-batch codes (liv/sms/sjd/
yrk/bua/evn/niv/ale/ain — verified liv 0.1019 -> 0.0748) and possibly
other g-bearing rows outside northeuralex; those rows are intentionally
left untouched here (out of scope, owned by other in-flight work) for
the next full scoreboard regen to pick up.

Co-authored-by: Claude Sonnet under Fable orchestration

* chore: refresh the 9 co-registered NEL rows for the g/ɡ fold

* fix: fully recompute the 8 co-affected NEL rows (per+CI+exact_match) — adversarial review finding
* data: Siberian double-win batch A (Uralic+Yukaghir)

Cited Cyrillic grapheme tables for 8 REGISTRY STUBs whose NorthEuraLex gold
was already waiting, promoting each to research tier: Meadow Mari (mhr,
Alhoniemi 1985), Hill Mari (mrj, Kangasmaa-Minn 1998), Northern Khanty (kca,
Nikolaeva 1999), Northern Mansi (mns, Riese 2001), Northern Selkup (sel,
Helimski 1998 in Abondolo), Nganasan (nio, Wagner-Nagy 2018), Forest Enets
(enf, Siegl 2013) and Northern Yukaghir (ykg, Maslova 2003).

Each spec reconciles its grapheme table against the pre-existing PHOIBLE
phoneme inventory, documents a cited stress exemption, registers the
NorthEuraLex gold row (Language_ID verified against cldf/languages.csv;
all eight equal the o2i code, no av->ava-style translation needed), and
went through one error-analysis iteration against the gold before the
final PER was recorded:

- mhr: 0.3037 -> 0.1869 (a as /ɑ/, л palatalises to fused /ʎ/)
- mrj: 0.0629 -> 0.0140 (д as lenited /ð/, not Meadow Mari's /d/)
- kca: 0.3236 -> 0.0232 (ӆ as /ɬ/, х as /χ/, ы as /ɪ/, э as /ə/, т unaspirated)
- mns: 0.3102 -> 0.1024 (vowel-quality fixes, labialised кв/хв clusters,
  plain ɲ/ʎ palatals, sʲ series added)
- sel: 0.1852 -> 0.0353 (a not ä, fused ɲ/ʎ palatals)
- nio: 0.2283 -> 0.1075 (a as /ɐ/, complete н/д palatalisation series)
- enf: 0.3161 -> 0.1073 (a not ɑ, е/э as /ɛ/, х as /h/, ɲ/ʎ palatals, ⟨ҫ⟩ added)
- ykg: 0.5090 -> 0.3940 (ч as /tʃ/, нь/дь as /nʲ/dʲ/ per Maslova's own
  transcription convention, preferred over inherited PHOIBLE symbols)

Authorship: Claude Sonnet under Fable orchestration.

* fix: kca same-corpus-tuning caveat + mns fixed-initial stress block — adversarial review findings
* fix: n=0 gold vox_communis rows (tn, ug fake-stub; yue dead pairing)

benchmarks/results.json recorded tn/ug/yue vox_communis rows at a fake
per=1.0/n=0 ("stub" tier snapshot). n=0 in build_scoreboard() means
`covered` (G2P-transcribable words) was zero, not that the loader
returned nothing -- the upstream tn.tsv/ug.tsv/yue.tsv files all fetch
fine (live-checked) and load_vox_communis() yields thousands of pairs
for each.

Root cause differs per language:
- tn, ug: the recorded n=0 was STALE. Both specs now transcribe their
  respective gold real words fine (tn: 2271/2272 covered, PER 0.40;
  ug: 40716/40721 covered, PER 0.09) -- re-running the same scoring
  code the committed row used shows they never should have been 0.
  Refreshed both rows with current numbers.
- yue: genuinely UNTRANSCRIBABLE, not stale. The `yue` (Cantonese)
  spec is a documented grapheme-inventory STUB: Cantonese is
  logographic and has no letter-to-sound mapping without a
  Jyutping/Yale romanisation step this library doesn't have (same
  class of gap as `zh` needing pinyin). vox-communis' yue.tsv gives
  raw Han characters, so G2P('yue') emits "" for every row -- the
  n=0/per=1.0 the harness recorded was real, but reporting it as a
  benchmark result is dishonest (reads as "loader broken", not "this
  pairing can never score"). Deregistered `yue` from
  `_VOX_COMMUNIS_FILES` with a comment explaining why, matching the
  existing `_IPADICT_UNWIRED`-style honesty precedent for the same
  Han-script problem, and dropped its row from results.json/scoreboard.md.

Full test suite green (196593 passed, 0 failed).

Co-Authored-By: Claude Sonnet 5 (Fable) <noreply@anthropic.com>

* data: sources wave 4 -- 2 skeletons promoted to research (tn, chb)

Fresh audit of the skeleton + non-empty-graphemes + registered-gold
pool (docs/quality_tiers.md research-tier criteria) after wave 3.
Citation-verifies 2 skeletons; the rest of the pool (33 candidates:
ale, aot, apw, bjb, cnk, gwc, gwd, hts, irk, kix, lou, lsi, mtq, ngh,
nhg, nhx, nmy, pbv, pcc, pt-CV, pt-MO, rgn, sce, sdc, sia, tew, twf,
ulw, wbk, xsl, ycl, yux, zom) is skipped honestly this wave: most only
carry Glottolog/Wikipedia/Omniglot citations with no independently
verifiable primary reference behind the grapheme table, and two
(pt-CV, pt-MO, ale) already carry an explicit "kept deliberately at
skeleton, do not promote" note from a prior pass -- respected here,
not re-litigated.

- tn (Tswana): already cited Cole 1955 ("An Introduction to Tswana
  Grammar") as a read primary alongside Wikipedia. Grapheme table
  (ejective k/p/t/ts/tl/pj vs aspirate kh/ph/th/tsh/tlh series,
  implosive b, kg=/x/, g=/ɣ/, click q/qh restricted to
  ideophones/loans) checked against it and against the cited
  Wikipedia 'Tswana phonology' article: no discrepancy found. Stress
  is non-contrastive/predictable in Tswana (tone carries the
  distinctive prosodic load instead), documented as an exemption
  matching the sibling `st`/Southern Sotho precedent, which was
  promoted without a stress block on the same grounds. Gold:
  vox_communis, PER 0.40, n=2271 (also fixed in the prior commit).
- chb (Chibcha/Muisca, extinct): the spec's own notes already named
  Constenla (1984) and Gonzalez de Perez (2006) in prose as the basis
  for the reconstructed phonemic values, but neither was a formal
  `sources` entry -- only Glottolog+Wikipedia were. Verified both are
  real, independently-published works (Constenla Umaña, "Los fonemas
  del muisca", Estudios de Lingüística Chibcha 2:65-111, 1984;
  González de Pérez, "Aproximación al sistema fonético-fonológico de
  la lengua muisca", Instituto Caro y Cuervo, 2006) and added them as
  proper cited sources. Stress is exempt: the language is extinct with
  no living pronunciation and neither reconstruction recovers word
  stress from the colonial spelling. Gold: wikipron, PER 0.13, n=99.

Full test suite green (196593 passed, 0 failed).

Co-Authored-By: Claude Sonnet 5 (Fable) <noreply@anthropic.com>

* fix: refuse to record zero-coverage scoreboard rows — adversarial review finding

evaluate_words defaults per/wer to 1.0 on covered==0 and build_scoreboard
appended the row unconditionally, so a transient loader failure fabricated
a plausible-looking per=1.0, n=0 row (the exact origin of the stale tn/ug/
yue rows this PR cleans up). build_scoreboard now loudly refuses such rows;
regression tests pin both the refusal and the normal path.

---------

Co-authored-by: Claude Sonnet 5 (Fable) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants