Skip to content

fix(#544): a credential run keeps its ambiguous members - #552

Merged
derek73 merged 11 commits into
masterfrom
claude/544-comma-credential-run
Sep 29, 2026
Merged

derek73 merged 11 commits into
masterfrom
claude/544-comma-credential-run

Conversation

@derek73

@derek73 derek73 commented Sep 28, 2026 •

Copy link
Copy Markdown
Owner

Closes #544.

What changes

A credential run keeps its ambiguous members (#544). Readers that met an ambiguous acronym (ma, ba, ed, do, jd, meng, lac, …) took its name reading without looking at the credential in front of it, and C1 read only a one-word part after a comma as a credential. #540's meng/lac marking and #289's case lean turned both into ordinary misreadings.

2.3.0 master now
John Smith, PhD MEng suffix PhD MEng given PhD, middle MEng, family John Smith suffix PhD MEng, reported
John Smith, Ed Ma given Ed, middle Ma, family John Smith the same suffix Ed Ma, reported
Jane Doe, MS LAc suffix MS LAc title MS, given LAc, silent suffix MS LAc, reported
John Smith PhD MEng suffix PhD MEng middle Smith PhD, family MEng suffix PhD MEng, reported
abdul Smith Jr Ma suffix Jr Ma middle Jr, family Ma suffix Jr Ma
Smith, PhD Ma given PhD, middle Ma the same suffix PhD Ma, reported
doe, jane v phd do family do doe the same suffix v phd do, reported
Wang M.Eng. suffix M.Eng. family M.Eng. suffix M.Eng.
  • C1 reads a run. With two or more name words before the comma, a part of two or more words, each suffix vocabulary or a member of the ambiguous credential class, with no one-letter roman numeral, is the credential run, and the flip reports once. A run whose every listed member is written in capitals in a mixed-case name is left to the listing-form path, which already reads it whole (John Smith, PhD MA, silent as before). 1.4.0 read all of these as suffixes.
  • A credential in front speaks for the member at every trailing slot: the no-comma peel (the maiden walk and the P5 reserve inherit it), a comma part read wholly as credentials, and the given slot, where it outranks P6's particle attachment. Only a credential IN FRONT speaks (Wang Ma PhD keeps family Ma); a connective, a particle (vd, mc: Smith vd Ma, John keeps family Smith vd Ma), a one-letter numeral, a dual in the given part's leading title run, and the walk's own leading word (Om Ma, PhD Ma keep family Ma) speak for nothing, and it does not cross a maiden clause. This reverses decisions.md#S2's Use letter case to disambiguate suffix vs. surname: "Jack MA" vs "Jack Ma" #289 item (ii).
  • Reports: an anchored pick is reported where the member's own writing declined it; a member whose capitals already say credential is not.
  • M.Eng. passes S2's period gate as M.A. does (two or more period-closed chunks spelling a listed member).
  • A part read wholly as suffixes raises no name-reading report (rules.md#C2). Found on the way: since 2.0.0, John Smith, Jr., Freiherr von Richthofen reported particle-or-given for von, a word the same parse put in the suffix; this branch's run rule also made the particle chain's report reachable in John Smith, PhD Do Ma. Report-only; no field moves.

Decisions taken along the way (Derek, 2026-09-27/28)

  • The run rule takes all-member runs and a leading member (Ed Ma, MEng PhD), not only a trailing one.
  • One rule at every trailing slot, anchored in front only.
  • A title/suffix dual counts as suffix vocabulary in the C1 run (John Smith, MD MEng → suffix), but a dual in the given part's leading title run is a title: Smith, Ms Ma keeps given Ma, and Smith, Ms MD Ma keeps master's title Ms MD, given Ma.
  • A one-letter roman numeral anchors nothing and voids a run (single-letter shape, as S3); Jr, III anchor.
  • A by-shape member never settles a run: John Smith, X.Y.Z. MA reads suffix X.Y.Z. MA, reported.
  • An anchored pick in a comma part read wholly as credentials reports (Smith, PhD Ma, John Smith, PhD Ma Prof.).

Recorded boundaries and costs

  • Accepted: John Smith, Ms Ma → suffix Ms Ma, reported (as John Smith, Ms alone reads); Om Jr Ma → suffix Jr Ma, no family; a capitalised MA opening a one-word-family given part with a degree behind it (Smith, MA PhD Ma) reads wholly as credentials, reported; doe, jane v phd do now reports suffix-or-name rather than particle-or-given.
  • Limits kept a name word (rules.md#S2 Accepted): John Smith Ph. D. MEng, John Smith PhD Prof. Ma, John Smith PhD Do Do, Smith, PhD Do Ma (the P2 chain takes Do Ma).
  • Jane Doe Jr. nee Smith Ma keeps maiden Smith Ma (rules.md#M2 Accepted).

Verification

  • Suite: 10,487 passed. mypy and uv run ruff check clean; sphinx doctest and html -W clean; _assign.py, _group.py, _pieces.py, _segment.py, _vocab.py at 100%.
  • Differential gate: exit 0 at all five baselines, 0 unexplained, radar unclassified unchanged (0/5/6/7/7). At 2.3.0 five fix(#544) rules classify 17 names. Every new or moved corpus name is attributed against the baseline wheel, master and HEAD; Wang M.Eng. belongs to feat(#449) / fix(suffix-routing), not Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544, and two labels are joint with parse("John Smith MD PhD").suffix returns "MD, PhD" — a run without a comma renders with one #436/Should the suffix separator be derived from the comma the writer typed, rather than from segment shape? #437 where the suffix diff is only the spacing change.
  • Grid (254,496 parses, recipe in decisions.md's Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544 entry, comparator e10e83b): 89,825 move; 0 new violations of either invariant (anchored member in a name field 29,199 → 1,530; unambiguous credential in a name field 36,675 → 4,734); clean-to-clean moves are only M.Eng.'s dropped report.
  • Corpus sweep (master's 1,418 names): 4 names move, all intended.
  • Frames per parse (py3.11, master → now): unchanged for ordinary names (Smith, John 182, John Smith 151, John Q. Public 226, Doe, John MA 283, Smith, Ed 213); a comma name with two or more words each side pays one (Doe Smith, Jane Q. 317 → 318); a name whose ambiguous member declines on its writing pays a cheap reach test and, only where a suffix piece stands in front, the anchor pass (John Smith Ma 244 → 246, Smith, John Ma 275 → 279, Doe, John Q. Ma 316 → 320); anchored names pay the pass (John Smith PhD MEng 286 → 329); reference band 370/407 unmoved.
  • Negative controls: anchor off → the company property fails on 48 parses; the walk's leading word allowed to anchor (both exclusions removed) → the converse fails on 42; anchor_in_reach reading a suffix word as none → its sweep fails at 878 member positions; per-member look-behind → credential_run 15.8× for 4× the input.
  • Review: spec and quality review per commit, re-review of every fix. Findings fixed on the branch: an inline fold that duplicated a predicate (now _vocab.run_word_fold, with an agreement test); the walk's own leading word anchoring (Om Ma lost its family); a property oracle blind to the no-comma half; ledger attribution (Wang M.Eng., three 1.4.0 maiden names, joint labels); two silent readings from the design-docs review (commit 6, decided by Derek); the stray tail report (commit 7); a frame on double-surname comma names (commit 8). A whole-branch review found no critical or important issue. A final four-agent pass (code, tests by mutation, comments, silent failures) found a particle anchoring the acronym behind it (Smith vd Ma, John lost the family's contiguity, silently), a duplicated anchor walk, two unpinned branches and a set of stale comments: commits 9-10, each reviewed again. A /simplify pass (reuse, simplification, efficiency, altitude) folded the three hand-built given-slot anchor queries into one _pieces.given_slot_anchors (commit 11); readings byte-identical over 27,662 × 3 and 76,128 × 3 generated names plus every case row, plain names at master's frames.

Commits

  1. 076a28a fix(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): a listed member written in period-closed chunks passes S2's period gate
  2. 460e2aa fix(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): C1's name-word count reads a credential run as it reads one word
  3. 4b708ca fix(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): an unambiguous credential in front of an ambiguous member speaks for it
  4. 9e37aad test(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): case rows, rules.md examples, corpora and ledgers
  5. 0c8d333 docs(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): decision records, release notes and prose sweep
  6. 16d835f fix(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): an anchored pick after a family comma reports, and a dual title run keeps its reading
  7. a83cb81 fix(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): a part read wholly as suffixes reports no name reading of its words
  8. 364cc33 perf(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): the C1 run test ends on a name word before the numeral test
  9. 080810c fix(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): a particle anchors nothing, and the anchor pass runs only where a suffix piece is in reach
  10. 5c8e8ac perf(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): a member opening a comma part asks no anchor pass
  11. a075420 refactor(Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith #544): one given-slot anchor query, and a flatter anchor branch

🤖 Generated with Claude Code

derek73 and others added 8 commits September 27, 2026 15:04
…s period gate

S2's period gate counted an ambiguous acronym as unambiguous only when
written with a period after each letter, so the chunked spelling of the
two members #540 marked -- 'M.Eng.', 'L.Ac.' -- read as the bare word
does and 'Wang M.Eng.' lost the suffix 2.0 through 2.3 read. _dotted now
also accepts two or more letter chunks each closed by a period; one
trailing period ('Ma.') stays outside the gate. is_single_letter_numeral
is added for the run rule and the anchor that follow. rules.md#S2 states
the gate's second spelling, with the two code excerpts that quote it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…e word

C1 flipped a part after the comma to the suffix comma by the NAME-word
count only when the part was one token, so a run ending in an
ambiguous member fell through to the family comma: 'John Smith, PhD
MEng' read given 'PhD', middle 'MEng', and 'Jane Doe, MS LAc' title
'MS', given 'LAc'. A part of two or more words, each suffix vocabulary
or a class member, at least one a member and none a single-letter roman
numeral, now reads by the same count, and the flip reports once over
the whole part. A title/suffix dual opening it counts as suffix
vocabulary after a full name; a run whose every listed member is in
capitals is left to the family-comma path, which already reads it
whole with the report it always made. The test is skipped unless two
words precede the comma, and an inline fold answers the common token
without a Python frame, so a comma name with no run pays nothing.

The fold is a named, tested predicate (_vocab.run_word_fold) rather
than a hand-copied condition at the call site, kept over removing it
outright because an ordinary comma name that enters the run loop and
breaks on its first token still costs 6 frames more without it.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…speaks for it

The trailing readers met a listed member first, took its name lean and
stopped, so the credential in front of it was never reached: 'John
Smith PhD MEng' read middle 'Smith PhD', family 'MEng', 'Doe, Jane PhD
MEng' middle 'MEng', and 'abdul Smith Jr Ma' middle 'Jr' -- the cost
decisions.md#S2 had accepted as #289's item (ii). A member standing
behind an unambiguous credential in one run of suffix words now reads
as the credential whatever its writing: on the no-comma peel, in the
comma part read wholly as credentials, and at the given slot, where it
outranks P6's attachment as capitals do ('doe, jane v phd do'). Only a
credential in FRONT speaks ('Wang Ma PhD' keeps family 'Ma'); a
connective, a single-letter numeral and a dual opening the given part
speak for nothing, and the reading does not reach across a maiden
clause.

The walk's own leading piece never anchors: it is the name a reserve
keeps whatever its vocabulary, so 'Om Ma' and 'PhD Ma' keep family
'Ma' (with it anchoring, the family was lost outright), while 'John
Om Ma' reads suffix 'Om Ma'. A single-letter roman numeral is
excluded for being initial-shaped ('V' can be a middle initial); a
multi-letter one ('Jr', 'III') anchors like any other suffix word.

_pieces.credential_anchors is the one forward pass, linear in a run;
credential_at_the_given_slot takes it as a thunk asked last, so a
member the writing settles never pays for it. The M2 clause-agreement
walk now also asks every parse it takes two questions that share one
walk-back (`_qualifying_front`): whether a listed member behind an
unambiguous credential reads as one (48 failures with the anchor off,
0 here), and the converse, whether a member read as a credential
because of the word in front has that word in the suffix too (30
failures with the leading piece allowed to anchor, 0 here). It pins
the pairs a maiden clause makes differ as its anchored_head class.
test_benchmark gains the credential_run shape (15.8x for 4x the input
with a per-member look-behind, 4.2x here).

The reserve the company check exempts is the name's leading piece in
a name with no comma before it (H4's carve-out, where 'PhD Ma' keeps
family 'Ma'); a family-comma given part's first piece reads through
`segment_suffix_reading` instead, so a comma before a candidate front
exempts nothing, and the walk continues through a maiden clause to
the name past it. The converse forces its extra parse only for a
front outside both TITLE and SUFFIX, which keeps the walk at 2.5s,
and each control trips its own assert, ordered ahead of the
pair-agreement one so neither masks the other.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
Twenty-four case rows: the issue's targets in each comma shape, and
the boundaries each half keeps -- a credential BEHIND the member ('Wang
Ma PhD'), a dual opening the given part ('Smith, Ms Ma', 'Smith, MD
MEng'), a numeral in front ('smith, v ed'), the run the capitals settle
('John Smith, PhD MA'), a by-shape member ('John Smith, X.Y.Z. MA'),
the maiden-clause boundary ('Jane Doe Jr. nee Smith Ma') and the three
limits rules.md#S2 accepts. rules.md gains the C1, S2 and M2 example
lines; the corpora are rebuilt.

Ledgers: a rule is named for the change that moves the name against
its baseline. fix(#544) rules classify the names #544 moves; #540's
comma-run and chunked-dotted rules are retired, the comma-run names
now the fix(#544) rules' and 'Wang M.Eng.', whose roles every release
from 2.0 read, feat(#449)'s report rule at 2.0-2.2 and the dotted
fix(suffix-routing) rule beside 'Jack M.A.' at 1.4.0. Names whose
remaining diff is R1's spacing join the fix(#436/#437) alternations,
and where the spacing rides with another change's diff the label is
joint: the anchor rule is fix(#436/#437/#544) at 2.0-2.2, and
fix(#425), taking `given` back at 2.0/2.1 as 'abdul Smith Jr Ma'
leaves the fix(#289) ones, is fix(#425/#436/#437). At 1.4.0 the
maiden-clause names #544 moves no role on join the rules for the
changes that do (fix(#274/#436/#437) for the two PhD MEng clauses,
fix(#274/#424) for 'Jane Doe Jr. nee Smith Ma', which joins fix(#533)'s
report rule at 2.x). 'Smith, PhD MEng' is fix(#325)'s at 1.4.0, pinned
beside 'Smith, PhD Jr.' with the same argument. Gate: exit 0 at all
five baselines, radar counts unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
decisions.md#S2 gains the #544 entry: the eight forks (the whole run
at C1, every trailing path anchored in front, the chunked dotted gate,
single-letter numerals, no new report where the listed members'
capitals settle the run, the maiden-clause boundary, the anchor over
P6 at the given slot, the dual exclusion scoped to the given part's
head); the four boundaries of what may anchor (a connective, a dual
opening the given part, the walk's own leading piece, a single-letter
numeral for being initial-shaped); the accepted costs ('John Smith,
Ms Ma', 'Om Jr Ma', the report 'doe, jane v phd do' now makes) and
limits (the merged 'Ph. D.' without a comma, a title in the run, a
particle member P2 has chained, 'Smith, PhD Do Ma' among them); the
two-input check's recorded controls; and the grid, corpus and frame
measurements re-taken on this tree against e10e83b with the recipe
and comparator. Why no mechanisms entry is owed is stated there.

Dated addenda, nothing earlier rewritten: #289's accepted item (ii)
reversed; #531's P6 pairing gains the anchor as a second exception;
C1 records the run rule; M2 records the clause boundary; and
suffix-acronym-collisions answers #540's two pending questions,
saying where 'Wang M.Eng.' is now classified (feat(#449) at 2.0-2.2,
fix(suffix-routing) at 1.4.0, no diff at 2.3.0) rather than under a
fix(#544) rule.

rules.md#C1: the capitals settle a run only where every word of the
class in it is a LISTED one; a by-shape member leaves the part to the
count. rules.md#S2's interacts line gains M2.

docs/release_log.rst: a #544 bullet, and the #540 bullet's comma-run,
walk-stopping and dotted passages replaced by the costs that remain.
_types.py's SUFFIX_OR_NAME note says which slots report an anchored
pick and that the first-piece emitter stays silent on 'Smith, PhD
MEng'. AGENTS.md's benchmark paragraph drops its shape count and adds
the anchor-pass shape. tests/v2/cases.py: the 'smith, v ed' row's note
gives the numeral's shape, not its meaning, as why it anchors nothing.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…title run keeps its reading

A member the company decides reports where it was decided. When a
credential in front makes a family comma's given part read wholly as
credentials, each member whose own writing declined and which the
anchor read as the credential reports suffix-or-name, as the peel's
picks do: 'Smith, PhD Ma', 'Smith, PhD MEng', 'Smith, Ph. D. MEng',
'Smith, Dr. PhD LAc', 'john smith, v phd ma' and 'John Smith, PhD Ma
Prof.' each report the member. A member its own capitals made the
credential stays silent ('Smith, PhD MA'), and the part's first piece
is the first-slot report's word, never this one's.
`segment_suffix_reading` names those picks and assign emits them.

A title/suffix dual in the given part's leading title run is a title
there, and no credential behind it speaks for a member of the
ambiguous class in that part: the next word is the given name, and
the parent's reading stands -- 'Smith, Ms MD Ma' and 'Smith, MD MS Ma'
title plus given 'Ma', 'Smith, MD PhD Ma' given 'PhD', middle 'Ma'
(reported), 'SMITH, MD MS BA' given 'BA'. A plain title does not do
this ('Smith, Dr. PhD LAc' reads suffix 'PhD LAc'), behind a real
given name the company reads as ever ('Doe, Jane MD Ma' suffix 'MD
Ma'), and past the title run the given slot's company still speaks
('Smith, MD PhD Jr Ma' suffix 'Jr Ma'). A part with no member to
speak for, or only members whose capitals decide them, reads as it
did ('Smith, MD PhD', 'Smith, Ms MD MA').

rules.md P6 names two exceptions to the attachment, the capitals and
S2's company ('doe, jane v phd do'), and limits the one-case sentence
to a word with nothing in front of it; S2's own sentence about the
particle member and the unreleased #531 release bullet say the same.

rules.md: S2's company clause states the dual's leading-title-run
scope, the report of a decided member, and the single-letter numeral
exclusion as a matter of shape in any case; C1 states the numeral
exclusion as shape ('John Smith, III Ma' is a run) and which runs
report, naming the silent ones. `is_single_letter_numeral`'s comment
gives the shape reason too. Example lines 'Smith, PhD Ma' and
'Smith, MD PhD Ma'. The SUFFIX_OR_NAME docstring and assign's emitter
roster say the same.

decisions.md: the #544 entry gains forks (9) and (10), restates
refinement (b) and boundary (d) (the exclusion is a single-letter
roman numeral in any case, which `is_single_letter_numeral` tests;
`is_initial_shaped` is False for a lower-case 'v'), drops fork (5)'s
unrecomputable counts, states the accepted cost as its shape (a
capitalised 'MA' opening a one-word-family part, a degree behind it:
138 grid parses, 46 texts, from given 'MA' to no given name), corrects
boundary (c) for the family-first orders, and re-measures the grid against e10e83b with
the detector's token sets and the attribution order in the recipe:
89,825 of 254,496 parses move, the invariants 29,199 -> 1,530 and
36,675 -> 4,734 with 0 new violations. The #540 addendum names the
successor case rows. The release note says which runs report,
adds the two readings, and says a one-letter numeral in front no
longer stops the part reading whole ('john smith, v phd ma').

Case rows pin 'Smith, PhD Ma', 'John Smith, PhD Ma Prof.' against
'John Smith, PhD Ma', 'Smith, Ms MD Ma' and 'Smith, MD PhD Ma';
'Smith, PhD MEng' now reports. Unit tests pin the
silence for 'Smith, PhD MA' against 'Smith, PhD Ma', and 'Smith, M.D.
PhD Ma' (a dotted credential is no title-run dual) reporting 'Ma'. Ledgers: 'Smith, PhD Ma' is a new
fix(#544) rule at 2.2.0/2.3.0 and, with 'Smith, PhD MEng',
fix(#296/#544)'s at 2.0.0/2.1.0; 'Smith, PhD MEng' joins the anchor
rule at 2.2.0/2.3.0; 'John Smith, PhD Ma' joins the run rule;
'Smith, MD PhD Ma' joins fix(#531)'s declining rule at 2.2.0/2.3.0 and
is fix(#296/#531)'s at 2.0.0/2.1.0 and fix(#296)'s at 1.4.0; 'Smith,
PhD Ma' is fix(#325)'s at 1.4.0, pinned beside 'Smith, PhD MEng'.
Gate exit 0 at all five baselines, radar unclassified unchanged.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
…its words

group's particle chain runs over every comma segment, and both of its
emitters reported inside a tail segment, which assign reads wholly as
suffixes: particle-or-given for a particle chained behind a word of
both the title and particle vocabularies (every release from 2.0.0
through 2.3.0: 'John Smith, Jr., Freiherr von Richthofen' reports it on
'von', a suffix token), and suffix-or-name when the chain takes an
ambiguous acronym into the name (unreleased; the C1 run rule made it
reachable behind one comma, so 'John Smith, PhD Do Ma' carried the
flip and a second report on 'Ma'). Each named a reading the parse
never made. A family comma's tails were already silent.

group now hands the chain no report list in a tail segment after
either comma. The maiden channel is untouched: a tail's reader is
NONE, so the maiden walk reports nothing there.

Measured against the same tree with the old condition restored: no
differential-corpus name moves (the gate is unchanged at all five
baselines); over a comma grid of 11,049 texts x 3 orders, 360 parses
lose one suffix-or-name report each, every one on a suffix-role token,
with 0 field moves and 0 reports added. That grid holds no word of
both the title and particle vocabularies, so the particle-or-given half
is pinned by a case row ('John Smith, Jr., Freiherr von Richthofen');
a wider sweep over such words removes particle-or-given reports too,
again only on suffix-role tokens and with no field move. Frame counts
are unchanged for the reference list and the call_count band
(370/407).

rules.md#C2 states the boundary; two case rows pin it beside the rows
the chain still reports on; decisions.md carries a dated C1 bullet with
the recompute recipe; the release log gains a Fix bullet; AGENTS.md's
decision-site note names the tail case.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
A comma name with two or more words on each side of the comma enters
the run test, and its first name word ends the run; the numeral test
stood ahead of the name-word test and cost that ordinary name a frame
for nothing. The name-word test goes first -- a one-letter roman
numeral is suffix vocabulary, so it never folds as a name word and
the order cannot change a reading. 'Doe Smith, Jane Q.' and 'Garcia
Lopez, Maria Jose' now cost 318 and 331 frames, one over e10e83b
(run_word_fold's own call), where they cost 320 and 333; the
run_word_fold docstring and decisions.md's #544 frame line say so.

A comment in segment claimed three runs are credential runs "at every
policy"; with unlisted_dotted_suffixes off 'X.Y.Z.' is a name word,
so it now carries the qualifier the decisions entry already states.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
@derek73 derek73 added this to the 2.4 milestone Sep 28, 2026
@derek73 derek73 added the bug label Sep 28, 2026
@derek73 derek73 self-assigned this Sep 28, 2026
@codecov

codecov Bot commented Sep 28, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.85%. Comparing base (e10e83b) to head (a075420).

Additional details and impacted files
@@            Coverage Diff             @@
##           master     #552      +/-   ##
==========================================
+ Coverage   98.81%   98.85%   +0.03%     
==========================================
  Files          45       45              
  Lines        3812     3934     +122     
==========================================
+ Hits         3767     3889     +122     
  Misses         45       45              

☔ 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 3 commits September 28, 2026 13:41
…where a suffix piece is in reach

A word of both the particle and the unambiguous suffix vocabulary
('vd', 'mc') heads the family name behind it (rules.md#P2), so it
speaks for no member of the ambiguous class behind it
(rules.md#S2's company clause). Anchoring there split the family
around a suffix: 'Smith vd Ma, John' read family 'Smith Ma', suffix
'vd', and 'Jan vd Ma' suffix 'vd Ma' with no family. Both, and
'Smith Mc Ma, John' and 'D. Mc Ba Ed, Smith', read as e10e83b reads
them again. A particle member behind a credential is still spoken
for ('doe, jane v phd do' keeps suffix 'v phd do').

segment_suffix_reading asks credential_anchors (first_kept=False)
instead of carrying a hand-kept copy of it; a comma part holding a
name word returns before any member is asked, so a plain comma name
pays no frame for it.

_pieces.anchor_in_reach answers, from tags alone, where the pass
must answer False -- past the lone members in front, the first piece
is no suffix piece -- and is asked only before the pass exists. An
ordinary name ending in a declined member stops paying for the pass
('John Smith Ma' 250 -> 246 frames, 'Doe, John Q. Ma' 328 -> 320).
On the no-comma peel its reach starts past the kept leading piece,
which is what made the by-shape guard there unreachable; it is
removed.

A tail segment reads wholly as suffixes outside a maiden clause
standing in it ('Jane Doe, PhD, Jr nee van Ma' keeps maiden 'van
Ma'); rules.md#C2, AGENTS.md and _group's comments say so. The comma
run's report names a run as holding a word that is also a name word.

Case rows pin the particle exclusion and the two maiden-walk release
checks' anchor thunks; each row fails with its thunk replaced by
None. A frame-count test holds the run test's reject-before-numeral
order. decisions.md's #544 entry gains a dated addendum with the
measurements; the property test's second recorded control reads 42.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
rules.md#S2's company clause speaks only for a member with a
credential in front of it, so the first piece of a comma part is
never anchored. segment_suffix_reading now builds its
credential_anchors pass only where anchor_in_reach finds a suffix
piece in front of the declined member; a member opening the part
asks neither. 'Smith, Ed' and 'Smith, Ma' go back to 213 frames,
'Smith, Ed John' to 270, and credential_anchors is entered 0 times
for each, which a frame-count test pins.

A sweep test holds anchor_in_reach's one-way exactness -- False
implies credential_anchors False at every lone member -- over the
case table's texts and every run of one to three words behind two
heads (4,497 texts, 0.23s); with the reach test reading a
"vocab:suffix" token as no suffix piece, 878 positions fail.

rules.md#S2's reworded sentence is reflowed to the rule body's
width, and decisions.md's #544 addendum carries the new figures.

Co-Authored-By: Claude Opus 5.5 <[email protected]>
`_pieces.given_slot_anchors` is now the one home of the given slot's
anchor pass, indexed by piece: assign's given slot, group's GIVEN_SLOT
reader and the maiden clause's take each built it by hand, with three
spellings of the leading-title start and of the pieces before it. Each
caller keeps its own reach test and its own cache; assign's starts at
the `n` `_peel_leading_titles` already counted, rather than counting
the run again, and group's cache is a `nonlocal` rather than a
one-slot list.

`segment_suffix_reading`'s anchor branch reads as `peel_trailing`'s
does: build the pass if a suffix piece is in reach, then ask it, each
early branch ending in `continue`. Its leading-title-run flags stay
walk-local, with a comment saying why: `leading_titles` counts a
period-shaped suffix ('Esq.') into the run, which would move 'Smith,
Esq. MD Ma'.

`segment`'s run loop ends on a name word or a single-letter numeral in
one branch, and the #516 narrowing comment keeps only why it stands.

In test_properties, `_credential_without_suffix_role` forces
`_one_case(name.original)` itself instead of taking a thunk both
callers built from that same text, the walk's paired `company` /
`orphaned` updates share a local `audit`, and the literal
"shape:acronym" is the imported SHAPE_ACRONYM_TAG.

Readings are byte-identical (all seven fields, ambiguity kinds and
token indices) over a 27,662-name grid under three policies and over
tests/v2/cases.py plus a 76,128-name maiden/title grid. Frames: the
plain names are unchanged, the anchored given-slot names drop 2-5
('Doe, Jane PhD Ma' 360 -> 357, 'Doe, Dr. Jane PhD Ma' 419 -> 414);
call_count stays 370/407. Both recorded controls in the maiden walk
still reproduce (48 company, 42 orphaned).

Co-Authored-By: Claude Opus 5.5 <[email protected]>
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.

Should a credential run after a comma keep its comma when the last word is an ambiguous acronym? John Smith, PhD MEng reads first PhD, last John Smith

1 participant