fix(#531): a credential ending the given part after a family comma reads as one, and reports - #532
Merged
Merged
Conversation
After a family comma, a member of the ambiguous credential class standing at the END of the given part read as a middle name and reported nothing, while the comma-less spelling of the same name did the opposite on both counts. Over a generated sweep of 78 pairs, 48 disagreed about whether the word was a credential or a name, every one of them in the same direction. After this change 3 disagree, and all three are the lower-case `do` rows rules.md#P6 owns. The comma has already named the family and the first word after it is the given name, so the words to spare S2's count asks about are there by construction and the count says nothing at this slot. What decides is the writing, which is the same evidence the comma-less spelling reads: a member written in a cased form that is neither capitals nor wholly lower, in a name written in more than one case, stays a name. `Doe, John MA` reads suffix `MA` again, as 1.4.0 read it; `Doe, John Ma` keeps middle `Ma`. Either reading is now reported. The branch is INLINE in `reads_as_a_suffix`, the one predicate both readers of this walk already ask, with the membership test first on tags already in hand: measured, a comma name carrying no class member pays +0 frames, and a helper on that path cost +1 on every one of them. `do` is the one class member that is also particle vocabulary. P6's attachment keeps every spelling but the capitals: `Doe, John DO` reads suffix `DO` while `Doe, John do`, `Doe, John Do`, `DOE, JOHN DO` and `doe, john do` attach to the family exactly as they do today, each reporting P6's own kind and no second report. P6's run walk declines a one-token suffix-roled piece carrying `vocab:suffix-ambiguous`, which is narrow enough to leave `vd` and `mc` inside the run. The three generated corpora move with the case rows and the rules.md example lines: 26 distinct names join, 1230 to 1256, and twelve `_CORPUS_CLAIMS` digests follow the corpus text rather than any rule -- seven at 1.4.0, three at 2.0.0, two at 2.1.0, no roles joined. Review round: that trailing walk re-entered the predicate that owns it, so a run of k class members cost 2**k -- 'Doe, John ' + 'MA '*24 took 5.8s where cc78c96 took 0.24ms. The member verdict is now memoized per (piece, titled), which is sound because nothing the verdict rests on reads `.role`, and the report's own walk runs ONCE for the loop rather than per member, that emitter having been cubic over the same run. Readings are byte-identical over 17,015 names x four policies; a frame-ratio guard in test_benchmark.py fails at 168x on the unfixed code and reads 2.1x now. Also: the cost comment no longer claims a member is asked once, SUFFIX_OR_NAME's docstring names the THIRD silent boundary and stops claiming both directions where P6 reports instead, and the 'Doe, John Ma' note no longer calls itself the only report-without-a-move. Two control rows join, 'Doe, John van DO' (grouping merges the member into a particle piece, so the capitals lean never reaches it) and 'Doe, Dr. MA' (the third boundary), which takes the counts above to 28 names, 1230 to 1258, and seventeen digests -- ten at 1.4.0, four at 2.0.0, three at 2.1.0, still no roles joined. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Twenty-one rules, written from the gate's own output rather than predicted beside the change -- the plan's "six rules, two corpus names" was written before commit 1 admitted twenty-eight names to the corpora, and every count in it is superseded by the numbers below. TWENTY corpus names move under #531, measured name by name against the tree at cc78c96: eighteen on the contract tier and the two caseless comma forms on the radar tier. Thirteen take the credential reading, four keep their name reading because the WRITING declines and gain the report alone, one is the `do` spelling the capitals take from P6, and two are the CJK forms where the lean is inert and the positional reading is not. At 1.4.0 the existing given-part-trailing-slot rule neither retired as its own comment predicted nor narrowed to `_ambiguities`: it CHANGED NAMES. 'Doe, John MA' now matches the 1.4.0 wheel on every role and leaves the ledger -- the report it gains is a v2 surface that cannot enter a diff below baseline 2.0 -- and the four names that replace it carry the same reading the rule describes, declined by the writing rather than by the slot's silence. Its dotted sibling gets a rule of its own: 'Doe, John X.Y.Z.' is a middle name at 1.4.0 too, so reading it as a suffix is a new divergence rather than a restoration, and it is recorded as the accepted cost it is. Six more 1.4.0 divergences are NOT this change's and are attributed where they belong. 'Doe, John MA Smith' is a 2.0-era family-comma routing difference and files under fix(comma-family), the classification its case row already carries. The five trailing particle-and-credential names -- 'Berg, Jan mc' and the four `do` rows -- are P6's, and carry fix(#380)'s decision read over the other two collision words; 'Doe, John DO' is the spelling #531 takes OUT of that set, and is a _MUST_NOT_MATCH probe there because of it. Three lone post-comma credentials ('Doe, MA', 'Doe, MA PhD', 'Doe, Dr. MA') join the existing fix(#289) rule at the four 2.x ledgers only; at 1.4.0 an earlier comma rule already owns their diff. Every rule is literal-anchored for the reason its siblings give: the class is a SLOT, and a regex for the slot would claim every family-comma name whose given part ends in an ambiguous acronym, including the ones that do not move. _MUST_NOT_MATCH gains a key per new rule, and fix(#380)'s key is rekeyed to its full issue text, the same repair fix(#360)'s pair already records. All five gates exit 0 with `unexplained: 0`: 1.4.0 1255 names; intentional 465; unexplained 0; radar 0 2.0.0 1262 names; intentional 419; unexplained 0; radar 5 2.1.0 1262 names; intentional 331; unexplained 0; radar 6 2.2.0 1262 names; intentional 188; unexplained 0; radar 7 2.3.0 1262 names; intentional 74; unexplained 0; radar 7 Radar-unclassified drops by exactly the two CJK movers at every 2.x baseline (7/8/9/9 to 5/6/7/7); the seven that remain are older and were verified byte-identical across this change. No cross-rule contest appeared: _CROSS_RULE_WINNERS and _RECORDED_DIFFS need no new row, because the comma rules that reach 'Doe, John X.Y.Z.' narrow by roles its diff does not move. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
rules.md#S2 states the rule the given part's trailing slot now
follows -- the comma settled the count, so the writing is the only
evidence there is -- and says what "ending the given part" reaches
past, what ends its reach, and how many times a run of members
reports. Its "evidence is SECOND" clause is split between the two
comma slots, since it was only ever true of the first one. #C1 names
the second place the comma's own decision is reported, and #P6 gains
the capitals exception with three example lines. #S2 gains P6 to its
`interacts:` and three example lines of its own: the two-report run
('Doe, John MA JD'), and 'Doe, John MA Ma' twice, where the LAST
member declines and the run stays middle text on ONE report. S2's
slot sentence and S3's exclusion went in commit 1 and are not
touched again.
decisions.md gets two dated bullets under S2. The first records
Derek's `do` decision and the two carve-outs it takes, one of them in
the report rather than the reading, plus the spelling the pairing
cannot reach ('Doe, John van DO', where grouping merges the member
into a particle piece before this slot exists). The second CLOSES the
2026-09-18 comma-reach bullet -- which is left exactly as it landed,
and is referred to by its heading rather than by position -- and
records the measurement that settled the noise question: 48 of 78
generated pairs disagreed about this word before the change and 3 do
after. It also records Derek's choice of restoring the ROLE over a
report-only or capitals-only change, the parity split, the seven
accepted costs, and the blast radius as the gate can see it: twenty
corpus names move and TWO of them predate this branch. One-line
cross-amendments go to #P6 (the stand-down condition, narrowed to the
ambiguous tag so `vd` and `mc` stay inside the run) and to #ma-do.
mechanisms.md gains a field note for the trap this arc hit: a frame
BUDGET pinned on one reference name cannot see algorithmic blowup and
a frame RATIO over two sizes can -- 412/449 never moved while a run
of 24 credentials went from 0.24ms to 5.8s.
The release log gains a bullet and loses a sentence: the existing
comma-report bullet named this slot as one that stays silent, and
2.4.0 being unreleased, that sentence is corrected in place rather
than supplemented. customize.rst's two 2.4 switch entries name the
family-comma form the slot brings into their reach.
corpus_rules.jsonl takes the three new example texts. All three were
already in corpus_shapes.jsonl, so the gate's deduped name set does
not grow, no _CORPUS_CLAIMS digest moves, and all five gates still
exit 0 with `unexplained: 0`.
Design-docs review round: the capitals exception and this slot's
silences were both stated universally, and a particle falsifies both.
#P6 and #S2 now carry the carve-out -- a particle in front of the caps
`do` makes one particle run the attachment takes whole, and
'Doe, John van DO' is P6's example line for it -- #S2's reach clause
names the particle BEHIND the member and the `vd`/`mc` exception to
that, and SUFFIX_OR_NAME's silences go from THREE to FOUR, the new one
covering both directions with the caps spellings that are NOT in it.
The `do` bullet's "one spelling" was a SHAPE; its sweep composition
multiplied to 108 rather than 78 and now reads as the test builds it;
and mechanisms.md stops quoting one wall-clock figure where the two
recorded runs read 5.8s and 5.9s. corpus_rules.jsonl takes one further
example text, already a corpus_shapes.jsonl name, so the gate set is
again unchanged.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #532 +/- ##
==========================================
+ Coverage 98.73% 98.74% +0.01%
==========================================
Files 45 45
Lines 3475 3509 +34
==========================================
+ Hits 3431 3465 +34
Misses 44 44 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
… and the silences the docstring left out A. The trailing slot is ONE monotone descent per `titled` value, shared by the predicate and by the report, so both are linear: `'Doe, John ' + 'MA '*k` measures 2.1/4.1/8.3/17.1ms at k=200/400/800/1600 against the memo's 8.6/31.4/120/463 and cc78c96's 1.5/3.2/7.2/17.3. The report's own walk is gone -- it was cubic on `'Doe, ' + 'John '*r + 'MA '*r` (5.8/28/175/1229ms at r=100..800), now 1.8/3.7/8.0. Readings byte-identical over 64,322 names x 6 policies; call_count 412.00/449.00; frames +0 on all five controls, -2 on 'Doe, John MA PhD', -1 on 'Doe, John MA JD'. test_benchmark gains a second frame pair (16 vs 64): 8-vs-16 cannot separate quadratic from linear -- the memo reads 2.08x there against this tree's 1.73x -- while 16-vs-64 reads 7.42x against 3.53x. Bounds 6.0 and 5.0, asserted in that order. B. Eleven case rows. 'Doe, John MA y' and 'Doe, John DO Ed' kill the two `len(piece) == 1` guards, which both SURVIVED at e7fbb4c (each deleted in a scratch copy to prove it). The rest pin the documented silences and boundaries, measured, plus the stale-floor catcher 'Doe, John MA Ma MA'. corpus_shapes/corpus_rules regenerated (+7/+2 names), five _CORPUS_CLAIMS digests re-recorded, two new 1.4.0 rules and two 2.x literal sets widened; all five differential gates exit 0 with 0 unexplained. C. "a kind is worth adding only if a reader would hesitate too" is AGENTS.md's, not rules.md#A1's, at both sites; the exponential's timings are quoted once with the profiled/unprofiled split named; SUFFIX_OR_NAME's silences now cover the member HEADING a particle chain and say the first-piece emitter reads that piece and no further, with rules.md#S2 and four ledger sentences corrected to match; one release-log clause for the report belonging to the spelling. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
… descent left uncovered 'Doe, John MA Prof. Jr' puts the titled piece between the member and a suffix, so the descent steps over it; every existing row put the title at an end of the run. Found by the patch-coverage gate (97.14% of the diff against a 98.73% target); _assign.py is back to 100%. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
derek73
added a commit
to IMGillusion/python-nameparser
that referenced
this pull request
Sep 22, 2026
…nd the ph removal is on the record Maintainer fix-up on PR derek73#521 after the merge from master, the eight items of the 2026-09-16 review comment: - decisions.md R4: the reach is remeasured on the merged tree with the recipe's comparator named (master's `_cap_word` at 23e52dc), and the two earlier snapshots are explained rather than replaced -- the `ph` removal took 13 forced movers back to `Ph. D.`, and the rows PRs derek73#530/derek73#532/derek73#534 added account for the rest of the drift. The exceptions map's job is stated as the spellings `str.capitalize()` gets wrong, not "non-all-caps" (II/III/IV are all-caps); the precedence over Mac/Mc and the role-not-tag reach of the gate are recorded. - decisions.md: an `Excluded (SUFFIX_ACRONYMS — ph)` block beside esq's, so a wordlist sweep does not put the fragment back. - rules.md R4: the non-acronym clause is qualified by the exceptions map (`john smith ii` -> `II`), the acronym repair's precedence over the Mac/Mc convention is stated and pinned by a `john smith mcse` row (`McSe` without it), and the Accepted paragraph names which clause it is about and states the acronym repair's contrast on a spliced suffix. - release_log.rst: the bullet moves from the shipped 2.3.0 section to 2.4.0 with the current digits, and `ph` leaving the set gets its own bullet in the rai/cha shape. - corpus_rules.jsonl regenerated (three new R4 rows). Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #531.
What changes
After a family comma, a member of the ambiguous credential class that ends the given part is now read by the same rule the comma-less spelling uses, and reports
suffix-or-namewhichever way it reads. Words to spare are there by construction at this slot (the comma named the family, the first word is the given name), so the writing is the only evidence left.Doe, John MA/DOE, JOHN MA/doe, john maMA, reports (1.4.0's reading)Doe, John Q. MAQ. MAQ., suffixMA, reportsDoe, John MA PhD/Doe, John MA, PhDMA, suffixPhDMA PhD/MA, PhD, reportsDoe, John Ma/Doe, Mary Jo Ma/Doe, John EdDoe, John X.Y.Z.Doe, John DODO DoeDO, reportsDoe, John do/Do/DOE, JOHN DODoe, John MA Smith,Doe, John V, PhD,Doe, MAdo— capitals decide, otherwise the particle rule keeps it.dois the one class member that is also a particle. One-caseNASCIMENTO, EDSON ARANTES DOandSMITH, JOHN DOare the same shape and read alike (familyDO …,particle-or-given): right about the first, wrong about the second, which is the accepted cost. In mixed case the writing can tell them apart, and does:Nascimento, Edson Arantes dokeeps familydo Nascimento,Doe, John DOgives suffixDO. P6 gained a stand-down condition for exactly that piece;vd/mcare untouched. A particle in front (Doe, John van DO) is one particle run before this slot exists and attaches whole — pre-existing, recorded.Design calls made with Derek
dorows P6 owns.Doe, John van MA→ familyvan Doe, suffixMA(P6 now seesvantrailing the given part, as inBerg, Jan van Jr.);Doe, John Prof. MAgains titleProf.(H5 transparency);Smith, LEED APunderunlisted_caps_suffixes→ suffixAP; declined members report.Doe, Jane nee Smith MAstays maidenSmith MA, silent).Four silences remain and are named in
AmbiguityKind.SUFFIX_OR_NAME's docstring: a name word behind the member, the maiden walk's take, no name word in front (Doe, Dr. MA), and a member a particle run absorbed or left behind (Doe, John van Ma,Doe, John MA do).Commits
fix(#531)— the branch insidereads_as_a_suffix(one predicate for both of the walk's readers), the fifthSUFFIX_OR_NAMEemitter, P6's condition, 42 case rows, unit tests, the agreement property test, rules.md example lines, corpora and claims. Review found the first draft exponential in the length of a trailing member run (24 members: 5.8 s); fixed with a member memo and one hoisted floor walk, readings byte-identical over 68,056 generated rows, and guarded by a frame-ratio test (168× unfixed, 2.08× fixed, bound 10×).test(#531)— ledgers at all five baselines. The 1.4.0 rulefix(given-part-trailing-slot)is re-pointed to the declined members (_ambiguitiescannot diff below 2.0).docs(#531)— rules.md S2/C1/P6, decisions.md (### S2bullets closing the open follow-up, cross-amendments under P6 and ma-do), mechanisms.md field note (a frame budget cannot see algorithmic blowup; a ratio can), release log (new bullet, and the existing 2.4.0 bullet's now-false "stays silent" sentence corrected in place), customize.rst.Verification
Smith, John,Doe, John Q.,Smith, John V,Smith, MA,Berg, Jan vd); triggersDoe, John MA+6,Doe, John MA PhD+25.Doe, John MA,Doe, John X.Y.Z., both added by Case and shape decide a bare ambiguous credential acronym (#289, #516) #530). The rest of the ledger growth is this change's own case rows.🤖 Generated with Claude Code