From 77de1e65d09a0b9aadacdcf25d8b2890f9e1b1e1 Mon Sep 17 00:00:00 2001 From: Derek Gulbranson Date: Sun, 16 Aug 2026 23:23:12 -0700 Subject: [PATCH 1/2] docs(decisions): C-i needs a positional qualifier C-i as first recorded asked whether a word is borne as an ordinary name in some tradition. Applied to this set's most load-bearing member it self-destructs: "De" is a borne Bengali and Odia surname (parse("Bimal De").family == "De"), so the criterion said mark `de` AMBIGUOUS -- which would break "de la Vega" and every leading-particle reading. The qualifier the existing set was already obeying: P1 acts on the LEADING position, or a lone particle in the GIVEN role, so what matters is whether the naming use occupies THAT position. van/bar/do collide there and are ambiguous; "De" is a trailing surname and never reaches the rule. Consequence rather than tidying: `das` was called ambiguous on #360 under the old reading. Measured, "Anjali Das" and "Bimal Das" are unchanged by never-given `das`, while "Maria das Neves" GAINS its particle -- family="Neves" today, family="das Neves" with it. The old reading would have declined a fix. Corrected on #360, which carried the wrong table publicly. Caught by writing a per-word evidence record for `de`. A verdict alone hides its reasoning; a record has to state why, which forces the collision question. The criterion had survived three review agents and a merge because nothing tested it against `de`, and the error pointed at the safe side so it could never surface as a misparse. Co-Authored-By: Claude Opus 5 --- docs/design/decisions.md | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/docs/design/decisions.md b/docs/design/decisions.md index f77ef6c4..0c3cee30 100644 --- a/docs/design/decisions.md +++ b/docs/design/decisions.md @@ -122,8 +122,33 @@ The mechanism shipped twice before anyone wrote down its criterion. Sizes as of uv run python -c "from nameparser import Parser; L=Parser().lexicon; print({s: len(getattr(L,s)) for s in ('particles','particles_ambiguous','suffix_words','suffix_acronyms','suffix_acronyms_ambiguous','titles')})" - 2026-08-16 (collision keystone; #348, #360, #342, #385) — the 58%-vs-0.65% gap is BASE RATE, not disagreement. Both sets apply the same test; most particles are short words that double as names (van, bin, le, do, bar, mac) while most credential acronyms are not (abpp, acp). Recorded because the gap reads as an inconsistency and is not one — a reviewer who "harmonizes" the two shares will break one of them. -- **C-i, vocabulary vs. name.** A word belongs in its set's ambiguous subset iff it is also borne as an ordinary name (given or family) in some tradition. Under uncertainty, default to AMBIGUOUS. This generalizes the evidence standard already stated in NON_GIVEN_NAME_PARTICLES' docstring — a wrong unambiguous claim misparses a real person, a wrong ambiguous marking only adds a flag — from "which set" to "which subset". Applies uniformly to particles, suffix_acronyms and titles. +- **C-i, vocabulary vs. name.** A word belongs in its set's ambiguous subset iff it is borne as an ordinary name IN THE POSITION THE VOCABULARY CLAIM ACTS ON. Existence of a bearer anywhere is not the test, and the first draft of this criterion (recorded 2026-08-16, corrected 2026-08-17) got that wrong. Under uncertainty, default to AMBIGUOUS. This generalizes the evidence standard already stated in NON_GIVEN_NAME_PARTICLES' docstring — a wrong unambiguous claim misparses a real person, a wrong ambiguous marking only adds a flag — from "which set" to "which subset". Applies uniformly to particles, suffix_acronyms and titles. - **C-ii, vocabulary vs. vocabulary.** Where two sets claim a word and NEITHER reading is a name, precedence is a frequency judgment recorded per word. vd is the live case: never-given particle AND credential acronym (the British Volunteer Decoration), neither of them a name. Decision: the Dutch van der reading, as the more common. That is what unblocks #380, whose trailing-orphan half is a separate decision recorded under its own rule. +- 2026-08-17 — C-i CORRECTED: the position qualifier. Writing the + per-word records for the never-given particles falsified the first + draft on the set's most load-bearing member. "De" is a borne Bengali + and Odia surname (parse("Bimal De").family == "De"), so C-i as first + written said mark `de` AMBIGUOUS -- which would break "de la Vega" + and every leading-particle reading. Nothing had tested the criterion + against `de`, and the error pointed at the safe side, so it would + never have announced itself as a misparse. + The qualifier the existing set was already obeying: P1 acts on the + LEADING position or a lone particle in the GIVEN role, so what + matters is whether the naming use occupies THAT position. + van Vietnamese Văn in given position collides ambiguous + bar Bar Refaeli, given position collides ambiguous + do Đỗ leads a surname collides ambiguous + de "De" is a TRAILING surname no clash never-given + Consequence, and the reason this is not merely tidier: `das` was + called ambiguous on #360 under the old reading because Das is a + borne Bengali surname. Measured, "Anjali Das" and "Bimal Das" are + unchanged by never-given `das` (the surname is trailing, the rule + acts leading) while "Maria das Neves" GAINS its particle -- + family="Neves" today, family="das Neves" with it. The old reading + would have declined a fix. `lo` and `el` need re-judging on the same + axis; `Lo` does lead in romanized Chinese ("Lo Wei"), so it may + genuinely collide where `das` does not. + Corrected on #360, which carried the wrong table publicly. - The concrete demonstration is "do", which three vocabularies claim — titles, particles/ambiguous, suffix_acronyms/ambiguous. Two mark it ambiguous; the third, TITLES, is the one that actually decides "Do Quang Minh" (title="Do", given="Quang") and reports nothing. Same word behind #385's "Anh Do". - Applications, each still its own work: #360 (mc, ste — neither is a borne given name, so both leave the ambiguous half); #342 (rai — Rai IS a borne surname, so it earns the marking rather than moving); #385 (do — resolved at decisions.md#R2). - C-ii's per-word framing versus a rule stated for a SHAPE: measured 2026-08-16, the words that are both particle and suffix vocabulary are vd, do and mc — three, not the one this criterion adjudicated. rules.md#P6 states its precedence for the shape, so do and mc inherit vd's answer without being weighed. Recorded rather than papered over: stating a per-word judgement as a general clause is how an unexamined word acquires a decision, and the two are named here so the next reader knows which one was actually argued. From 558ff4cb77b16a8e4a7990f089dcb1bdfc283e2c Mon Sep 17 00:00:00 2001 From: Derek Gulbranson Date: Sun, 16 Aug 2026 23:23:12 -0700 Subject: [PATCH 2/2] docs(particles): evidence records for the never-given members Comments only -- membership is byte-identical, 28 never-given members before and after, 3459 tests green. #360's grievance is that only 9 of the 39 ambiguous members were ever individually justified. The never-given side had the same gap and is the side that matters: it is the falsifiable claim, since one attested bearer in the acting position overturns it, while "ambiguous" is the safe default and needs no argument. Each entry now states what the word IS -- article, preposition, or patronymic marker -- because that is the only form a never-given record can take. One bearer settles the ambiguous side; no amount of searching settles absence. The convention, and the reason it costs nothing: a BARE entry means nobody has examined it. Absence of a comment is the audit record, so #360's remaining work is visible at a glance rather than needing a ledger. Following the #269 Arabic/Hebrew blocks' style, which already did this for their own members. Two entries carry the interesting cases. `de` records that "De" is a borne Bengali/Odia surname but a trailing one, which is what forced C-i's positional qualifier. `vd` records that both its readings are non-names, so C-ii decides it on frequency. Not included: the ambiguous members #360 lists as candidates to move (mc, ste, aan, aen, heer, te, tho, thoe, vel, vande). Their records are their judgments, and #360 has not made them -- writing a comment now would pre-judge the issue. They stay bare, which the convention already reads as unexamined. Co-Authored-By: Claude Opus 5 --- nameparser/config/particles.py | 64 ++++++++++++++++++++++------------ 1 file changed, 42 insertions(+), 22 deletions(-) diff --git a/nameparser/config/particles.py b/nameparser/config/particles.py index a79bc860..247e9378 100644 --- a/nameparser/config/particles.py +++ b/nameparser/config/particles.py @@ -36,28 +36,48 @@ #: subset of :py:data:`PARTICLES` and disjoint from #: :py:data:`~nameparser.config.bound_given_names.BOUND_GIVEN_NAMES`. NON_GIVEN_NAME_PARTICLES = frozenset({ - "'t", - 'af', - 'auf', - 'av', - 'bint', - 'de', - "de'", - 'degli', - 'dei', - 'delle', - 'delli', - 'dello', - 'dem', - 'der', - 'dos', - 'het', - 'ibn', - 'op', - 'ter', - 'vd', - 'vom', - 'zu', + # Latin-script members. Every entry here is a grammatical particle -- + # an article, a preposition, or a patronymic marker -- and that is the + # form a never-given record has to take. One attested bearer settles + # the AMBIGUOUS side; no amount of searching settles absence, so what + # is recorded is what the word IS rather than a failed search. + # + # The test is POSITIONAL (decisions.md#vocabulary-collisions C-i, + # corrected 2026-08-17): membership asks whether the word is borne as + # a name in the position this rule ACTS on -- leading, or alone in the + # given role -- not whether a bearer exists anywhere. 'de' is why the + # qualifier is needed: "De" is a borne Bengali/Odia surname, but a + # TRAILING one, so it never meets the rule. + # + # A BARE entry, here or in PARTICLES below, means nobody has examined + # it. Absence of a comment is the audit record. + "'t", # Dutch contraction of 'het' ("'t Hooft"): the article itself + 'af', # Danish/Norwegian nobiliary "of" + 'auf', # German "upon" ("auf der Heide") + 'av', # Swedish/Norwegian "of" + 'bint', # Arabic "daughter of"; native-script بنت below + 'de', # French/Iberian/Italian "of". "De" IS a borne Bengali and + # Odia surname -- trailing, so it never reaches this rule. + # The case that forced C-i's positional qualifier. + "de'", # Italian elided "dei" ("de' Medici") + 'degli', # Italian "of the", masc. pl. + 'dei', # Italian "of the", masc. pl. + 'delle', # Italian "of the", fem. pl. + 'delli', # Italian "of the", regional variant of 'dei' + 'dello', # Italian "of the", masc. sg. + 'dem', # German dative article + 'der', # German article ("von der Leyen") + 'dos', # Portuguese "of the", masc. pl. + 'het', # Dutch definite article + 'ibn', # Arabic "son of"; native-script ابن below + 'op', # Dutch "at/on" ("op den Berg") + 'ter', # Dutch "at the" ("ter Horst") + 'vd', # Dutch abbreviation of "van der". Also the British + # Volunteer Decoration, a suffix acronym: two non-name + # readings, so C-ii decides it on frequency and the Dutch + # one wins (decisions.md#vocabulary-collisions). + 'vom', # German "from the" + 'zu', # German "at/to", nobiliary ("zu Guttenberg") # #269: Arabic native-script patronymic/clan particles. Unlike their # Latin transliterations, these live in a script namespace with no