Skip to content

fix(assign,vocab): a one-word family comma reads its credential run as suffixes (#296, #325) - #428

Open
derek73 wants to merge 5 commits into
masterfrom
fix/325-296-one-word-comma-credential-run
Open

fix(assign,vocab): a one-word family comma reads its credential run as suffixes (#296, #325)#428
derek73 wants to merge 5 commits into
masterfrom
fix/325-296-one-word-comma-credential-run

Conversation

@derek73

@derek73 derek73 commented Aug 23, 2026

Copy link
Copy Markdown
Owner

Closes #296, closes #325

Bundle 2, first PR: the first three commits of the approved #291/#296 comma-suffix bundle (spec 2026-07-30, plan 2026-08-01), in the plan's order, with the ordering step widened to cover #325 — plus a fourth commit for the review round. #291 (multi-word credentials, SUFFIX_PHRASES) is the bundle's fourth commit and the next PR.

The change

input before after
Smith, Jr., Smith, PhD, Kim, Jr. title Jr. / PhD (#296) family Smith, suffix Jr. / PhD
Smith, Ph. D. Jr., Smith, Ph. D. III, Smith, PhD Jr., Smith, Jr., PhD given Ph. D. (#325, a 1.4.0 regression) suffix Ph. D., Jr. etc. — the whole credential run
Smith, Sr. / Sr. Garcia; Smith, MS / Ms. Smith title / title postnominal / title — position decides the duals
Smith, Esq. / Esq. Smith title / title suffix Esq. / title Esq. — H2's inference doesn't run on the credential run
John Smith, Mr., John Smith, Mr. Jr., John Smith, Dr., Bob Jones, author family John Smith given John, family Smith, title (+ suffix) — a comma followed by no name word fixes no family boundary; de Mesnil Juan, Dr. keeps family de Mesnil under a family-first order
Do Quang Minh, Do Nguyen, Dr. Do Van Johnson, MD title Do given Do (with the particle-or-given fork) — do is a Vietnamese name, never a prenominal
PhD Smith, Jr Smith title given — the honest reading of strings nobody writes
John Smith Dr., Smith Dr suffix Dr. family Dr.dr was v1-residue suffix vocabulary; a trailing title-only word is a name part on the no-comma path today (#316)
Jack Ma. suffix Ma. (since 2.0) family Ma. — the ambiguous-acronym gate needs the acronym's own periods (M.A.), not any period; as 1.4.0 read it
Smith, Ms. title (every baseline) suffix Ms. — the cost of ms as a dual, recorded as Accepted; Smith, Ms. Jane keeps the title
Smith, Dr., Smith, Dr. Jr., Smith, Mr. Jr., Smith Jr., Mr., Smith, John Jr., John Smith, MS, Hardman, RN - CRNA, Md Abdul Karim, 田中さん, Dr. unchanged unchanged

Vocabulary audit (the approved table, two deviations). do, jr, junior, phd, se leave TITLES; dr leaves SUFFIX_WORDS and sra SUFFIX_ACRONYMS; the rest stay genuine duals, position deciding. Deviation 1 — md keeps dual membership: bare Md before a name is the Bengali and South Asian abbreviation of Muhammad (Md Abdul Karim, Md. Abdul Karim are #343/#345's corpus rows; the drop read the first as given Md, middle Abdul). Deviation 2 — ms and sa do not join the ambiguous set: the gate is position-blind and the collision is not — gated, John Smith, MS lost its suffix-comma route and read title MS, and Smith, Ms. passed the gate on its one period anyway (the review found it). Derek: confirm or overrule either — each is one line of vocabulary and a case row.

Mechanism. (1) _segment_holds_no_name (titles and suffixes only, by the peel's own title test) sends segment 0 through _assign_main when it has more than one name piece, and records the order, which post_rules' leading-piece scan now keys on (so P1's family-first fold reaches it). (2) In the FAMILY_COMMA branch a post-comma segment that is wholly suffix pieces reads as suffixes before the title peel. (3) suffix_as_written's period gate is the dotted-acronym form. The audit and the ordering are one commit because each alone is wrong (the plan's F1).

Review rounds

Four reviewers on the pushed PR (code, tests, comments, design-docs); everything found is in commit 4, not deferred:

  • critical Smith Jr., Mr. lost its family (the guard counted pieces; the positional read peels the suffix first) — counts name pieces now.
  • regression de Mesnil Juan, Dr. under a family-first order read family de — the order is recorded and post_rules' scan follows it.
  • regression Smith, Ms. / John Smith, MS under the table's ambiguous gate — the gate dropped for ms/sa (deviation 2), and the period gate tightened to the acronym's own periods (Smith, Ed., Jack Ma.).
  • doc gap John Smith, Mr. Jr. — C1's condition is "no name word", not "all titles"; H2's statement now says where the shape does not outrank vocabulary; S2 says "its periods".
  • recorded limits: Smith, RN - CRNA under extra_suffix_delimiters keeps v1's "the delimiter has no effect outside the suffix-comma form" (pinned in tests/test_suffixes.py); 田中さん, Dr. keeps the honorific glued (the peel runs before the comma is read); group's chain emitter does not report on the family-comma path.
  • ledger hygiene: shape rules that absorbed names they don't describe (Smith, Dr., Smith, Prof., Smith, Abd, Smith, Dr. Jr.) are ordered/literalized; counts in AGENTS.md and the release log are the shipped ones (five words left TITLES, twelve duals remain); a dead guard Codecov flagged is gone.

Verification

  • Suite 5628 passed / 221 skipped / 10 xfailed; ruff, mypy, benchmark clean; every behaviour change RED-first.
  • Differential gate exits 0 at 1.4.0, 2.0.0, 2.1.0 at each commit. 1.4.0 catch-all 15 → 14. Corpus 210 rules names + 98 CJK (+ the new C1/S2 examples). Every moved class has a rule whose prose describes it; the contested-name records follow the rules that now explain them.
  • Codecov: green on the head. The first push's patch red was a dead guard line; the project red after commit 4 was a witness lost, not a line added — test_revise_sets_a_missing_unjoined_mark rested on Do parsing alone as a title, which the audit made false, so _types.py's recompute branch ran in no test. Commit 5 respells it with St. (No codecov.yml: the project target is "no drop", so a reading change that orphans a witness fails it.)

Commits

  1. fix(assign) — the all-titles repair (plan commit 1), with the suffix-vocabulary clause the helper needed.
  2. fix(vocab,assign) — the audit (plan commit 2, md excepted) + the credential-run ordering (plan commit 3, widened for Smith, Ph. D. Jr. puts the credential in first (regression from 1.4.0) #325), tests and ledgers.
  3. docs(design) — C1/H2, the decisions entries, the arc, AGENTS.md, corpus.
  4. fix(assign,vocab) — the review round: no name word, the name count, the order, the duals (ms/sa excepted), the period gate; docs, ledgers and pins.
  5. test(parser) — the revise recompute's witness respelled with a word still in both vocabularies.

🤖 Generated with Claude Code

derek73 and others added 3 commits August 23, 2026 10:20
…y by titles

The FAMILY_COMMA rule that segment 0 is wholly the family name rests
on the writer having said where the family name ends. A comma
followed by nothing but titles said no such thing -- 'John Smith,
Mr.' is 'Mr. John Smith' with the honorific moved -- so 2.0's merge
of the pre-comma run into one family name threw away a split the
writer gave us: family 'John Smith', title 'Mr.'. Segment 0 keeps its
positional read there, with the script-order table and the
particle-or-given report that the merged read suppressed ('Van
Johnson, Mr.' reports the fork again).

"Nothing but titles" is title-shaped AND not suffix vocabulary, which
the approved plan's helper (2026-08-01) did not say: the title list
overlaps the suffix sets until the audit in the next commit, and the
period-abbreviation inference reads 'Jr.' as a title regardless, so
the helper as planned read 'Smith, PhD Jr.' as the title run 'PhD
Jr.' and 'Smith, Mr. Jr.' as 'Mr. Jr.' -- both master's suffix 'Jr.'
(the 2.1.0 gate showed the first; the second was measured against
master). A suffix piece is read where it stands, whatever else the
word is. One pre-comma piece has no split to keep ('Smith, Dr.' is
unchanged), and a post-comma name still fixes the family ('John
Smith, Jones').

This is the repair the #291/#296 bundle plan orders FIRST, so that
the vocabulary audit -- which makes 'Dr.' non-suffixy and would
otherwise flip 'John Smith, Dr.' into this merge -- lands on a path
that already keeps the split. Two corpus names move: 'Bob Jones,
author' and 'Bob Jones, compositeur' read given 'Bob', family 'Jones'
at every baseline (1.4.0 read first 'Bob Jones'), under a rule
written ahead of the comma-precomma-family rule whose fields had
absorbed them (11 -> 9, the count telling); the contested-name record
follows. 'John Smith, Dr.' itself is unchanged until the audit.

Tests first: the split, its two-piece guard, the all-title run, the
title-then-name and name-only non-flips, and the fork report; case
rows for the split, the guard and the non-flip.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…, and read a post-comma credential run as suffixes

v1's word lists encoded where the v1 parser needed words to be, not
where words can occur, and the listing form paid for it twice.
'Smith, Jr.' read title 'Jr.' (#296): with one word before the comma
C1 keeps the listing form, and the title peel -- 'jr' was title
vocabulary, and the period-abbreviation inference reads 'Jr.' as a
title regardless -- claimed the lone post-comma piece before the 2.0
deviation that routes a lone suffix piece to SUFFIX could. 'Smith,
Ph. D. Jr.' read given 'Ph. D.' (#325): the space-split credential
followed by another suffix was no longer the LONE piece, so it fell
through to v1's walk and became the given name -- a 1.4.0 regression
(v1 read suffix 'Ph. D.', title 'Jr.').

The two halves are one change because each alone is wrong (the
2026-08-01 plan's F1): reading the post-comma run as suffixes first
would make 'Smith, Dr.' a suffix, since 'dr' was in SUFFIX_WORDS as
v1 residue; cleaning the vocabulary alone leaves 'Smith, Jr.' a
title by inference. So: the nineteen TITLES/suffix overlap words get
the classes the approved 2026-07-30 audit table gives them -- 'do',
'jr', 'junior', 'phd' and 'se' leave TITLES (postnominal only; 'Do'
is a Vietnamese name), 'dr' leaves SUFFIX_WORDS and 'sra'
SUFFIX_ACRONYMS (v1 residue), 'ms' and 'sa' join the ambiguous set
so the bare spellings read as the honorific and Special Agent and
the perioded ones as the degree and the business form, and the rest
keep dual membership with position deciding -- and in the listing
form a post-comma segment that is nothing but suffix pieces is the
credential run C1 describes and reads as suffixes, whole, before the
title peel: 'Smith, Jr.' -> suffix 'Jr.', 'Smith, Ph. D. Jr.' ->
suffix 'Ph. D., Jr.', 'Smith, Sr.' -> Senior where 'Sr. Garcia' is
still Señor, 'Smith, Esq.' -> the postnominal where H2 still reads
'Esq. Smith' as a title. 'Smith, Dr.' never reaches the ordering,
'dr' not being suffix vocabulary; 'Smith, Dr. Jr.' keeps v1's walk
(title, then the last piece as the suffix); 'Smith, John Jr.' keeps
its given name.

One word deviates from the approved table, on evidence the table did
not have: 'md' KEEPS dual membership. Bare 'Md' before a name is the
Bengali and South Asian Muslim abbreviation of Muhammad -- 'Md Abdul
Karim' and 'Md. Abdul Karim' are #343/#345's corpus rows, and the
drop read the first as given 'Md', middle 'Abdul' -- while 'MD'
after the name is the degree. Position decides, as for 'sr'. Derek
to confirm or overrule.

Consequences, all measured: a leading 'PhD' or 'Jr' is a name word
now ('PhD Smith' -> given 'PhD', a string nobody writes); 'Do Quang
Minh' and 'Do Nguyen' read given 'Do' with the particle-or-given
fork 'Van Johnson' reports, and 'Dr. Do Van Johnson, MD' reads given
'Do', family 'Van Johnson' where 'do' had stopped #367's transparency
scan as a title-and-particle word (the fix(#367) rule for that name
is replaced; 'St' and 'Freiherr' still stop it, and the #367/#424
examples spelled with 'Do' are respelled); a trailing bare 'Dr' is a
name word ('John Smith Dr.' -> family 'Dr.'), which is what every
other title-only word already does there (#316 is the open question)
and what the #100 prefix-join tests relied on 'dr' NOT doing -- they
use 'lt' now, a genuine dual; '田中さん, PhD' reads suffix 'さん, PhD'.
The #367 ledger rule's alternation loses 'jr' (no longer a title),
and 'Jr. Van Johnson' -- the same reading, by inference -- has its
literal. rules.md#C1's #296 deviates-marker is a real example now,
with the #325 shape beside it; assign cites C1.

Tests first, at every level: the assign-level run, duals, non-flips
and mixed runs; case rows for each audit disposition in leading,
post-comma and trailing position, the ordering's shapes, the #325
shapes and the non-flips; test_post_rules' lexicon mirrors the
shipped classes. Ledger rules at every baseline for each class that
moves (literal where a word is involved; the #325 rule is the shape,
since an alternation over the credential spellings would reach the
spaced 'Ph. D.', which is no entry); the 1.4.0 catch-all drops 15 ->
14 as a name it had absorbed gets its rule. Two release-log bullets.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
… read for what it is

rules.md#C1 says what the listing form does with the part after the
comma: a part that is nothing but suffix words is the credential
run and reads as suffixes, whole ('Smith, Jr.', 'Smith, Sr.',
'Smith, Ph. D. Jr.'); a part that is nothing but titles fixes no
family boundary, so the part before the comma keeps its positional
read ('John Smith, Mr.'); a name word makes it the given name, with
titles before and suffixes after ('Smith, Dr. Jr.', 'John Smith,
Jones'). The #296 deviates-marker is an example; #291's stays. H2
carries the one place the two meet as Accepted: after a family comma
the credential run is not an opening the abbreviation inference
runs on, so 'Smith, Esq.' is the postnominal where 'Esq. Smith' is
the title.

decisions.md#C1 records the bundle's three commits in the plan's
order -- the repair and what "nothing but titles" had to mean, the
audit and the ordering as one change and why, the one deviation
from the approved table ('md' keeps dual membership: bare 'Md' is
Muhammad, #343/#345's corpus rows) for Derek to confirm, the #325
widening, and the audit's measured consequences. The comma-suffix
arc is shipped less #291. The three places that named {do,
freiherr, st} as the load-bearing TITLES ∩ ambiguous set say it is
{freiherr, st} since the audit, and the C-i demonstration's 'Do
Quang Minh' reads given 'Do' with the fork now. AGENTS.md's
positional gotcha points at the audit.

The new C1 examples are corpus names (203); 'John Smith, Mr.' gets
its literal rule beside 'Bob Jones, author' at every baseline, and
the reach pins follow the seven new names.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@derek73 derek73 added this to the v2.2 milestone Aug 23, 2026
@derek73 derek73 added the bug label Aug 23, 2026
@derek73 derek73 self-assigned this Aug 23, 2026
@codecov

codecov Bot commented Aug 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.59%. Comparing base (a8b61c0) to head (33b9c73).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #428   +/-   ##
=======================================
  Coverage   98.59%   98.59%           
=======================================
  Files          44       44           
  Lines        3053     3070   +17     
=======================================
+ Hits         3010     3027   +17     
  Misses         43       43           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

derek73 and others added 2 commits August 23, 2026 11:09
… name count, the order, the duals, the gate

Four reviewers on PR #428 (code, tests, comments, design docs). What
they found, and what changed.

The repair's condition is "no name word after the comma", not "all
titles": 'John Smith, Mr. Jr.' -- a title and a postnominal -- had
kept the merge the rationale argues against, and keeps its split now
(given 'John', family 'Smith', suffix 'Jr.'). Its guard counts NAME
pieces: the positional read peels a trailing suffix first, so 'Smith
Jr., Mr.' -- two pieces, one name -- read positionally lost its
family (the code review's critical); it keeps family 'Smith' at
every baseline. The positional read records its ORDER, and
post_rules' leading-piece scan keys on "assign records no order
after a family comma" instead of on the structure, so P1's family-
first fold reaches the pre-comma name as it does without the comma:
'de Mesnil Juan, Dr.' under a family-first order had read family
'de' (the test review). The dead segments-count guard the coverage
check flagged is gone; the helper is called on the family-comma
path alone.

Two deviations from the 2026-07-30 audit table now, both measured.
'ms' and 'sa' do NOT join the ambiguous set: the gate is position-
blind and the collision is not -- gated, 'John Smith, MS' lost its
suffix-comma route and read title 'MS', and 'Smith, Ms.' passed the
gate on its one period and read as a credential anyway. Both are
genuine duals and position decides: 'Smith, Ms.' reads suffix 'Ms.'
(title at every baseline; C1 carries it as Accepted, 'Smith, Ms.
Jane' keeping the title), 'John Smith, MS' keeps suffix 'MS'. And
the period gate means what S2 says: an ambiguous acronym counts when
written with ITS periods, one after each letter ('M.A.', 'J.D.'),
not on any period -- 'Smith, Ed.' had become a credential on a
name's trailing period, and 'Jack Ma.' had read suffix 'Ma.' since
2.0 (family 'Ma.' now, as 1.4.0 read it; S2 carries the boundary).

Recorded rather than fixed, with the reason: 'Smith, RN - CRNA'
under extra_suffix_delimiters keeps given 'RN' -- a draft stepped
over the core, and tests/test_suffixes.py pins "the delimiter must
not affect parsing at all" outside the suffix-comma form as v1
parity; '田中さん, Dr.' keeps the honorific glued, joining master's
'田中さん, Mr.' -- the peel runs in script_segment before group or
assign can say the comma fixed nothing; group's chain emitter still
reports no PARTICLE_OR_GIVEN on the family-comma path.

The docs follow: C1's statement carries the no-name-word condition,
the name count, the order and the three Accepted limits, with
examples; H2's statement says where the shape does not outrank
vocabulary; S2's says "its periods"; decisions#C1 records the round,
'Smith, Dr. Jr.' is attributed to the 2.0 deviation rather than v1,
'Jong, vd' is C1's by statement, the guard test is named by its real
name; AGENTS.md and the release log carry the shipped counts (five
words left TITLES, twelve duals remain, 694 title-only) and the
shipped examples. The ledgers: the lone-credential rule sits behind
the two comma-family rules so 'Smith, Dr.', 'Smith, Prof.' and
'Smith, Abd' keep the rules written for them; the #325 shape rule is
two literal rules that cannot absorb 'Smith, Dr. Jr.'; the 'do is a
name' rule states the baselines' reading and drops the title field
that did not move; comment corrections from the comment review; the
contested-name shape for '田中さん, PhD' re-recorded; reach pins
follow the thirteen new examples (corpus 210 + 98).

Tests first at every level -- the assign-level no-name-word read
and the recorded order, the family-first rows (core-only, v1 has no
order to declare), the duals in every position, the name-count
guard's three shapes, the mixed runs, the title runs, the three-
segment run, 'Smith, MD'; the pins the test review asked for.

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

test_revise_sets_a_missing_unjoined_mark rested on 'Do' alone parsing
as a TITLE, so that the sub-parse marked nothing and the recompute
had to mark the bare particle it re-roled into FAMILY. #296's audit
took 'do' out of TITLES, 'Do' alone is a marked given name now, and
the test passed without reaching the recompute -- which is what
Codecov's project check saw (one line of _types.py lost its witness;
the project has no codecov.yml, so any drop fails). 'St' is still in
both vocabularies; the Do case stays as the other path.

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Smith, Ph. D. Jr. puts the credential in first (regression from 1.4.0) Should parse("Smith, Jr.") put "Jr." in title rather than suffix?

1 participant