A tussenvoegsel after a family comma joins the family name - #403
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #403 +/- ##
=======================================
Coverage 98.53% 98.54%
=======================================
Files 44 44
Lines 2942 2954 +12
=======================================
+ Hits 2899 2911 +12
Misses 43 43 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
derek73
force-pushed
the
fix/379-tussenvoegsel-attaches
branch
4 times, most recently
from
August 19, 2026 04:41
4e929cf to
ef1bd9f
Compare
derek73
force-pushed
the
fix/379-tussenvoegsel-attaches
branch
from
August 19, 2026 04:47
ef1bd9f to
61e160e
Compare
"Beethoven, Ludwig van" is how "Ludwig van Beethoven" is filed in a
Dutch or Belgian alphabetized listing, and the trailing particle run
was read as a middle name. It now attaches to the family the comma has
already named and renders before it, so the listing and the plain
spelling agree:
Beethoven, Ludwig van -> given 'Ludwig', family 'van Beethoven'
Berg, Jan van der -> given 'Jan', family 'van der Berg'
rules.md#P6 has stated this since the 2026-08-16 keystone; both its
deviates: #379 markers come out, and its pointer moves from tracked:
to implemented:. The derived views move with the parse, which closes
the half of #130 that asked for them (family_particles 'van',
family_base 'Beethoven', where both were empty and 'Beethoven').
Keyed on the token's VOCABULARY, not its assigned role: that is what
gives P6's stated precedence over S2 its effect, since assign reads a
trailing `vd`/`mc`/`do` as a post-nominal. "Berg, Jan vd" therefore
reads family 'vd Berg' where 1.4.0 and 2.1 alike gave suffix 'vd',
which closes #380 on the same shape. The words-to-spare guard is a
piece test rather than a count, so "Nguyen, Van" keeps its only given
word.
One of 751 corpus names moves at all three baselines, and needed a
ledger rule in each. The ledger guards forced the regex to narrow: the
first draft reused the neighbouring comma rules' bare-comma pattern,
which claimed 215 names and reached two protected exclusions; the
member `des` came out too, being broad enough to match the name "Des".
Closes #379
Closes #380
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
derek73
force-pushed
the
fix/379-tussenvoegsel-attaches
branch
from
August 19, 2026 04:48
61e160e to
0251a00
Compare
derek73
added a commit
that referenced
this pull request
Aug 19, 2026
Price every candidate fix before choosing one, by simulating each in-process rather than implementing it. Recorded because the practice paid twice and its absence cost once, all in one session. #397 and #400 both turned on it: the obvious fix in #400 -- add the word to the list -- provably changed nothing on the common shape, and the two vocabulary alternatives each lost a credential spelling. The winner was a fifth option the wordlist framing had hidden, and none of that was visible until the candidates ran side by side. The counterexample is #403's ledger `fields`, widened on one reviewer's finding without pricing what else the widening claimed. It took {family, suffix} from a neighbouring rule and two more shapes from UNEXPLAINED -- diffs in which the rule's own subject does not move -- and had to be reverted. Filed here rather than in AGENTS.md because AGENTS.md's own rule sends a new reusable pattern to mechanisms.md, and it already points at this section twice. Refs #400, #403 Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
derek73
added a commit
that referenced
this pull request
Aug 19, 2026
From this session's practice, kept terse because AGENTS.md is loaded every session: - review the fix commit too -- second-round passes on #398, #400 and #403 each found defects in the first round's fixes - check the PR description before merging; a review that moves behavior leaves it stale, and a stale body reads as authoritative - a scripted multi-edit that asserts as it goes discards everything when a late pattern misses, silently, since prose edits fail no test mechanisms.md's "check the receiver" field note gains the other half: ask what the old behavior was CONCEALING. #379's attachment removed the input a test used to build an all-particle middle name (#402), and #400's reserve fix exposed the count shape #397 names. Co-Authored-By: Claude Opus 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.
"Beethoven, Ludwig van"is how"Ludwig van Beethoven"is filed in a Dutch or Belgian alphabetized listing. The trailing particle run was read as a middle name; it now attaches to the family the comma has already named and renders before it.rules.md#P6has stated this since the 2026-08-16 keystone, so the design was settled before the code — all threedeviates:markers come out and P6's pointer moves fromtracked:toimplemented:. The derived views move with the parse:family_particles='van',family_base='Beethoven', where they were''and'Beethoven'. (#130 asked for those views and shipped them in 1.3.0; what was wrong until now was the values they reported for this listing.)Read this first: an accepted cost
A Vietnamese name written in the Dutch listing convention loses its given name.
Nguyễn Thị Vân is family-middle-given, so
Vânis the given name.The cost is narrower than it first looks:
vânis not particle vocabulary, so the correctly spelled name never reaches this rule.It is the ASCII transliteration that collides, and there the two traditions write the same string with no signal to separate them.
The colliding spelling has a format that reads correctly, and it is one order, not both —
FAMILY_FIRSTstill sends the given name tomiddle:No ambiguity is reported for the collision, which
rules.md#A1calls for — filed as #405, since emitting one needspost_rulesadded to the stage-ownership map and that is a decision rather than a fix.That is also a retroactive argument for scoping the attachment to the comma form. Had #365's implied-comma reading been taken — treating a comma-less family-first name as if the comma were missing — Vietnamese would have had no working format at all.
P6 now carries this as an
Accepted:block with executable examples, andtussenvoegsel_takes_the_vietnamese_readingpins it so it cannot move without someone deciding to move it. P6's rationale previously claimed the words-to-spare test adjudicated this; it does not, and that sentence is gone.Two guards, both P6's
Words to spare. A name whose only given word is the particle keeps it —
"Nguyen, Van"still readsgiven='Van'. The test asks for a given word specifically:_NAME_ROLESwould includeFAMILY, and P1's fold runs earlier in the same function and retags all of segment 1 toFAMILY, so the wider test passed on family text P1 had just produced and hoisted the particle in front of a base it never preceded.Precedence over S2. The rule keys on the token's vocabulary, not its assigned role.
vd,mcanddoare the three words in both vocabularies;assignreads a trailingvdormcas a post-nominal, so those two need the override —"Berg, Jan vd"readsfamily='vd Berg'where 1.4.0 and 2.1 alike gavesuffix='vd', which closes #380.dois in the ambiguous acronym half, which already left it a name word, so it attaches by the plain rule.Differential
One of 751 corpus names moves —
"Vega, Juan de la"— at all three baselines, so each ledger needed a rule. Unlike the two preceding PRs the harness is informative here: this changes default-order output.The ledger guards did real work. The first draft reused the neighbouring comma rules' bare-comma regex, which claimed 215 names and reached two protected exclusions; the guards refused both. A member
desalso had to come out — not because it matched a name, but because it is not inPARTICLESat all and the text it reached was "Designated". Review then found the narrowed regex still had a leading.*, so a Cyrillic comma name whose diff had another cause classified asfix(#379); it is now Latin-anchored over the whole name.fieldsgainedsuffix, because the #380 half moves a token out of suffix and the rule could not otherwise classify the shape it is named for.Found in review, fixed here
"Smith, de Mesnil van"gavefamily='van Smith de Mesnil'. 312 generated inputs hit it."Berg, Jan van Jr."and"Berg, Jan van, Jr."parsed two ways on nothing but a comma. The backward walk now steps over a trailing piece holding no name — unless it is itself particle vocabulary, sincevdarrives suffix-roled and is the run.MIDDLEarm of the guard was dead — 0 witnesses in 8,862 generated parses — and P6 says "given" only, so it is narrowed to match."Vega, Santa de la","Berg, Van der"and"Nguyen, Van Le"still produce one), adecisions.mdline stating as shipped the predicate three lines below it calls the defect, thedesaccount, the#130closes,doinheritingvd's adjudication, and aparitylabel on a row 1.4.0 does not agree with.Related, not fixed here
"Vega, Juan de la"was the inputtests/test_initials.pyused to build an all-particle middle name. That shape survives on other inputs, so the guard is repointed at"Nguyen, Van Le"rather than deleted. Whether such a middle should exist is #402, and #404 proposes the principle that subsumes it: a particle with no name word to attach to is not doing particle work, so it is positioned and rendered as ordinary text.3557 tests pass, mypy clean, 0 unexplained at all three baselines.
Closes #379
Closes #380
🤖 Generated with Claude Code