From 845b7538b1276818d95959262bf5253f3ac67929 Mon Sep 17 00:00:00 2001 From: Derek Gulbranson Date: Tue, 20 Oct 2026 00:45:33 -0700 Subject: [PATCH 1/4] Give the credentials their languages (part 1 of #751) The 605 credential readings in und.toml move to en.toml, and fourteen to de.toml: the German parliamentary memberships and StB alone, and BA, BSc, MA, MSc, MEng, MBA and LL.M. beside en.toml, on #18's evidence that German names carry them. The rai/cha/mai refusals move with them. No compiled set moves; the snapshot matches. und.toml's vetting comments become fields: the case-mask block is `excluded = { cased = ... }` on meng, edd, lac and ded, ba gains the note that earned its marking, abd's credential half becomes expands and a note, and the class-level ambiguity block, already held by decisions/suffix-acronym-collisions and rules/S1/S4/S6, is gone. Co-Authored-By: Claude Opus 5.5 --- .../design/decisions/vocabulary-exclusions.md | 2 +- docs/design/decisions/vocabulary-model.md | 8 + nameparser/vocab/README.md | 4 +- nameparser/vocab/de.toml | 56 + nameparser/vocab/en.toml | 2422 +++++++++++++++- nameparser/vocab/und.toml | 2566 +---------------- tests/v2/test_vocab.py | 6 +- 7 files changed, 2487 insertions(+), 2577 deletions(-) diff --git a/docs/design/decisions/vocabulary-exclusions.md b/docs/design/decisions/vocabulary-exclusions.md index ec1c2382..0976f14f 100644 --- a/docs/design/decisions/vocabulary-exclusions.md +++ b/docs/design/decisions/vocabulary-exclusions.md @@ -80,7 +80,7 @@ Excluded (MAIDEN_MARKERS, the birth_marker readings): Excluded (CAPITALIZATION_EXCEPTIONS — meng, edd, lac, ded, left out of the 2026-09-24 masks, #459): -- `meng` (MEng) and `edd` (EdD) are conventionally mixed-case credentials and listed acronyms, and must not get a mask while the map stays role-free: a mask applies in every role, and both are borne as given names or surnames. Measured 2026-09-24 with each mask added to a private lexicon: `MENG LI` gives `MEng Li`, `meng wang` gives `MEng Wang`, `edd smith` gives `EdD Smith` and `EDD KIMBER` gives `EdD Kimber`, where the shipped map and every release give `Meng Li`, `Meng Wang`, `Edd Smith` and `Edd Kimber`. The same holds for two sweep candidates, `lac` (LAc, Licensed Acupuncturist; `Lac` is a Vietnamese given name — the trailing word in native order, `Nguyễn Văn Lạc` — and a French surname; corrected 2026-09-25, #540, from "a Vietnamese and French surname") and `ded` (DEd; `Ded` is an Albanian given name, `ded gjo luli` giving `DEd Gjo Luli` under the mask). A writer who spells one mixed-case keeps it (decisions/R5, 2026-09-24); a caller who wants the mask adds it to a private lexicon. A NOTE on `SUFFIX_ACRONYMS` itself, which this map does not decide. The two name-word collisions there come from two bulk additions, not one: `lac` (with `edd` and `ded`) from the Wikipedia post-nominals import, `af5bdab` (2019-12-11, #93), and `meng` from `3e14ea20` (2026-07-01, the German/Dutch title and degree batch, first shipped in 1.3.0). Both read as a suffix after a given name, and lose a family name to it (superseded 2026-09-25 by #540: both words are marked ambiguous, `wang meng` reads family `meng` and renders `Wang Meng` — see #suffix-acronym-collisions). Measured 2026-09-24 on the released wheels, the parent 4d0680e6 and this tree: `wang meng`, `li meng` and `zhang meng` read family `meng` on 1.4.0 and suffix `meng`, with no family, on every release from 2.0.0; and since #521 on master the suffix renders `Wang MENG` (parent and tree alike), where 2.3.0 gave `Wang Meng`. `nguyen van lac` reads suffix `lac` with family `van` on every release from 1.4.0, and since #521 renders `Nguyen Van LAC` where 2.3.0 gave `Nguyen Van Lac`. This is a #vocabulary-collisions C-i question about the acronym set, not about this map. +- A listed credential borne as a name gets no mask while the map stays role-free: a mask applies in every role, so it re-spells the name wherever the word is one. MEng, EdD, LAc and DEd are conventionally mixed-case credentials and listed acronyms, and each is borne as a given name or surname (Meng, Edd, Lac, Ded). A writer who spells one mixed-case keeps it (decisions/R5, 2026-09-24); a caller who wants the mask adds it to a private lexicon. The per-word refusals are data since #751 (2026-10-20): each word carries `excluded = { cased = … }` on its credential reading in en.toml, its reason the rendering measured with the mask added to a private lexicon (`MENG LI` giving `MEng Li`, 2026-09-24; `lac`'s on 2026-09-25), and `uv run python tools/vocab/query.py --excluded cased` lists them; a contributor who adds one of the masks meets the reason as a build error. Where `meng` and `lac` stand in SUFFIX_ACRONYMS itself, a #vocabulary-collisions C-i question this map does not decide, is #suffix-acronym-collisions' #540 entry. `lac`, `edd` and `ded` arrived with the Wikipedia post-nominals import (af5bdab, 2019-12-11, #93) and `meng` with 3e14ea20 (2026-07-01, the German/Dutch title and degree batch). Excluded (CAPITALIZATION_EXCEPTIONS — md, ii, iii, iv, removed 2026-09-23, #459): diff --git a/docs/design/decisions/vocabulary-model.md b/docs/design/decisions/vocabulary-model.md index ba37c381..719b4ef7 100644 --- a/docs/design/decisions/vocabulary-model.md +++ b/docs/design/decisions/vocabulary-model.md @@ -74,3 +74,11 @@ The vocabulary was a set of base sets plus marker subsets (`particles` and `part - **Gender** follows part 1's rule. The man's title of a noble pair is marked (`count`, `baron`, `graf`) as `king` is, and so is a `-man` word whose `-woman` pair the list holds (`businessman`); a descriptive noun beside its `-ess` form marks only the feminine (`actress`, `heiress`). `sultan` records none, Ottoman usage having given it to imperial women too (its note in tr.toml). - **Comments became fields.** The #269, #343 and #344 block comments over the native-script titles are notes on one entry of each group (the Hebrew quote-boundary probe on `ד"ר`, the Bengali doctor split on `ড`); `duke`'s one-line keep-out is an exclusion in en.toml with its counts; the notes part 1 left on `lord`, `lady`, `venerable`, `rabbi` and `imam` moved with them. The readings `und.toml` shares with a moved title, all credentials (`cpl`, `cpo`, `cpt`, `csm`, `lt`, `md`, `ra`, `sa`, `sgm`, `vc`, and `ms` from part 1), sit in a section of their own, as #749's did. - **Recompute** rather than quoting: `uv run python tools/vocab/query.py --kind title --file und --count`, `--file en --kind modifier --count`, `--file mul`. + +- **2026-10-20 #751 — the credentials given their languages (part 1 of #751).** No compiled set moves: `tools/vocab/build.py --check` reports the committed module current, and `tools/differential/snapshot.py` matches. The 605 credential readings in `und.toml` on a0edfeda left it, so `und.toml` holds no suffix reading, and the three credential refusals (`rai`, `cha`, `mai`) went with them to en.toml. + - **English holds all but seven.** 505 of the 605 came from one import (af5bdab, 2019, #93), the United States post-nominal letters of two Wikipedia lists, and most of the rest are British and Commonwealth honours and degrees, from the list's first versions and #7; all of these are in en.toml. Recompute the provenance with `git blame -w 6803a261 -- nameparser/config/suffixes.py`, the last commit before the TOML. + - **German names hold fourteen.** #18 (3e14ea20) added the German parliamentary memberships (`mdb`, `mdl`, `mda`, `mdbb`, `mdep`, `mdhb`) and `stb` (Steuerberater) for German names; they are in de.toml alone, with `expands`. The same batch added `ba`, `bsc` and `meng` for German degree holders, and #18's test data writes BA, BSc, M.Sc., M.A., M.Eng., MBA and LL.M. after German names, so those seven are in de.toml beside en.toml. A degree goes to a file on evidence that names in that language carry it, which is why no credential went to mul.toml: the Bologna degrees are written after names in most European languages, but the evidence in hand is German. + - **A behavioral property travels to every file, a descriptive one stays on one.** Check 5 holds every behavioral property of a word's suffix readings to one value in every file, `cased` among them, so the de.toml readings repeat `may_be_name` and `cased` (check 7's "at most one `cased` per word" counts values, not files); the `note`, `expands` and `issue` of the English reading stay in en.toml, and each German reading cites #18. + - **Comments became fields.** und.toml's block over the ambiguous credentials was class-level — the criterion is decisions/suffix-acronym-collisions' and decisions/vocabulary-collisions' C-i, the reading rules/S4 and S6, the bracket escape rules/S1 — and is gone, its per-word facts already notes on `ms`, `sa`, `se`, `om`, `mc`, `vd`, `meng` and `lac`; `ba` gained the note that earned its marking. The block over the case masks became `excluded = { cased = … }` on `meng`, `edd`, `lac` and `ded`, each with the rendering a mask would cost (decisions/vocabulary-exclusions' CAPITALIZATION_EXCEPTIONS block keeps the class-level part), and the credential half of `abd`'s comment became `expands` and a `note` on its en.toml reading. + - **`mc` sorts as a credential now.** An entry sorts under its earliest kind and `credential` precedes `clan`, so en.toml's `mc` left `mac`'s side for the credential block, its `same_as` kept. + - **Recompute** rather than quoting: `uv run python tools/vocab/query.py --kind credential --file en --count`, `--kind credential --file de`, `--kind suffix --file und --count`, `--excluded cased`. diff --git a/nameparser/vocab/README.md b/nameparser/vocab/README.md index 4ae825c0..496b5d68 100644 --- a/nameparser/vocab/README.md +++ b/nameparser/vocab/README.md @@ -12,7 +12,7 @@ A file is named for a BCP 47 language tag in canonical case: `fr.toml`, `pt-BR.t Two tags are not languages: -- **`und`** (undetermined) holds the words not yet assigned a language. A third of the entries are still here (653 of 1,941 on 2026-10-19, after #750 classified the titles), converted mechanically from the Python lists it used to be; assigning a word to a language means moving its entry to that language's file. The comments above an entry here are the vetting notes that stood above the word in the Python module, in their old order; classifying a category is what turns them into fields. +- **`und`** (undetermined) holds the words not yet assigned a language. A few are still here (46 of 1,938 on 2026-10-20, after #751 gave the credentials their languages): the conjunctions, the bound given names, the birth markers and two particles, converted mechanically from the Python lists they used to be; assigning a word to a language means moving its entry to that language's file. The comments above an entry here are the vetting notes that stood above the word in the Python module, in their old order; classifying a category is what turns them into fields. - **`mul`** (multiple) holds words shared on purpose, such as the Roman numerals. The script is read from the word, not from the file: `sr.toml` holds `mlađi` and `млађи` side by side. A script subtag (`zh-Hant`) is for a difference the text cannot show. @@ -49,7 +49,7 @@ expands = "of the, masc. sg." note = "Vietnamese Đỗ leads a great many surnames" ``` -`do` has two readings in two categories, a credential (still in `und.toml`) and a particle (a Portuguese preposition, in `pt.toml`), so it is in both `SUFFIX_ACRONYMS` and `PARTICLES`; which one applies is decided by where the word stands. A word's readings are where clashes between categories are recorded: before this format, such a clash was visible only as two sets that happened to overlap. +`do` has two readings in two categories, a credential (an American degree, in `en.toml`) and a particle (a Portuguese preposition, in `pt.toml`), so it is in both `SUFFIX_ACRONYMS` and `PARTICLES`; which one applies is decided by where the word stands. A word's readings are where clashes between categories are recorded: before this format, such a clash was visible only as two sets that happened to overlap. ```toml [[word]] diff --git a/nameparser/vocab/de.toml b/nameparser/vocab/de.toml index 7b9ea75b..e824878c 100644 --- a/nameparser/vocab/de.toml +++ b/nameparser/vocab/de.toml @@ -118,6 +118,62 @@ nobility = { gender = "m", expands = "imperial count" } text = "ritter" nobility = { gender = "m", expands = "knight" } +[[word]] +text = "ba" +credential = { may_be_name = true, issue = 18 } + +[[word]] +text = "bsc" +credential = { cased = "BSc", issue = 18 } + +[[word]] +text = "llm" +credential = { issue = 18 } + +[[word]] +text = "ma" +credential = { may_be_name = true, issue = 18 } + +[[word]] +text = "mba" +credential = { issue = 18 } + +[[word]] +text = "mda" +credential = { issue = 18, expands = "Mitglied des Abgeordnetenhauses" } + +[[word]] +text = "mdb" +credential = { issue = 18, expands = "Mitglied des Bundestages" } + +[[word]] +text = "mdbb" +credential = { issue = 18, expands = "Mitglied der Bremischen Bürgerschaft" } + +[[word]] +text = "mdep" +credential = { issue = 18, expands = "Mitglied des Europäischen Parlaments" } + +[[word]] +text = "mdhb" +credential = { issue = 18, expands = "Mitglied der Hamburgischen Bürgerschaft" } + +[[word]] +text = "mdl" +credential = { issue = 18, expands = "Mitglied des Landtages" } + +[[word]] +text = "meng" +credential = { may_be_name = true, issue = 18 } + +[[word]] +text = "msc" +credential = { cased = "MSc", issue = 18 } + +[[word]] +text = "stb" +credential = { issue = 18, expands = "Steuerberater, tax adviser" } + [[word]] text = "auf" preposition = { may_be_given = false, issue = 18, expands = "upon: \"auf der Heide\"" } diff --git a/nameparser/vocab/en.toml b/nameparser/vocab/en.toml index 8a28f82e..f15dc29a 100644 --- a/nameparser/vocab/en.toml +++ b/nameparser/vocab/en.toml @@ -47,6 +47,8 @@ salutation = { gender = "f" } [[word]] text = "ms" salutation = { gender = "f" } +[word.credential] +note = "NOT may_be_name, though #296's audit table put it there for the leading-title collision: the gate is position-blind and the collision is not (gated, 'John Smith, MS' read title 'MS'); a title/credential dual that position decides (decisions/C8)" [[word]] text = "mx" @@ -103,6 +105,7 @@ academic = { expands = "the address of an engineer, 'Engr. Cruz' in the Philippi [[word]] text = "md" academic = { note = "the medical degree written before the name (#32); a leading Md. abbreviating Muhammad lands in the same field (decisions/indic-honorifics)" } +credential = {} [[word]] text = "nurse" @@ -509,6 +512,7 @@ military = { same_as = "captain" } [[word]] text = "cpt" military = { same_as = "captain" } +credential = {} [[word]] text = "ccmsgt" @@ -553,14 +557,17 @@ military = {} [[word]] text = "cpl" military = { same_as = "corporal" } +credential = {} [[word]] text = "cpo" military = { expands = "Chief Petty Officer" } +credential = {} [[word]] text = "csm" military = { expands = "Command Sergeant Major" } +credential = {} [[word]] text = "cwo2" @@ -641,6 +648,7 @@ military = {} [[word]] text = "lt" military = { same_as = "lieutenant" } +credential = {} [[word]] text = "ltc" @@ -749,6 +757,7 @@ military = { same_as = "radm" } [[word]] text = "sa" military = { expands = "Seaman Apprentice" } +credential = { note = "NOT may_be_name, for the reason recorded on ms (decisions/C8)" } [[word]] text = "scpo" @@ -769,6 +778,7 @@ military = { expands = "Sergeant First Class" } [[word]] text = "sgm" military = { expands = "Sergeant Major" } +credential = {} [[word]] text = "sgtmaj" @@ -1097,6 +1107,7 @@ office = {} [[word]] text = "vc" office = { expands = "Vice-Chancellor" } +credential = {} [[word]] text = "verderer" @@ -2264,6 +2275,2408 @@ generation = {} text = "snr" generation = { same_as = "sr" } +[[word]] +text = "8-vsb" +credential = {} + +[[word]] +text = "aas" +credential = {} + +[[word]] +text = "aba" +credential = {} + +[[word]] +text = "abc" +credential = {} + +[[word]] +text = "abd" +[word.credential] +expands = "All But Dissertation" +note = "also the Latin transliteration of the Arabic bound given name abd; position decides at the two ends but not in a family comma's given slot, where 'Smith, Abd' reads suffix 'Abd' (decisions/P5)" + +[[word]] +text = "abpp" +credential = {} + +[[word]] +text = "abr" +credential = {} + +[[word]] +text = "aca" +credential = {} + +[[word]] +text = "acas" +credential = {} + +[[word]] +text = "ace" +credential = {} + +[[word]] +text = "acha" +credential = {} + +[[word]] +text = "acp" +credential = {} + +[[word]] +text = "ae" +credential = {} + +[[word]] +text = "aem" +credential = {} + +[[word]] +text = "afasma" +credential = {} + +[[word]] +text = "afc" +credential = {} + +[[word]] +text = "afm" +credential = {} + +[[word]] +text = "agsf" +credential = {} + +[[word]] +text = "aia" +credential = {} + +[[word]] +text = "aicp" +credential = {} + +[[word]] +text = "ala" +credential = {} + +[[word]] +text = "alc" +credential = {} + +[[word]] +text = "alp" +credential = {} + +[[word]] +text = "am" +credential = {} + +[[word]] +text = "amd" +credential = {} + +[[word]] +text = "ame" +credential = {} + +[[word]] +text = "amieee" +credential = {} + +[[word]] +text = "ams" +credential = {} + +[[word]] +text = "aphr" +credential = {} + +[[word]] +text = "apn" +credential = {} + +[[word]] +text = "apr" +credential = {} + +[[word]] +text = "aprn" +credential = {} + +[[word]] +text = "apss" +credential = {} + +[[word]] +text = "aqp" +credential = {} + +[[word]] +text = "arm" +credential = {} + +[[word]] +text = "arrc" +credential = {} + +[[word]] +text = "asa" +credential = {} + +[[word]] +text = "asc" +credential = {} + +[[word]] +text = "asid" +credential = {} + +[[word]] +text = "asla" +credential = {} + +[[word]] +text = "asp" +credential = {} + +[[word]] +text = "atc" +credential = {} + +[[word]] +text = "awb" +credential = {} + +[[word]] +text = "ba" +[word.credential] +may_be_name = true +expands = "Bachelor of Arts" +issue = 342 +note = "Ba is a real surname (Vietnamese; Senegalese Fula) about as common as BA is a credential, the ma/Ma shape" + +[[word]] +text = "bca" +credential = {} + +[[word]] +text = "bcl" +credential = {} + +[[word]] +text = "bcss" +credential = {} + +[[word]] +text = "bds" +credential = {} + +[[word]] +text = "bem" +credential = {} + +[[word]] +text = "bls-i" +credential = {} + +[[word]] +text = "bn" +credential = {} + +[[word]] +text = "bpe" +credential = {} + +[[word]] +text = "bpi" +credential = {} + +[[word]] +text = "bpt" +credential = {} + +[[word]] +text = "bsc" +credential = { cased = "BSc" } + +[[word]] +text = "bt" +credential = { cased = "Bt" } + +[[word]] +text = "btcs" +credential = {} + +[[word]] +text = "bts" +credential = {} + +[[word]] +text = "cacts" +credential = {} + +[[word]] +text = "cae" +credential = {} + +[[word]] +text = "caha" +credential = {} + +[[word]] +text = "caia" +credential = {} + +[[word]] +text = "cams" +credential = {} + +[[word]] +text = "cap" +credential = {} + +[[word]] +text = "capa" +credential = {} + +[[word]] +text = "capm" +credential = {} + +[[word]] +text = "capp" +credential = {} + +[[word]] +text = "caps" +credential = {} + +[[word]] +text = "caro" +credential = {} + +[[word]] +text = "cas" +credential = {} + +[[word]] +text = "casp" +credential = {} + +[[word]] +text = "cb" +credential = {} + +[[word]] +text = "cbe" +credential = {} + +[[word]] +text = "cbm" +credential = {} + +[[word]] +text = "cbne" +credential = {} + +[[word]] +text = "cbnt" +credential = {} + +[[word]] +text = "cbp" +credential = {} + +[[word]] +text = "cbrte" +credential = {} + +[[word]] +text = "cbs" +credential = {} + +[[word]] +text = "cbsp" +credential = {} + +[[word]] +text = "cbt" +credential = {} + +[[word]] +text = "cbte" +credential = {} + +[[word]] +text = "cbv" +credential = {} + +[[word]] +text = "cca" +credential = {} + +[[word]] +text = "ccc" +credential = {} + +[[word]] +text = "ccca" +credential = {} + +[[word]] +text = "cccm" +credential = {} + +[[word]] +text = "cce" +credential = {} + +[[word]] +text = "cchp" +credential = {} + +[[word]] +text = "ccie" +credential = {} + +[[word]] +text = "ccim" +credential = {} + +[[word]] +text = "cciso" +credential = {} + +[[word]] +text = "ccm" +credential = {} + +[[word]] +text = "ccmt" +credential = {} + +[[word]] +text = "ccna" +credential = {} + +[[word]] +text = "ccnp" +credential = {} + +[[word]] +text = "ccp" +credential = {} + +[[word]] +text = "ccp-c" +credential = {} + +[[word]] +text = "ccpr" +credential = {} + +[[word]] +text = "ccs" +credential = {} + +[[word]] +text = "ccufc" +credential = {} + +[[word]] +text = "cd" +credential = {} + +[[word]] +text = "cdal" +credential = {} + +[[word]] +text = "cdfm" +credential = {} + +[[word]] +text = "cdmp" +credential = {} + +[[word]] +text = "cds" +credential = {} + +[[word]] +text = "cdt" +credential = {} + +[[word]] +text = "cea" +credential = {} + +[[word]] +text = "ceas" +credential = {} + +[[word]] +text = "cebs" +credential = {} + +[[word]] +text = "ceds" +credential = {} + +[[word]] +text = "ceh" +credential = {} + +[[word]] +text = "cela" +credential = {} + +[[word]] +text = "cem" +credential = {} + +[[word]] +text = "cep" +credential = {} + +[[word]] +text = "cera" +credential = {} + +[[word]] +text = "cet" +credential = {} + +[[word]] +text = "cfa" +credential = {} + +[[word]] +text = "cfc" +credential = {} + +[[word]] +text = "cfcc" +credential = {} + +[[word]] +text = "cfce" +credential = {} + +[[word]] +text = "cfcm" +credential = {} + +[[word]] +text = "cfe" +credential = {} + +[[word]] +text = "cfeds" +credential = {} + +[[word]] +text = "cfi" +credential = {} + +[[word]] +text = "cfm" +credential = {} + +[[word]] +text = "cfp" +credential = {} + +[[word]] +text = "cfps" +credential = {} + +[[word]] +text = "cfr" +credential = {} + +[[word]] +text = "cfre" +credential = {} + +[[word]] +text = "cga" +credential = {} + +[[word]] +text = "cgap" +credential = {} + +[[word]] +text = "cgb" +credential = {} + +[[word]] +text = "cgc" +credential = {} + +[[word]] +text = "cgfm" +credential = {} + +[[word]] +text = "cgfo" +credential = {} + +[[word]] +text = "cgm" +credential = {} + +[[word]] +text = "cgma" +credential = {} + +[[word]] +text = "cgp" +credential = {} + +[[word]] +text = "cgr" +credential = {} + +[[word]] +text = "cgsp" +credential = {} + +[[word]] +text = "ch" +credential = {} + +[[word]] +text = "cha" +[word.excluded.credential] +reason = "Cha, the Korean 차, dominates CHA (Certified Hotel Administrator): removed 2026-09-07 by the relative-frequency criterion (decisions/suffix-acronym-collisions)" +issue = 342 + +[[word]] +text = "chba" +credential = {} + +[[word]] +text = "chdm" +credential = {} + +[[word]] +text = "che" +credential = {} + +[[word]] +text = "ches" +credential = {} + +[[word]] +text = "chfc" +credential = { cased = "ChFC" } + +[[word]] +text = "chi" +credential = {} + +[[word]] +text = "chmc" +credential = {} + +[[word]] +text = "chmm" +credential = {} + +[[word]] +text = "chp" +credential = {} + +[[word]] +text = "chpa" +credential = {} + +[[word]] +text = "chpe" +credential = {} + +[[word]] +text = "chpln" +credential = {} + +[[word]] +text = "chpse" +credential = {} + +[[word]] +text = "chrm" +credential = {} + +[[word]] +text = "chsc" +credential = {} + +[[word]] +text = "chse" +credential = {} + +[[word]] +text = "chse-a" +credential = {} + +[[word]] +text = "chsos" +credential = {} + +[[word]] +text = "chss" +credential = {} + +[[word]] +text = "cht" +credential = {} + +[[word]] +text = "cia" +credential = {} + +[[word]] +text = "cic" +credential = {} + +[[word]] +text = "cie" +credential = {} + +[[word]] +text = "cig" +credential = {} + +[[word]] +text = "cip" +credential = {} + +[[word]] +text = "cipm" +credential = {} + +[[word]] +text = "cips" +credential = {} + +[[word]] +text = "ciro" +credential = {} + +[[word]] +text = "cisa" +credential = {} + +[[word]] +text = "cism" +credential = {} + +[[word]] +text = "cissp" +credential = {} + +[[word]] +text = "cla" +credential = {} + +[[word]] +text = "clsd" +credential = {} + +[[word]] +text = "cltd" +credential = {} + +[[word]] +text = "clu" +credential = {} + +[[word]] +text = "cm" +credential = {} + +[[word]] +text = "cma" +credential = {} + +[[word]] +text = "cmas" +credential = {} + +[[word]] +text = "cmc" +credential = {} + +[[word]] +text = "cmfo" +credential = {} + +[[word]] +text = "cmg" +credential = {} + +[[word]] +text = "cmp" +credential = {} + +[[word]] +text = "cms" +credential = {} + +[[word]] +text = "cmsp" +credential = {} + +[[word]] +text = "cmt" +credential = {} + +[[word]] +text = "cna" +credential = {} + +[[word]] +text = "cnm" +credential = {} + +[[word]] +text = "cnp" +credential = {} + +[[word]] +text = "cp" +credential = {} + +[[word]] +text = "cp-c" +credential = {} + +[[word]] +text = "cpa" +credential = {} + +[[word]] +text = "cpacc" +credential = {} + +[[word]] +text = "cpbe" +credential = {} + +[[word]] +text = "cpcm" +credential = {} + +[[word]] +text = "cpcu" +credential = {} + +[[word]] +text = "cpe" +credential = {} + +[[word]] +text = "cpfa" +credential = {} + +[[word]] +text = "cpfo" +credential = {} + +[[word]] +text = "cpg" +credential = {} + +[[word]] +text = "cph" +credential = {} + +[[word]] +text = "cpht" +credential = { cased = "CPhT" } + +[[word]] +text = "cpim" +credential = {} + +[[word]] +text = "cplp" +credential = {} + +[[word]] +text = "cpm" +credential = {} + +[[word]] +text = "cpp" +credential = {} + +[[word]] +text = "cppm" +credential = {} + +[[word]] +text = "cprc" +credential = {} + +[[word]] +text = "cpre" +credential = {} + +[[word]] +text = "cprp" +credential = {} + +[[word]] +text = "cpsc" +credential = {} + +[[word]] +text = "cpsi" +credential = {} + +[[word]] +text = "cpss" +credential = {} + +[[word]] +text = "cpwa" +credential = {} + +[[word]] +text = "crde" +credential = {} + +[[word]] +text = "crisc" +credential = {} + +[[word]] +text = "crma" +credential = {} + +[[word]] +text = "crme" +credential = {} + +[[word]] +text = "crna" +credential = {} + +[[word]] +text = "cro" +credential = {} + +[[word]] +text = "crp" +credential = {} + +[[word]] +text = "crt" +credential = {} + +[[word]] +text = "crtt" +credential = {} + +[[word]] +text = "csa" +credential = {} + +[[word]] +text = "csbe" +credential = {} + +[[word]] +text = "csc" +credential = {} + +[[word]] +text = "cscp" +credential = {} + +[[word]] +text = "cscu" +credential = {} + +[[word]] +text = "csep" +credential = {} + +[[word]] +text = "csi" +credential = {} + +[[word]] +text = "csp" +credential = {} + +[[word]] +text = "cspo" +credential = {} + +[[word]] +text = "csre" +credential = {} + +[[word]] +text = "csrte" +credential = {} + +[[word]] +text = "csslp" +credential = {} + +[[word]] +text = "cssm" +credential = {} + +[[word]] +text = "cst" +credential = {} + +[[word]] +text = "cste" +credential = {} + +[[word]] +text = "ctbs" +credential = {} + +[[word]] +text = "ctfa" +credential = {} + +[[word]] +text = "cto" +credential = {} + +[[word]] +text = "ctp" +credential = {} + +[[word]] +text = "cts" +credential = {} + +[[word]] +text = "cua" +credential = {} + +[[word]] +text = "cusp" +credential = {} + +[[word]] +text = "cva" +credential = {} + +[[word]] +text = "cvo" +credential = {} + +[[word]] +text = "cvp" +credential = {} + +[[word]] +text = "cvrs" +credential = {} + +[[word]] +text = "cwap" +credential = {} + +[[word]] +text = "cwb" +credential = {} + +[[word]] +text = "cwdp" +credential = {} + +[[word]] +text = "cwep" +credential = {} + +[[word]] +text = "cwna" +credential = {} + +[[word]] +text = "cwne" +credential = {} + +[[word]] +text = "cwp" +credential = {} + +[[word]] +text = "cwsp" +credential = {} + +[[word]] +text = "cxa" +credential = {} + +[[word]] +text = "cyds" +credential = {} + +[[word]] +text = "cysa" +credential = {} + +[[word]] +text = "dabfm" +credential = {} + +[[word]] +text = "dabvlm" +credential = {} + +[[word]] +text = "dacvim" +credential = {} + +[[word]] +text = "dbe" +credential = {} + +[[word]] +text = "dc" +credential = {} + +[[word]] +text = "dcb" +credential = {} + +[[word]] +text = "dcm" +credential = {} + +[[word]] +text = "dcmg" +credential = {} + +[[word]] +text = "dcvo" +credential = {} + +[[word]] +text = "dd" +credential = {} + +[[word]] +text = "dds" +credential = {} + +[[word]] +text = "ded" +[word.credential] +[word.credential.excluded] +cased = { reason = "a mask applies in every role, and Ded is an Albanian given name: 'ded gjo luli' would render 'DEd Gjo Luli' (measured 2026-09-24)", issue = 459 } + +[[word]] +text = "dep" +credential = {} + +[[word]] +text = "dfc" +credential = {} + +[[word]] +text = "dfm" +credential = {} + +[[word]] +text = "diplac" +credential = { cased = "DiplAc" } + +[[word]] +text = "diplom" +credential = {} + +[[word]] +text = "djur" +credential = {} + +[[word]] +text = "dma" +credential = {} + +[[word]] +text = "dmd" +credential = {} + +[[word]] +text = "dmin" +credential = { cased = "DMin" } + +[[word]] +text = "dnp" +credential = {} + +[[word]] +text = "do" +credential = { may_be_name = true, expands = "Doctor of Osteopathic Medicine" } + +[[word]] +text = "dpm" +credential = {} + +[[word]] +text = "dpt" +credential = {} + +[[word]] +text = "drb" +credential = {} + +[[word]] +text = "drmp" +credential = {} + +[[word]] +text = "drph" +credential = { cased = "DrPH" } + +[[word]] +text = "dsc" +credential = { cased = "DSc" } + +[[word]] +text = "dsm" +credential = {} + +[[word]] +text = "dso" +credential = {} + +[[word]] +text = "dss" +credential = {} + +[[word]] +text = "dtr" +credential = {} + +[[word]] +text = "dvep" +credential = {} + +[[word]] +text = "dvm" +credential = {} + +[[word]] +text = "ea" +credential = {} + +[[word]] +text = "ed" +credential = { may_be_name = true, expands = "Doctor of Education" } + +[[word]] +text = "edd" +[word.credential] +[word.credential.excluded] +cased = { reason = "a mask applies in every role, and Edd is borne as a given name: 'edd smith' would render 'EdD Smith' and 'EDD KIMBER' 'EdD Kimber' (measured 2026-09-24)", issue = 459 } + +[[word]] +text = "ei" +credential = {} + +[[word]] +text = "eit" +credential = {} + +[[word]] +text = "els" +credential = {} + +[[word]] +text = "emd" +credential = {} + +[[word]] +text = "emt-b" +credential = {} + +[[word]] +text = "emt-i/85" +credential = {} + +[[word]] +text = "emt-i/99" +credential = {} + +[[word]] +text = "emt-p" +credential = {} + +[[word]] +text = "enp" +credential = {} + +[[word]] +text = "erd" +credential = {} + +[[word]] +text = "evp" +credential = {} + +[[word]] +text = "faafp" +credential = {} + +[[word]] +text = "faan" +credential = {} + +[[word]] +text = "faap" +credential = {} + +[[word]] +text = "fac-c" +credential = {} + +[[word]] +text = "facc" +credential = {} + +[[word]] +text = "facd" +credential = {} + +[[word]] +text = "facem" +credential = {} + +[[word]] +text = "facep" +credential = {} + +[[word]] +text = "facha" +credential = {} + +[[word]] +text = "facofp" +credential = {} + +[[word]] +text = "facog" +credential = {} + +[[word]] +text = "facp" +credential = {} + +[[word]] +text = "facph" +credential = {} + +[[word]] +text = "facs" +credential = {} + +[[word]] +text = "faia" +credential = {} + +[[word]] +text = "faicp" +credential = {} + +[[word]] +text = "fala" +credential = {} + +[[word]] +text = "fashp" +credential = {} + +[[word]] +text = "fasid" +credential = {} + +[[word]] +text = "fasla" +credential = {} + +[[word]] +text = "fasma" +credential = {} + +[[word]] +text = "faspen" +credential = {} + +[[word]] +text = "fca" +credential = {} + +[[word]] +text = "fcas" +credential = {} + +[[word]] +text = "fcela" +credential = {} + +[[word]] +text = "fd" +credential = {} + +[[word]] +text = "fec" +credential = {} + +[[word]] +text = "fhames" +credential = {} + +[[word]] +text = "fic" +credential = {} + +[[word]] +text = "ficf" +credential = {} + +[[word]] +text = "fieee" +credential = {} + +[[word]] +text = "fmp" +credential = {} + +[[word]] +text = "fmva" +credential = {} + +[[word]] +text = "fnss" +credential = {} + +[[word]] +text = "fp&a" +credential = {} + +[[word]] +text = "fp-c" +credential = {} + +[[word]] +text = "fpc" +credential = {} + +[[word]] +text = "frm" +credential = {} + +[[word]] +text = "fsa" +credential = {} + +[[word]] +text = "fsdp" +credential = {} + +[[word]] +text = "fws" +credential = {} + +[[word]] +text = "gba" +credential = {} + +[[word]] +text = "gbe" +credential = {} + +[[word]] +text = "gc" +credential = {} + +[[word]] +text = "gcb" +credential = {} + +[[word]] +text = "gchs" +credential = {} + +[[word]] +text = "gcie" +credential = {} + +[[word]] +text = "gcmg" +credential = {} + +[[word]] +text = "gcsi" +credential = {} + +[[word]] +text = "gcvo" +credential = {} + +[[word]] +text = "gisp" +credential = {} + +[[word]] +text = "git" +credential = {} + +[[word]] +text = "gm" +credential = {} + +[[word]] +text = "gmb" +credential = {} + +[[word]] +text = "gmr" +credential = {} + +[[word]] +text = "gphr" +credential = {} + +[[word]] +text = "gri" +credential = {} + +[[word]] +text = "grp" +credential = {} + +[[word]] +text = "gsmieee" +credential = {} + +[[word]] +text = "hccp" +credential = {} + +[[word]] +text = "hrs" +credential = {} + +[[word]] +text = "iaccp" +credential = {} + +[[word]] +text = "iaee" +credential = {} + +[[word]] +text = "iccm-d" +credential = {} + +[[word]] +text = "iccm-f" +credential = {} + +[[word]] +text = "idsm" +credential = {} + +[[word]] +text = "ifgict" +credential = {} + +[[word]] +text = "iom" +credential = {} + +[[word]] +text = "ipep" +credential = {} + +[[word]] +text = "ipm" +credential = {} + +[[word]] +text = "iso" +credential = {} + +[[word]] +text = "issp-csp" +credential = {} + +[[word]] +text = "issp-sa" +credential = {} + +[[word]] +text = "itil" +credential = {} + +[[word]] +text = "jd" +credential = { may_be_name = true, expands = "Juris Doctor" } + +[[word]] +text = "jp" +credential = {} + +[[word]] +text = "kbe" +credential = {} + +[[word]] +text = "kcb" +credential = {} + +[[word]] +text = "kchs/dchs" +credential = {} + +[[word]] +text = "kcie" +credential = {} + +[[word]] +text = "kcmg" +credential = {} + +[[word]] +text = "kcsi" +credential = {} + +[[word]] +text = "kcvo" +credential = {} + +[[word]] +text = "kg" +credential = {} + +[[word]] +text = "khs/dhs" +credential = {} + +[[word]] +text = "knt" +credential = { expands = "Knight", issue = 606, note = "the older spelling of kt", cased = "Knt" } + +[[word]] +text = "kp" +credential = {} + +[[word]] +text = "kt" +credential = { cased = "Kt" } + +[[word]] +text = "lac" +[word.credential] +may_be_name = true +expands = "Licensed Acupuncturist" +issue = 540 +note = "Lac is a Vietnamese given name (the trailing word in native order, Nguyen Van Lac) and a French surname" +[word.credential.excluded] +cased = { reason = "a mask applies in every role, and Lac is a Vietnamese given name and a French surname: 'tran lac' would render 'Tran LAc' (measured 2026-09-25, #540)", issue = 459 } + +[[word]] +text = "lcmt" +credential = {} + +[[word]] +text = "lcpc" +credential = {} + +[[word]] +text = "lcsw" +credential = {} + +[[word]] +text = "lg" +credential = {} + +[[word]] +text = "litk" +credential = {} + +[[word]] +text = "litl" +credential = {} + +[[word]] +text = "litp" +credential = {} + +[[word]] +text = "llm" +credential = {} + +[[word]] +text = "lm" +credential = {} + +[[word]] +text = "lmsw" +credential = {} + +[[word]] +text = "lmt" +credential = {} + +[[word]] +text = "lp" +credential = {} + +[[word]] +text = "lpa" +credential = {} + +[[word]] +text = "lpc" +credential = {} + +[[word]] +text = "lpn" +credential = {} + +[[word]] +text = "lpss" +credential = {} + +[[word]] +text = "lsi" +credential = {} + +[[word]] +text = "lsit" +credential = {} + +[[word]] +text = "lvn" +credential = {} + +[[word]] +text = "lvo" +credential = {} + +[[word]] +text = "lvt" +credential = {} + +[[word]] +text = "ma" +credential = { may_be_name = true, expands = "Master of Arts" } + +[[word]] +text = "maaa" +credential = {} + +[[word]] +text = "mai" +[word.excluded.credential] +reason = "Mai, a Vietnamese given and family name, a Chinese surname (麥) and a Japanese given name, dominates MAI (Member, Appraisal Institute): removed 2026-10-16 by the relative-frequency criterion (decisions/suffix-acronym-collisions)" +issue = 687 + +[[word]] +text = "mba" +credential = {} + +[[word]] +text = "mbe" +credential = {} + +[[word]] +text = "mbs" +credential = {} + +[[word]] +text = "mc" +[word.clan] +may_be_given = false +issue = 360 +expands = "son of, Mac contracted" +same_as = "mac" +note = "Unlike 'mac' (Mac Miller) it is not a standalone given name. Measured misparse: \"Mc Donald\" gave given='Mc'. Also in SUFFIX_ACRONYMS as Master of Ceremonies, but that is trailing position and unaffected -- \"John Smith MC\" still reads suffix (#360)." +[word.credential] +note = "NOT may_be_name though also a particle: #454 closed by design, neither mc nor vd is a borne name (rules/P6's Accepted clause)" + +[[word]] +text = "mcct" +credential = {} + +[[word]] +text = "mcdba" +credential = {} + +[[word]] +text = "mches" +credential = {} + +[[word]] +text = "mcm" +credential = {} + +[[word]] +text = "mcp" +credential = {} + +[[word]] +text = "mcpd" +credential = {} + +[[word]] +text = "mcsa" +credential = {} + +[[word]] +text = "mcsd" +credential = {} + +[[word]] +text = "mcse" +credential = {} + +[[word]] +text = "mct" +credential = {} + +[[word]] +text = "mdiv" +credential = { cased = "MDiv" } + +[[word]] +text = "mem" +credential = {} + +[[word]] +text = "meng" +[word.credential] +may_be_name = true +expands = "Master of Engineering" +issue = 540 +note = "Meng is a Chinese surname and given name" +[word.credential.excluded] +cased = { reason = "a mask applies in every role, and Meng is borne as a given name and a surname: 'MENG LI' would render 'MEng Li' and 'meng wang' 'MEng Wang' (measured 2026-09-24)", issue = 459 } + +[[word]] +text = "mfa" +credential = {} + +[[word]] +text = "micp" +credential = {} + +[[word]] +text = "mieee" +credential = {} + +[[word]] +text = "mirm" +credential = {} + +[[word]] +text = "mle" +credential = {} + +[[word]] +text = "mls" +credential = {} + +[[word]] +text = "mlse" +credential = {} + +[[word]] +text = "mlt" +credential = {} + +[[word]] +text = "mm" +credential = {} + +[[word]] +text = "mmad" +credential = {} + +[[word]] +text = "mmas" +credential = {} + +[[word]] +text = "mnaa" +credential = {} + +[[word]] +text = "mnae" +credential = {} + +[[word]] +text = "mp" +credential = {} + +[[word]] +text = "mpa" +credential = {} + +[[word]] +text = "mph" +credential = {} + +[[word]] +text = "mpse" +credential = {} + +[[word]] +text = "mra" +credential = {} + +[[word]] +text = "msa" +credential = {} + +[[word]] +text = "msc" +credential = { cased = "MSc" } + +[[word]] +text = "mscmsm" +credential = {} + +[[word]] +text = "msm" +credential = {} + +[[word]] +text = "mt" +credential = {} + +[[word]] +text = "mts" +credential = {} + +[[word]] +text = "mvo" +credential = {} + +[[word]] +text = "nbc-his" +credential = {} + +[[word]] +text = "nbcch" +credential = {} + +[[word]] +text = "nbcch-ps" +credential = {} + +[[word]] +text = "nbcdch" +credential = {} + +[[word]] +text = "nbcdch-ps" +credential = {} + +[[word]] +text = "nbcfch" +credential = {} + +[[word]] +text = "nbcfch-ps" +credential = {} + +[[word]] +text = "nbct" +credential = {} + +[[word]] +text = "ncarb" +credential = {} + +[[word]] +text = "nccp" +credential = {} + +[[word]] +text = "ncidq" +credential = {} + +[[word]] +text = "ncps" +credential = {} + +[[word]] +text = "ncso" +credential = {} + +[[word]] +text = "ncto" +credential = {} + +[[word]] +text = "nd" +credential = {} + +[[word]] +text = "ndtr" +credential = {} + +[[word]] +text = "nmd" +credential = {} + +[[word]] +text = "np" +credential = {} + +[[word]] +text = "nraemt" +credential = {} + +[[word]] +text = "nremr" +credential = {} + +[[word]] +text = "nremt" +credential = {} + +[[word]] +text = "nrp" +credential = {} + +[[word]] +text = "obe" +credential = {} + +[[word]] +text = "obi" +credential = {} + +[[word]] +text = "oca" +credential = {} + +[[word]] +text = "ocm" +credential = {} + +[[word]] +text = "ocp" +credential = {} + +[[word]] +text = "od" +credential = {} + +[[word]] +text = "om" +[word.credential] +note = "NOT may_be_name: weighed 2026-09-07 with #342, no surname evidence worth standing behind, and OM is the Order of Merit" + +[[word]] +text = "oscp" +credential = {} + +[[word]] +text = "ot" +credential = {} + +[[word]] +text = "pa-c" +credential = {} + +[[word]] +text = "pcc" +credential = {} + +[[word]] +text = "pci" +credential = {} + +[[word]] +text = "pe" +credential = {} + +[[word]] +text = "pfmp" +credential = {} + +[[word]] +text = "pg" +credential = {} + +[[word]] +text = "pgmp" +credential = {} + +[[word]] +text = "pharmd" +credential = { cased = "PharmD" } + +[[word]] +text = "phc" +credential = { cased = "PhC" } + +[[word]] +text = "phd" +credential = { expands = "Doctor of Philosophy", cased = "PhD" } + +[[word]] +text = "phr" +credential = {} + +[[word]] +text = "phrca" +credential = {} + +[[word]] +text = "pla" +credential = {} + +[[word]] +text = "pls" +credential = {} + +[[word]] +text = "pmc" +credential = {} + +[[word]] +text = "pmi-acp" +credential = {} + +[[word]] +text = "pmp" +credential = {} + +[[word]] +text = "pp" +credential = {} + +[[word]] +text = "pps" +credential = {} + +[[word]] +text = "prm" +credential = {} + +[[word]] +text = "psm" +credential = {} + +[[word]] +text = "psp" +credential = {} + +[[word]] +text = "psyd" +credential = { cased = "PsyD" } + +[[word]] +text = "pt" +credential = {} + +[[word]] +text = "pta" +credential = {} + +[[word]] +text = "qam" +credential = {} + +[[word]] +text = "qc" +credential = {} + +[[word]] +text = "qcsw" +credential = {} + +[[word]] +text = "qfsm" +credential = {} + +[[word]] +text = "qgm" +credential = {} + +[[word]] +text = "qpm" +credential = {} + +[[word]] +text = "qsd" +credential = {} + +[[word]] +text = "qsp" +credential = {} + +[[word]] +text = "ra" +credential = {} + +[[word]] +text = "rai" +[word.excluded.credential] +reason = "Rai, a common surname across Hindi- and Bengali-speaking regions, dominates RAI (RETA Authorized Instructor): removed 2026-09-07 by the relative-frequency criterion (decisions/suffix-acronym-collisions)" +issue = 342 + +[[word]] +text = "rba" +credential = {} + +[[word]] +text = "rci" +credential = {} + +[[word]] +text = "rcp" +credential = {} + +[[word]] +text = "rd" +credential = {} + +[[word]] +text = "rdcs" +credential = {} + +[[word]] +text = "rdh" +credential = {} + +[[word]] +text = "rdms" +credential = {} + +[[word]] +text = "rdn" +credential = {} + +[[word]] +text = "res" +credential = {} + +[[word]] +text = "rfp" +credential = {} + +[[word]] +text = "rhca" +credential = {} + +[[word]] +text = "rid" +credential = {} + +[[word]] +text = "rls" +credential = {} + +[[word]] +text = "rmsks" +credential = {} + +[[word]] +text = "rn" +credential = {} + +[[word]] +text = "rp" +credential = {} + +[[word]] +text = "rpa" +credential = {} + +[[word]] +text = "rph" +credential = { cased = "RPh" } + +[[word]] +text = "rpl" +credential = {} + +[[word]] +text = "rrc" +credential = {} + +[[word]] +text = "rrt" +credential = {} + +[[word]] +text = "rrt-accs" +credential = {} + +[[word]] +text = "rrt-nps" +credential = {} + +[[word]] +text = "rrt-sds" +credential = {} + +[[word]] +text = "rtrp" +credential = {} + +[[word]] +text = "rvm" +credential = {} + +[[word]] +text = "rvt" +credential = {} + +[[word]] +text = "same" +credential = {} + +[[word]] +text = "sasm" +credential = {} + +[[word]] +text = "sccp" +credential = {} + +[[word]] +text = "scmp" +credential = {} + +[[word]] +text = "se" +[word.credential] +note = "NOT may_be_name: weighed 2026-09-07 with #342, no surname evidence worth standing behind" + +[[word]] +text = "secb" +credential = {} + +[[word]] +text = "sfp" +credential = {} + +[[word]] +text = "shrm-cp" +credential = {} + +[[word]] +text = "shrm-scp" +credential = {} + +[[word]] +text = "si" +credential = {} + +[[word]] +text = "siie" +credential = {} + +[[word]] +text = "smieee" +credential = {} + +[[word]] +text = "sphr" +credential = {} + +[[word]] +text = "sscp" +credential = {} + +[[word]] +text = "stmieee" +credential = {} + +[[word]] +text = "tbr-ct" +credential = {} + +[[word]] +text = "td" +credential = {} + +[[word]] +text = "thd" +credential = { cased = "ThD" } + +[[word]] +text = "thm" +credential = { cased = "ThM" } + +[[word]] +text = "ud" +credential = {} + +[[word]] +text = "usa" +credential = {} + +[[word]] +text = "usaf" +credential = {} + +[[word]] +text = "usar" +credential = {} + +[[word]] +text = "uscg" +credential = {} + +[[word]] +text = "usmc" +credential = {} + +[[word]] +text = "usn" +credential = {} + +[[word]] +text = "usnr" +credential = {} + +[[word]] +text = "uxc" +credential = {} + +[[word]] +text = "uxmc" +credential = {} + +[[word]] +text = "vcp" +credential = {} + +[[word]] +text = "vd" +[word.credential] +note = "NOT may_be_name though also a particle: #454 closed by design, neither mc nor vd is a borne name (rules/P6's Accepted clause)" + +[[word]] +text = "vrd" +credential = {} + [[word]] text = "ret" [word.status] @@ -2288,12 +4701,3 @@ text = "mac" may_be_given = true expands = "son of" note = "Mac Miller: a real given name. This is the case that shows #360's vowel heuristic was not the criterion -- 'mac' and 'mc' differ by attestation, not by shape" - -[[word]] -text = "mc" -[word.clan] -may_be_given = false -issue = 360 -expands = "son of, Mac contracted" -same_as = "mac" -note = "Unlike 'mac' (Mac Miller) it is not a standalone given name. Measured misparse: \"Mc Donald\" gave given='Mc'. Also in SUFFIX_ACRONYMS as Master of Ceremonies, but that is trailing position and unaffected -- \"John Smith MC\" still reads suffix (#360)." diff --git a/nameparser/vocab/und.toml b/nameparser/vocab/und.toml index d8b0b0d3..69c18411 100644 --- a/nameparser/vocab/und.toml +++ b/nameparser/vocab/und.toml @@ -1,82 +1,15 @@ # Words not yet assigned a language. Every category but the suffix # words was converted here mechanically from nameparser/config/*.py, -# in source order -- with generic kinds, except the credential -# acronyms, which already have their classified kind -- and the -# comments above an entry are the vetting notes that stood above it -# there. A comment headed by a constant's name in parentheses, as -# "# (SUFFIX_ACRONYMS_AMBIGUOUS)", came from that constant's block, -# where the entry's own reading came from another. Moving a word to a -# language file changes no compiled set. +# in source order, and the comments above an entry are the vetting +# notes that stood above it there. Moving a word to a language file +# changes no compiled set. schema = 1 -# ---- the other readings of words whose title reading has a language ---- -# (#750 moved each title reading to the files of the languages whose -# names it occurs in, or to mul.toml; `uv run python tools/vocab/query.py --word ` -# shows both halves) -[[word]] -text = "ms" -[word.credential] -note = "NOT may_be_name, though #296's audit table put it there for the leading-title collision: the gate is position-blind and the collision is not (gated, 'John Smith, MS' read title 'MS'); a title/credential dual that position decides (decisions/C8)" - -[[word]] -text = "cpl" -credential = {} - -[[word]] -text = "cpo" -credential = {} - -[[word]] -text = "cpt" -credential = {} - -[[word]] -text = "csm" -credential = {} - -[[word]] -text = "lt" -credential = {} - -[[word]] -text = "md" -credential = {} - -[[word]] -text = "ra" -credential = {} - -[[word]] -text = "sa" -credential = { note = "NOT may_be_name, for the reason recorded on ms (decisions/C8)" } - -[[word]] -text = "sgm" -credential = {} - -[[word]] -text = "vc" -credential = {} - # ---- the other readings of words whose particle reading has a language ---- # (#749 moved each particle reading to the files of the languages whose # names it occurs in; `uv run python tools/vocab/query.py --word ` # shows both halves) -[[word]] -text = "mc" -[word.credential] -note = "NOT may_be_name though also a particle: #454 closed by design, neither mc nor vd is a borne name (rules/P6's Accepted clause)" - -[[word]] -text = "vd" -[word.credential] -note = "NOT may_be_name though also a particle: #454 closed by design, neither mc nor vd is a borne name (rules/P6's Accepted clause)" - -[[word]] -text = "do" -credential = { may_be_name = true, expands = "Doctor of Osteopathic Medicine" } - [[word]] text = "abu" bound_given = {} @@ -231,23 +164,15 @@ bound_given = {} # covered the Arabic-script side since #269 (shipped in 2.0). # # Collides with the postnominal ABD ("All But Dissertation"), -# which stays in SUFFIX_ACRONYMS. Position decides at the two ends +# a credential in en.toml. Position decides at the two ends # -- a leading `abd` reads as a name, a trailing one as the # credential -- but not everywhere: in the given slot of a # family-comma name the credential still wins, so "Smith, Abd" # reports suffix 'Abd' and no given name, where "Smith, Abdul" # reports the given name. Recorded at decisions/P5. -# (SUFFIX_ACRONYMS) -# "All But Dissertation". Also the Latin transliteration of the -# Arabic bound given-name word in BOUND_GIVEN_NAMES (whose -# Arabic-script counterpart عبد is in that set only) -- the one -# word in both sets, kept in both deliberately. Position decides -# at the two ends but not in a family comma's given slot; see -# decisions/P5. [[word]] text = "abd" bound_given = {} -credential = {} [[word]] text = "abou" @@ -343,2486 +268,3 @@ birth_marker = {} [[word]] text = "旧姓" birth_marker = {} - -# ---- credential acronyms ---- - -[[word]] -text = "8-vsb" -credential = {} - -[[word]] -text = "aas" -credential = {} - -[[word]] -text = "aba" -credential = {} - -[[word]] -text = "abc" -credential = {} - -[[word]] -text = "abpp" -credential = {} - -[[word]] -text = "abr" -credential = {} - -[[word]] -text = "aca" -credential = {} - -[[word]] -text = "acas" -credential = {} - -[[word]] -text = "ace" -credential = {} - -[[word]] -text = "acha" -credential = {} - -[[word]] -text = "acp" -credential = {} - -[[word]] -text = "ae" -credential = {} - -[[word]] -text = "aem" -credential = {} - -[[word]] -text = "afasma" -credential = {} - -[[word]] -text = "afc" -credential = {} - -[[word]] -text = "afm" -credential = {} - -[[word]] -text = "agsf" -credential = {} - -[[word]] -text = "aia" -credential = {} - -[[word]] -text = "aicp" -credential = {} - -[[word]] -text = "ala" -credential = {} - -[[word]] -text = "alc" -credential = {} - -[[word]] -text = "alp" -credential = {} - -[[word]] -text = "am" -credential = {} - -[[word]] -text = "amd" -credential = {} - -[[word]] -text = "ame" -credential = {} - -[[word]] -text = "amieee" -credential = {} - -[[word]] -text = "ams" -credential = {} - -[[word]] -text = "aphr" -credential = {} - -[[word]] -text = "apn" -credential = {} - -[[word]] -text = "aprn" -credential = {} - -[[word]] -text = "apr" -credential = {} - -[[word]] -text = "apss" -credential = {} - -[[word]] -text = "aqp" -credential = {} - -[[word]] -text = "arm" -credential = {} - -[[word]] -text = "arrc" -credential = {} - -[[word]] -text = "asa" -credential = {} - -[[word]] -text = "asc" -credential = {} - -[[word]] -text = "asid" -credential = {} - -[[word]] -text = "asla" -credential = {} - -[[word]] -text = "asp" -credential = {} - -[[word]] -text = "atc" -credential = {} - -[[word]] -text = "awb" -credential = {} - -# (SUFFIX_ACRONYMS_AMBIGUOUS) -# Suffix acronyms that also commonly work as given-name nicknames on -# their own (e.g. "Ed", "JD"). Read wherever the pipeline decides an -# acronym's bare reading (rules/S4) and by the delimited-content -# escape (content matching one of these stays a nickname, the more -# common reading in ambiguous, delimiter-only context). _classify -# also tags membership as "vocab:suffix-ambiguous". -# -# When adding a credential acronym, set may_be_name = true on its -# reading only if the exact letter sequence could plausibly be someone's name on its -# own -- a given name or nickname (e.g. 'jd', 'ed') or a common -# surname (e.g. 'ma', 'do'). Unambiguous certifications/degrees -# (e.g. 'mba', 'cpa', 'phd') don't need the flag. In 2.0 the flag -# also gates bare recognition: a bare ambiguous acronym reads as -# the credential only with words to spare in front of it, or -# written in capitals inside a mixed-case name; inside a -# mixed-case name any other cased form that is not wholly lower -# ('Ma', 'MEng') reads as the name even with words to spare -- -# rules/S4 and rules/S6. The parse reports the fork where it decides one, -# so 'Jack Ma' keeps its family name. -# -# The other half of the criterion, added 2026-09-07 with #342. -# Being borne at all is only the entry ticket; what decides among -# the three answers is a comparison of FREQUENCIES -- how common -# the word is as a borne name in the TRAILING position against how -# common it is as a credential. Roughly balanced earns the marking -# here, and the parse reports the fork: 'ba' is the entry that -# earned it that day, BA being a common credential and Ba a real -# surname (Vietnamese; Senegalese Fula) about as common as the -# credential, which is the ma/Ma shape exactly. Where the NAME -# reading dominates, the entry is REMOVED from SUFFIX_ACRONYMS -# instead of marked: 'rai' and 'cha' left the set that day, both -# far more common as surnames than their credentials are as -# credentials (RAI is "RETA Authorized Instructor", CHA is -# Certified Hotel Administrator or Certified Healthcare Auditor, -# both tenuous or specialized; Rai is a common surname across -# Hindi- and Bengali-speaking regions and Cha the Korean 차). -# Where the CREDENTIAL dominates, the entry stays unambiguous. -# LENGTH is a correlate and not the test -- a short acronym is -# more often a common credential AND more often a name -- so do -# not read the letter counts here as a rule. #540 (2026-09-25) -# marked 'lac' and 'meng', the first entries here longer than -# two letters: MEng and LAc are credentials people write after -# their names, and Meng and Lac are borne in the trailing slot -# by real people, and neither reading is rare enough to give the -# word to the other -- so the marking, whatever the letter -# count. -# -# Removal does not take the DOTTED spelling with it: since 2.4 an -# unlisted word of two or more period-separated chunks is a suffix -# by position, with words to spare in front (rules/S3, -# Policy.unlisted_dotted_suffixes, default on), so "John Smith -# R.A.I.", "John Smith R.A.X." and "John Smith C.H.A." all read -# suffix, the vocabulary playing no part (checked 2026-10-19). A caller who needs an entry back -# adds it -- Lexicon.default().add(suffix_acronyms={"cha"}) -- -# which is the answer this library gives for every -# locale-specific vocabulary. The cost is stated and accepted: -# with the entry gone, "John Smith RAI" reads family 'RAI'. See -# decisions/suffix-acronym-collisions. -# -# NOT 'ms' or 'sa', though #296's audit table put them here for the -# leading-title collision (bare "Ms" the honorific, "M.S." the -# degree): the gate is position-blind and the collision is not. -# Gated, 'John Smith, MS' lost its suffix-comma route and read -# title 'MS', and 'Smith, Ms.' passed the gate on its one period -# and read as a credential anyway. Both words are genuine duals -- -# title and unambiguous suffix -- and position decides, as for -# 'sr' and 'lt' (decisions/C8). -# -# NOT 'se' or 'om' either, weighed 2026-09-07 with #342 and left -# alone: no surname evidence worth standing behind, and OM is the -# Order of Merit. And NOT 'mc' or 'vd', which are also PARTICLES: -# #454 closed by design -- neither is a borne name, so a bare -# trailing one is the decoration, and rules/P6's Accepted -# clause names them as the two words whose positional reading -# does not hold. -[[word]] -text = "ba" -credential = { may_be_name = true, expands = "Bachelor of Arts", issue = 342 } - -[[word]] -text = "bca" -credential = {} - -[[word]] -text = "bcl" -credential = {} - -[[word]] -text = "bcss" -credential = {} - -[[word]] -text = "bds" -credential = {} - -[[word]] -text = "bem" -credential = {} - -[[word]] -text = "bls-i" -credential = {} - -[[word]] -text = "bn" -credential = {} - -[[word]] -text = "bpe" -credential = {} - -[[word]] -text = "bpi" -credential = {} - -[[word]] -text = "bpt" -credential = {} - -[[word]] -text = "bsc" -credential = { cased = "BSc" } - -# (CAPITALIZATION_EXCEPTIONS) -# Listed post-nominals whose conventional spelling is mixed case -# (#459): without a mask the acronym repair writes each in -# capitals. A mask applies wherever its word stands, so a word -# borne as a name must not get one -- meng and edd are listed -# acronyms that are, and stay out on purpose (the meng/edd/lac/ded -# CAPITALIZATION_EXCEPTIONS block in decisions/vocabulary-exclusions). -[[word]] -text = "bt" -credential = { cased = "Bt" } - -[[word]] -text = "btcs" -credential = {} - -[[word]] -text = "bts" -credential = {} - -[[word]] -text = "cacts" -credential = {} - -[[word]] -text = "cae" -credential = {} - -[[word]] -text = "caha" -credential = {} - -[[word]] -text = "caia" -credential = {} - -[[word]] -text = "cams" -credential = {} - -[[word]] -text = "cap" -credential = {} - -[[word]] -text = "capa" -credential = {} - -[[word]] -text = "capm" -credential = {} - -[[word]] -text = "capp" -credential = {} - -[[word]] -text = "caps" -credential = {} - -[[word]] -text = "caro" -credential = {} - -[[word]] -text = "cas" -credential = {} - -[[word]] -text = "casp" -credential = {} - -[[word]] -text = "cb" -credential = {} - -[[word]] -text = "cbe" -credential = {} - -[[word]] -text = "cbm" -credential = {} - -[[word]] -text = "cbne" -credential = {} - -[[word]] -text = "cbnt" -credential = {} - -[[word]] -text = "cbp" -credential = {} - -[[word]] -text = "cbrte" -credential = {} - -[[word]] -text = "cbs" -credential = {} - -[[word]] -text = "cbsp" -credential = {} - -[[word]] -text = "cbt" -credential = {} - -[[word]] -text = "cbte" -credential = {} - -[[word]] -text = "cbv" -credential = {} - -[[word]] -text = "cca" -credential = {} - -[[word]] -text = "ccc" -credential = {} - -[[word]] -text = "ccca" -credential = {} - -[[word]] -text = "cccm" -credential = {} - -[[word]] -text = "cce" -credential = {} - -[[word]] -text = "cchp" -credential = {} - -[[word]] -text = "ccie" -credential = {} - -[[word]] -text = "ccim" -credential = {} - -[[word]] -text = "cciso" -credential = {} - -[[word]] -text = "ccm" -credential = {} - -[[word]] -text = "ccmt" -credential = {} - -[[word]] -text = "ccna" -credential = {} - -[[word]] -text = "ccnp" -credential = {} - -[[word]] -text = "ccp" -credential = {} - -[[word]] -text = "ccp-c" -credential = {} - -[[word]] -text = "ccpr" -credential = {} - -[[word]] -text = "ccs" -credential = {} - -[[word]] -text = "ccufc" -credential = {} - -[[word]] -text = "cd" -credential = {} - -[[word]] -text = "cdal" -credential = {} - -[[word]] -text = "cdfm" -credential = {} - -[[word]] -text = "cdmp" -credential = {} - -[[word]] -text = "cds" -credential = {} - -[[word]] -text = "cdt" -credential = {} - -[[word]] -text = "cea" -credential = {} - -[[word]] -text = "ceas" -credential = {} - -[[word]] -text = "cebs" -credential = {} - -[[word]] -text = "ceds" -credential = {} - -[[word]] -text = "ceh" -credential = {} - -[[word]] -text = "cela" -credential = {} - -[[word]] -text = "cem" -credential = {} - -[[word]] -text = "cep" -credential = {} - -[[word]] -text = "cera" -credential = {} - -[[word]] -text = "cet" -credential = {} - -[[word]] -text = "cfa" -credential = {} - -[[word]] -text = "cfc" -credential = {} - -[[word]] -text = "cfcc" -credential = {} - -[[word]] -text = "cfce" -credential = {} - -[[word]] -text = "cfcm" -credential = {} - -[[word]] -text = "cfe" -credential = {} - -[[word]] -text = "cfeds" -credential = {} - -[[word]] -text = "cfi" -credential = {} - -[[word]] -text = "cfm" -credential = {} - -[[word]] -text = "cfp" -credential = {} - -[[word]] -text = "cfps" -credential = {} - -[[word]] -text = "cfr" -credential = {} - -[[word]] -text = "cfre" -credential = {} - -[[word]] -text = "cga" -credential = {} - -[[word]] -text = "cgap" -credential = {} - -[[word]] -text = "cgb" -credential = {} - -[[word]] -text = "cgc" -credential = {} - -[[word]] -text = "cgfm" -credential = {} - -[[word]] -text = "cgfo" -credential = {} - -[[word]] -text = "cgm" -credential = {} - -[[word]] -text = "cgma" -credential = {} - -[[word]] -text = "cgp" -credential = {} - -[[word]] -text = "cgr" -credential = {} - -[[word]] -text = "cgsp" -credential = {} - -[[word]] -text = "ch" -credential = {} - -[[word]] -text = "chba" -credential = {} - -[[word]] -text = "chdm" -credential = {} - -[[word]] -text = "che" -credential = {} - -[[word]] -text = "ches" -credential = {} - -[[word]] -text = "chfc" -credential = { cased = "ChFC" } - -[[word]] -text = "chi" -credential = {} - -[[word]] -text = "chmc" -credential = {} - -[[word]] -text = "chmm" -credential = {} - -[[word]] -text = "chp" -credential = {} - -[[word]] -text = "chpa" -credential = {} - -[[word]] -text = "chpe" -credential = {} - -[[word]] -text = "chpln" -credential = {} - -[[word]] -text = "chpse" -credential = {} - -[[word]] -text = "chrm" -credential = {} - -[[word]] -text = "chsc" -credential = {} - -[[word]] -text = "chse" -credential = {} - -[[word]] -text = "chse-a" -credential = {} - -[[word]] -text = "chsos" -credential = {} - -[[word]] -text = "chss" -credential = {} - -[[word]] -text = "cht" -credential = {} - -[[word]] -text = "cia" -credential = {} - -[[word]] -text = "cic" -credential = {} - -[[word]] -text = "cie" -credential = {} - -[[word]] -text = "cig" -credential = {} - -[[word]] -text = "cip" -credential = {} - -[[word]] -text = "cipm" -credential = {} - -[[word]] -text = "cips" -credential = {} - -[[word]] -text = "ciro" -credential = {} - -[[word]] -text = "cisa" -credential = {} - -[[word]] -text = "cism" -credential = {} - -[[word]] -text = "cissp" -credential = {} - -[[word]] -text = "cla" -credential = {} - -[[word]] -text = "clsd" -credential = {} - -[[word]] -text = "cltd" -credential = {} - -[[word]] -text = "clu" -credential = {} - -[[word]] -text = "cm" -credential = {} - -[[word]] -text = "cma" -credential = {} - -[[word]] -text = "cmas" -credential = {} - -[[word]] -text = "cmc" -credential = {} - -[[word]] -text = "cmfo" -credential = {} - -[[word]] -text = "cmg" -credential = {} - -[[word]] -text = "cmp" -credential = {} - -[[word]] -text = "cms" -credential = {} - -[[word]] -text = "cmsp" -credential = {} - -[[word]] -text = "cmt" -credential = {} - -[[word]] -text = "cna" -credential = {} - -[[word]] -text = "cnm" -credential = {} - -[[word]] -text = "cnp" -credential = {} - -[[word]] -text = "cp" -credential = {} - -[[word]] -text = "cp-c" -credential = {} - -[[word]] -text = "cpa" -credential = {} - -[[word]] -text = "cpacc" -credential = {} - -[[word]] -text = "cpbe" -credential = {} - -[[word]] -text = "cpcm" -credential = {} - -[[word]] -text = "cpcu" -credential = {} - -[[word]] -text = "cpe" -credential = {} - -[[word]] -text = "cpfa" -credential = {} - -[[word]] -text = "cpfo" -credential = {} - -[[word]] -text = "cpg" -credential = {} - -[[word]] -text = "cph" -credential = {} - -[[word]] -text = "cpht" -credential = { cased = "CPhT" } - -[[word]] -text = "cpim" -credential = {} - -[[word]] -text = "cplp" -credential = {} - -[[word]] -text = "cpm" -credential = {} - -[[word]] -text = "cpp" -credential = {} - -[[word]] -text = "cppm" -credential = {} - -[[word]] -text = "cprc" -credential = {} - -[[word]] -text = "cpre" -credential = {} - -[[word]] -text = "cprp" -credential = {} - -[[word]] -text = "cpsc" -credential = {} - -[[word]] -text = "cpsi" -credential = {} - -[[word]] -text = "cpss" -credential = {} - -[[word]] -text = "cpwa" -credential = {} - -[[word]] -text = "crde" -credential = {} - -[[word]] -text = "crisc" -credential = {} - -[[word]] -text = "crma" -credential = {} - -[[word]] -text = "crme" -credential = {} - -[[word]] -text = "crna" -credential = {} - -[[word]] -text = "cro" -credential = {} - -[[word]] -text = "crp" -credential = {} - -[[word]] -text = "crt" -credential = {} - -[[word]] -text = "crtt" -credential = {} - -[[word]] -text = "csa" -credential = {} - -[[word]] -text = "csbe" -credential = {} - -[[word]] -text = "csc" -credential = {} - -[[word]] -text = "cscp" -credential = {} - -[[word]] -text = "cscu" -credential = {} - -[[word]] -text = "csep" -credential = {} - -[[word]] -text = "csi" -credential = {} - -[[word]] -text = "csp" -credential = {} - -[[word]] -text = "cspo" -credential = {} - -[[word]] -text = "csre" -credential = {} - -[[word]] -text = "csrte" -credential = {} - -[[word]] -text = "csslp" -credential = {} - -[[word]] -text = "cssm" -credential = {} - -[[word]] -text = "cst" -credential = {} - -[[word]] -text = "cste" -credential = {} - -[[word]] -text = "ctbs" -credential = {} - -[[word]] -text = "ctfa" -credential = {} - -[[word]] -text = "cto" -credential = {} - -[[word]] -text = "ctp" -credential = {} - -[[word]] -text = "cts" -credential = {} - -[[word]] -text = "cua" -credential = {} - -[[word]] -text = "cusp" -credential = {} - -[[word]] -text = "cva" -credential = {} - -[[word]] -text = "cvo" -credential = {} - -[[word]] -text = "cvp" -credential = {} - -[[word]] -text = "cvrs" -credential = {} - -[[word]] -text = "cwap" -credential = {} - -[[word]] -text = "cwb" -credential = {} - -[[word]] -text = "cwdp" -credential = {} - -[[word]] -text = "cwep" -credential = {} - -[[word]] -text = "cwna" -credential = {} - -[[word]] -text = "cwne" -credential = {} - -[[word]] -text = "cwp" -credential = {} - -[[word]] -text = "cwsp" -credential = {} - -[[word]] -text = "cxa" -credential = {} - -[[word]] -text = "cyds" -credential = {} - -[[word]] -text = "cysa" -credential = {} - -[[word]] -text = "dabfm" -credential = {} - -[[word]] -text = "dabvlm" -credential = {} - -[[word]] -text = "dacvim" -credential = {} - -[[word]] -text = "dbe" -credential = {} - -[[word]] -text = "dc" -credential = {} - -[[word]] -text = "dcb" -credential = {} - -[[word]] -text = "dcm" -credential = {} - -[[word]] -text = "dcmg" -credential = {} - -[[word]] -text = "dcvo" -credential = {} - -[[word]] -text = "dd" -credential = {} - -[[word]] -text = "dds" -credential = {} - -[[word]] -text = "ded" -credential = {} - -[[word]] -text = "dep" -credential = {} - -[[word]] -text = "dfc" -credential = {} - -[[word]] -text = "dfm" -credential = {} - -[[word]] -text = "diplac" -credential = { cased = "DiplAc" } - -[[word]] -text = "diplom" -credential = {} - -[[word]] -text = "djur" -credential = {} - -[[word]] -text = "dma" -credential = {} - -[[word]] -text = "dmd" -credential = {} - -[[word]] -text = "dmin" -credential = { cased = "DMin" } - -[[word]] -text = "dnp" -credential = {} - -[[word]] -text = "dpm" -credential = {} - -[[word]] -text = "dpt" -credential = {} - -[[word]] -text = "drb" -credential = {} - -[[word]] -text = "drmp" -credential = {} - -[[word]] -text = "drph" -credential = { cased = "DrPH" } - -[[word]] -text = "dsc" -credential = { cased = "DSc" } - -[[word]] -text = "dsm" -credential = {} - -[[word]] -text = "dso" -credential = {} - -[[word]] -text = "dss" -credential = {} - -[[word]] -text = "dtr" -credential = {} - -[[word]] -text = "dvep" -credential = {} - -[[word]] -text = "dvm" -credential = {} - -[[word]] -text = "ea" -credential = {} - -[[word]] -text = "ed" -credential = { may_be_name = true, expands = "Doctor of Education" } - -[[word]] -text = "edd" -credential = {} - -[[word]] -text = "ei" -credential = {} - -[[word]] -text = "eit" -credential = {} - -[[word]] -text = "els" -credential = {} - -[[word]] -text = "emd" -credential = {} - -[[word]] -text = "emt-b" -credential = {} - -[[word]] -text = "emt-i/85" -credential = {} - -[[word]] -text = "emt-i/99" -credential = {} - -[[word]] -text = "emt-p" -credential = {} - -[[word]] -text = "enp" -credential = {} - -[[word]] -text = "erd" -credential = {} - -[[word]] -text = "evp" -credential = {} - -[[word]] -text = "faafp" -credential = {} - -[[word]] -text = "faan" -credential = {} - -[[word]] -text = "faap" -credential = {} - -[[word]] -text = "fac-c" -credential = {} - -[[word]] -text = "facc" -credential = {} - -[[word]] -text = "facd" -credential = {} - -[[word]] -text = "facem" -credential = {} - -[[word]] -text = "facep" -credential = {} - -[[word]] -text = "facha" -credential = {} - -[[word]] -text = "facofp" -credential = {} - -[[word]] -text = "facog" -credential = {} - -[[word]] -text = "facp" -credential = {} - -[[word]] -text = "facph" -credential = {} - -[[word]] -text = "facs" -credential = {} - -[[word]] -text = "faia" -credential = {} - -[[word]] -text = "faicp" -credential = {} - -[[word]] -text = "fala" -credential = {} - -[[word]] -text = "fashp" -credential = {} - -[[word]] -text = "fasid" -credential = {} - -[[word]] -text = "fasla" -credential = {} - -[[word]] -text = "fasma" -credential = {} - -[[word]] -text = "faspen" -credential = {} - -[[word]] -text = "fca" -credential = {} - -[[word]] -text = "fcas" -credential = {} - -[[word]] -text = "fcela" -credential = {} - -[[word]] -text = "fd" -credential = {} - -[[word]] -text = "fec" -credential = {} - -[[word]] -text = "fhames" -credential = {} - -[[word]] -text = "fic" -credential = {} - -[[word]] -text = "ficf" -credential = {} - -[[word]] -text = "fieee" -credential = {} - -[[word]] -text = "fmp" -credential = {} - -[[word]] -text = "fmva" -credential = {} - -[[word]] -text = "fnss" -credential = {} - -[[word]] -text = "fp&a" -credential = {} - -[[word]] -text = "fp-c" -credential = {} - -[[word]] -text = "fpc" -credential = {} - -[[word]] -text = "frm" -credential = {} - -[[word]] -text = "fsa" -credential = {} - -[[word]] -text = "fsdp" -credential = {} - -[[word]] -text = "fws" -credential = {} - -[[word]] -text = "gba" -credential = {} - -[[word]] -text = "gbe" -credential = {} - -[[word]] -text = "gc" -credential = {} - -[[word]] -text = "gcb" -credential = {} - -[[word]] -text = "gchs" -credential = {} - -[[word]] -text = "gcie" -credential = {} - -[[word]] -text = "gcmg" -credential = {} - -[[word]] -text = "gcsi" -credential = {} - -[[word]] -text = "gcvo" -credential = {} - -[[word]] -text = "gisp" -credential = {} - -[[word]] -text = "git" -credential = {} - -[[word]] -text = "gm" -credential = {} - -[[word]] -text = "gmb" -credential = {} - -[[word]] -text = "gmr" -credential = {} - -[[word]] -text = "gphr" -credential = {} - -[[word]] -text = "gri" -credential = {} - -[[word]] -text = "grp" -credential = {} - -[[word]] -text = "gsmieee" -credential = {} - -[[word]] -text = "hccp" -credential = {} - -[[word]] -text = "hrs" -credential = {} - -[[word]] -text = "iaccp" -credential = {} - -[[word]] -text = "iaee" -credential = {} - -[[word]] -text = "iccm-d" -credential = {} - -[[word]] -text = "iccm-f" -credential = {} - -[[word]] -text = "idsm" -credential = {} - -[[word]] -text = "ifgict" -credential = {} - -[[word]] -text = "iom" -credential = {} - -[[word]] -text = "ipep" -credential = {} - -[[word]] -text = "ipm" -credential = {} - -[[word]] -text = "iso" -credential = {} - -[[word]] -text = "issp-csp" -credential = {} - -[[word]] -text = "issp-sa" -credential = {} - -[[word]] -text = "itil" -credential = {} - -[[word]] -text = "jd" -credential = { may_be_name = true, expands = "Juris Doctor" } - -[[word]] -text = "jp" -credential = {} - -[[word]] -text = "kbe" -credential = {} - -[[word]] -text = "kcb" -credential = {} - -[[word]] -text = "kchs/dchs" -credential = {} - -[[word]] -text = "kcie" -credential = {} - -[[word]] -text = "kcmg" -credential = {} - -[[word]] -text = "kcsi" -credential = {} - -[[word]] -text = "kcvo" -credential = {} - -[[word]] -text = "kg" -credential = {} - -[[word]] -text = "khs/dhs" -credential = {} - -[[word]] -text = "knt" -[word.credential] -expands = "Knight" -issue = 606 -note = "the older spelling of kt" -cased = "Knt" - -[[word]] -text = "kp" -credential = {} - -[[word]] -text = "kt" -credential = { cased = "Kt" } - -# (SUFFIX_ACRONYMS_AMBIGUOUS) -# #540: LAc, Licensed Acupuncturist; Lac is a Vietnamese given name -# (the trailing word in native order, Nguyen Van Lac) and a French -# surname -[[word]] -text = "lac" -[word.credential] -may_be_name = true -expands = "Licensed Acupuncturist" -issue = 540 -note = "Lac is a Vietnamese given name (the trailing word in native order, Nguyen Van Lac) and a French surname" - -[[word]] -text = "lcmt" -credential = {} - -[[word]] -text = "lcpc" -credential = {} - -[[word]] -text = "lcsw" -credential = {} - -[[word]] -text = "lg" -credential = {} - -[[word]] -text = "litk" -credential = {} - -[[word]] -text = "litl" -credential = {} - -[[word]] -text = "litp" -credential = {} - -[[word]] -text = "llm" -credential = {} - -[[word]] -text = "lm" -credential = {} - -[[word]] -text = "lmsw" -credential = {} - -[[word]] -text = "lmt" -credential = {} - -[[word]] -text = "lp" -credential = {} - -[[word]] -text = "lpa" -credential = {} - -[[word]] -text = "lpc" -credential = {} - -[[word]] -text = "lpn" -credential = {} - -[[word]] -text = "lpss" -credential = {} - -[[word]] -text = "lsi" -credential = {} - -[[word]] -text = "lsit" -credential = {} - -[[word]] -text = "lvn" -credential = {} - -[[word]] -text = "lvo" -credential = {} - -[[word]] -text = "lvt" -credential = {} - -[[word]] -text = "ma" -credential = { may_be_name = true, expands = "Master of Arts" } - -[[word]] -text = "maaa" -credential = {} - -[[word]] -text = "mba" -credential = {} - -[[word]] -text = "mbe" -credential = {} - -[[word]] -text = "mbs" -credential = {} - -[[word]] -text = "mcct" -credential = {} - -[[word]] -text = "mcdba" -credential = {} - -[[word]] -text = "mches" -credential = {} - -[[word]] -text = "mcm" -credential = {} - -[[word]] -text = "mcp" -credential = {} - -[[word]] -text = "mcpd" -credential = {} - -[[word]] -text = "mcsa" -credential = {} - -[[word]] -text = "mcsd" -credential = {} - -[[word]] -text = "mcse" -credential = {} - -[[word]] -text = "mct" -credential = {} - -[[word]] -text = "mda" -credential = {} - -[[word]] -text = "mdb" -credential = {} - -[[word]] -text = "mdbb" -credential = {} - -[[word]] -text = "mdep" -credential = {} - -[[word]] -text = "mdhb" -credential = {} - -[[word]] -text = "mdiv" -credential = { cased = "MDiv" } - -[[word]] -text = "mdl" -credential = {} - -[[word]] -text = "mem" -credential = {} - -# (SUFFIX_ACRONYMS_AMBIGUOUS) -# #540: MEng, Master of Engineering; Meng, a Chinese surname and given name -[[word]] -text = "meng" -[word.credential] -may_be_name = true -expands = "Master of Engineering" -issue = 540 -note = "Meng is a Chinese surname and given name" - -[[word]] -text = "mfa" -credential = {} - -[[word]] -text = "micp" -credential = {} - -[[word]] -text = "mieee" -credential = {} - -[[word]] -text = "mirm" -credential = {} - -[[word]] -text = "mle" -credential = {} - -[[word]] -text = "mls" -credential = {} - -[[word]] -text = "mlse" -credential = {} - -[[word]] -text = "mlt" -credential = {} - -[[word]] -text = "mm" -credential = {} - -[[word]] -text = "mmad" -credential = {} - -[[word]] -text = "mmas" -credential = {} - -[[word]] -text = "mnaa" -credential = {} - -[[word]] -text = "mnae" -credential = {} - -[[word]] -text = "mp" -credential = {} - -[[word]] -text = "mpa" -credential = {} - -[[word]] -text = "mph" -credential = {} - -[[word]] -text = "mpse" -credential = {} - -[[word]] -text = "mra" -credential = {} - -[[word]] -text = "msa" -credential = {} - -[[word]] -text = "msc" -credential = { cased = "MSc" } - -[[word]] -text = "mscmsm" -credential = {} - -[[word]] -text = "msm" -credential = {} - -[[word]] -text = "mt" -credential = {} - -[[word]] -text = "mts" -credential = {} - -[[word]] -text = "mvo" -credential = {} - -[[word]] -text = "nbc-his" -credential = {} - -[[word]] -text = "nbcch" -credential = {} - -[[word]] -text = "nbcch-ps" -credential = {} - -[[word]] -text = "nbcdch" -credential = {} - -[[word]] -text = "nbcdch-ps" -credential = {} - -[[word]] -text = "nbcfch" -credential = {} - -[[word]] -text = "nbcfch-ps" -credential = {} - -[[word]] -text = "nbct" -credential = {} - -[[word]] -text = "ncarb" -credential = {} - -[[word]] -text = "nccp" -credential = {} - -[[word]] -text = "ncidq" -credential = {} - -[[word]] -text = "ncps" -credential = {} - -[[word]] -text = "ncso" -credential = {} - -[[word]] -text = "ncto" -credential = {} - -[[word]] -text = "nd" -credential = {} - -[[word]] -text = "ndtr" -credential = {} - -[[word]] -text = "nmd" -credential = {} - -[[word]] -text = "np" -credential = {} - -[[word]] -text = "nraemt" -credential = {} - -[[word]] -text = "nremr" -credential = {} - -[[word]] -text = "nremt" -credential = {} - -[[word]] -text = "nrp" -credential = {} - -[[word]] -text = "obe" -credential = {} - -[[word]] -text = "obi" -credential = {} - -[[word]] -text = "oca" -credential = {} - -[[word]] -text = "ocm" -credential = {} - -[[word]] -text = "ocp" -credential = {} - -[[word]] -text = "od" -credential = {} - -[[word]] -text = "om" -[word.credential] -note = "NOT may_be_name: weighed 2026-09-07 with #342, no surname evidence worth standing behind, and OM is the Order of Merit" - -[[word]] -text = "oscp" -credential = {} - -[[word]] -text = "ot" -credential = {} - -[[word]] -text = "pa-c" -credential = {} - -[[word]] -text = "pcc" -credential = {} - -[[word]] -text = "pci" -credential = {} - -[[word]] -text = "pe" -credential = {} - -[[word]] -text = "pfmp" -credential = {} - -[[word]] -text = "pg" -credential = {} - -[[word]] -text = "pgmp" -credential = {} - -[[word]] -text = "pharmd" -credential = { cased = "PharmD" } - -[[word]] -text = "phc" -credential = { cased = "PhC" } - -[[word]] -text = "phd" -credential = { expands = "Doctor of Philosophy", cased = "PhD" } - -[[word]] -text = "phr" -credential = {} - -[[word]] -text = "phrca" -credential = {} - -[[word]] -text = "pla" -credential = {} - -[[word]] -text = "pls" -credential = {} - -[[word]] -text = "pmc" -credential = {} - -[[word]] -text = "pmi-acp" -credential = {} - -[[word]] -text = "pmp" -credential = {} - -[[word]] -text = "pp" -credential = {} - -[[word]] -text = "pps" -credential = {} - -[[word]] -text = "prm" -credential = {} - -[[word]] -text = "psm" -credential = {} - -[[word]] -text = "psp" -credential = {} - -[[word]] -text = "psyd" -credential = { cased = "PsyD" } - -[[word]] -text = "pt" -credential = {} - -[[word]] -text = "pta" -credential = {} - -[[word]] -text = "qam" -credential = {} - -[[word]] -text = "qc" -credential = {} - -[[word]] -text = "qcsw" -credential = {} - -[[word]] -text = "qfsm" -credential = {} - -[[word]] -text = "qgm" -credential = {} - -[[word]] -text = "qpm" -credential = {} - -[[word]] -text = "qsd" -credential = {} - -[[word]] -text = "qsp" -credential = {} - -[[word]] -text = "rba" -credential = {} - -[[word]] -text = "rci" -credential = {} - -[[word]] -text = "rcp" -credential = {} - -[[word]] -text = "rd" -credential = {} - -[[word]] -text = "rdcs" -credential = {} - -[[word]] -text = "rdh" -credential = {} - -[[word]] -text = "rdms" -credential = {} - -[[word]] -text = "rdn" -credential = {} - -[[word]] -text = "res" -credential = {} - -[[word]] -text = "rfp" -credential = {} - -[[word]] -text = "rhca" -credential = {} - -[[word]] -text = "rid" -credential = {} - -[[word]] -text = "rls" -credential = {} - -[[word]] -text = "rmsks" -credential = {} - -[[word]] -text = "rn" -credential = {} - -[[word]] -text = "rp" -credential = {} - -[[word]] -text = "rpa" -credential = {} - -[[word]] -text = "rph" -credential = { cased = "RPh" } - -[[word]] -text = "rpl" -credential = {} - -[[word]] -text = "rrc" -credential = {} - -[[word]] -text = "rrt" -credential = {} - -[[word]] -text = "rrt-accs" -credential = {} - -[[word]] -text = "rrt-nps" -credential = {} - -[[word]] -text = "rrt-sds" -credential = {} - -[[word]] -text = "rtrp" -credential = {} - -[[word]] -text = "rvm" -credential = {} - -[[word]] -text = "rvt" -credential = {} - -[[word]] -text = "same" -credential = {} - -[[word]] -text = "sasm" -credential = {} - -[[word]] -text = "sccp" -credential = {} - -[[word]] -text = "scmp" -credential = {} - -[[word]] -text = "se" -[word.credential] -note = "NOT may_be_name: weighed 2026-09-07 with #342, no surname evidence worth standing behind" - -[[word]] -text = "secb" -credential = {} - -[[word]] -text = "sfp" -credential = {} - -[[word]] -text = "shrm-cp" -credential = {} - -[[word]] -text = "shrm-scp" -credential = {} - -[[word]] -text = "si" -credential = {} - -[[word]] -text = "siie" -credential = {} - -[[word]] -text = "smieee" -credential = {} - -[[word]] -text = "sphr" -credential = {} - -[[word]] -text = "sscp" -credential = {} - -[[word]] -text = "stb" -credential = {} - -[[word]] -text = "stmieee" -credential = {} - -[[word]] -text = "tbr-ct" -credential = {} - -[[word]] -text = "td" -credential = {} - -[[word]] -text = "thd" -credential = { cased = "ThD" } - -[[word]] -text = "thm" -credential = { cased = "ThM" } - -[[word]] -text = "ud" -credential = {} - -[[word]] -text = "usa" -credential = {} - -[[word]] -text = "usaf" -credential = {} - -[[word]] -text = "usar" -credential = {} - -[[word]] -text = "uscg" -credential = {} - -[[word]] -text = "usmc" -credential = {} - -[[word]] -text = "usn" -credential = {} - -[[word]] -text = "usnr" -credential = {} - -[[word]] -text = "uxc" -credential = {} - -[[word]] -text = "uxmc" -credential = {} - -[[word]] -text = "vcp" -credential = {} - -[[word]] -text = "vrd" -credential = {} - -[[word]] -text = "rai" -[word.excluded.credential] -reason = "Rai, a common surname across Hindi- and Bengali-speaking regions, dominates RAI (RETA Authorized Instructor): removed 2026-09-07 by the relative-frequency criterion (decisions/suffix-acronym-collisions)" -issue = 342 - -[[word]] -text = "cha" -[word.excluded.credential] -reason = "Cha, the Korean 차, dominates CHA (Certified Hotel Administrator): removed 2026-09-07 by the relative-frequency criterion (decisions/suffix-acronym-collisions)" -issue = 342 - -[[word]] -text = "mai" -[word.excluded.credential] -reason = "Mai, a Vietnamese given and family name, a Chinese surname (麥) and a Japanese given name, dominates MAI (Member, Appraisal Institute): removed 2026-10-16 by the relative-frequency criterion (decisions/suffix-acronym-collisions)" -issue = 687 diff --git a/tests/v2/test_vocab.py b/tests/v2/test_vocab.py index aaad06f2..36923a5b 100644 --- a/tests/v2/test_vocab.py +++ b/tests/v2/test_vocab.py @@ -113,10 +113,10 @@ def _edit(shipped: dict[str, str], file: str, old: str, new: str) -> dict[str, s def test_dropping_a_flag_changes_the_compiled_module(shipped: dict[str, str]) -> None: - files = _edit(shipped, "und.toml", 'text = "ma"\ncredential = { may_be_name = true, ', - 'text = "ma"\ncredential = { ') + files = _edit(shipped, "en.toml", 'text = "jd"\ncredential = { may_be_name = true, ', + 'text = "jd"\ncredential = { ') c = _compile(files) - assert "ma" not in c["SUFFIX_ACRONYMS_AMBIGUOUS"] + assert "jd" not in c["SUFFIX_ACRONYMS_AMBIGUOUS"] assert build.render(c) != build.OUTPUT.read_text(encoding="utf-8") From ca61322dd0b57621ee1872c1332a2abcfea10256 Mon Sep 17 00:00:00 2001 From: Derek Gulbranson Date: Tue, 20 Oct 2026 01:02:50 -0700 Subject: [PATCH 2/4] Keep ma, msc, mba and llm in en.toml alone #18's test data puts those degrees beside one name, John Meyer, which #18 calls international degrees rather than German names, so it is no evidence that German names carry them. de.toml keeps the ten 3e14ea20 added for German names; the decisions entry cites the commit. Co-Authored-By: Claude Opus 5.5 --- docs/design/decisions/vocabulary-model.md | 2 +- nameparser/vocab/de.toml | 16 ---------------- 2 files changed, 1 insertion(+), 17 deletions(-) diff --git a/docs/design/decisions/vocabulary-model.md b/docs/design/decisions/vocabulary-model.md index 719b4ef7..016083d9 100644 --- a/docs/design/decisions/vocabulary-model.md +++ b/docs/design/decisions/vocabulary-model.md @@ -77,7 +77,7 @@ The vocabulary was a set of base sets plus marker subsets (`particles` and `part - **2026-10-20 #751 — the credentials given their languages (part 1 of #751).** No compiled set moves: `tools/vocab/build.py --check` reports the committed module current, and `tools/differential/snapshot.py` matches. The 605 credential readings in `und.toml` on a0edfeda left it, so `und.toml` holds no suffix reading, and the three credential refusals (`rai`, `cha`, `mai`) went with them to en.toml. - **English holds all but seven.** 505 of the 605 came from one import (af5bdab, 2019, #93), the United States post-nominal letters of two Wikipedia lists, and most of the rest are British and Commonwealth honours and degrees, from the list's first versions and #7; all of these are in en.toml. Recompute the provenance with `git blame -w 6803a261 -- nameparser/config/suffixes.py`, the last commit before the TOML. - - **German names hold fourteen.** #18 (3e14ea20) added the German parliamentary memberships (`mdb`, `mdl`, `mda`, `mdbb`, `mdep`, `mdhb`) and `stb` (Steuerberater) for German names; they are in de.toml alone, with `expands`. The same batch added `ba`, `bsc` and `meng` for German degree holders, and #18's test data writes BA, BSc, M.Sc., M.A., M.Eng., MBA and LL.M. after German names, so those seven are in de.toml beside en.toml. A degree goes to a file on evidence that names in that language carry it, which is why no credential went to mul.toml: the Bologna degrees are written after names in most European languages, but the evidence in hand is German. + - **German names hold ten.** #18 (3e14ea20) added the German parliamentary memberships (`mdb`, `mdl`, `mda`, `mdbb`, `mdep`, `mdhb`) and `stb` (Steuerberater) for German names; they are in de.toml alone, with `expands`. The same commit added `ba`, `bsc` and `meng` among its "German title/degree suffixes", so those three are in de.toml beside en.toml. A degree goes to a file on evidence that names in that language carry it, and a commit adding it for that language's names is such evidence. #18's test data is not: its degree rows put BA, M.A., M.Sc., MBA and LL.M. beside one name, John Meyer, which #18 itself calls international degrees rather than German names, so `ma`, `msc`, `mba` and `llm` are in en.toml alone. No credential went to mul.toml for the same reason: the Bologna degrees are written after names in most European languages, but nothing in hand shows which. - **A behavioral property travels to every file, a descriptive one stays on one.** Check 5 holds every behavioral property of a word's suffix readings to one value in every file, `cased` among them, so the de.toml readings repeat `may_be_name` and `cased` (check 7's "at most one `cased` per word" counts values, not files); the `note`, `expands` and `issue` of the English reading stay in en.toml, and each German reading cites #18. - **Comments became fields.** und.toml's block over the ambiguous credentials was class-level — the criterion is decisions/suffix-acronym-collisions' and decisions/vocabulary-collisions' C-i, the reading rules/S4 and S6, the bracket escape rules/S1 — and is gone, its per-word facts already notes on `ms`, `sa`, `se`, `om`, `mc`, `vd`, `meng` and `lac`; `ba` gained the note that earned its marking. The block over the case masks became `excluded = { cased = … }` on `meng`, `edd`, `lac` and `ded`, each with the rendering a mask would cost (decisions/vocabulary-exclusions' CAPITALIZATION_EXCEPTIONS block keeps the class-level part), and the credential half of `abd`'s comment became `expands` and a `note` on its en.toml reading. - **`mc` sorts as a credential now.** An entry sorts under its earliest kind and `credential` precedes `clan`, so en.toml's `mc` left `mac`'s side for the credential block, its `same_as` kept. diff --git a/nameparser/vocab/de.toml b/nameparser/vocab/de.toml index e824878c..e220936b 100644 --- a/nameparser/vocab/de.toml +++ b/nameparser/vocab/de.toml @@ -126,18 +126,6 @@ credential = { may_be_name = true, issue = 18 } text = "bsc" credential = { cased = "BSc", issue = 18 } -[[word]] -text = "llm" -credential = { issue = 18 } - -[[word]] -text = "ma" -credential = { may_be_name = true, issue = 18 } - -[[word]] -text = "mba" -credential = { issue = 18 } - [[word]] text = "mda" credential = { issue = 18, expands = "Mitglied des Abgeordnetenhauses" } @@ -166,10 +154,6 @@ credential = { issue = 18, expands = "Mitglied des Landtages" } text = "meng" credential = { may_be_name = true, issue = 18 } -[[word]] -text = "msc" -credential = { cased = "MSc", issue = 18 } - [[word]] text = "stb" credential = { issue = 18, expands = "Steuerberater, tax adviser" } From c7e9ff1be44d5d71cd35d913c01dfd5ed5e215ed Mon Sep 17 00:00:00 2001 From: Derek Gulbranson Date: Tue, 20 Oct 2026 01:11:05 -0700 Subject: [PATCH 3/4] Keep the seven international degrees in en.toml alone 3e14ea20 added ba, bsc and meng from #18's "John Meyer" test rows only because the list lacked them; ma, msc, mba and llm rest on the same rows. #18 calls them international degrees, not German names, so none of the seven is German evidence. de.toml keeps the German parliamentary memberships and StB. The README's dated count follows. Co-Authored-By: Claude Opus 5.5 --- docs/design/decisions/vocabulary-model.md | 5 ++--- nameparser/vocab/README.md | 2 +- nameparser/vocab/de.toml | 12 ------------ 3 files changed, 3 insertions(+), 16 deletions(-) diff --git a/docs/design/decisions/vocabulary-model.md b/docs/design/decisions/vocabulary-model.md index 016083d9..b1faac3c 100644 --- a/docs/design/decisions/vocabulary-model.md +++ b/docs/design/decisions/vocabulary-model.md @@ -76,9 +76,8 @@ The vocabulary was a set of base sets plus marker subsets (`particles` and `part - **Recompute** rather than quoting: `uv run python tools/vocab/query.py --kind title --file und --count`, `--file en --kind modifier --count`, `--file mul`. - **2026-10-20 #751 — the credentials given their languages (part 1 of #751).** No compiled set moves: `tools/vocab/build.py --check` reports the committed module current, and `tools/differential/snapshot.py` matches. The 605 credential readings in `und.toml` on a0edfeda left it, so `und.toml` holds no suffix reading, and the three credential refusals (`rai`, `cha`, `mai`) went with them to en.toml. - - **English holds all but seven.** 505 of the 605 came from one import (af5bdab, 2019, #93), the United States post-nominal letters of two Wikipedia lists, and most of the rest are British and Commonwealth honours and degrees, from the list's first versions and #7; all of these are in en.toml. Recompute the provenance with `git blame -w 6803a261 -- nameparser/config/suffixes.py`, the last commit before the TOML. - - **German names hold ten.** #18 (3e14ea20) added the German parliamentary memberships (`mdb`, `mdl`, `mda`, `mdbb`, `mdep`, `mdhb`) and `stb` (Steuerberater) for German names; they are in de.toml alone, with `expands`. The same commit added `ba`, `bsc` and `meng` among its "German title/degree suffixes", so those three are in de.toml beside en.toml. A degree goes to a file on evidence that names in that language carry it, and a commit adding it for that language's names is such evidence. #18's test data is not: its degree rows put BA, M.A., M.Sc., MBA and LL.M. beside one name, John Meyer, which #18 itself calls international degrees rather than German names, so `ma`, `msc`, `mba` and `llm` are in en.toml alone. No credential went to mul.toml for the same reason: the Bologna degrees are written after names in most European languages, but nothing in hand shows which. - - **A behavioral property travels to every file, a descriptive one stays on one.** Check 5 holds every behavioral property of a word's suffix readings to one value in every file, `cased` among them, so the de.toml readings repeat `may_be_name` and `cased` (check 7's "at most one `cased` per word" counts values, not files); the `note`, `expands` and `issue` of the English reading stay in en.toml, and each German reading cites #18. + - **English holds all but seven.** 505 of the 605 came from one import (af5bdab, 2019, #93), the United States post-nominal letters of two Wikipedia lists, and most of the rest are British and Commonwealth honours and degrees, from the list's first versions and #7; these, and the degrees below, are in en.toml. Recompute the provenance with `git blame -w 6803a261 -- nameparser/config/suffixes.py`, the last commit before the TOML. + - **German names hold seven, alone.** #18 (3e14ea20) added the German parliamentary memberships (`mdb`, `mdl`, `mda`, `mdbb`, `mdep`, `mdhb`) and `stb` (Steuerberater) for German names, German by what they mean; they are in de.toml alone, with `expands`. The degrees #18 asked for are not there. Its test data writes BA, BSc, M.A., M.Sc., M.Eng., B. Eng., MBA and LL.M. beside one name, John Meyer, and #18 itself calls them international degrees rather than German names; 3e14ea20 added `ba`, `bsc` and `meng` from those rows only because the list lacked them, `ma`, `msc`, `mba` and `llm` being listed already. So the seven are in en.toml alone. A word goes to a file on evidence that names in that language carry it, and that is why no credential went to mul.toml either: the Bologna degrees are written after names in most European languages, but nothing in hand shows which. - **Comments became fields.** und.toml's block over the ambiguous credentials was class-level — the criterion is decisions/suffix-acronym-collisions' and decisions/vocabulary-collisions' C-i, the reading rules/S4 and S6, the bracket escape rules/S1 — and is gone, its per-word facts already notes on `ms`, `sa`, `se`, `om`, `mc`, `vd`, `meng` and `lac`; `ba` gained the note that earned its marking. The block over the case masks became `excluded = { cased = … }` on `meng`, `edd`, `lac` and `ded`, each with the rendering a mask would cost (decisions/vocabulary-exclusions' CAPITALIZATION_EXCEPTIONS block keeps the class-level part), and the credential half of `abd`'s comment became `expands` and a `note` on its en.toml reading. - **`mc` sorts as a credential now.** An entry sorts under its earliest kind and `credential` precedes `clan`, so en.toml's `mc` left `mac`'s side for the credential block, its `same_as` kept. - **Recompute** rather than quoting: `uv run python tools/vocab/query.py --kind credential --file en --count`, `--kind credential --file de`, `--kind suffix --file und --count`, `--excluded cased`. diff --git a/nameparser/vocab/README.md b/nameparser/vocab/README.md index 496b5d68..14997627 100644 --- a/nameparser/vocab/README.md +++ b/nameparser/vocab/README.md @@ -12,7 +12,7 @@ A file is named for a BCP 47 language tag in canonical case: `fr.toml`, `pt-BR.t Two tags are not languages: -- **`und`** (undetermined) holds the words not yet assigned a language. A few are still here (46 of 1,938 on 2026-10-20, after #751 gave the credentials their languages): the conjunctions, the bound given names, the birth markers and two particles, converted mechanically from the Python lists they used to be; assigning a word to a language means moving its entry to that language's file. The comments above an entry here are the vetting notes that stood above the word in the Python module, in their old order; classifying a category is what turns them into fields. +- **`und`** (undetermined) holds the words not yet assigned a language. A few are still here (46 of 1,931 on 2026-10-20, after #751 gave the credentials their languages): the conjunctions, the bound given names, the birth markers and two particles, converted mechanically from the Python lists they used to be; assigning a word to a language means moving its entry to that language's file. The comments above an entry here are the vetting notes that stood above the word in the Python module, in their old order; classifying a category is what turns them into fields. - **`mul`** (multiple) holds words shared on purpose, such as the Roman numerals. The script is read from the word, not from the file: `sr.toml` holds `mlađi` and `млађи` side by side. A script subtag (`zh-Hant`) is for a difference the text cannot show. diff --git a/nameparser/vocab/de.toml b/nameparser/vocab/de.toml index e220936b..5052cb72 100644 --- a/nameparser/vocab/de.toml +++ b/nameparser/vocab/de.toml @@ -118,14 +118,6 @@ nobility = { gender = "m", expands = "imperial count" } text = "ritter" nobility = { gender = "m", expands = "knight" } -[[word]] -text = "ba" -credential = { may_be_name = true, issue = 18 } - -[[word]] -text = "bsc" -credential = { cased = "BSc", issue = 18 } - [[word]] text = "mda" credential = { issue = 18, expands = "Mitglied des Abgeordnetenhauses" } @@ -150,10 +142,6 @@ credential = { issue = 18, expands = "Mitglied der Hamburgischen Bürgerschaft" text = "mdl" credential = { issue = 18, expands = "Mitglied des Landtages" } -[[word]] -text = "meng" -credential = { may_be_name = true, issue = 18 } - [[word]] text = "stb" credential = { issue = 18, expands = "Steuerberater, tax adviser" } From 8b1b3dcd439dd2d049f0cab0c6d84c38083f9108 Mon Sep 17 00:00:00 2001 From: Derek Gulbranson Date: Tue, 20 Oct 2026 01:12:02 -0700 Subject: [PATCH 4/4] Say which of #18's degrees the #751 entry means Co-Authored-By: Claude Opus 5.5 --- docs/design/decisions/vocabulary-model.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/design/decisions/vocabulary-model.md b/docs/design/decisions/vocabulary-model.md index b1faac3c..2d808013 100644 --- a/docs/design/decisions/vocabulary-model.md +++ b/docs/design/decisions/vocabulary-model.md @@ -77,7 +77,7 @@ The vocabulary was a set of base sets plus marker subsets (`particles` and `part - **2026-10-20 #751 — the credentials given their languages (part 1 of #751).** No compiled set moves: `tools/vocab/build.py --check` reports the committed module current, and `tools/differential/snapshot.py` matches. The 605 credential readings in `und.toml` on a0edfeda left it, so `und.toml` holds no suffix reading, and the three credential refusals (`rai`, `cha`, `mai`) went with them to en.toml. - **English holds all but seven.** 505 of the 605 came from one import (af5bdab, 2019, #93), the United States post-nominal letters of two Wikipedia lists, and most of the rest are British and Commonwealth honours and degrees, from the list's first versions and #7; these, and the degrees below, are in en.toml. Recompute the provenance with `git blame -w 6803a261 -- nameparser/config/suffixes.py`, the last commit before the TOML. - - **German names hold seven, alone.** #18 (3e14ea20) added the German parliamentary memberships (`mdb`, `mdl`, `mda`, `mdbb`, `mdep`, `mdhb`) and `stb` (Steuerberater) for German names, German by what they mean; they are in de.toml alone, with `expands`. The degrees #18 asked for are not there. Its test data writes BA, BSc, M.A., M.Sc., M.Eng., B. Eng., MBA and LL.M. beside one name, John Meyer, and #18 itself calls them international degrees rather than German names; 3e14ea20 added `ba`, `bsc` and `meng` from those rows only because the list lacked them, `ma`, `msc`, `mba` and `llm` being listed already. So the seven are in en.toml alone. A word goes to a file on evidence that names in that language carry it, and that is why no credential went to mul.toml either: the Bologna degrees are written after names in most European languages, but nothing in hand shows which. + - **German names hold seven, alone.** #18 (3e14ea20) added the German parliamentary memberships (`mdb`, `mdl`, `mda`, `mdbb`, `mdep`, `mdhb`) and `stb` (Steuerberater) for German names, German by what they mean; they are in de.toml alone, with `expands`. The degrees #18 wrote AFTER a name are not there (`dipl.-ing`, written before one, is a de.toml title since #750). Its test data writes BA, BSc, M.A., M.Sc., M.Eng., B. Eng., MBA and LL.M. beside one name, John Meyer, and #18 itself calls them international degrees rather than German names; 3e14ea20 added `ba`, `bsc` and `meng` from those rows only because the list lacked them, `ma`, `msc`, `mba` and `llm` being listed already. So those seven credentials are in en.toml alone (B. Eng. is in no file). A word goes to a file on evidence that names in that language carry it, and that is why no credential went to mul.toml either: the Bologna degrees are written after names in most European languages, but nothing in hand shows which. - **Comments became fields.** und.toml's block over the ambiguous credentials was class-level — the criterion is decisions/suffix-acronym-collisions' and decisions/vocabulary-collisions' C-i, the reading rules/S4 and S6, the bracket escape rules/S1 — and is gone, its per-word facts already notes on `ms`, `sa`, `se`, `om`, `mc`, `vd`, `meng` and `lac`; `ba` gained the note that earned its marking. The block over the case masks became `excluded = { cased = … }` on `meng`, `edd`, `lac` and `ded`, each with the rendering a mask would cost (decisions/vocabulary-exclusions' CAPITALIZATION_EXCEPTIONS block keeps the class-level part), and the credential half of `abd`'s comment became `expands` and a `note` on its en.toml reading. - **`mc` sorts as a credential now.** An entry sorts under its earliest kind and `credential` precedes `clan`, so en.toml's `mc` left `mac`'s side for the credential block, its `same_as` kept. - **Recompute** rather than quoting: `uv run python tools/vocab/query.py --kind credential --file en --count`, `--kind credential --file de`, `--kind suffix --file und --count`, `--excluded cased`.