fix(#535, #538): a trailing title ends the maiden clause; a delimiter core is stepped over beside a link - #550
Merged
Conversation
The link exception inside a maiden clause asks for a name word on each side of the link. A delimiter core past the clause's first word was an ordinary index to the neighbour walk and passed for that word, so 'Smith, John, PhD née Puig Mr. - i Soler' under a ' - ' delimiter kept 'i Soler' in the maiden name. The walk now steps over a core as it steps over a connective, so the clause reads as the same text written without the core. rules.md#M2's deviation becomes a statement and two examples; decisions.md records the boundary reading declined. The same stepping also applies to the `frozen` loop's own `_run_neighbours` call, which reaches every credential tail and not just a maiden clause: a connective of generational vocabulary beside a declared delimiter core looks past it, and where a credential or nothing stands beyond, it stays a lone suffix word and the core -- a lone piece with nothing joined to it -- is dropped as #206 drops any lone core, so 'Smith, John, PhD - i Soler' reads suffix 'PhD - i Soler' -> 'PhD, i Soler'. Where a name word stands beyond the core instead, the link joins across it and the core survives in the suffix text ('Smith, John, Puig - i Soler' stays 'Puig - i Soler'); an ordinary connective's join still takes the core as its neighbour regardless ('Smith, John, PhD - and MD' keeps 'PhD - and MD'). rules.md#P3 states the general separator-stepping sentence this rests on; rules.md#R1 gains an example; both cross-reference each other and M2. decisions.md's #538 entry records the measured population and the unrepaired cases. Two new corpus names land in the ledgers. 'Smith, John, PhD née Puig - i Soler' landed in _CORPUS_CLAIMS, in _NOT_A_VOCABULARY_COPY in tests/v2/test_ledger_guards.py, and in the #397 rule's alternation in all five tools/differential/expected_since_*.toml ledgers, since it reaches the DEFAULT facade there with no delimiter configured. 'Smith, John, PhD - i Soler' diffs at no baseline (the tree's own default reading is unchanged from every baseline's), so it needed no ledger alternation, only the corpus-wide growth in two 1.4.0 _CORPUS_CLAIMS comma rules (372 -> 373). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The maiden walk read the trailing suffix run and never the trailing title chain, so 'Jane Doe nee Smith Prof.' kept the title in the maiden name and a title behind a credential or numeral hid it from the #533 and #424 stops: 'Smith MA Prof.' and 'Smith Prof. MA' disagreed. Where a trailing rule reads the words, the walk now reads the end of the name as assign does (tail_reading), so a title is a stop and the two spellings agree. The credential and title stops each ask one question of the whole span they give up: does the name left standing read it as titles or suffixes, with no join below absorbing it (rules.md#M2's invariant), and each spares the first word after the marker. The numeral stop does not: it reads FROM the marker by design, so a numeral standing straight after it declines the clause outright rather than sparing the word -- 'Jane Smith née V' stays a marker with nothing behind it, and 'Jane Doe nee V Prof.' declines through the title the same way, title 'Prof.' landing on the declined name exactly as it would on 'Jane Doe nee V' bare. The numeral stop never asked the join half either, so 'Berg, abdul nee Smith V' read given 'abdul nee', suffix 'V' at 2.0/2.1 and given 'abdul V' at 2.2/2.3 (#411's own reserve differs between those pairs before #535 ever runs); it keeps maiden 'Smith V' now at every baseline. The first-word floor lives in the H5 chain itself (`trailing_titles` and `tail_reading` take a `floor`, defaulting to 1; the maiden walk passes the position just past the marker's first word), not in a clamp read after the fact -- a chain that took the first word had already spliced it out of the count the re-peel reads, which is why 'Jane Doe nee King. ba' lost the suffix 'Jane Doe nee Smith ba' keeps. The join half of the release check is scoped to the GIVEN_SLOT reader alone: P5's bound-given join is `BoundJoin.LENIENT` only after a family comma, and before one the reserve is `BoundJoin.STRICT` and already declines a join that would change a suffix reading, so asking there over-declined 'abdul nee Smith V'. And after a family comma the given slot reads a lone numeral as a suffix only where the given part is the LAST comma part (#144), asked of the maiden clause too now: a credential tail behind the numeral withdraws the release, so 'Doe, Jane nee Smith V, PhD' keeps 'V' where the comma-less 'Doe, Jane nee Smith V' gives it up -- and the withdrawal reaches through a title behind the numeral too, so 'Doe, Jane nee Smith Prof. V, PhD' never gets to H5 at all and keeps maiden 'Smith Prof. V', unlike its numeral-first twin 'Doe, Jane nee Smith V Prof., PhD' (title 'Prof.', maiden 'Smith V') -- the same asymmetry the bare given slot already has with no marker in it ('Doe, Jane Prof. V, PhD' vs 'Doe, Jane V Prof., PhD'). The differential ledgers classify a diff by every change that causes it, not #535 alone: a name whose reading already differed from a baseline before this change (checked against the parent tree d9d8049) keeps that earlier rule, or gets a joint label when #535 moves it further. This landed seven such attributions across the five ledgers: fix(#274) for 'Dr. nee Jones Smith Prof.' at 1.4.0 (only a title precedes the marker there, so #535 moves nothing -- v1's missing maiden reading is the whole diff); fix(#274/#535) for the rest of 1.4.0's title-stop names; fix(#274/#296/#535) for 'Jane Doe nee Prof. Dr.' at 1.4.0 alone, where v1's missing maiden reading and 'dr' still being suffix vocabulary both predate #535; fix(#411/#535) for the numeral-join name, shared by 1.4.0 and 2.0.0/2.1.0 (they read it identically, so #274 moves nothing there either -- the bound-given reserve decides given/maiden before #535 runs); a new fix(#399) sibling for 'Jane van der Berg nee Smith Prof.' at 2.0.0/2.1.0 (the general rule's one-trailing-word anchor can't reach it, and #535 moves nothing there either); fix(#296/#535) for 'Jane Doe nee Prof. Dr.' at 2.0.0/2.1.0 alone, where 'dr' is still suffix vocabulary at those two baselines but not at 1.4.0; and fix(#533/#535) for 'Jane Doe nee Smith Prof. MA' at every 2.x baseline (#533 already gives the credential up to `suffix` and reports the fork; #535 then reads the title standing in front of it through the credential). 'Jane Doe nee King. ba' is NOT an eighth: the parent tree already reads it exactly as HEAD does at every baseline (no chain ever ran on it, since nothing but its own first word and a trailing credential stand after the marker), so its whole diff is #533's and it joins the existing declining-half/movers rules there; #535 moves nothing. 'Doe, Jane nee Smith V, PhD' gets its own fix(#535) rule at 2.2.0/2.3.0, the only baselines where it moves anything. Mutation-checked: `_release_reads_off`'s particle-ahead `return False` replaced with `pass` fails test_a_released_title_behind_a_particle_is_withdrawn. Mutation-checked: the title-stop's `if _release_reads_off(...)` replaced with `if True` fails test_the_title_stop_needs_a_name_word_left_standing. Mutation-checked: `trailing_titles`' `while k > floor:` replaced with `while k > 1:` fails test_the_floor_keeps_the_first_word_in_the_chains_count. Mutation-checked: the given-slot numeral's `tail_follows` clause dropped from `kept = (...)` fails test_a_given_slot_numeral_with_a_credential_tail_stays. Mutation-checked: `_join_takes_the_member`'s `reader is TailReader.GIVEN_SLOT` guard dropped fails test_the_bound_given_half_of_the_join_model_is_the_given_slots_alone. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
decisions.md (M2): the 2026-09-26 #535 entry, after the #538 one. It resolves the NOT TRANSPARENT HERE clause of the #533 entry and records: both halves taken together (a trailing title ends the clause, and the credential or numeral in front of it gets its stop); reader scope unchanged; the first-word floor moved into the H5 chain as a `floor` parameter, and why a clamp was measurably wrong ('Jane Doe nee King. ba'); the one span-level release check for all three stops, with the first draft's 513-of-5,198 evidence; the join rules (a title with a particle ahead declines; the P5 half is the given slot's alone, and 'abdul nee Smith Dr.' reading as 'abdul Dr.' does); the three numeral-stop readings that move with it ('Berg, abdul nee Smith V', 'Doe, Jane nee Smith V, PhD', 'Jane Doe nee V Prof.'); the bracketed '(nee Smith Prof.)' accepted; the plain suffix-word stop deferred as D5, Open: follow-up to be filed; the two generated grids as dated snapshots with the recipe in words (0 new M2 violations against d9d8049; 2,012 and 1,222 fixed; 17,854 and 11,149 remaining, every one ending the clause before a suffix-vocabulary word); and the frame costs on CPython 3.11.16 with the recompute. release_log.rst (2.4.0 Unreleased): - new bullet: a trailing title after a maiden marker (closes #535); - new bullet: a roman numeral ending a maiden clause landing in the first or middle name (#535); - #538 is folded into the Catalan link bullet rather than given one of its own: measured on the 2.3.0 wheel, both of its names already read there as the tree reads them now, the defect having existed only inside this cycle, after the link landed. That bullet now closes #397 and #538. Prose fixes, each a statement the change had made false: - release_log.rst, the #533 bullet: it said a trailing title is not transparent in a clause and the MA Prof. / Prof. MA spellings disagree; it now points at the trailing-title bullet. - _group.py, TailReader docstring: the reader was described as the acronym fork's alone; it is what every stop's release check asks, and it decides whether the walk reads the title chain at all. TRAILING's member comment names the H5 chain beside the S2 peel. - _group.py, the rules.md#S2 citation comment: the maiden walk no longer ends at trailing_start's answer wherever a trailing rule reads the clause; it ends at tail_reading's. - _group.py, the rules.md#M2 citation comment: the walk's stops were listed as a suffix word or the trailing numeral; they now include the trailing credential and, where a trailing rule reads the clause, a trailing title. - mechanisms.md#ONE-PREDICATE-PER-QUESTION: trailing_start is what M2's walk stops at only where no trailing rule reads the clause; tail_reading gains the maiden walk as a caller; the walk asks the bare peel only for that same reader. Read and left alone: AGENTS.md's Architecture, Extension Patterns and Gotchas (nothing there describes the maiden walk's stops); _group.py's module docstring (its Reads: line still matches the Policy/Lexicon fields the module consults); _pieces.py's module docstring; rules.md M2, H5, P3, P5 and M4, which the two fix commits already brought in line ('J. nee Jones Smith Prof.' reads family 'J.' by H1, which M4 assigns to H1). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Each claim below was checked by a parse run for this commit, on this tree
and, where a release is named, on that release's wheel.
rules.md
- M2: "No stop takes the first word after the marker" now names the
credential and title stops, and adds that a numeral there declines the
clause as it does written alone ('Jane Smith née V', 'Jane Doe nee V
Prof.').
- M2: "Those stops are each asked TWICE" now names the trailing numeral,
credential and title stops.
- M2: the title-release sentence is scoped to the three trailing stops
and to the whole run each gives up. The quoted invariant is left
word for word. A new Accepted row covers the plain first-suffix-word
stop, which asks no release question: 'Doe nee Smith Jr. Prof., Jane'
gives family 'Doe Prof.'. Open: #548.
- M2: the delimiter sentence gains the period-final exception. S1's
statement does not say that a trailing period makes content
suffix-shaped. M3's Accepted note says so, and _extract's
`_suffix_shaped` does it, so the sentence cites M3 for the shape and
S1 for the dropped brackets. The bracket Accepted row's "(S1)" becomes
"(M3) … (S1)" the same way, and S1 gains `interacts: M2`.
- M2: new Accepted row for the transparency boundary. Where the clause
keeps the credential, the two spellings differ: 'Doe nee Smith ba
Prof.' gives maiden 'Smith ba' and 'Doe nee Smith Prof. ba' gives
maiden 'Smith Prof. ba'. 2.3.0 read maiden 'Smith ba Prof.' and
'Smith Prof. ba'.
- M2: new Accepted row for H5's reach. 'Jane Doe nee Smith King.' gives
title 'King.' with maiden 'Smith'; 2.3.0 gave maiden 'Smith King.'.
- H5: the "not such a join" sentence gains "where the name the take
leaves reads it as a title (M2)".
decisions.md
- #535 entry: "the two spellings give one answer" is scoped to where the
clause gives the credential up. It now records the transparency
boundary, measured: 'Doe nee Smith ba/Prof.' and 'abdul nee Smith
MA/Prof.' pairs, with the report difference ('Doe, Dr. nee Smith MA
Prof.' reports nothing, '… Prof. MA' reports). It also records H5's
King. reach.
- #535 entry: the "D5" label is dropped in favour of "the plain
suffix-word stop"; its Open line is now #548.
- #535 entry: grid B's fourteen hand-written texts are listed. The count
of 11,149 remaining violations is recorded as including one detector
artifact, the quoted nickname in 'Doe, Jane nee Smith V "Bo"'. Every
other violation stops at an unambiguous suffix word written the way
the plain stop takes it; this was re-measured by stop word.
- #538 entry: the three heads of the 191-of-8,097 sweep are named, with
the comparison stated ('_run_neighbours' handed its cores vs none).
Re-measured here: 191 texts, all moving `suffix` alone. The follow-up
phrase is now "Open: #549".
- New pointer entries dated 2026-09-26 at #P3 (the separator sentence,
pointing to #538) and #H5 (the Accepted row's maiden half, pointing to
#535).
release_log.rst
- #533 bullet: the title sentence is scoped to where the clause gives
the credential up.
- #535 bullet: the MA Prof. / Prof. MA agreement is scoped the same way.
It adds the 'Doe nee Smith ba Prof.' pair and the 'Jane Doe nee Smith
King.' reach, and scopes "the clause keeps the title" to where the
title itself ends the clause.
Comments and docstrings
- _group.py: the #538 comment's "stops at the title" becomes "ends at
the link after the title … the title is the word on the link's left
and refuses".
- test_group.py: "ran on past a title it otherwise stops at" becomes
"ran on past the link it otherwise ends at".
- test_properties.py: the transparency invariant's docstring is scoped
to heads and runs where the credential is given up. All 72 of its
parses were checked to release it. The test logic is unchanged.
Differential
- corpus_rules.jsonl is rebuilt with four new example names.
- 'Doe nee Smith Jr. Prof., Jane' diffs at no baseline, so it needs no
rule; only reach grows.
- 'Jane Doe nee Smith King.' joins the title-stop rule at every
baseline: fix(#535) at 2.x, fix(#274/#535) at 1.4.0.
- 'Doe nee Smith ba Prof.' joins fix(#535) at 2.3.0. At the earlier
baselines its diff also has #342's cause ('ba' was a plain suffix
word there) and, at 2.0/2.1/1.4.0, #445's (plus #274's at 1.4.0), so
each of those gets a joint-labelled rule. This was checked against
the parent tree d9d8049, which reads maiden 'Smith ba Prof.'.
- 'Doe nee Smith Prof. ba': the parent tree reads it as HEAD does, so
#535 moves nothing. It joins "fix(#533) the maiden clause reports the
credential it keeps" at 2.3.0 and gets joint #342/#533-labelled rules
(with #445, and #274 at 1.4.0) elsewhere.
- Ledger-guard values are recorded as printed. The #535 roster sets
gain King.; 2.3.0 splits from 2.2.0 for 'Doe nee Smith ba Prof.'.
The #533 report set gains 'Doe nee Smith Prof. ba'.
- _CORPUS_CLAIMS changes:
- 1.4.0 fix(#274) reach: 91 -> 95.
- 1.4.0 comma-family and comma-precomma-family rules: 377 -> 378,
from corpus growth.
- Title-stop rules: 8 -> 9 (1.4.0), 7 -> 8 (2.0.0 and 2.1.0),
8 -> 9 (2.2.0), 8 -> 10 (2.3.0).
- 2.3.0 #533 report rule: 14 -> 15.
- Eight new one-name rules.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every reading below was checked with a parse run for this commit on the tree, and where a baseline is named, on the 2.3.0 wheel or on the parent tree d9d8049. Transparency (the #535 entry, the release bullets, rules.md#M2, and the transparency test's docstring). Two spellings can give the credential up in both and still differ. That happens where something ahead of the clause would take the title: the first-suffix-word stop ends the clause before the title check runs, and the title check then declines on its own. The measured pairs: - 'Jane van der Berg nee Smith PhD Prof.' gives title 'Prof.'; '... Prof. PhD' gives maiden 'Smith Prof.'. - 'Berg, abdul nee Smith ... ' and 'Doe, Dr. nee Smith ...' split the same way. - The bare 'Jane van der Berg Smith PhD Prof.' / '... Prof. PhD' also split, which is H5's accepted particle-chain boundary. - The parent and 2.3.0 read all of these as the tree does. A released particle with a title behind it is withdrawn: - 'Jane Doe nee Smith DO Prof.' gives maiden 'Smith DO'. - '... Prof. DO' gives suffix 'DO'. The claims are narrowed to "and nothing ahead stands to take the title", and M2 gains an Accepted pair for each shape. Numeral straight after the marker. It declines the clause only where the name left standing reads it as a suffix; otherwise the clause keeps it: - 'Dr. nee V' keeps maiden 'V' (a new M2 boundary example). - 'Doe, Dr. nee V' and 'Doe, Jane nee V, PhD' keep maiden 'V' as well. This is fixed in rules.md#M2, the #535 entry, the numeral release bullet, the _maiden_take docstring, and one case note. Unrecorded movement, now recorded. 'Doe, Jane nee V, PhD' read given 'Jane', middle 'nee V' at 2.3.0 and at the parent; it now reads maiden 'V', suffix 'PhD'. 'Doe, Jane nee V, Jr.' moves the same way. The change is recorded as a new case row (fix(#535), no shape tag), a sentence in the #535 entry, and a sentence in the numeral release bullet. #533 release bullet: "does not change that" now reads "does not change how the credential is read", and is scoped to where nothing ahead of the clause would take a title. Ledgers: the joint-cause comments on the 'Doe nee Smith ba Prof.' rules now say Three (2.0.0, 2.1.0) and Four (1.4.0) causes together. Differential. Five new rules.md example names entered corpus_rules.jsonl. Each is classified with a one-name rule, attributed against the parent tree: - 'Jane Doe nee Smith DO Prof.': - 2.x: fix(#535). - 1.4.0: fix(#274/#535). - 'Jane Doe nee Smith Prof. DO' (the parent already gave DO up and reported it): - 2.x: fix(#533/#535). - 1.4.0: fix(#274/#535), as 'Prof. MA' is labelled there. - 'Jane van der Berg nee Smith PhD Prof.': - 2.2.0: fix(#316). - 2.0.0/2.1.0: fix(#316/#399). - 1.4.0: fix(#274/#316). - 'Jane van der Berg nee Smith Prof. PhD': - 2.0.0/2.1.0: fix(#399). - 1.4.0: explained by the fix(#274) marker rule. - 2.2.0/2.3.0: no diff. - 'Dr. nee V': - 1.4.0: fix(#274). - 2.x: no diff. _CORPUS_CLAIMS is recorded as printed: - 1.4.0 fix(#274) reach: 95 -> 100. - 1.4.0 initials-per-word reach: 113 -> 115. - Seventeen new one-name claims. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…a title behind it After a family comma, the maiden walk's release check accepted a title word anywhere in the run it gave up. Assign reads that run differently: the given part's title chain runs from the END, over what its FIRST suffix pass leaves. That pass takes a class member as the credential only where every piece behind it is taken too, so a member with a title behind it is still a name word there, and the chain stops at it. The bare 'Doe, Jane Dr. MA Prof.' reads middle 'Dr.', title 'Prof.'. A clause that gave up 'Rev. MA Prof.' therefore put 'Rev.' in the current middle name. 'Doe, Jane nee Smith Rev. MA Prof.' read title 'Prof.', middle 'Rev.', suffix 'MA', maiden 'Smith', which breaks rules.md#M2's invariant. The spellings with 'King.' and 'Dr.' in place of 'Rev.' did the same. The GIVEN_SLOT branch of `_release_reads_off` now models the two passes. `chain_ok[q]` says whether the chain, walking from the end, is still running at `q`, and a title word counts as covered only there. That name now reads title 'Prof.', suffix 'MA', maiden 'Smith Rev.'. 2.3.0 and d9d8049 read maiden 'Smith Rev. MA Prof.'. The one suffix that first pass reads and `is_suffix_piece` does not is the lenient trailing numeral (#144). It counts only as the LAST piece, and only where a later numeral stop has already asked it. 'Doe, Jane nee Smith Prof. V' reads title 'Prof.', suffix 'V', maiden 'Smith', as 'Doe, Jane Prof. V' reads title 'Prof.', suffix 'V'. 2.3.0 read maiden 'Smith Prof.', suffix 'V'. Two new case rows pin both names, as does the new unit test tests/v2/pipeline/test_group.py:: test_the_given_title_chain_stops_at_a_member_with_a_title_behind. Mutation-checked in a copy of the tree, running test_group.py, test_cases.py and test_properties.py: - The `chain_ok[q]` requirement was dropped, so any title word counted as covered. 2 tests failed: the new unit test, and the case row the_given_title_chain_stops_at_a_member_with_a_title_behind. - The lenient-numeral clause was dropped. 3 tests failed: the new unit test, the case row a_lenient_numeral_leaves_with_the_title_in_front, and test_a_trailing_title_is_transparent_to_the_maiden_clause. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…sured Each claim below is stated over a measured population or as a list of examples; none is universal. Every reading was checked for this commit on the tree and on the 2.0.0, 2.1.0, 2.2.0 and 2.3.0 wheels, or on the parent tree d9d8049 where noted. Transparency (decisions.md #535 entry, release_log #535 and #533 bullets, rules.md#M2, the transparency property's docstring): - The two spellings agree over the forms the property test exercises. - They split where something in or ahead of the clause stands to take the title: a particle chain ahead of the clause or inside it, a bound-given join, or a name left with no name word. - The recorded Accepted pairs are examples, not a complete list. - M2's particle block gains the inside-the-clause pair: 'Jane Doe nee Smith do MA Prof.' gives maiden 'Smith do MA'; '... do Prof. MA' gives maiden 'Smith do', suffix 'MA'. Both have title 'Prof.'; 2.3.0 kept every word of both in the maiden name. Numeral straight after the marker (rules.md#M2, decisions.md, the release bullet, _maiden_take's docstring, two case notes): - The sentence is replaced with a non-universal one: the numeral stop is not held to the first-word floor and may decline the clause. - The examples are 'Jane Smith née V' and 'Dr. nee V'. - decisions.md adds 'Doe, J. nee V', which keeps maiden 'V' though 'Doe, J. V' reads suffix 'V'. - It also adds 'Doe nee V, Jane' and 'Smith, John, PhD nee V', which read no clause at all, as at 2.3.0. 'Doe, Jane nee V, PhD' now reads maiden 'V', which is what 2.0.0 and 2.1.0 read. 2.2.0, 2.3.0 and the parent read middle 'nee V'. The case row, decisions.md and the release bullet all say so. rules.md#M2's release sentence is scoped to where a trailing rule reads the words. The #548 Accepted row gains 'Doe nee Smith V, Jane', which gives family 'Doe V'. Before a family comma the trailing numeral's stop is made over the peel alone, with no release question. 2.2.0, 2.3.0 and the parent read the same; 2.0.0 and 2.1.0 read maiden 'Smith V'. decisions.md's #548 paragraph records it too. The #535 entry's MEASURED recipe adds grid C: five heads, ' nee ', every four-word sequence over eleven words, and '' or ', PhD'. That is 146,410 texts. Its counts are 0 new, 1,368 fixed and 15,534 remaining against d9d8049. I re-ran grids A and B on this tree: 0 / 2,012 / 17,854 and 0 / 1,222 / 11,149, unchanged. The counts are now labelled per grid, and the stop-word classification is scoped to grids A and B, which is where it was measured. Differential. Three new rules.md example names entered corpus_rules.jsonl. Each gets a one-name rule, attributed against the parent tree: - 'Jane Doe nee Smith do MA Prof.': fix(#535) at 2.x, fix(#274/#535) at 1.4.0. - 'Jane Doe nee Smith do Prof. MA': the parent already gave MA up and reported it. It gets fix(#533/#535) at 2.x and fix(#274/#535) at 1.4.0. - 'Doe nee Smith V, Jane': "fix(#424) accepted: ..." at 2.0.0 and 2.1.0. It has no diff at 1.4.0, 2.2.0 or 2.3.0. _CORPUS_CLAIMS changes, recorded as printed: - 1.4.0 fix(#274) reach: 100 -> 103. - 1.4.0 comma-family and comma-precomma-family rules: 378 -> 379. - Twelve new one-name claims. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… check does not ask decisions.md's #535 entry listed the causes of a split between the '<run> Prof.' and 'Prof. <run>' spellings as if the list were complete; after a family comma the given part's own title chain adds one (`Doe, Jane nee Smith Rev. MA Prof.` against `... Rev. Prof. MA`, as bare `Doe, Jane Rev. MA Prof.` reads middle 'Rev.'). The list now says "for example" and names it. `_release_reads_off`'s docstring said the given slot's lenient numeral is a reading the check does not model; the given-slot title chain now counts it as the first pass's suffix. The sentence says what the span check does and does not ask. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Two property tests looped over `runs` with `run`, shadowing the `run` the module imports (ruff F402). Renamed the loop variable to `tail`; the tests are otherwise unchanged. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #550 +/- ##
==========================================
+ Coverage 98.78% 98.81% +0.02%
==========================================
Files 45 45
Lines 3703 3796 +93
==========================================
+ Hits 3658 3751 +93
Misses 45 45 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
…sk the release question Reading the end of the clause through the title chain lets the link exception refuse a link it used to join. In 'Jane Doe nee Smith i DO Prof.', the DO is the trailing peel's once 'Prof.' is chained. A stop at a link gives up every word behind it, and nothing asked what those words would become. 'Jane Doe nee Smith i DO Prof.' read middle 'Doe i', family 'DO Prof.'. 'Berg, abdul nee Smith i V Prof., MD' read middle 'V'. 'Doe, Jane nee Smith i DO Prof., MD' read middle 'DO Prof.'. The walk now handles a link the exception refuses like this: - It asks `_release_reads_off` of the run it would give up. - It asks only where a trailing rule reads the clause, and only when the link is not the first word after the marker. A stop there declines the clause and gives nothing up. - Where the check fails, the clause keeps the link and walks on. Readings now: - 'Jane Doe nee Smith i DO Prof.': title 'Prof.', maiden 'Smith i DO', with a report on the kept DO. 2.3.0 read middle 'Doe i', family 'DO Prof.'. - 'Berg, abdul nee Smith i V Prof., MD': maiden 'Smith i V Prof.', suffix 'MD'. After a family comma, P6 attaches a particle trailing the given part to the family. A released title that is also particle vocabulary is exactly that, so 'Doe, Jane nee Smith St.' read family 'St. Doe'. `_join_takes_the_member` now declines a released title with the particle tag under GIVEN_SLOT. It applies to titles only: the credential DO is the given slot's own lean, which the credential stop has already asked (#533). 'Doe, Jane nee Smith St.' and 'Doe, Jane nee Smith MA St.' read maiden 'Smith St.' and 'Smith MA St.', as 2.3.0 did. rules.md#M2 gains one implementation-free sentence for each of these, with examples 'Jane Doe nee Smith i DO Prof.' and 'Doe, Jane nee Smith St.'. The decisions.md #535 entry records both and re-measures the grids against d9d8049 (2026-09-26): - Grid A: 0 new, 3,772 fixed, 16,094 both. It was 0 / 2,012 / 17,854 before this commit. - Grid C: 0 / 1,368 / 15,534. - Grid B: 0 / 1,222 / 11,149. A fuzz of 107,352 parses against e0f1a2f fixes 2,228 texts and newly violates 12. All 12 are 'Dr. nee Smith i MA|V' followed by 'Prof.', 'King.' or 'St.', with or without ', MD'. Each is the title-carrying twin of 'Dr. nee Smith i MA' / 'Dr. nee Smith i V', which read family 'i' at e0f1a2f already. That is #548's class, and the entry records it. Tests: - Case rows for the four names above, plus 'Jane Doe nee Smith MA Ph. D.' and 'Doe, Jane nee Smith MA Ph. D.' (maiden 'Smith', suffix 'MA Ph. D.'; 2.3.0 read maiden 'Smith MA'). These two pin the TRAILING reader's `"suffix" in view_tags[q]` clause, which nothing covered. - Two unit tests in tests/v2/pipeline/test_group.py, each with a contrasting control: 'i MA Prof.' gives the link up; 'Prof.', the credential 'DO' and the comma-less 'St.' still leave. - test_a_title_the_clause_gives_up_lands_in_title gains five bodies (240 texts, about 0.03s). Its recorded control, re-measured 2026-09-26 on a copy of this tree with the title stop's check replaced by `if True:`: 83 tokens across 78 of 240 texts. Mutation checks, run on a copy of this tree with --import-mode=append, over test_group.py, test_cases.py and test_properties.py: - New link release check dropped: 4 failed. They are the new unit test, both link case rows, and the title-landing property. - `j > m + run` dropped: 1 failed, test_the_marker_is_not_the_name_word_on_the_links_left. 'Doe, Jane nee i PhD Smith' already reads middle 'nee Smith' on this tree and at 2.3.0. - Particle-title clause dropped: 4 failed. They are the new unit test, both St. case rows, and the title-landing property. - `or "suffix" in view_tags[q]` dropped: 1 failed, the 'Jane Doe nee Smith MA Ph. D.' case row. Differential: 'Doe, Jane nee Smith St.' diffs at no baseline. 'Jane Doe nee Smith i DO Prof.' gets a one-name rule at every baseline. The parent read maiden 'Smith i DO Prof.', so the label is fix(#397/#535) at 2.x and fix(#274/#397/#535) at 1.4.0. _CORPUS_CLAIMS changes, recorded as printed: - 1.4.0 fix(#274): 103 -> 105. - 1.4.0 comma-family and comma-precomma-family: 379 -> 380. - Five new one-name claims. No release-log bullet. 'Doe, Jane nee Smith St.' reads as 2.3.0 did. 'Jane Doe nee Smith i DO Prof.' moves from 2.3.0 in the way the Catalan-link and trailing-title bullets already describe. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ew found stale No parse changes. The full suite passes, all five differential gates are unchanged, and frames per parse are identical to 4525770 on CPython 3.11.16 for all ten reference names. Reader dispatch: - `_release_reads_off` takes `reader: Literal[TailReader.TRAILING, TailReader.GIVEN_SLOT]` and dispatches `if GIVEN_SLOT / elif TRAILING / else assert_never`. - `_maiden_take` has three reader branches: the walk's first reading, the numeral view check, and the link release check. Each names TRAILING and GIVEN_SLOT explicitly and ends in `assert_never`. - The title stop is gated `reader is not NONE`. `chained` is empty for NONE anyway, and the gate narrows the type. - TailReader's promise, "a fourth member is a type error at every reader", now holds at every reader. mypy is clean, and test_an_unmapped_reader_is_a_loud_failure_rather_than_a_default passes. `stop < trailing` is restored in the acronym fork. The floor is an index, and the title chain's splice can leave the numeral stop in front of it: in 'Jane Doe nee V Prof.' the fork sees stop 4 against trailing 3 (instrumented in a copy of the tree). The paragraph that said the condition guarded nothing is rewritten. `tail_follows` is keyword-only and required on `_maiden_take`, and the duplicated `reader is GIVEN_SLOT` test beside it is gone: group() computes the flag from that reader. `_group_segment` keeps its default, because its test callers do not pass it. `_join_takes_the_member`: - The docstring now names all three joins, each with its condition: - P2's chain, including a particle with a title behind it. - P6's attachment, for a released particle title after a family comma. - P5's bound-given join. - The duplicated P5 rationale is gone. - The `rules.md#P5:` citation now sits on one line, and test_doc_citations collects it. - A note about a never-shipped intermediate reading is dropped. Other code comments and docstrings: - `_maiden_take`: all three stops, and a link the walk stops at, ask the release check; only the credential and title stops spare the first word. - `_maiden_take`: the numeral view check reads only `Peel.numeral` for the NONE reader. - `_maiden_take`: `peel_start` is the title-aware start for the other readers, and a `peel_start` past `trailing` is harmless because the walk never reaches `trailing`. - `_maiden_take`: a frame comparison against a baseline that was never committed is dropped. - The lone-core "keep in step" comments now say the #206 drop's copy adds `len(pieces) > 1`. - `_run_neighbours` and the core-invariant test: "the #206 drop takes a LONE core out". - `GIVEN_SLOT`'s comment names the H5 chain. - `_pieces.py`: `trailing_start` names who stops at it. `trailing_titles` documents `floor`. `credential_at_the_given_slot` and `tail_reading` name their callers instead of counting them. Tests and cases: - Case a_title_behind_a_tail_bound_numeral_keeps_both: the title stop IS asked, and declines because 'V' stays a name word and the given part's chain stops at it. - The clamp-era names are renamed and rewritten: - The case is now the_first_word_floor_holds_for_titles_too. - The unit test is now test_the_first_word_floor_holds_a_title_out_of_the_chain. - Case notes name "the #538 commit d9d8049". A note describing a never-shipped state is dropped. test_group says "at 2.2.0 and 2.3.0". - test_a_title_the_clause_gives_up_lands_in_title: the reader list is corrected. 'Jane Doe, PhD' is a tail segment and reaches NONE, and no head puts the clause before a family comma. The property holds at e0f1a2f over all 240 texts (checked). - test_a_title_first_word_counts_as_a_word also asserts that both sides take a clause whose first word is the head. Its recorded control was re-measured 2026-09-26 with the floor removed entirely (`tail_reading` handed 1): all 30 pairs fail, on the head check alone, and 0 disagree on the suffix. The earlier "14 of 30" for a clamp variant is replaced. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
`_maiden_take` asked `assert_never` at four sites, and only the first was reachable: a reader outside the enum raises there, so the other three were dead lines (codecov/patch flagged them). The walk now dispatches ONCE, exhaustively, and binds `reads` -- the reader where a trailing rule reads the clause, None where none does -- which every later site branches on, narrowed. A fourth `TailReader` member is still a type error at that dispatch, and `_release_reads_off` keeps its own two-reader dispatch, now reached by a test with a value outside the enum as `_maiden_take`'s is. No reading changes: full suite passes and `_group.py` / `_pieces.py` are at 100% line coverage. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…ade the refusal
The walk's release check at a refused link fired on every refused link,
so it kept links the name left standing reads off: `Doe, Jane nee Smith
i V` kept maiden 'Smith i' where every release gives up suffix 'i V',
`Berg, abdul nee Smith i PhD` kept 'Smith i', and `Doe, J. nee Smith i
Prof. V` swallowed the title -- 23,472 of a 411,936-parse link grid
(links i, y, e, and and their runs, 8 heads, 3 cases, 3 name orders)
moved clean readings. The check is now asked only where the link
exception, bounded by the peel over the words as WRITTEN, would have
joined the link: the refusal is the title chain's, which is the case
the check exists for ('Jane Doe nee Smith i DO Prof.' still keeps maiden
'Smith i DO'). The as-written peel is read only on a refused link.
The given-part model inside `_release_reads_off` now reads the lenient
numeral (#144) in both of assign's passes -- the literal last piece in
the first, the last one standing once the chain has taken the titles
behind it in the second -- and only where no comma part follows the
given one (`tail_follows`, now a required keyword): `Doe, Jane nee
Smith i V Prof.` gives up 'i V' and the title, as bare `Doe, Jane i V
Prof.` reads them, and `... i V Prof., PhD` keeps maiden 'Smith i V'.
Measured 2026-09-26 against the tree before the link check (ff29a18):
link grid 0 new M2 violations, 6,195 fixed; the clean readings that
still move now match how the given part reads the same run without a
clause (`DOE, JANE NEE SMITH MA I` gives up 'MA I', as `DOE, JANE MA I`
reads suffix 'MA I'). Against d9d8049: grid A (327,936) 0 new / 2,012
fixed, grid C (146,410) 0 / 1,368; the 107,352-parse fuzz keeps only
its 12 bare-title-head twins of #548's class. Full suite passes; all
five differential gates exit 0 with radar counts unchanged; rules.md#M2
and decisions.md's #535 entry say the narrower rule.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… the narrowed tree decisions.md's #535 entry quoted grid A and the fuzz as an intermediate tree measured them, before the link check was narrowed; re-stated at 0 / 2,012 / 17,854 and 588 fixed / 12 new, with the intermediate figures labelled as that tree's. One clause records that the lenient- numeral model moves the credential stop too ('Doe, Jane nee Smith MA V' gives up 'MA V', as 'Doe, Jane MA V' reads it). The 'stop < trailing' note is marked defensive: its example never reaches the class-member test, and dropping the guard moves no reading on the maiden grids. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Sep 27, 2026
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 #535. Closes #538.
What changes
A trailing title after a maiden clause is a title (#535). The maiden walk (rules.md#M2) now reads the end of a name the way assign does — the S2 peel and the H5 title chain to their fixed point — wherever a trailing rule reads the clause (no comma, the part before a suffix comma, the given part after a family comma).
Jane Doe nee Smith Prof.Smith Prof.Prof., maidenSmithJane Doe nee Smith MA Prof.Smith MA Prof.Prof., suffixMA, maidenSmithJane Doe nee Smith Prof. MASmith Prof. MAJane Doe nee Smith V Prof.Smith V Prof.Prof., suffixV, maidenSmithMary Smith née Jones Prof.Jones Prof.Prof., maidenJonesJane Doe nee King.keeps its maiden name, andJane Doe nee Prof. Dr.keepsProf.and gives upDr..Berg, abdul nee Smith Vread givenabdul Vat 2.2/2.3; it now keeps maidenSmith V.Doe, Jane nee Smith V, PhDread middleVat 2.2/2.3; it now keeps maidenSmith V, as 2.0/2.1 did. This follows assign's Issues with names in the format Last, First Middle Suffix where Suffix is I #144 rule: a numeral ending the given part is a suffix only if no comma part follows.Doe, Jane nee Smith Rev. MA Prof.reads maidenSmith Rev., not middleRev.), and a lenient numeral counts as a suffix where only chained titles stand behind it (Doe, Jane nee Smith MA Vgives upMA V, as bareDoe, Jane MA Vreads it).Jane Doe nee Smith i DO Prof.keeps maidenSmith i DOinstead of puttingDoe iin the middle name. Links refused either way stop as before (Doe, Jane nee Smith i Vgives up suffixi V).Doe, Jane nee Smith St.keeps maidenSmith St.).A delimiter core is stepped over beside a link (#538). Under
Policy(extra_suffix_delimiters=(" - ",)),Smith, John, PhD née Puig Mr. - i Solerkeeps maidenPuig Mr., as the text written without the delimiter does. This is recorded in rules.md#P3 (a separator sentence), #M2 and #R1. The defect existed only within this cycle, so the release log folds it into the Catalan-link bullet.Recorded boundaries (M2 Accepted rows, rather than code)
… Smith <run> Prof.and… Smith Prof. <run>split where something in or ahead of the clause could take the title: a particle chain, a bound-given join, a name left with no name word, or, after a family comma, the given part's own title chain stopping short of a title word.Doe nee Smith ba Prof.against… Prof. ba.Jane Doe (nee Smith Prof.)gives titleProf..Jane Doe nee Smith King.gives titleKing.. That is H5's acceptedMary Jane King.cost, now reaching into the birth name.Follow-ups filed
Dr. nee Smith PhD Prof.reads familyPhD#548: the walk's plain suffix-word stop asks no release question.Dr. nee Smith PhD Prof.gives familyPhD, andDoe nee Smith V, Janegives familyDoe V. Unchanged here.Smith, John, Puig - i Solerkeeps the-in the suffix #549: a delimiter core merged into a joined connective run stays in the suffix text.Verification
Full suite: 10208 passed. mypy and ruff are clean;
_group.pyand_pieces.pyare at 100% line coverage.Differential gate: exit 0 at all five baselines, and the radar-unclassified counts are unchanged (0/5/6/7/7). Each new corpus name is attributed to the change that moves it, checked against the baseline wheel, the parent tree and HEAD, with joint labels where more than one change moves it.
M2 invariant against the parent
d9d80492(every word after the marker ends maiden, title or suffix), over three generated grids whose recipes are in decisions.md:The remaining violations are the Should a maiden clause keep a credential it would hand to a name part?
Dr. nee Smith PhD Prof.reads familyPhD#548 class. Two more populations came from the toolkit review: a 411,936-parse link grid (linksi,y,e,andand their runs × 3 name orders) shows 0 new violations against the tree before the link check, and every clean reading that moved now matches the same run read without a clause; a 107,352-parse fuzz with titles, links andSt.shows 12 new violations against master, allDr. nee Smith i MA|V <title>twins of master's ownDr. nee Smith i MA(Should a maiden clause keep a credential it would hand to a name part?Dr. nee Smith PhD Prof.reads familyPhD#548's class).Frames per parse (py3.11): unchanged for names without a clause, +2 for a plain clause, +11 for
Jane Doe nee Smith MA, and more for a clause that now releases a title.Review: spec and quality review per commit, a design-docs review, a whole-branch review, and a
/pr-review-toolkitround (code, tests, comments). Each fix commit was reviewed again. The second passes found the given-part regression82148faafixes; the toolkit round found the link and particle-title regressions45257708fixes, and its re-review found that fix over-reaching, whichd585c01dnarrows.Commits
d9d80492fix(Should a suffix delimiter inside a maiden clause count as a name word beside a link?Smith, John, PhD née Puig Mr. - i Solerkeepsi Solerin the maiden name #538)7564a0abfix(ShouldJane Doe nee Smith Prof.readProf.as a title? The maiden name keeps it, whereJane Doe Prof.gives the title #535)b1c98995,d54fcb1d,88c9682e: decision records, release notes, and claims scoped to what holds82148faafix(ShouldJane Doe nee Smith Prof.readProf.as a title? The maiden name keeps it, whereJane Doe Prof.gives the title #535): the given part's title chain stops at a class member with a title behind it78a8d749,8ebcaf22: claims bounded to measured populationsff29a18atest: lint (a loop variable shadowed an import)45257708fix(ShouldJane Doe nee Smith Prof.readProf.as a title? The maiden name keeps it, whereJane Doe Prof.gives the title #535): a refused link and a released particle title ask the release question222a7f5d,188569carefactor: exhaustive reader dispatch (one site per function), stale commentsd585c01dfix(ShouldJane Doe nee Smith Prof.readProf.as a title? The maiden name keeps it, whereJane Doe Prof.gives the title #535): the link check only where the title chain made the refusal; the given part's lenient numeral in both passes55bc9215docs: grid counts re-measured on the final tree🤖 Generated with Claude Code