diff --git a/docs/design/decisions/S2-suffix-word-ends-a-name-and-never-opens-the-string.md b/docs/design/decisions/S2-suffix-word-ends-a-name-and-never-opens-the-string.md index c908e09e..3c9cc437 100644 --- a/docs/design/decisions/S2-suffix-word-ends-a-name-and-never-opens-the-string.md +++ b/docs/design/decisions/S2-suffix-word-ends-a-name-and-never-opens-the-string.md @@ -1,6 +1,27 @@ # S2 — a suffix word ends a name and never opens the string -- 2026-10-07 (Derek), #614 — S2'S TRAILING RUN IS READ ONCE, BETWEEN P3'S CONNECTIVE JOINS AND THE PARTICLE CHAIN, AND BINDS. The issue's diagnosis held on the day: the words-to-spare count is taken over pieces and group's joins make pieces, so group re-asked the peel before and after its own joins -- the particle chain's stop and its re-ask and rollback, the bound-given reserve's two views (P5) -- and assign then read the run again. Now the run of a main segment (no comma, or the part before a suffix comma) of three or more pieces is read once, after the Ph. D. merge, the maiden take and P3's connective joins, which do not depend on the run and make the units it counts, and before the particle chain and the bound-given join, which do; the run is split off, the chain and the join group the name in front of it, and the run is put back unchanged (`_pieces.read_trailing_run`). The chain's stop is the end of what is left and the reserve counts the name pieces the read left; assign places and reports the run off the read (`ParseState.tail_reads`, `_assign._placed`). The read COUNTS a particle run and the plain name words after it as the one unit the chain will make of them (`_counting_view`, a copy; rules/P3's own count, mechanisms.md#UNIT-PARTITION), the words both particles and suffix vocabulary straight behind a particle among them, while anything the read weighs stays a word of its own -- suffix vocabulary, the ambiguous class and its shape-only members, roman numerals by shape, initials, period-marked titles. +## Standing + +Examples name each field as the default order reads it; under the family-first orders the given and family names trade places. + +- The trailing run of a main segment (no comma, or the part before a suffix comma) of three or more pieces is read once, after the `Ph. D.` merge, the maiden take and P3's connective joins and before the particle chain (P2) and the bound given-name join (P5), and binds: neither join reaches a word it took (`John van der Berg Prof.` → title 'Prof.', family 'van der Berg'), and a salutation keeps its connective (`Mr. and Mrs.` → title 'Mr. and Mrs.') — 2026-10-07 #614. +- The read counts a particle run and the plain words the chain joins to it as one name word, and a connective join as one, while a word the read weighs (a suffix word, a member of the ambiguous class by listing or by shape, an initial, a roman numeral by shape, a period-marked title) keeps a unit of its own: `Freiherr von Berg X.Y.Z.` keeps family 'von Berg X.Y.Z.', `Juan de la Vega VI` reads suffix 'VI' and `Freiherr von Berg MA X.Y.Z.` suffix 'MA X.Y.Z.' — 2026-10-07 #614; 2026-10-08 #620. +- The count is taken as marks over the pieces as written, asking the chain's own run end, never through a merged copy of the pieces — 2026-10-08 #620. +- Group merges each run of two or more adjacent particles past the chain's leading position before the read, so the read counts, stops at and absorbs the run as one piece; the merged piece keeps `prefix` and drops `title` — 2026-10-10 #625. +- A pick the particle chain takes into the name is reported by the chain, in its own words (`Jan vd Ma` → family 'vd Ma', reported), and assign reports the read's other picks — 2026-10-07 #614. +- Where the run is not read once (a segment of fewer than three pieces, or a run with a name piece inside it, as in `John Dr. G.J.`), group re-asks the peel and assign reads for itself, the procedure before #614; and where a name group's joins leave no name word in front of the run, assign reads it again so it keeps one — 2026-10-07 #614. +- The numeral fork reads the piece in front of the numeral as written, not the unit's first word (`John van B and Smith X` → family 'van B and Smith X') — 2026-10-08 #620. +- The chain reports `particle-or-given` where its run claims something past the particle or is a run the merge made (`Freiherr von der`) — 2026-10-10 #625. + +Not standing: the split of 2026-10-17 #682, the clause move of 2026-10-19 and the skeleton migration of 2026-10-20 #761, each carried out. + +Elsewhere: where the name starts behind a title-particle head, which the chain and the count share — decisions/P2's 2026-10-10 (Derek), #624 entry; the bound given-name reserve reading no view — decisions/P5's 2026-10-07 #614 entry. + +Open: none in this file. + +## Log + +- 2026-10-07 (Derek), #614 (its counting view, a merged copy of the pieces, superseded by #620, below, and the view's name start inside the titles by #624, decisions/P2) — S2'S TRAILING RUN IS READ ONCE, BETWEEN P3'S CONNECTIVE JOINS AND THE PARTICLE CHAIN, AND BINDS. The issue's diagnosis held on the day: the words-to-spare count is taken over pieces and group's joins make pieces, so group re-asked the peel before and after its own joins -- the particle chain's stop and its re-ask and rollback, the bound-given reserve's two views (P5) -- and assign then read the run again. Now the run of a main segment (no comma, or the part before a suffix comma) of three or more pieces is read once, after the Ph. D. merge, the maiden take and P3's connective joins, which do not depend on the run and make the units it counts, and before the particle chain and the bound-given join, which do; the run is split off, the chain and the join group the name in front of it, and the run is put back unchanged (`_pieces.read_trailing_run`). The chain's stop is the end of what is left and the reserve counts the name pieces the read left; assign places and reports the run off the read (`ParseState.tail_reads`, `_assign._placed`). The read COUNTS a particle run and the plain name words after it as the one unit the chain will make of them (`_counting_view`, a copy; rules/P3's own count, mechanisms.md#UNIT-PARTITION), the words both particles and suffix vocabulary straight behind a particle among them, while anything the read weighs stays a word of its own -- suffix vocabulary, the ambiguous class and its shape-only members, roman numerals by shape, initials, period-marked titles. STALE IN THE ISSUE, measured before designing: segment no longer decides the comma or emits S2 reports (#613 moved C1 to `_comma.decide`); assign predicts P1's fold but no longer P6, which it decides since #613; the two comma restart inputs (`John Smith, PhD vd DO`, `PhD DO DO`) no longer reach the chain, decide binding that part first; `credential_run` already applied in one place; and #613's `name_word_count` reads particle and suffix facts at P1's reach and ignores connective and bound-given joins, so S2 could not share it as it stood. The issue's 'licensed by neighbour', read literally, moves about 25 inputs (`JOHN SMITH MA`, six S3 example lines) and still five read as scoped to the duals, so it was not taken; the counting view's particle run is the one part of it the design needed. THE FIRST DESIGN AND THE REVIEW THAT REVERSED IT. Derek decided first that the read WINS OVER EVERY JOIN, connectives included -- prototyped both ways in a scratch copy -- and that implementation passed the suite, the gates and the fingerprint. #614's PR review then found it broke what the corpus never tests: a salutation alone read its connective as the family name (`Mr. and Mrs.` gave title 'Mr. Mrs.', family 'and' -- the H5 chain took 'Mrs.' before P3 could join), a joined leading salutation counted as three words (`Mr. and Mrs. Jr` gave family 'and', `Mr. and Mrs. Do` a spurious report), and the read counted a particle chain's or a connective join's words one by one where rules/P3 says a joined part is one name word wherever another rule counts (`Freiherr von Berg X.Y.Z.` and `Juan y Garcia X.Y.Z.` took the acronym as a credential against every release, while `Freiherr Berg X.Y.Z.` kept it the family). DECIDED (Derek, 2026-10-07): connectives join first, and the read counts the chain's units -- which returns every one of those to master's reading, and most of the first design's 'tail beats connectives' class with them. A second-round finding the counting view itself made: folding the plain words after a particle into its unit swallowed a shape-only roman numeral (`Juan de la Vega VI` read family 'de la Vega VI'), the #610 class AGENTS.md's spelling sweep records, so a word the numeral fork reads by shape stays out of the unit. DECIDED BEFORE THE REVERSAL AND STANDING: (1) the read wins over the particle chain and the bound-given join; (2) the consequences below, accepted as a class. @@ -10,7 +31,7 @@ RESIDUALS, the paths that read as before #614: a segment of fewer than three pieces (no join reaches it); a run with a name piece inside it (an H5 title in front of a name word the peel declined, `John Dr. G.J.`, `John van V Dr. V`), which is not split -- group re-asks and assign reads for itself; and a name group's joins leave without a name word in front of the run, which assign reads again so it keeps one -- the same procedure as before #614, not always the same answer, the Freiherr garbage above being the measured case. MEASURED 2026-10-07 against 0c54662b (#618's merge), py3.11, `nameparser.__file__` asserted on each side; #619, merged between, moved no reading. The two #617 harnesses as decisions/P3's 2026-10-06 entry records them (the fingerprint, 78,324 parses; the connective grid, 485,300), and an S2 stress grid built for this entry: the 22 heads `John`, `John Smith`, `John Q. Smith`, `Mary Ann Smith`, `John van Smith`, `Juan de la Vega`, `John van`, `anh van`, `Jan Freiherr von Berg`, `Freiherr von Berg`, `abdul salam`, `abdul rahman al-said`, `Juan y Garcia`, `Josep Carod i Rovira`, `Jane Doe nee van der Berg`, `Dr. John Smith`, `JOHN SMITH`, `john smith`, `Smith`, `de Mesnil`, `Kim Min Jun`, `Ortega y Gasset`, each followed by every one- and two-word tail over the 35 words `PhD MA Ma DO Do do vd VD mc Mc MD Jr Jr. Sr III V V. VI I X.Y.Z. XYZ Ph. D. Esq. Prof. Dr. Sir MBA RN G.J. Ed van and Jones Ed. ba` (`Ph. D.` one word of the list); then 25,000 draws seeded `random.seed(614)`, each `choice(heads)`, `randint(3, 5)` and that many `choice(words)`, joined by spaces; then every head before a comma with every two-word pair behind it, and `Smith, ` and ` , John` for every word; deduplicated, under four policies (default, both family-first orders, strict comma suffixes) -- 81,138 names, 324,552 parses, comparing the seven roles, every ambiguity's kind and detail, `initials()` and `capitalized()`. Results: fingerprint 6 parses move (`John van der Berg Prof.` under six policies), connective grid 1,248 (1,212 the title class, 36 garbage) and stress grid 8,472 (its head-plus-one-word slice under the default policy, 12 parses, all the title class), no corpus or case name among them; five differential gates exit 0 with the one move classified `fix(#614)` (PR #621). COST, `tools/perf/call_count.py` against adf6da88 (#619's merge): `parse` 317 -> 308 frames on 3.11, segments of fewer than three pieces unchanged (decisions/parse-cost, this date; PR #621). -- 2026-10-08 (Derek), #620 — S2'S READ COUNTS THE CHAIN'S UNITS OVER THE PIECES AS WRITTEN, RATHER THAN MERGING A COPY OF THEM. The #614 read above counted through a merged copy of the pieces, a second statement of P2's chain with its own stop list, and its reviews found three defects that were that copy's: an index applied across the two layouts (`Freiherr St van Berg MA`), a unit formed inside #602's run hiding a title (`John Smith MD van Secretary Jones`), and a shape-only numeral folded into a unit (`Juan de la Vega VI`), each patched in the copy. Now `_pieces._chain_units` marks each piece by the unit the chain will put it in -- OPENS, JOINED (a name word the chain joins to the run in front of it) or BOUND (a particle inside the run, a word the run took; retired by #625, this section, 2026-10-10, group merging the run first) -- asking `chain_run_end`, the chain's run end, which `_group`'s chain now calls too. The peel's words to spare (`second_unit`) and #602's run start count in those marks and the peel stops at any piece the chain joins into a run, which is a name word whichever mark it carries; everything else reads the pieces as written, so nothing is hidden, and the copy, its view index and its credential-run gate are gone. +- 2026-10-08 (Derek), #620 (its BOUND mark and the gathering of an absorbed particle run superseded by #625, below) — S2'S READ COUNTS THE CHAIN'S UNITS OVER THE PIECES AS WRITTEN, RATHER THAN MERGING A COPY OF THEM. The #614 read above counted through a merged copy of the pieces, a second statement of P2's chain with its own stop list, and its reviews found three defects that were that copy's: an index applied across the two layouts (`Freiherr St van Berg MA`), a unit formed inside #602's run hiding a title (`John Smith MD van Secretary Jones`), and a shape-only numeral folded into a unit (`Juan de la Vega VI`), each patched in the copy. Now `_pieces._chain_units` marks each piece by the unit the chain will put it in -- OPENS, JOINED (a name word the chain joins to the run in front of it) or BOUND (a particle inside the run, a word the run took; retired by #625, this section, 2026-10-10, group merging the run first) -- asking `chain_run_end`, the chain's run end, which `_group`'s chain now calls too. The peel's words to spare (`second_unit`) and #602's run start count in those marks and the peel stops at any piece the chain joins into a run, which is a name word whichever mark it carries; everything else reads the pieces as written, so nothing is hidden, and the copy, its view index and its credential-run gate are gone. WHAT THE COUNT KEEPS. A word the reading weighs -- a suffix word of either kind, the ambiguous class, a word in it by shape, an initial, a roman numeral by shape, a period-marked title word (`_weighed`) -- keeps a unit of its own though the chain may join it, as a position always counted it; only the plain words behind a particle run are JOINED, and a unit with nothing past its opener moves no name start into the titles (SUPERSEDED IN PART by #624, decisions/P2, 2026-10-10: no unit opens inside the titles, so the gate is gone). The first prototype marked every word the chain reaches JOINED, by the chain's own rule alone, and the review found it wrong in two shapes the earlier count read right: `Freiherr von Berg MA X.Y.Z.` kept 'MA X.Y.Z.' in the family (a member the chain would join counted as no word in front of the next), and `St St VI` and `Freiherr St MA` read title 'St St', 'Freiherr St' with the numeral or acronym the whole family (a unit of words the read then takes, which the chain never builds). Both masters read all three as they read now. (#624 since reads `St St VI` and `Freiherr St MA` as title 'St St' / 'Freiherr St' again, by a different route: the chain and the count now share one leading position, the last title-particle, so neither builds the unit -- decisions/P2, 2026-10-10.) The copy's exclusion list had been carrying the count positions always kept -- a member in front counts -- and the marks keep it without the copy. The numeral fork still reads the piece in front of the numeral as written -- reading the unit's first word broke rules/P2's `John van der J. V` -- so `John van B and Smith X` reads family 'van B and Smith X' again, the reading #614's copy had moved. ALSO COUNTED IN UNITS: #602's run start, a particle opening a chain run counting once and its bound particle not at all (`John der la Jr. Prof. Smith` keeps its run, `van la Smith Secretary Jr. Dr. Smith` starts none, as on master). And `credential_run`, on the read's path, gathers adjacent particles into the one absorbed piece the chain makes of them (`Dr. John Smith Esq. RN Mc Mc` reports 'Mc Mc'; SUPERSEDED by #625, this section, 2026-10-10: group merges the run before the read, which absorbs it as one piece); M2's clause-free view reports word by word as it always has. DECLINED, measured: a units test in `tail_reading`'s resume condition. A splice lowers a count only by taking out titles that open units of their own, and with fewer than two units in front of it every piece there is in the first piece's chain run, which the titles behind it join; fuzzed over 372,330 names, the test changed nothing. diff --git a/docs/design/decisions/S5-given-parts-trailing-slot-after-a-family-comma.md b/docs/design/decisions/S5-given-parts-trailing-slot-after-a-family-comma.md index 561e5598..b89fab58 100644 --- a/docs/design/decisions/S5-given-parts-trailing-slot-after-a-family-comma.md +++ b/docs/design/decisions/S5-given-parts-trailing-slot-after-a-family-comma.md @@ -1,8 +1,27 @@ # S5 — the given part's trailing slot after a family comma -- 2026-09-18 — THE COMMA REPORT'S REACH IS THE FIRST POST-COMMA PIECE, AND THE GIVEN SEGMENT'S TRAILING SLOT IS AN OPEN FOLLOW-UP. `assign`'s family-comma emitter reads `state.pieces[1][0]` — the first piece after the comma — so a class member standing at the END of the given part is never asked about. PRE-EXISTING and unchanged by this arc: `Doe, John MA` reads middle `MA` and `Doe, John X.Y.Z.` middle `X.Y.Z.`, both silent, at 1f78bef and on this tree alike. What this arc adds is names that MOVED into that silence: `Doe, John J.u.n.i.o.r.` and `Doe, John X.Y.I.` went suffix → middle, and `John Smith nee Jones R.A.I.` suffix → maiden (the maiden walk absorbs it). `Freiherr von Berg X.Y.I.` was listed here too and does not belong: corrected in the verification round of 2026-09-18, it moved suffix → family but GAINED a report rather than losing one. At 1f78bef and on the 2.3.0 wheel it read title `Freiherr`, family `von Berg`, suffix `X.Y.I.`, reporting `particle-or-given` alone; on this tree it reads title `Freiherr`, family `von Berg X.Y.I.` and reports `particle-or-given` AND `suffix-or-name`, the chain emitter taking it by its shape tag. The role moved into a slot that does not report and the report came from the chain instead, so the name is evidence for the emitter rather than for the silence. The universal claims are narrowed to what ships rather than the emitters widened: `nameparser/_types.py`'s `SUFFIX_OR_NAME` member now names the slots it covers and the one it does not, and rules/S3's "and the same at a comma" now says which parts of a comma form it means. Widening it is a MAINTAINER DECISION and is left open, filed as [#531](https://github.com/derek73/python-nameparser/issues/531): the slot is `_assign`'s given-part walk, the fork is genuine there, and whether a middle initial's neighbourhood should start reporting is a judgement about noise (rules/A1's "a kind is worth adding only if a reader would hesitate too" applies to a SLOT the same way). And the open question is a 1.4.0 PARITY question as well as a noise one, which the verification round of 2026-09-18 established and the entry had backwards: `Doe, John MA` reads suffix `MA` on the 1.4.0 wheel and middle `MA` at 2.0.0 through 2.3.0 and here, so the silence at this slot is a 2.0-era reading that has never matched v1 — "every release" was the wrong span and it is now "every 2.x release" wherever this is stated (`nameparser/_types.py`'s `SUFFIX_OR_NAME` member, docs/release_log.rst). The dotted sibling does not divide that way: `Doe, John X.Y.Z.` is middle `X.Y.Z.` at 1.4.0 too. So a maintainer widening the slot is choosing between reporting the fork and restoring v1's ROLE, which are different repairs, and only the bare-acronym half has a parity claim behind it. Recorded under 3-0-reevaluations' standing rule that a design citing 1.4 parity as load-bearing says so where the design lives. Two more report movements recorded here rather than repaired: `van MA` LOSES its `particle-or-given` (1f78bef reported both kinds; the caps lean now takes `MA` to suffix, leaving `van` the only name piece, and assign's leading-particle emitter wants more pieces following), and `John Smith Ma Ma` reports ONCE where 1f78bef reported twice (the first `Ma` is a middle name now, not a second declined pick). And a reach of the default-on dotted switch worth naming: `John Smith www.example.com` reads suffix `www.example.com` with a report, where 1f78bef read family — a URL is three alphabetic period-separated chunks and the shape rule cannot tell it from an acronym. +## Standing + +Examples name each field as the default order reads it; under the family-first orders the given and family names trade places. + +- After a family comma a member of the ambiguous class ending the given part is read by its writing, not the count, and reports whichever way it goes: `Doe, John MA` → suffix 'MA', `Doe, John Ma` → middle 'Ma', `Doe, John X.Y.Z.` → suffix 'X.Y.Z.'; the bare-acronym half restores 1.4.0's role, the dotted half leaves it to agree with `John Doe X.Y.Z.` — 2026-09-18 #531, THE COMMA REPORT'S REACH NOW. +- Accepted with it: one-case and caseless names take the credential with no case evidence (`doe, john ma` → suffix 'ma', `田中, 太郎 MA` → suffix 'MA'), `Doe, John van MA` reads family 'van Doe', suffix 'MA', `Doe, John Prof. MA` gains title 'Prof.', and `DOE, JOHN ED` reads suffix 'ED' — 2026-09-18 #531, THE COMMA REPORT'S REACH NOW. +- `do`, the one member that is also a particle, is read by its capitals at this slot: in a mixed-case name `Doe, John DO` reads suffix 'DO', and every other spelling attaches to the family by P6, which reports the fork (`Doe, John do` → family 'do Doe'); the one-case `SMITH, JOHN DO` reading family 'DO SMITH' is the accepted cost, paired with `NASCIMENTO, EDSON ARANTES DO` — 2026-09-18 #531, CAPITALS DECIDE. +- A particle in front of the caps `DO` takes it out of the slot (`Doe, John van DO` → family 'van DO Doe'), and a particle behind a member that is not also an unambiguous suffix word ends the given part where this slot reads it (`Doe, John MA do` keeps middle 'MA'), while `vd` and `mc` are looked past (`Doe, John MA vd` → suffix 'MA', family 'vd Doe') — 2026-09-18 #531, CAPITALS DECIDE. +- A never-given particle opening the given part leaves no word to spare, so the member behind it is the surname it heads unless mixed-case capitals say credential (`SMITH, VD MA` → family 'SMITH VD MA'; `Smith, de MA` → suffix 'MA') — 2026-10-02 #573. +- Two report movements stay as recorded: `van MA` reports only `suffix-or-name`, and `John Smith Ma Ma` reports once; and `John Smith www.example.com` reads suffix 'www.example.com', reported, the dotted shape unable to tell a URL from an acronym — 2026-09-18. + +Not standing: the split of 2026-10-17 #682, carried out. + +Elsewhere: `Doe, Jane PhD vd Ma` reads suffix 'PhD vd Ma' and reports, the credential starting the given part's run — decisions/S8's 2026-10-04 (Derek), #602 entry; an unambiguous credential in front of the member overrides P6 as the capitals do (`Doe, John PhD Do` → suffix 'PhD Do') — decisions/S7's 2026-09-27 (Derek), #544 entry headed THE #531 PAIRING GAINS A SECOND EXCEPTION; the maiden gap the #531 entry left open, closed by decisions/S4's 2026-09-19 (Derek), #533 entry and since moved by decisions/M2's 2026-10-04 (Derek), #601 entry, under which a marker after a family comma is an ordinary word (`Doe, Jane nee Smith MA` → middle 'nee Smith', suffix 'MA'). + +Open: none in this file. + +## Log + +- 2026-09-18 (its open follow-up superseded by #531, the 2026-09-18 (Derek) entry below headed THE COMMA REPORT'S REACH NOW INCLUDES, which reads and reports the slot) — THE COMMA REPORT'S REACH IS THE FIRST POST-COMMA PIECE, AND THE GIVEN SEGMENT'S TRAILING SLOT IS AN OPEN FOLLOW-UP. `assign`'s family-comma emitter reads `state.pieces[1][0]` — the first piece after the comma — so a class member standing at the END of the given part is never asked about. PRE-EXISTING and unchanged by this arc: `Doe, John MA` reads middle `MA` and `Doe, John X.Y.Z.` middle `X.Y.Z.`, both silent, at 1f78bef and on this tree alike. What this arc adds is names that MOVED into that silence: `Doe, John J.u.n.i.o.r.` and `Doe, John X.Y.I.` went suffix → middle, and `John Smith nee Jones R.A.I.` suffix → maiden (the maiden walk absorbs it). `Freiherr von Berg X.Y.I.` was listed here too and does not belong: corrected in the verification round of 2026-09-18, it moved suffix → family but GAINED a report rather than losing one. At 1f78bef and on the 2.3.0 wheel it read title `Freiherr`, family `von Berg`, suffix `X.Y.I.`, reporting `particle-or-given` alone; on this tree it reads title `Freiherr`, family `von Berg X.Y.I.` and reports `particle-or-given` AND `suffix-or-name`, the chain emitter taking it by its shape tag. The role moved into a slot that does not report and the report came from the chain instead, so the name is evidence for the emitter rather than for the silence. The universal claims are narrowed to what ships rather than the emitters widened: `nameparser/_types.py`'s `SUFFIX_OR_NAME` member now names the slots it covers and the one it does not, and rules/S3's "and the same at a comma" now says which parts of a comma form it means. Widening it is a MAINTAINER DECISION and is left open, filed as [#531](https://github.com/derek73/python-nameparser/issues/531): the slot is `_assign`'s given-part walk, the fork is genuine there, and whether a middle initial's neighbourhood should start reporting is a judgement about noise (rules/A1's "a kind is worth adding only if a reader would hesitate too" applies to a SLOT the same way). And the open question is a 1.4.0 PARITY question as well as a noise one, which the verification round of 2026-09-18 established and the entry had backwards: `Doe, John MA` reads suffix `MA` on the 1.4.0 wheel and middle `MA` at 2.0.0 through 2.3.0 and here, so the silence at this slot is a 2.0-era reading that has never matched v1 — "every release" was the wrong span and it is now "every 2.x release" wherever this is stated (`nameparser/_types.py`'s `SUFFIX_OR_NAME` member, docs/release_log.rst). The dotted sibling does not divide that way: `Doe, John X.Y.Z.` is middle `X.Y.Z.` at 1.4.0 too. So a maintainer widening the slot is choosing between reporting the fork and restoring v1's ROLE, which are different repairs, and only the bare-acronym half has a parity claim behind it. Recorded under 3-0-reevaluations' standing rule that a design citing 1.4 parity as load-bearing says so where the design lives. Two more report movements recorded here rather than repaired: `van MA` LOSES its `particle-or-given` (1f78bef reported both kinds; the caps lean now takes `MA` to suffix, leaving `van` the only name piece, and assign's leading-particle emitter wants more pieces following), and `John Smith Ma Ma` reports ONCE where 1f78bef reported twice (the first `Ma` is a middle name now, not a second declined pick). And a reach of the default-on dotted switch worth naming: `John Smith www.example.com` reads suffix `www.example.com` with a report, where 1f78bef read family — a URL is three alphabetic period-separated chunks and the shape rule cannot tell it from an acronym. - 2026-09-18 (Derek), #531 — CAPITALS DECIDE FOR `do`, AND THE PARTICLE RULE KEEPS EVERY OTHER SPELLING. `do` is the one member of the ambiguous credential class (`ba`, `do`, `ed`, `jd`, `ma` — recompute with `sorted(Lexicon.default().suffix_acronyms_ambiguous)`) that is also particle vocabulary, so the trailing slot of the given part and P6's attachment want the same word. Where the writing carries a positive credential lean — an all-caps member in a name written in more than one case — the credential reading wins and P6 stands down: `Doe, John DO` reads suffix `DO` and reports `suffix-or-name`. Every other spelling attaches exactly as it did before, with P6's own `particle-or-given` and no second report: `Doe, John do`, `Doe, John Do`, `DOE, JOHN DO`, `doe, john do` all read family `do Doe` in their own case. THE PAIRING IS THE ARGUMENT, and the accepted cost and the reason are the two halves of it. In ONE CASE the rule cannot tell `NASCIMENTO, EDSON ARANTES DO` from `SMITH, JOHN DO` and reads both as the particle — right about the Brazilian record, wrong about the osteopath, whose `DO` 1.4.0 read as a suffix; both report `particle-or-given`, which is how a caller finds the second. In MIXED CASE it can, and does: `Nascimento, Edson Arantes do` keeps family `do Nascimento` while `Doe, John DO` gives suffix `DO`. Accepted rather than repaired: the one-case reading is the commoner of the two collisions, and the Nascimento record is the name a wrong answer would damage. The other four members are not particles and are unaffected. This is the exception rules/P6's "this attachment outranks the suffix reading (S2)" clause now names. Implementing it takes TWO carve-outs rather than one, which is worth recording because the second is in the REPORT and not the reading: the reading carve-out takes a particle-tagged member only on a POSITIVE credential lean, since `Doe, John do` leans nothing and the positional reading would otherwise take it — the wrong ANSWER, not merely a stray report; and the emitter beside it skips a particle-tagged member it did not itself take, since an emitter gated on tag membership alone reported both kinds on every `do` row. Where P6 owns the fork, P6 reports it, which is mechanisms.md#AMBIGUITY-AT-THE-DECISION-SITE read strictly. ONE SHAPE THE PAIRING DOES NOT REACH — a shape, not a spelling, and the difference is the review finding: ANY particle or particle chain standing in front of the caps `DO` takes it out of this slot, because grouping's prefix chain merges the two into ONE particle piece before the slot exists and there is then no lone member for the capitals to lean on. It is a fact about this WORD being particle vocabulary itself, not about particles generally — the caps `MA` in `Doe, John van MA` is not swallowed, reads as the credential, and leaves `van` to attach behind it. `Doe, John van DO` reads family `van DO Doe`, and so do the `de`, `von`, `del`, `la` and `van der` spellings of it (measured 2026-09-19 — parse them and read `family`). Pre-existing and unmoved by #531; `Doe, John van DO` is the case row and rules/P6's example line, and P6's statement carries the carve-out. The mirror shape is silent rather than merely unreached and is recorded on `AmbiguityKind.SUFFIX_OR_NAME`'s fourth boundary: a particle BEHIND the member ends the given part where this walk reads it, so `Doe, John MA do` keeps middle `MA` beside family `do Doe` though the capitals would otherwise have taken it, the attachment that moves `do` running a stage later. -- 2026-09-18 (Derek), #531 — THE COMMA REPORT'S REACH NOW INCLUDES THE GIVEN SEGMENT'S TRAILING SLOT, AND THE OPEN FOLLOW-UP IS CLOSED. The 2026-09-18 bullet above headed THE COMMA REPORT'S REACH IS THE FIRST POST-COMMA PIECE recorded this slot as an open maintainer decision and named the two questions it turned on — whether a middle initial's neighbourhood should start reporting (a noise judgement, rules/A1) and whether the silence was a 1.4 parity gap. Both are answered here, and that bullet stands as it landed. The slot now reads and reports: `Doe, John MA` gives suffix `MA` and `Doe, John Ma` keeps middle `Ma`, each saying which way it went. Derek chose to restore the ROLE and report both ways — one rule for both spellings — over a report-only change and over a capitals-only one, because the issue exists in the first place because two spellings of one name disagree. The noise question was settled by MEASURING THE DISAGREEMENT rather than by argument: over a generated sweep of 78 pairs — five listed members and two by-shape tokens in three cased spellings each, plus five controls in one spelling apiece, so 26 words against three name shapes — 48 pairs disagreed about whether the word was a credential or a name, and every one of the 48 disagreed in the same direction, the comma form declining what the comma-less form took. After this change 3 disagree and all three are the lower-case `do` rows P6 owns. The sweep and its allowlist are `tests/v2/test_properties.py`; a slot that answers differently from the same name written without a comma is not a quiet slot, it is an inconsistent one. Recorded under `3-0-reevaluations`' standing rule because v1 parity is LOAD-BEARING for one half of this and explicitly NOT for the other: `Doe, John MA` reads suffix `MA` on the 1.4.0 wheel, so the bare-acronym half RESTORES v1's role and the report is all that is new there — its 1.4.0 ledger rule neither retired nor narrowed to `_ambiguities` (nothing below baseline 2.0 can diff on that pseudo-field) but was RE-POINTED to the four names where the writing declines the credential, which keep the 2.0-era middle name against v1. `Doe, John X.Y.Z.` reads middle `X.Y.Z.` at 1.4.0 too, so the dotted half LEAVES v1 and carries a 1.4.0 ledger rule of its own; it moves to match the comma-less `John Doe X.Y.Z.` and rules/S3's shape rule, not to restore anything. BLAST RADIUS, stated the way this log's own rule asks: twenty corpus names move, and only TWO of them were in any corpus before this branch (`Doe, John MA` and `Doe, John X.Y.Z.`, both admitted by #530's own arc) — the other eighteen are this change's own case rows, so what the differential measures on pre-existing data is two names, and the population the rule reaches is a SHAPE (every family-comma listing whose given part ends in a member of this class) that the corpora barely sample. ACCEPTED COSTS, all measured on the differential corpora: `SMITH, JOHN DO` keeps family `DO SMITH` where 1.4.0 read suffix `DO`, paired with the Nascimento record in the bullet above; one-case and caseless names take the credential with no case evidence at all, so `DOE, MARY JO MA`, `doe, john ma`, `田中, 太郎 MA` and `김, 민준 MA` all read a suffix, which is what 1.4.0 read for each of the four — "caseless is inert" holds for the LEAN and not for the outcome, since `is_one_case` answers True for a script with no case and the positional reading then decides; `Doe, John van MA` loses its middle to the family, reading family `van Doe`, suffix `MA` with two reports where it read middle `van MA` in silence, which is `Berg, Jan van Jr.`'s reading arriving through a shape it could not reach before (Derek accepted it 2026-09-18 as P6 working correctly rather than as a cascade to carve out); `Doe, John Prof. MA` gains a TITLE role `Prof.` never had, H5's transparency reaching it once `MA` leaves the walk, landing it on the same answer as `Doe, John MA Prof.`; `Smith, LEED AP` moves under the default-off caps switch alone, to given `LEED`, family `Smith`, suffix `AP` with two reports, so no default reading is at stake; and a genuine middle name that is also a class member is now a credential wherever it ends the given part and is not Title-cased — `DOE, JOHN ED` reads suffix `ED` — which is the same cost the comma-less form has carried since 2.0. NOT REPAIRED HERE and left open: the maiden walk claims `Smith MA` whole in `Doe, Jane nee Smith MA` before this slot exists, so the rule cannot reach it and the name stays silent with maiden `Smith MA` — the same gap #530's close-out saw from the other side with `John Smith nee Jones R.A.I.`, and it is out of scope for #531. +- 2026-09-18 (Derek), #531 (its open maiden gap, `Doe, Jane nee Smith MA`, superseded by #533, decisions/S4, and then by #601, decisions/M2) — THE COMMA REPORT'S REACH NOW INCLUDES THE GIVEN SEGMENT'S TRAILING SLOT, AND THE OPEN FOLLOW-UP IS CLOSED. The 2026-09-18 bullet above headed THE COMMA REPORT'S REACH IS THE FIRST POST-COMMA PIECE recorded this slot as an open maintainer decision and named the two questions it turned on — whether a middle initial's neighbourhood should start reporting (a noise judgement, rules/A1) and whether the silence was a 1.4 parity gap. Both are answered here, and that bullet stands as it landed. The slot now reads and reports: `Doe, John MA` gives suffix `MA` and `Doe, John Ma` keeps middle `Ma`, each saying which way it went. Derek chose to restore the ROLE and report both ways — one rule for both spellings — over a report-only change and over a capitals-only one, because the issue exists in the first place because two spellings of one name disagree. The noise question was settled by MEASURING THE DISAGREEMENT rather than by argument: over a generated sweep of 78 pairs — five listed members and two by-shape tokens in three cased spellings each, plus five controls in one spelling apiece, so 26 words against three name shapes — 48 pairs disagreed about whether the word was a credential or a name, and every one of the 48 disagreed in the same direction, the comma form declining what the comma-less form took. After this change 3 disagree and all three are the lower-case `do` rows P6 owns. The sweep and its allowlist are `tests/v2/test_properties.py`; a slot that answers differently from the same name written without a comma is not a quiet slot, it is an inconsistent one. Recorded under `3-0-reevaluations`' standing rule because v1 parity is LOAD-BEARING for one half of this and explicitly NOT for the other: `Doe, John MA` reads suffix `MA` on the 1.4.0 wheel, so the bare-acronym half RESTORES v1's role and the report is all that is new there — its 1.4.0 ledger rule neither retired nor narrowed to `_ambiguities` (nothing below baseline 2.0 can diff on that pseudo-field) but was RE-POINTED to the four names where the writing declines the credential, which keep the 2.0-era middle name against v1. `Doe, John X.Y.Z.` reads middle `X.Y.Z.` at 1.4.0 too, so the dotted half LEAVES v1 and carries a 1.4.0 ledger rule of its own; it moves to match the comma-less `John Doe X.Y.Z.` and rules/S3's shape rule, not to restore anything. BLAST RADIUS, stated the way this log's own rule asks: twenty corpus names move, and only TWO of them were in any corpus before this branch (`Doe, John MA` and `Doe, John X.Y.Z.`, both admitted by #530's own arc) — the other eighteen are this change's own case rows, so what the differential measures on pre-existing data is two names, and the population the rule reaches is a SHAPE (every family-comma listing whose given part ends in a member of this class) that the corpora barely sample. ACCEPTED COSTS, all measured on the differential corpora: `SMITH, JOHN DO` keeps family `DO SMITH` where 1.4.0 read suffix `DO`, paired with the Nascimento record in the bullet above; one-case and caseless names take the credential with no case evidence at all, so `DOE, MARY JO MA`, `doe, john ma`, `田中, 太郎 MA` and `김, 민준 MA` all read a suffix, which is what 1.4.0 read for each of the four — "caseless is inert" holds for the LEAN and not for the outcome, since `is_one_case` answers True for a script with no case and the positional reading then decides; `Doe, John van MA` loses its middle to the family, reading family `van Doe`, suffix `MA` with two reports where it read middle `van MA` in silence, which is `Berg, Jan van Jr.`'s reading arriving through a shape it could not reach before (Derek accepted it 2026-09-18 as P6 working correctly rather than as a cascade to carve out); `Doe, John Prof. MA` gains a TITLE role `Prof.` never had, H5's transparency reaching it once `MA` leaves the walk, landing it on the same answer as `Doe, John MA Prof.`; `Smith, LEED AP` moves under the default-off caps switch alone, to given `LEED`, family `Smith`, suffix `AP` with two reports, so no default reading is at stake; and a genuine middle name that is also a class member is now a credential wherever it ends the given part and is not Title-cased — `DOE, JOHN ED` reads suffix `ED` — which is the same cost the comma-less form has carried since 2.0. NOT REPAIRED HERE and left open: the maiden walk claims `Smith MA` whole in `Doe, Jane nee Smith MA` before this slot exists, so the rule cannot reach it and the name stays silent with maiden `Smith MA` — the same gap #530's close-out saw from the other side with `John Smith nee Jones R.A.I.`, and it is out of scope for #531. - 2026-10-02 (Derek), #573 — a never-given particle opening the given part after a family comma leaves no word to spare; the member behind it is the surname it heads, unless mixed-case capitals say credential. The record is decisions/P9's entry of the same date (decisions/P6's until 2026-10-19). -- 2026-10-02 (Derek), #578 — A PARTICLE BETWEEN A CREDENTIAL AND A TITLE-CASE WORD STAYS SILENT, AS IT READS. `Doe, Jane PhD vd Ma` reads given 'Jane', middle 'vd Ma', family 'Doe', suffix 'PhD', reporting nothing. No new rule decides that: S2's given-part slot already says a particle in front of a member takes the member out of the slot, and where the word behind reads as a name the two are one name, asked nothing and reporting nothing — `vd` reads as `van` does (`Doe, Jane PhD van Ma`, the same reading), and S2's own boundary example is `Doe, John van Ma`. The writing is malformed whichever reading is meant: a Title-case `Ma` behind a lowercase `vd` behind a `PhD` is neither a Dutch listing nor a credential run as anyone writes one. A reader leaning anywhere leans suffix (Derek: both words follow a known credential, and the writer likely did not know how suffixes are capitalized), but that is a guess about a writer's mistake, not a convention the writing carries. Declined: (a) reading `vd Ma` as suffixes, which needs code to make a credential speak across a particle — against P2 (a particle joins the word behind it) and #554 (`vd` speaks for nothing behind it); (b) reporting the fork, which needs an emitter on the family-comma path for a decision the particle chain makes before assign knows which read the part gets (AGENTS.md: prefer leaving a fork silent and documenting the omission over machinery for input nobody reads with confidence). Where the writing does speak the parser already follows it: `Doe, Jane PhD vd MA` reads suffix 'PhD vd MA' and reports (#573). Pinned by the case row `a_particle_after_a_credential_heads_a_title_case_name`. +- 2026-10-02 (Derek), #578 — SUPERSEDED by 2026-10-04 #602, decisions/S8, under which the credential starts the given part's run and `Doe, Jane PhD vd Ma` reads suffix 'PhD vd Ma' — A PARTICLE BETWEEN A CREDENTIAL AND A TITLE-CASE WORD STAYS SILENT, AS IT READS. `Doe, Jane PhD vd Ma` reads given 'Jane', middle 'vd Ma', family 'Doe', suffix 'PhD', reporting nothing. No new rule decides that: S2's given-part slot already says a particle in front of a member takes the member out of the slot, and where the word behind reads as a name the two are one name, asked nothing and reporting nothing — `vd` reads as `van` does (`Doe, Jane PhD van Ma`, the same reading), and S2's own boundary example is `Doe, John van Ma`. The writing is malformed whichever reading is meant: a Title-case `Ma` behind a lowercase `vd` behind a `PhD` is neither a Dutch listing nor a credential run as anyone writes one. A reader leaning anywhere leans suffix (Derek: both words follow a known credential, and the writer likely did not know how suffixes are capitalized), but that is a guess about a writer's mistake, not a convention the writing carries. Declined: (a) reading `vd Ma` as suffixes, which needs code to make a credential speak across a particle — against P2 (a particle joins the word behind it) and #554 (`vd` speaks for nothing behind it); (b) reporting the fork, which needs an emitter on the family-comma path for a decision the particle chain makes before assign knows which read the part gets (AGENTS.md: prefer leaving a fork silent and documenting the omission over machinery for input nobody reads with confidence). Where the writing does speak the parser already follows it: `Doe, Jane PhD vd MA` reads suffix 'PhD vd MA' and reports (#573). Pinned by the case row `a_particle_after_a_credential_heads_a_title_case_name`. - 2026-10-17 #682 — SPLIT FROM decisions/S2 with the rule. The entries above were written under decisions/S2 while this rule was part of rules/S2, and moved here unchanged but for pointers the move broke; where one says rules/S2 it means the rule as it then stood, which held this one. diff --git a/docs/design/decisions/S7-company-of-an-unambiguous-credential.md b/docs/design/decisions/S7-company-of-an-unambiguous-credential.md index c28d9a41..3fe3ec89 100644 --- a/docs/design/decisions/S7-company-of-an-unambiguous-credential.md +++ b/docs/design/decisions/S7-company-of-an-unambiguous-credential.md @@ -1,6 +1,26 @@ # S7 — the company of an unambiguous credential -- 2026-09-27 (Derek), #544 (the `doe, jane v phd do` reading in its (7) and its 2026-09-28 addendum superseded by #721, decisions/S10: the one-case `v` is an initial and ends the run, so the name reads middle 'v', suffix 'phd do', the company still taking 'do') — A CREDENTIAL RUN KEEPS ITS AMBIGUOUS MEMBERS: C1'S NAME-WORD COUNT READS A RUN (rules/C4 since #728) AS IT READS ONE WORD, AN UNAMBIGUOUS CREDENTIAL IN FRONT OF A MEMBER SPEAKS FOR IT AT EVERY TRAILING SLOT, AND A LISTED MEMBER'S CHUNKED DOTTED SPELLING PASSES THE PERIOD GATE. Three readers never looked past the member itself: C1 flipped a part to the suffix comma by the name-word count only when it was ONE token, and the trailing readers — the no-comma peel, the comma part read wholly as credentials, the given part's trailing slot — met the member first, took its name lean and stopped, so the credential in front of it was never reached. #540 marked `meng` and `lac`, whose conventional spellings lean name, which turned the one-case-row cost decisions/S6's 2026-09-15 item (ii) accepted into the ordinary spelling of two degrees. DECIDED, ten forks, (9) and (10) on 2026-09-28. (1) THE WHOLE RUN AT C1: two or more words after the comma, every one suffix vocabulary or a class candidate, at least one a candidate, behind two or more name words, is the credential run — all-member runs (`John Smith, Ed Ma`) and a leading member (`John Smith, MEng PhD`) included; offered and declined were an anchored-only rule and the issue's own "last word ambiguous" wording, which contradicted its `Ed Ma` consequence. (2) ALL TRAILING PATHS, ANCHORED IN FRONT: a listed member with an unambiguous credential in front of it, through other members, reads as the credential on the no-comma peel, in the comma part read wholly as credentials and at the given slot; a credential BEHIND it anchors nothing (`Wang Ma PhD` keeps family 'Ma'). (3) THE CHUNKED DOTTED GATE: a listed member written in two or more period-closed letter chunks (`M.Eng.`, `L.Ac.`) passes as `M.A.` does; one trailing period (`Ma.`, `Ed.`) still does not. (4) SINGLE-LETTER ROMAN NUMERALS neither anchor nor count toward a C1 run, S3's single-character retirement being the precedent; they peel as before, and the anchor's half of the exclusion is a matter of their shape, boundary (d) below. (5) NO NEW REPORT WHERE THE WRITING SETTLED IT: a run whose every member is LISTED and leans credential — S2's lean, capitals in a mixed-case name — is not flipped, the family-comma path already reading it as the credential run with the fields and the report it always had (`John Smith, PhD MA`) — narrowed 2026-10-01 by decisions/C4's #562 entry: a part holding two particles side by side is read by the count instead, and reports; the alternative, flipping such a run and suppressing only the flip's report, removes reports the family-comma path makes today, `John Smith, MA Jr` losing the one it makes for 'MA'. Because the lean is the listed set's, a by-shape member in capitals never settles a run: `John Smith, X.Y.Z. MA` flips to suffix 'X.Y.Z. MA' and reports. (6) THE ANCHOR DOES NOT REACH ACROSS A MAIDEN CLAUSE: `Jane Doe Jr. nee Smith Ma` keeps maiden 'Smith Ma' where `Jane Doe Jr. Ma` reads suffix 'Jr. Ma' — rules/M2's Accepted boundary, and the M2 bullet of this date. (7) AN ANCHOR OVERRIDES P6 AT THE GIVEN SLOT: `doe, jane v phd do` reads suffix 'v phd do' where it read family 'do doe'; the bullet below amends #531's pairing. (8) THE DUAL EXCLUSION IS SCOPED TO THE GIVEN PART'S LEADING TITLE RUN, NOT THE C1 RUN: after a full name the dual counts as the suffix vocabulary it is, as the legacy disjunct already counted it (`John Smith, MS MA`, `John Smith, MD`), and that is what reads the issue's headline `Jane Doe, MS LAc` as suffix 'MS LAc'. (9) A MEMBER THE COMPANY DECIDES REPORTS WHERE IT WAS DECIDED, in a family comma's part read wholly as credentials as at the peel: each member whose own writing declined and which the credential in front made the credential reports `suffix-or-name` at that reading. `Smith, PhD Ma`, `Smith, PhD MEng` and `Smith, Ph. D. MEng` report the member; `Smith, Dr. PhD LAc` and `John Quincy Smith, Prof. PhD LAc` report 'LAc'; `john smith, v phd ma` reports 'ma'; `John Smith, PhD Ma Prof.`, which C1 does not flip for its trailing title, reports 'Ma' where its twin `John Smith, PhD Ma` reports C1's flip once over the part. A member its own capitals made the credential stays silent (`Smith, PhD MA`), and the part's first piece, which nothing stands in front of, is the first-slot report's word and never this one's. (10) A DUAL IN THE GIVEN PART'S LEADING TITLE RUN SILENCES THE WHOLE PART: refinement (b) below reads such a dual as a title that speaks for nothing, and in a part whose leading title run holds one no credential behind the dual speaks for a member of the ambiguous class either, so the company never reads such a part wholly as credentials: the titles give it its reading, the dual a title and the next word the given name, and behind that given name the given slot reads as it reads any (`Smith, MD PhD Jr Ma` reads suffix 'Jr Ma', as `Smith, MD Jane Jr Ma` does). A part with no member to speak for, or only members whose capitals decide them, reads as it did: `Smith, MD PhD` suffix 'MD PhD', `Smith, Ms MD MA` suffix 'Ms MD MA'. `Smith, Ms MD Ma`, `Smith, MD MS Ma` and `SMITH, MD MS BA` read title 'Ms MD' / 'MD MS', given 'Ma' / 'BA'; `Smith, MD PhD Ma` reads title 'MD', given 'PhD', middle 'Ma', the given slot reporting 'Ma'; e10e83b4 read each of them so. The run is the walk's leading title run, so a dual behind a plain title stands in it too (`Smith, Prof. MD Ma` and `smith, prof. md ma` read title 'Prof. MD', given 'Ma'; `Smith, Dr. MD PhD Ma` keeps given 'PhD'), while a plain title alone silences nothing (`Smith, Dr. PhD LAc` reads title 'Dr.', suffix 'PhD LAc'). Behind a real given name the company reads as ever (`Doe, Jane MD Ma` and `Doe, Jane Ms Ma` read suffix 'MD Ma' and 'Ms Ma'), and past the title run a dual speaks like any suffix word (`Smith, PhD Ms Ma` reads suffix 'PhD Ms Ma'); `Smith, Ms Ma`, `Nguyen, Sr Ba` and `Smith, MD Do` are unchanged. +## Standing + +Examples name each field as the default order reads it; under the family-first orders the given and family names trade places. + +- A listed member of the ambiguous class standing behind an unambiguous credential in one run of suffix words, other members between passing it on, reads as the credential at every trailing slot whatever its writing or the count (`John Smith PhD Ed Ma` → suffix 'PhD Ed Ma'; `Smith, PhD MEng` and `Doe, Jane PhD MEng` → suffix 'PhD MEng'); a credential behind the member speaks for nothing (`Wang Ma PhD` keeps family 'Ma') — 2026-09-27 #544, A CREDENTIAL RUN. +- Where no credential run starts (S8's, or C13's in a part a credential opens after a comma), as with one name word before the credential and no comma, what anchors nothing and ends the run is the walk's own leading piece (`PhD Ma` → given 'PhD', family 'Ma'), a connective (`Jane Doe nee Puig i Ma` keeps maiden 'Puig i Ma'), a single-letter roman numeral in any case (`Om Jr V Ma` keeps family 'Ma', where `Om Jr III Ma` reads suffix 'Jr III Ma'), and a word of both the particle and the unambiguous suffix vocabulary (`Jan vd Ma` → family 'vd Ma'; `Smith vd Ma, John` → family 'Smith vd Ma'), whose exclusion is of the word in front only; where either run starts it takes them all (`John Smith PhD V Ma` and `Smith, PhD V Ma` → suffix 'PhD V Ma') — 2026-09-27 #544, A CREDENTIAL RUN. +- A title/suffix dual in the given part's leading title run after a one-word family comma is a title there, anchors nothing and silences the company for the part (`Smith, Ms Ma` → given 'Ma'; `Smith, MD PhD Ma` → title 'MD', given 'PhD', middle 'Ma'); anywhere else a dual anchors as any suffix word (`Jane Doe, MS LAc` → suffix 'MS LAc', at the accepted cost `John Smith, Ms Ma` → suffix 'Ms Ma') — 2026-09-27 #544, A CREDENTIAL RUN. +- A member the company decides reports `suffix-or-name` where it was decided (`Smith, PhD Ma`); a member its own capitals made the credential reports nothing new (`John Smith, PhD MA`) — 2026-09-27 #544, A CREDENTIAL RUN. +- Accepted: `Om Jr Ma` reads given 'Om', suffix 'Jr Ma' with no family name, and `Smith, MA PhD Ma` reads suffix 'MA PhD Ma' with no given name; the split `Ph. D.` in a main segment (no comma, or before a suffix comma) is outside the walk, so `John Smith Ph. D. MEng` keeps family 'MEng', while the comma and given-slot spellings anchor (`Smith, Ph. D. MEng` → suffix 'Ph. D. MEng') — 2026-09-27 #544, A CREDENTIAL RUN. +- An unambiguous credential in front of the member overrides P6's attachment at the given slot, as the capitals do (`Doe, John PhD Do` → suffix 'PhD Do'); the one-case record with nothing in front keeps P6's reading (`NASCIMENTO, EDSON ARANTES DO` → family 'DO NASCIMENTO') — 2026-09-27 #544, THE #531 PAIRING. +- `abdul Smith Jr Ma` reads given 'abdul', family 'Smith', suffix 'Jr Ma', the anchor reversing decisions/S6's accepted item (ii) — 2026-09-27 (#544). + +Not standing: the split of 2026-10-17 #682, carried out. + +Elsewhere: C1's count reading a post-comma run as it reads one word (`John Smith, Ed Ma` → suffix 'Ed Ma') — decisions/C4's 2026-09-27 (Derek), #544 entry; a listed member's chunked dotted spelling passing the period gate (`Wang M.Eng.`) — decisions/suffix-acronym-collisions' 2026-09-27 (#544) entry; a title between the credential and the member, and a member a particle chain took, read into the credential's run (`John Smith PhD Prof. Ma` → suffix 'PhD Ma', title 'Prof.') — decisions/S8's 2026-10-04 (Derek), #602 entry; a marker behind a credential is an ordinary word the run takes (`Jane Doe Jr. nee Smith Ma` → suffix 'Jr. nee Smith Ma') — decisions/M2's 2026-10-04 (Derek), #601 entry; `om` marked ambiguous, so it anchors nothing (`John Om Ma` → family 'Ma') — decisions/suffix-acronym-collisions' 2026-10-21 entry marking 33 credential readings ambiguous. + +Open: none in this file. + +## Log + +- 2026-09-27 (Derek), #544 (the `doe, jane v phd do` reading in its (7) and its 2026-09-28 addendum superseded by #721, decisions/S10: the one-case `v` is an initial and ends the run, so the name reads middle 'v', suffix 'phd do', the company still taking 'do') (its (6) and the addendum's `Jane Doe, PhD, Jr nee van Ma` superseded by #601, decisions/M2, a marker behind a credential or past a comma being an ordinary word; its ACCEPTED LIMITS' `John Smith PhD Prof. Ma`, `John Smith PhD Do Do` and `Smith, PhD Do Ma` superseded by the credential's run, #602, decisions/S8, and #603, decisions/C13, which read each as suffixes; (d)'s `John Smith PhD V Ma` superseded the same way, suffix 'PhD V Ma'; (c)'s `John Om Ma` superseded by the 2026-10-21 marking of `om` ambiguous, decisions/suffix-acronym-collisions, so it reads family 'Ma') — A CREDENTIAL RUN KEEPS ITS AMBIGUOUS MEMBERS: C1'S NAME-WORD COUNT READS A RUN (rules/C4 since #728) AS IT READS ONE WORD, AN UNAMBIGUOUS CREDENTIAL IN FRONT OF A MEMBER SPEAKS FOR IT AT EVERY TRAILING SLOT, AND A LISTED MEMBER'S CHUNKED DOTTED SPELLING PASSES THE PERIOD GATE. Three readers never looked past the member itself: C1 flipped a part to the suffix comma by the name-word count only when it was ONE token, and the trailing readers — the no-comma peel, the comma part read wholly as credentials, the given part's trailing slot — met the member first, took its name lean and stopped, so the credential in front of it was never reached. #540 marked `meng` and `lac`, whose conventional spellings lean name, which turned the one-case-row cost decisions/S6's 2026-09-15 item (ii) accepted into the ordinary spelling of two degrees. DECIDED, ten forks, (9) and (10) on 2026-09-28. (1) THE WHOLE RUN AT C1: two or more words after the comma, every one suffix vocabulary or a class candidate, at least one a candidate, behind two or more name words, is the credential run — all-member runs (`John Smith, Ed Ma`) and a leading member (`John Smith, MEng PhD`) included; offered and declined were an anchored-only rule and the issue's own "last word ambiguous" wording, which contradicted its `Ed Ma` consequence. (2) ALL TRAILING PATHS, ANCHORED IN FRONT: a listed member with an unambiguous credential in front of it, through other members, reads as the credential on the no-comma peel, in the comma part read wholly as credentials and at the given slot; a credential BEHIND it anchors nothing (`Wang Ma PhD` keeps family 'Ma'). (3) THE CHUNKED DOTTED GATE: a listed member written in two or more period-closed letter chunks (`M.Eng.`, `L.Ac.`) passes as `M.A.` does; one trailing period (`Ma.`, `Ed.`) still does not. (4) SINGLE-LETTER ROMAN NUMERALS neither anchor nor count toward a C1 run, S3's single-character retirement being the precedent; they peel as before, and the anchor's half of the exclusion is a matter of their shape, boundary (d) below. (5) NO NEW REPORT WHERE THE WRITING SETTLED IT: a run whose every member is LISTED and leans credential — S2's lean, capitals in a mixed-case name — is not flipped, the family-comma path already reading it as the credential run with the fields and the report it always had (`John Smith, PhD MA`) — narrowed 2026-10-01 by decisions/C4's #562 entry: a part holding two particles side by side is read by the count instead, and reports; the alternative, flipping such a run and suppressing only the flip's report, removes reports the family-comma path makes today, `John Smith, MA Jr` losing the one it makes for 'MA'. Because the lean is the listed set's, a by-shape member in capitals never settles a run: `John Smith, X.Y.Z. MA` flips to suffix 'X.Y.Z. MA' and reports. (6) THE ANCHOR DOES NOT REACH ACROSS A MAIDEN CLAUSE: `Jane Doe Jr. nee Smith Ma` keeps maiden 'Smith Ma' where `Jane Doe Jr. Ma` reads suffix 'Jr. Ma' — rules/M2's Accepted boundary, and the M2 bullet of this date. (7) AN ANCHOR OVERRIDES P6 AT THE GIVEN SLOT: `doe, jane v phd do` reads suffix 'v phd do' where it read family 'do doe'; the bullet below amends #531's pairing. (8) THE DUAL EXCLUSION IS SCOPED TO THE GIVEN PART'S LEADING TITLE RUN, NOT THE C1 RUN: after a full name the dual counts as the suffix vocabulary it is, as the legacy disjunct already counted it (`John Smith, MS MA`, `John Smith, MD`), and that is what reads the issue's headline `Jane Doe, MS LAc` as suffix 'MS LAc'. (9) A MEMBER THE COMPANY DECIDES REPORTS WHERE IT WAS DECIDED, in a family comma's part read wholly as credentials as at the peel: each member whose own writing declined and which the credential in front made the credential reports `suffix-or-name` at that reading. `Smith, PhD Ma`, `Smith, PhD MEng` and `Smith, Ph. D. MEng` report the member; `Smith, Dr. PhD LAc` and `John Quincy Smith, Prof. PhD LAc` report 'LAc'; `john smith, v phd ma` reports 'ma'; `John Smith, PhD Ma Prof.`, which C1 does not flip for its trailing title, reports 'Ma' where its twin `John Smith, PhD Ma` reports C1's flip once over the part. A member its own capitals made the credential stays silent (`Smith, PhD MA`), and the part's first piece, which nothing stands in front of, is the first-slot report's word and never this one's. (10) A DUAL IN THE GIVEN PART'S LEADING TITLE RUN SILENCES THE WHOLE PART: refinement (b) below reads such a dual as a title that speaks for nothing, and in a part whose leading title run holds one no credential behind the dual speaks for a member of the ambiguous class either, so the company never reads such a part wholly as credentials: the titles give it its reading, the dual a title and the next word the given name, and behind that given name the given slot reads as it reads any (`Smith, MD PhD Jr Ma` reads suffix 'Jr Ma', as `Smith, MD Jane Jr Ma` does). A part with no member to speak for, or only members whose capitals decide them, reads as it did: `Smith, MD PhD` suffix 'MD PhD', `Smith, Ms MD MA` suffix 'Ms MD MA'. `Smith, Ms MD Ma`, `Smith, MD MS Ma` and `SMITH, MD MS BA` read title 'Ms MD' / 'MD MS', given 'Ma' / 'BA'; `Smith, MD PhD Ma` reads title 'MD', given 'PhD', middle 'Ma', the given slot reporting 'Ma'; e10e83b4 read each of them so. The run is the walk's leading title run, so a dual behind a plain title stands in it too (`Smith, Prof. MD Ma` and `smith, prof. md ma` read title 'Prof. MD', given 'Ma'; `Smith, Dr. MD PhD Ma` keeps given 'PhD'), while a plain title alone silences nothing (`Smith, Dr. PhD LAc` reads title 'Dr.', suffix 'PhD LAc'). Behind a real given name the company reads as ever (`Doe, Jane MD Ma` and `Doe, Jane Ms Ma` read suffix 'MD Ma' and 'Ms Ma'), and past the title run a dual speaks like any suffix word (`Smith, PhD Ms Ma` reads suffix 'PhD Ms Ma'); `Smith, Ms Ma`, `Nguyen, Sr Ba` and `Smith, MD Do` are unchanged. WHAT MAY ANCHOR, four boundaries of the company clause, each a rule. (a) A CONNECTIVE (P3) anchors nothing and ends the run: the generational `i` is also Catalan's conjunction, and `Jane Doe nee Puig i Ma` keeps its link, maiden 'Puig i Ma'. (b) A TITLE/SUFFIX DUAL IN THE GIVEN PART'S LEADING TITLE RUN after a one-word family comma is a title there and anchors nothing — and, by (10), no credential behind it speaks for a member in that part — so the given slot's pass starts past the leading title run: `Smith, Ms Ma`, `Nguyen, Sr Ba` and `Smith, MD Do` keep their given names, and `Smith, MD MA Ma` keeps middle 'Ma', no unambiguous credential standing in its run once the title is set aside. Everywhere else a dual anchors like any suffix word (`John Smith MD MEng`, and (8)). (c) THE WALK'S OWN LEADING PIECE NEVER ANCHORS. In a name with no comma before the run, the leading piece is the name word H4's carve-out keeps whatever its vocabulary, and letting it anchor spends that name: in `Om Ma` and `PhD Ma` 'Ma' stays a name word under every name order (family 'Ma' in the default order, given 'Ma' under both family-first orders), where an anchoring `PhD` would leave given 'PhD', suffix 'Ma' and no family at all. One name word in front frees the same word — `John Om Ma` reads suffix 'Om Ma'. A family comma's given part has no such position, its first piece being read by the comma part's own credential reading, so `Smith, PhD MEng` reads family 'Smith', suffix 'PhD MEng'. (d) A SINGLE-LETTER ROMAN NUMERAL, IN ANY CASE (`V`, `v`, `I.`), anchors nothing for its SHAPE — one letter is how a middle initial is written, and S3 retired single-character vocabulary matches for the same reason (`John Smith PhD V Ma` keeps family 'Ma') — not because a generation is no credential. The rule is stated by that shape and the code tests exactly it (`_vocab.is_single_letter_numeral`); "initial-shaped" was the wrong word for it, `is_initial_shaped` answering False for a lower-case `v` that the exclusion covers too. And the exclusion is not about generations: a multi-letter numeral or generational word anchors as any suffix word does (`John Smith PhD III Ma` reads suffix 'PhD III Ma', `abdul Smith Jr Ma` suffix 'Jr Ma'). ACCEPTED COSTS, each a reading this design chooses. `John Smith, Ms Ma` → suffix 'Ms Ma', reported, as `John Smith, Ms` alone already reads suffix (8). `Om Jr Ma` → given 'Om', suffix 'Jr Ma' and no family name: 'Jr' is not the leading piece, so it anchors 'Ma', and rules/S2's standing Accepted clause already consumes an unambiguous suffix that leaves no family (`Om Jr` → given 'Om', suffix 'Jr'); every release from 2.0.0 made that same role assignment. `doe, jane v phd do` reports `suffix-or-name` where it reported `particle-or-given`, the fork reported being the credential pick rather than P6's attachment (7). And a one-word family comma whose given part OPENS with a capitalised `MA` in a mixed-case name, with an unambiguous credential behind it, reads the whole part as a credential run, family 'Smith' and no given name, where the parent kept given 'MA': `Smith, MA PhD Ma` read given 'MA', middle 'Ma', suffix 'PhD' and reads suffix 'MA PhD Ma'. 'MA' leans credential on its capitals, so it is read as the credential it is written as, and what follows it is then the company's (or, for `M.Eng.`, the chunked gate's). Measured 2026-09-28 on the grid below: 138 parses (46 texts, three orders each) go from given 'MA' to no given name, 72 of them with no `M.Eng.` in the run; 12 of the 138 are the parses the attribution below leaves unattributed, the rest falling in the anchor and `M.Eng.` classes. Each reports 'MA' at the first slot, and a member behind the credential reports as the company's pick (9). ACCEPTED LIMITS, each keeping the member a name word, rules/S2's Accepted block and case rows: the merged `Ph. D.` is outside the no-comma walk (`John Smith Ph. D. MEng` family 'MEng'; the comma and given-slot spellings do anchor it, `Smith, Ph. D. MEng` and `Doe, Jane Ph. D. MEng` reading suffix 'Ph. D. MEng'), a title between the credential and the member breaks the run (`John Smith PhD Prof. Ma`), and a particle member P2 has chained before the peel is out of reach (`John Smith PhD Do Do` family 'Do Do'; `Smith, PhD Do Ma` given 'PhD', middle 'Do Ma'). diff --git a/docs/design/decisions/S8-credentials-trailing-run.md b/docs/design/decisions/S8-credentials-trailing-run.md index 6bb037b9..a0a412e5 100644 --- a/docs/design/decisions/S8-credentials-trailing-run.md +++ b/docs/design/decisions/S8-credentials-trailing-run.md @@ -1,6 +1,25 @@ # S8 — the credential's trailing run -- 2026-10-04 (Derek), #602 — A CREDENTIAL AFTER THE NAME CORE STARTS A RUN TO THE END OF ITS PART. An unambiguous Latin suffix word (the Latin restriction retracted by #679, below) of two or more letters standing after two name words with no comma (a lone particle not counting toward the two; qualified by #627, below), or after the given word in the part after a family comma, makes every later word of that part a suffix, except a title word, which reads as a title: `John Smith PhD Jones` → suffix 'PhD Jones', `Eric H. Holder Jr. Attorney General` → suffix 'Jr.', title 'Attorney General'. A name word the run absorbs is reported `suffix-or-name`, a reader hesitating over `Jones` there. Before this the three comma shapes disagreed — middle 'Smith PhD' with no comma, middle 'Jones' and suffix 'PhD' after a family comma, and suffix 'Jr., Jones' after a suffix comma (C2's tail) — and the no-comma reading made a credential a middle name, the one reading nobody intends. The suffix-comma path already read it this way, and the comma spelling of the Holder name always did. +## Standing + +Examples name each field as the default order reads it; under the family-first orders the given and family names trade places. + +- An unambiguous suffix word of two or more letters, in any script, other than the split `Ph. D.` in a main segment (below), standing after two name words with no comma or before a suffix comma, or after the given word in the part after a family comma, starts a run to the end of its part: every later word reads as a suffix except a title word, which reads as a title, and an absorbed name word reports `suffix-or-name` (`John Smith PhD Jones` → suffix 'PhD Jones'; `Eric H. Holder Jr. Attorney General` → suffix 'Jr.', title 'Attorney General') — 2026-10-04 #602; 2026-10-14 #679. +- What never starts the run: a title word (`Mary Jane King Smith` keeps family 'Smith'), a member of the ambiguous class, a single letter, a connective (`Josep Carod i Rovira` keeps family 'Carod i Rovira'), and a word that is also particle or bound given-name vocabulary (`Mohamed Ali Abd Allah` → family 'Allah'); a title/suffix dual does start it — 2026-10-04 #602. +- An honorific or generational word starts the run as a credential does, whatever its script (`राम शर्मा साहब मोहन` → suffix 'साहब मोहन'); the one-character honorifics stay out by the two-letter minimum — 2026-10-14 #679. +- A lone particle counts toward the two name words only where the credential stands right behind it (`John von PhD Jones` → family 'von', suffix 'PhD Jones', under the family-first orders given 'von'); a particle run counts once, and a particle the run took is not asked (`Freiherr von vd PhD Jones` keeps middle 'PhD') — 2026-10-10 #627. +- Lifting the credential out of the name, the family-comma path's older reading (`John Smith PhD Jones` as family 'Jones', suffix 'PhD'), was declined — 2026-10-04 #602. +- An ambiguous acronym written with its periods starts the run (`John Smith M.A. Jones` → suffix 'M.A. Jones'); its capitals alone do not (`John Smith MA Jones` → middle 'Smith MA', family 'Jones') — 2026-10-20 #761. + +Not standing: the split of 2026-10-17 #682, carried out. + +Elsewhere: the split `Ph. D.` in a main segment (no comma, or before a suffix comma) starts no run, the trailing peel's walk never holding the merged piece (`John Smith Ph. D. Jones` → family 'Jones', suffix 'Ph. D.', unreported; `John Smith Ph. D. Jones, Jr.` → suffix 'Ph. D., Jr.') — decisions/C13's 2026-10-04 (Derek), #603 entry, and the #602 entry's own REVERSED paragraph; a credential opening the part after the comma, and the split `Ph. D.` starting the run as `PhD` does (`Smith, John Ph. D. Jones` → suffix 'Ph. D. Jones') — decisions/C13's 2026-10-04 (Derek), #603 entry; the run taking a lone letter behind a credential ahead of a further comma (`Smith, John PhD I, Jr.` → suffix 'PhD I, Jr.'), which the #602 entry does not record — decisions/C9's Elsewhere line. + +Open: [#785](https://github.com/derek73/python-nameparser/issues/785) (whether capitals in a mixed-case name start the run as periods do); [#819](https://github.com/derek73/python-nameparser/issues/819) (whether a letter behind a credential ahead of a further comma stays a middle initial). + +## Log + +- 2026-10-04 (Derek), #602 (its Latin restriction and its non-Latin honorific exclusion superseded by #679, below; its lone particle's count superseded in part by #627, below) — A CREDENTIAL AFTER THE NAME CORE STARTS A RUN TO THE END OF ITS PART. An unambiguous Latin suffix word (the Latin restriction retracted by #679, below) of two or more letters standing after two name words with no comma (a lone particle not counting toward the two; qualified by #627, below), or after the given word in the part after a family comma, makes every later word of that part a suffix, except a title word, which reads as a title: `John Smith PhD Jones` → suffix 'PhD Jones', `Eric H. Holder Jr. Attorney General` → suffix 'Jr.', title 'Attorney General'. A name word the run absorbs is reported `suffix-or-name`, a reader hesitating over `Jones` there. Before this the three comma shapes disagreed — middle 'Smith PhD' with no comma, middle 'Jones' and suffix 'PhD' after a family comma, and suffix 'Jr., Jones' after a suffix comma (C2's tail) — and the no-comma reading made a credential a middle name, the one reading nobody intends. The suffix-comma path already read it this way, and the comma spelling of the Holder name always did. WHAT STARTS THE RUN is one predicate, `_pieces.starts_a_credential_run`, read by the trailing peel (`credential_run`, applied to every finished peel, so assign, P5's reserve, P2's chain stop and the maiden walk see one answer) and by the given-part walk. EXCLUDED, each with its reason: a TITLE WORD — 746 title words are in no suffix set (measured 2026-10-04: `len(L.titles - L.suffix_acronyms - L.suffix_words)` for the default lexicon), many of them surnames (`King`, `Bishop`, `Judge`), so `Mary Jane King Smith` keeps family 'Smith'; a title is read from the end of a name only behind a comma or with a period (H5, Derek). The AMBIGUOUS CLASS, which carries no evidence of which it is. A SINGLE LETTER, in any case: a lowercase `i` or `v` carries no `initial` tag, and found by the v1 off-switch test, `Josep Carod i Rovira` with `i` removed from the conjunctions read suffix 'i Rovira'. A CONNECTIVE. A word that is also PARTICLE or BOUND GIVEN-NAME vocabulary — found by the suite, not foreseen: `abd` is in the credential list (ABD) and heads `Abd Allah`, and `Mohamed Ali Abd Allah` read suffix 'Abd Allah' until it was excluded. The NON-LATIN HONORIFIC words, an honorific followed by a name word being a different question from a credential followed by one (retracted by #679, below). A word that is also a title (`MD`, `Ms`, `Sr.`) does start the run: position decides, and after the name core it is the suffix. DECLINED: lifting the credential out — `John Smith PhD Jones` as given 'John', middle 'Smith', family 'Jones', suffix 'PhD', the family-comma path's old reading. It keeps every name word in a name field, but it reads a credential as something written in the middle of a name, which is the reading the rule rejects. REVERSED BY THIS ENTRY rather than edited: decisions/S5's #578 bullet (`Doe, Jane PhD vd Ma` now reads suffix 'PhD vd Ma', the credential starting the given part's run), and two of the three shapes #544's ACCEPTED LIMITS (decisions/S7) kept out of the company's reach — a title standing between the credential and the member, and a member a particle chain had taken. The case rows `a_title_between_degree_and_member_keeps_it_a_name` and `a_member_the_particle_chain_took_is_out_of_reach` keep their ids and now pin the run. The third, the merged `Ph. D.`, stays out of reach: that piece is outside the walk the run is read over. diff --git a/docs/design/decisions/S9-unlisted-words-that-join-the-ambiguous-class-by-shape.md b/docs/design/decisions/S9-unlisted-words-that-join-the-ambiguous-class-by-shape.md index d3745717..a67ca0ab 100644 --- a/docs/design/decisions/S9-unlisted-words-that-join-the-ambiguous-class-by-shape.md +++ b/docs/design/decisions/S9-unlisted-words-that-join-the-ambiguous-class-by-shape.md @@ -1,10 +1,35 @@ # S9 — unlisted words that join the ambiguous class by shape -- 2026-09-14 (Derek) — #516's DOTTED HALF IS A SWITCH, `Policy.unlisted_dotted_suffixes`, DEFAULT ON: an unlisted token of two or more period-separated chunks, any chunk length (`X.Y.Z.`, `B.Tech.`, `Q.W.E.R.T.`), joins the ambiguous class BY SHAPE; whole-token vocabulary still wins (`M.A.`, `Ph.D.`, `A.B.C.` — `abc` IS a suffix acronym). The positional rule then decides and reports either way: `John Smith X.Y.Z.` → suffix, `Jack X.Y.Z.` → family, `Smith, A.B.` → given, `John Smith, A.B.` → suffix. Case is irrelevant — the periods are the evidence — so `john smith x.y.z.` reads as its mixed-case twin. Switch OFF: name material everywhere as 2.3 read it, and the fork is STILL reported, the parser having chosen the name reading over a credential one. +## Standing + +Examples name each field as the default order reads it; under the family-first orders the given and family names trade places. + +- `Policy.unlisted_dotted_suffixes`, default on: an unlisted token of two or more period-separated chunks joins the ambiguous class by shape, whole-token vocabulary still winning, and the positional rule decides and reports (`John Smith X.Y.Z.` → suffix, `Jack X.Y.Z.` → family); case is no evidence (`john smith x.y.z.` → suffix); switched off, the token is name material and the fork still reports — 2026-09-14 (Derek). +- The dotted shape admits only alphabetic chunks (`John Smith 1.4` → family '1.4', unreported) and no script without period abbreviations (`John Smith 田.中.` → family '田.中.') — 2026-09-17/18 #516 review rounds. +- A dotted token of unlisted single-letter chunks joins by shape and reports (`Smith, J.R.` → given 'J.R.'), and the comma's wholly-suffix test never reads the by-shape class (`Smith Jr., A.B.` → given 'A.B.', suffix 'Jr.') — 2026-09-17 #516 review round. +- At the first slot after a comma, paired initials (two single letters joined by a period, the trailing period optional) are the given name and report (`García Márquez, G.J.` → given 'G.J.'); only an unambiguous suffix word in front that is not title vocabulary, or a second dotted-shape word in the part, makes them the credential run (`John Smith, PhD X.Y.` → suffix 'PhD X.Y.'; `García Márquez, Ms G.J.` → title 'Ms', given 'G.J.'), while a word behind (`De La Cruz, M.J. PhD`) or a class member in front (`García Márquez, Ed G.J.` → given 'Ed') speaks for nothing, and three letters run together read by the count (`García Márquez, G.J.R.` → suffix 'G.J.R.') — 2026-09-30 #563. +- A flip resting only on dotted-shape words is silent (`John Smith, X.Y.Z. G.J.`) unless the only words speaking for a pair are other pairs (`John Smith, X.Y. P.Q.` reports); the trailing slots keep #516's reading (`John Smith R.T.` and `Doe, John R.T.` → suffix 'R.T.') — 2026-09-30 #563. +- `Policy.unlisted_caps_suffixes` takes OFF, AFTER_COMMA or EVERYWHERE, default AFTER_COMMA, and a bool raises: an unlisted all-caps alphabetic word of two or more letters joins the class by shape in the part right after a comma behind two or more name words (`John Smith, XYZ` → suffix 'XYZ', `Smith, XYZ` → given 'XYZ'), beside listed credentials as well as alone (`John Smith, PhD XYZ` → suffix 'PhD XYZ'), and under EVERYWHERE at every suffix position — 2026-10-01 #564. +- The comma's case contrast is carried by a word of the name before the comma that holds a capital, ends in a lowercase cased letter and is claimed by no wordlist as a non-name, so an all-caps record keeps its given name (`MÜLLER WEIß, HANS`, `LLOYD WEBBER, ANDREW PhD`) and a name written in lowercase reads the listing form (`john smith, XYZ` → given 'XYZ'); a lone two-letter word is never admitted at the comma (`García Márquez, MJ` → given 'MJ') — 2026-10-01 #564. +- Accepted: a given name written in capitals behind a two-word surname reads as the credential (`García Márquez, GABRIEL` → suffix 'GABRIEL', reported), OFF being the escape; and case repair follows the reading, a caps word in the part a suffix comma opened being tagged under AFTER_COMMA, one in a third or later part only under EVERYWHERE — 2026-10-01 #564. +- Under EVERYWHERE the cost is the three-word name (`Jean Pierre DUPONT` → family 'Pierre', suffix 'DUPONT'), while a two-word name keeps its family and reports (`Jean DUPONT`); unlisted is checked by wordlist membership rather than tags (`John Smith NEE` keeps family 'NEE'), and a roman numeral is the numeral fork's before the shape is asked (`John Smith VI` → suffix 'VI') — 2026-09-14 (Derek), corrected 2026-09-18. +- Neither switch reaches the v1 shim, which translates neither: `HumanName` follows both defaults and a v1 caller cannot turn them off (`HumanName("John Smith X.Y.Z.").suffix` and `HumanName("John Smith, XYZ").suffix` are 'X.Y.Z.' and 'XYZ'), the caps half since the AFTER_COMMA default — 2026-09-14 (Derek), corrected 2026-09-18; 2026-10-01 #564. +- A rule's statement names no `Policy` field; the example annotations carry the field names — 2026-09-18, RULES.MD STATEMENTS. +- An example's text is a default-policy corpus name whatever its annotation, so an annotated-only example is checked for a default-policy diff like any other — 2026-09-18, corrected. + +Not standing: the split of 2026-10-17 #682, carried out. + +Elsewhere: the wordlist roster the caps entry names, eleven of the thirteen vocabulary fields, corrected to all of them (a caller's surname keeps `Jean Pierre DUPONT` its family under EVERYWHERE) — decisions/S6's 2026-09-18, WHOLE-PR REVIEW ROUND entry; `De La Cruz, M.J. K.L.` → given 'M.J.', suffix 'K.L.' behind a one-word particle surname — decisions/C3's 2026-10-01 (Derek), #575 entry; the three listed and dotted runs the caps entry kept apart (`John Smith, Ed Ma`, `John Smith, ma do`, `John Smith, X.Y.Z. A.B.`), credential runs by C4's count — decisions/S7's 2026-09-27 (Derek), #544 entry headed A CREDENTIAL RUN KEEPS ITS AMBIGUOUS MEMBERS; the contrast test reused for a suffix word ending the name before the comma — decisions/C12's 2026-10-18 (Derek), #656 entry. + +Open: none in this file. + +## Log + +- 2026-09-14 (Derek) (its `John Smith, A.B.` → suffix and its "reports either way" at the first slot after a comma superseded by #563, below) — #516's DOTTED HALF IS A SWITCH, `Policy.unlisted_dotted_suffixes`, DEFAULT ON: an unlisted token of two or more period-separated chunks, any chunk length (`X.Y.Z.`, `B.Tech.`, `Q.W.E.R.T.`), joins the ambiguous class BY SHAPE; whole-token vocabulary still wins (`M.A.`, `Ph.D.`, `A.B.C.` — `abc` IS a suffix acronym). The positional rule then decides and reports either way: `John Smith X.Y.Z.` → suffix, `Jack X.Y.Z.` → family, `Smith, A.B.` → given, `John Smith, A.B.` → suffix. Case is irrelevant — the periods are the evidence — so `john smith x.y.z.` reads as its mixed-case twin. Switch OFF: name material everywhere as 2.3 read it, and the fork is STILL reported, the parser having chosen the name reading over a credential one. - 2026-09-17/18, #516 review rounds — THE SHAPE VERDICT NEEDS TWO FURTHER GATES, both found by measuring after the shape verdict shipped. (i) ALPHABETIC: `period_joined_vocab`'s "shape" branch now requires every chunk to be `.isalpha()` — a bare digit chunk is not an acronym letter by any reading, so `Smith, 1.4`, `John Smith 1.4` and `John Smith, 1.4` stay unclaimed (no report, no role move), where an unguarded shape verdict had wrongly admitted them; the delimited `Bridge (1.4)` control only proved digits reach extract's escape, saying nothing about the same digits undelimited, which is the gap this closes. (ii) INITIALLESS-SCRIPT: the same test `is_title_shaped` already makes for H2's own leading-abbreviation inference (#323) — `text.isascii() or not in_initialless_script(text)` — now gates the shape verdict too, so `John Smith 田.中.`, `김 민준 이.박.` and `John Smith たな.か.` stay family: a script with no period abbreviations at all has nothing for interior periods to abbreviate, so a CJK word glued into period-separated characters is not spelling an acronym either. `John Smith 田.中.` is pinned `tolerated=True` rather than `shape=` — a Latin period convention glued onto CJK characters is a composed form no writing system produces, and the case table's own validator refuses a Latin shape tag on CJK text; `이.박.` and `たな.か.` are covered by direct `period_joined_vocab` assertions instead of a second corpus row each. - 2026-09-17, #516 review round — `SMITH, J.R.` READS BY SHAPE FOR A REASON UNRELATED TO WHY IT DECLINES THE LISTED WORD. `_normalize` keeps interior periods ON PURPOSE (v1 parity, pinned 2026-07-17: `'J.R.'` must not collapse to the listed suffix word `'jr'`), so `ambiguous_class_member` correctly answers False for `Smith, J.R.`, `Smith, E.S.Q.` and `Smith, E.T., Jr.` for a reason that has nothing to do with #516. What #516 adds is a SEPARATE route: each chunk (`'j'`/`'r'`, `'e'`/`'s'`/`'q'`, `'e'`/`'t'`) is an unlisted single-letter chunk nothing in the vocabulary claims, so the token joins the class BY SHAPE instead, exactly as `'K.D.'` does in `J.A. K.D.`. The READING is unchanged in all three — one pre-comma name word is never enough to flip the structure — but each now gains `suffix-or-name`, the class having been considered and declined rather than never reached at all. `is_wholly_suffix` NEVER READS THE BY-SHAPE CLASS. A first version admitted a by-shape member there unconditionally, reasoning it was needed for `John Smith, A.B.`'s structure flip; proved wrong by mutation — that flip already goes through `_segment.py`'s own `pre_comma_names >= 2` disjunct alone, and nothing else in the suite depended on the admission except this predicate's own two unit tests. Left in, the admission combined with C1's LEGACY token-count disjunct (which counts WORDS, not NAME words, and predates the name-word-count decision of decisions/S6, 2026-09-14) to flip `Smith Jr., A.B.` to given `'Smith'`, suffix `'Jr., A.B.'` with a self-contradicting "holds 1 name words" report. Fixed by dropping the admission outright: the by-shape class reaches the comma form ONLY through `_vocab.ambiguous_class_candidate`, never through `is_wholly_suffix`. `Smith Jr., A.B.` now reads given `'A.B.'`, family `'Smith'`, suffix `'Jr.'` — the same shape the LISTED class reads for `Smith Jr., Ma` and `Smith Jr., ma` (given `'Ma'`/`'ma'`, family `'Smith'`, suffix `'Jr.'`), not for `Smith Jr., MA` (given `''`, family `'Smith'`, suffix `'Jr., MA'` — the caps lean has already moved that one into the suffix run, measured on this tree; at 2.3.0 it read given `'MA'`, family `'Smith'`, suffix `'Jr.'`, the very shape `Smith Jr., A.B.` reads now) — with the report; classification `parity`, not `fix(#516)`: FULL PARITY on the 1.4.0 wheel (first A.B., last Smith, suffix Jr.), only the report being new. -- 2026-09-14 (Derek), corrected 2026-09-18 — #516's ALL-CAPS HALF IS A SWITCH TOO, `Policy.unlisted_caps_suffixes`, DEFAULT OFF, and the asymmetry is the decision. An unlisted all-caps word of two or more letters, with no period ANYWHERE (`isalpha()` rejects a period anywhere, not merely an interior one, so a single TRAILING period, H2's own shape, is unaffected either way), in a name `one_case` says is written in more than one case, joins the class by shape (`_vocab.caps_shape_candidate`). +- 2026-09-14 (Derek), corrected 2026-09-18 (its default superseded by #564, below; its ELEVEN-list roster by decisions/S6's 2026-09-18 whole-PR review round, which checks every wordlist; the three readings its THE RUN IS THE CAPS CLASS'S ALONE paragraph pinned superseded by #544, decisions/S7) — #516's ALL-CAPS HALF IS A SWITCH TOO, `Policy.unlisted_caps_suffixes`, DEFAULT OFF, and the asymmetry is the decision. An unlisted all-caps word of two or more letters, with no period ANYWHERE (`isalpha()` rejects a period anywhere, not merely an interior one, so a single TRAILING period, H2's own shape, is unaffected either way), in a name `one_case` says is written in more than one case, joins the class by shape (`_vocab.caps_shape_candidate`). UNLISTED MEANS IN NO WORDLIST AT ALL, not merely "no whole-token suffix vocabulary" — found only by measuring after a narrower, tag-based guard shipped and reversed: `titles`, `given_name_titles`, `particles`, `particles_ambiguous`, `conjunctions`, `conjunctions_ambiguous`, `bound_given_names`, `suffix_acronyms`, `suffix_acronyms_ambiguous`, `suffix_words` and `maiden_markers` — ELEVEN lists, checked by direct membership rather than by tag, since `segment` calls the shape test before `classify` has tagged anything. Measured with the narrower guard alone (`John Smith DE`, `John Smith NEE` wrongly moved to suffix), and stated here as a recipe rather than a fixed count, since a raw per-list membership tally and a de-duplicated one (a word appearing in two lists, `abu`/`أبو`/`ابو` across `bound_given_names` and `particles_ambiguous`, is one leak, not two) give different totals: `len([w for w in getattr(lexicon, name) if w.isascii() and len(w) >= 2 and w.isalpha()])` per excluded list, run over the shipped `Lexicon.default()`, gives on the order of dozens for `particles` and `particles_ambiguous` and single digits for `conjunctions` and `bound_given_names` — every one of them a wordlist entry the caps shape test's earlier, narrower guard did not check at all. The one figure that reproduces exactly, because ASCII case is what the test needs and every other maiden marker is a non-Latin or non-ASCII spelling the shape test's own `isupper()`/`isalpha()` gate excludes on its own: FOUR maiden markers are ASCII (`geb`, `geboren`, `geborene`, `nee`), out of `len(lexicon.maiden_markers)` total (17, measured 2026-09-18) — `'NEE'`/`'GEB'` are two of those four, capitalized, which is what the narrower guard let through. ACCEPTED GAP, recorded rather than chased: an all-caps German title spelled with `SS` for `ß` (`GROSSFÜRST`) is unlisted by this same lookup too, for a reason predating this switch entirely — `_normalize` uses `lower()`, never `casefold()`, specifically so it does not corrupt `großfürst` to the misspelling `grossfürst`, and classify's own existing `vocab:title` check has never recognized this spelling either. Left for whoever next generalizes the ß-fold question. THE RUN IS THE CAPS CLASS'S ALONE. The multi-token shape `'LEED AP'` needs a RUN test (`John Smith, LEED AP` → suffix `'LEED AP'`), but the listed and dotted halves are single-token classes by construction — the listed set is inherently bare words and the dotted half never needed more than one token — so testing the run over either of them asks a question this design never posed. An un-narrowed run test measured three reversals before this was caught: `John Smith, Ed Ma` (both listed, Title-case, which #289's OWN lean reads as NAME), `John Smith, ma do` (both listed, lower) and `John Smith, X.Y.Z. A.B.` (both dotted) all wrongly moved to suffix as a run. Narrowed to the caps branch alone; `Smith, LEED AP` still declines and reports, and all three reversals are now pinned identical OFF/ON. `JACK VI` AND `JOHN SMITH VI` DO NOT MOVE, AND NOT FOR THE REASON A FIRST DRAFT GAVE. `VI` passes the caps shape test and carries both `SHAPE_ACRONYM_TAG` and `vocab:suffix-ambiguous` with the switch on — the predicate reaches it, contrary to what an early write-up of this entry said. What actually holds it unchanged is rules/S2's OWN roman-numeral fork (`_pieces.is_trailing_numeral_suffix`), which claims a bare `'VI'` piece and decrements the peel's walk BEFORE the bare-ambiguous/shape branches beneath it are ever reached — a mechanism this switch does not touch and never held `VI` back through non-membership. diff --git a/tests/v2/decisions_without_standing.json b/tests/v2/decisions_without_standing.json index c17a708b..c0fdaaa6 100644 --- a/tests/v2/decisions_without_standing.json +++ b/tests/v2/decisions_without_standing.json @@ -19,11 +19,6 @@ "R3", "R4", "R5", - "S2", - "S5", - "S7", - "S8", - "S9", "T1", "T3", "T4",