Repository navigation
Gate the suggester's trailing-initial vote on the group's share; fix a title-only name's crash - #1345
Merged
Merged
Conversation
…a title-only name's crash Parser.suggest raised IndexError on a group holding a name that is nothing but titles (`Dr.`, `Professor`, and `Jr.`, which rules/H2's shape reads as a title at the head): _ends_in_post_nominal read the last word before asking whether any was left. The trailing-initial signal now votes only where at least three names, and at least 60% of the group's names, end in initials it reads uncontested. A byline list ends nearly every name that way; in a South Asian list the letters are often the family (`Lakshmi R S`, `Durga B K`) and in a truncated Brazilian one a middle and a family initial, and there the vote moved whole lists to a family-first order. A set-aside vote leaves the name's NameEvidence, and the order evidence's note says why; the name still counts in the patronymic share's denominator. Measured with tools/differential/suggest_measure.py against 62bbdeb: no same-order row below 98%; the family-first rows under a given-first base lose where a given name carries a middle initial (Russian and Brazilian now reach 95% from 50 names). decisions/group-suggestion's 2026-11-11 #1254 entry holds the re-taken table. Refs #1254 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Nov 12, 2026
One rule at every count: where any name casts a trailing-initial vote and the gate fails, every one is set aside, a contested one included. The group is the names holding a word with a letter or a digit, so a mark or a zero-width character alone no longer counts; the note counts the names it names; the patronymic evidence says how many names whose only vote was set aside count in its share. suggest_measure.py leaves a threshold the base lacks to its own rule and draws an ORCID byline population. The decisions entry's costs, sources and Open line are corrected, with the re-taken table. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The group-word test's rows now each fail without it; the patronymic note counts only the names a set-aside vote left with none, and prints only where a patronymic vote exists; the byline population test says what it guards and an empty population is a note. The docs no longer claim every same-order row holds 98%: bylines written with the initials first are the exception, on the Open line. The declined short-capitals variant is recorded with its measurement. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The share stays at 60% and the minimum at 3 names. The decisions entry holds the curve behind that (lower shares recover bylines but move half-initialed South Indian, three-quarters-initialed Brazilian and, without the letters setting, Nepali groups to the wrong order) and declines 0.5, 0.4 and a minimum of 2 names. docs/suggest.rst tells a caller with a short byline list to set the order. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
derek73
added a commit
that referenced
this pull request
Nov 12, 2026
Resolved: _suggest.py keeps #1345's gate and #1347's letter runs, a group whose letters are its family setting its trailing-initial votes aside through the gate's path; test_suggest.py's recorded controls and suggest_measure.py's SETTABLE keep both PRs' rows; AGENTS.md and decisions/group-suggestion keep both PRs' text. Co-Authored-By: Claude Opus 5.5 <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.
Two fixes to
Parser.suggest(unreleased, 3.1), the first of three PRs implementing the #1254 decision (its decision comment is on the issue).A title-only name no longer raises
Parser().suggest(["Dr."])raisedIndexError. So did any group holding a name that is nothing but titles:Professor,Chief Physician, andJr., which rules/H2's shape reads as a title at the head. The cause: once the leading titles are read past,_ends_in_post_nominalreadwords[-1]before asking whether any word was left.test_no_signal_raisesand a new group-level test now sweep 32 inputs: empty and blank text, title-only, post-nominals only, a nickname clause only, punctuation only, one letter. 14 rows fail on the merge base.trailing-initialvotes only where initials end most of the groupOne rule at every count: where any name casts a trailing-initial order vote, the votes are cast only where at least 3 names, and at least 60% of the group's names, end in initials no other signal in the same name contradicts. Otherwise every one is set aside, a contested one included, so the given-name vote that contested it then stands.
\u200b) and a name of nothing but titles leave it.Anna R S) is not counted.Anna R S,Maria J MandMary A Bunder a family-first base read given-first with or without an uncontestedHuntley R Pbeside them.A byline list ends nearly every name in initials (
Huntley R P,Smith J.). Elsewhere the letters are often the family (Lakshmi R S, Nepal'sDurga B K) or a middle and a family initial (Brazil's truncatedMARIA J M B). Today the vote moves those whole lists to a family-first order.How a set-aside vote is handled:
NameEvidence.votes, so the counts add up anddisagreeing()names no one for a vote the group did not count.Popov Ivan I.left the denominator, and five East Slavic names of seven decided the rule.test_a_set_aside_name_still_counts_in_the_patronymic_sharefails without it. The patronymic evidence's note says how many names count there with no vote left.Measurements
suggest_measure.pyRun with
uv run python tools/differential/suggest_measure.py --base <checkout of 62bbdeb1>; outputs are in the 3.1 cycle's session notes.orcid-bylinebelow.Smith John A.). The trailing-initial vote had read those right. At sizes 2 / 3 / 4 / 5 / 10 / 20 / 50 / 200:orcid-byline, a population added to the tool here: ORCID credit names written as a byline, the holder's boxes confirming the word in front is the family and the first initial the given name's first letter (2,215 names on 2026-11-11). Written family-first under a given-first base: 47.7 / 78.3 / 92.0 / 98.0 / 100 / 100 / 100 / 100% → 0.0 / 34.7 / 68.3 / 84.3 / 84.0 / 91.3 / 98.0 / 100%, the gate's cost on real bylines. Its given-first writing (GH Yoon) keeps its order under a given-first base in 96 / 85 / 76 / 67 / 27 / 9 / 0 / 0% of groups and is read given-first under a family-first base in none, at the base and here alike: the capitals signal reads joined initials in front as a family name. That is pre-existing and left as found, noted in root AGENTS.md's anti-goal sentence.in_sansadmoved. It is still decided given-first, with 78 names against instead of 167. No TURKIC row moved.--checks: byte-identical to the base.The study's populations
These come from the throwaway prototype in the session notes (
vote.py,measure_letters.py). The readings are modelled from each name's shape; the suggestion is the real one from this tree. Mean share of known names read right over sizes 2–200, before → after:Whole real lists (ORCID, Lok Sabha, Turkey's parliament, ClinicalTrials.gov) are made worse in 0–2% of groups.
Threshold choice
Chosen with the prototype (
vote.py --trailing-share) on half of each population and read on the other half, then checked withsuggest_measure.py --set _MIN_TRAILING_SHARE=<v>. At a share of 0.3 or 0.4, groups of ten or more half-initialed Nepali or South Indian names are made worse in 70–100% of draws; at 0.6, in 0–4%. A list 75% or more initialed that is not a byline list is still read family-first at every share: no share tells it from a byline list.Decisions for the maintainer
NameEvidence.votes, a public type, rather than being kept and flagged. The docstring now says so.name_order=FAMILY_FIRSTstays the lever for a known bibliography.Docs
docs/suggest.rst: the trailing-initial evidence, with its threshold and one clause of why.Parser.suggest's docstring: the threshold, and the re-taken "95% from N names" figures.tools/differential/suggest_measure.py:--setaccepts the two new thresholds; a name the base tree lacks is left to its own rule there, with a note, rather than raising; theorcid-bylinepopulation.Parser.suggest()is unchanged; its claims still hold.Review round 1 (fix commit e9dfab2 on top of 4823493)
\u200balone no longer counts as a group name; the comma check that guarded nothing is gone, with the reason in the docstring.docs/suggest.rstand the docstring say "uncontested" and "the group's names".--setwith a name the base lacks no longer raisesAttributeError.orcid-bylinerow, a pointer from THRESHOLDS, andOpen:now names Should an ALL-CAPS word in a mixed-case name mark the family name?DUPONT Jeangives givenDUPONT#659 (Can nameparser suggest settings for a list of names? (Smith Mary,Kim Minjun,Wang Xiaomingshould read family-first) #1308 is closed).Zhi LI,Hoy AM) toward the share without its voting. It recoversorcid-byline's family-first row (0 / 68.7 / 90.3 / 98 / 100 …) and pure byline groups (73% → 84% of names read right), but makes Nepal's 75%-initialed groups of 200 worse in 98% of draws instead of 82%.isalnumskip, the contested test, the set-aside count, the early return).Review round 2 (fix commit 4587f3c)
test_suggest_measure.py: the byline test says it guards the filter alone, and an ORCID file holding no byline gives a note.Parser.suggest's docstring,docs/suggest.rstandtools/differential/README.mdnow name the exception. Bylines written with the initials first (GH Yoon) keep their order less often, because the capitals signal reads joined initials as a family name. This predates this PR, and the gap is on theOpen:line.The share, decided
The share stays at 60% and the minimum at 3 names. The decisions entry records the curve behind that, measured stacked with #1347 and then on this PR alone. A lower share recovers bylines: ORCID's at 10 / 20 names go from 84 / 91% to 95 / 99% at 0.5. But it moves groups to the wrong order:
0.5, 0.4 and a minimum of 2 names are each declined there.
docs/suggest.rsttells a caller with a short byline list to setname_order=FAMILY_FIRST.Conflicts with the PRs that follow
PR 2 (#1347, the letters-are-the-family setting and its suggestion) touches
nameparser/_suggest.py,tests/v2/test_suggest.py,tools/differential/suggest_measure.py,Parser.suggest's docstring,docs/suggest.rst, decisions/group-suggestion and the release log. PR 3 (the ambiguity report) shares only the release log with this one.Checks
uv run pytest: 45,439 passed.uv run pytest -n0 -m serial: left to CI; the frame band (test_parse_cost_stays_within_its_band) passes locally.uv run mypy,uv run ruff check,uv run sphinx-build -b doctest docs,uv run sphinx-build -W -b html docsanduv run python tools/vocab/build.py --check: clean.Refs #1254
🤖 Generated with Claude Code