The leading-particle claim takes its run plus one word (#390, retry) - #394
The leading-particle claim takes its run plus one word (#390, retry)#394derek73 wants to merge 1 commit into
Conversation
Second attempt. PR #391 put the claim in assign and could not reach three routes; this one puts it in GROUPING, where the pieces are built. de la Vega Juan family='de la Vega Juan' -> family='de la Vega' given='Juan' de la Cruz Maria family='de la Cruz Maria' -> family='de la Cruz' given='Maria' de Mesnil Juan family='de Mesnil Juan' -> family='de Mesnil' given='Juan' Smith, de Mesnil family='Smith de Mesnil' -> family='Smith' given='de Mesnil' What the first attempt could not do from assign: split a chained piece ("de la Vega Juan" groups as [de][la Vega Juan], so taking two pieces takes the whole name), reach the FAMILY_COMMA branch, or survive the particle-vocabulary gaps that made "de los Santos" regress to given='Santos'. #360 fixed the third by landing first, and it holds: de los Santos still reads family='de los Santos'. P4 is AMENDED rather than worked around. A never-given particle leading the name now chains, through its run onto one word; an ambiguous one still chains nothing, so "Van Johnson" survives. A run INSIDE the name still joins greedily -- P2 is untouched -- and the asymmetry is the two positions meaning different things: "pennie von bergen wessels" is a US politician whose surname is all three words, while "de la Vega Juan" is a surname plus a given name. Identical shape, and only position tells them apart. The comma path changed deliberately. "Smith, de Mesnil" was family="Smith de Mesnil" in v1; nobody writes a comma to mean "all of this is the family name", so the comma stays the primary order signal and the post-comma run reads as given text. A v1 parity break, and the three tests that pinned the old reading now pin this one. The guard was wrong twice before it was right, both times by testing a NEGATIVE. "vocab:particle-ambiguous" not in tags passes vacuously for a conjunction-merged piece headed by "and", which swallowed "and van Buren"; and a both-vocabulary word led the chain until `not title` was added -- the trap decisions.md#P1 already records under Declined. The head token must POSITIVELY be a never-given particle. Ledger: the new diff was again absorbed by fix(suffix-routing), the fields-only catch-all whose own comment says its prose fits all four of its names. Its own rule in all three ledgers, suffix-routing back to four, claims recorded, and a _CROSS_RULE_WINNERS row pins that 'de Mesnil Garcia' keeps the #390 rule -- without it the name falls to the catch-all with the gate still at 0 unexplained. Verification: differential exit 0 at 1.4.0, 2.0.0 and 2.1.0; 3470 tests, ruff and mypy clean. Both deviates: #364 markers removed from rules.md#P1, P4's statement and examples amended, P1's implemented: now names group/assign/post_rules. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #394 +/- ##
=======================================
Coverage 98.51% 98.52%
=======================================
Files 44 44
Lines 2895 2909 +14
=======================================
+ Hits 2852 2866 +14
Misses 43 43 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
|
Closing unmerged — second attempt. It fixed the three routes #391 could not reach, but regressed four shapes ( Full findings and a corrected rework strategy recorded on #390. The key insight is Derek's: a conjunction-joined run counts as ONE word, so the bound is "extend until the group has exactly one name word" rather than "take one more piece". |
A never-given particle opening the name took every remaining word into
the family in all three orders. Under a declared family-first order it
now takes one name word and leaves the rest to the order:
FAMILY_FIRST "de Mesnil Juan" -> family 'de Mesnil',
given 'Juan'
FAMILY_FIRST_GIVEN_LAST "de la Cruz Juan Carlos" -> middle 'Juan',
given 'Carlos'
Declaring a family-first order asserts that what follows the family is
not more surname, which is the question the stopping point asks. The
DEFAULT order is unchanged and that is the accepted cost: with nothing
declared, "de Mesnil Juan" has the shape of "pennie von bergen
wessels", whose whole text is the surname. Callers who mean otherwise
write the comma, which already parses that way.
Where it lives, and why not the two sites that failed before: the fold
in post_rules. Grouping was PR #394 and assignment PR #391 -- and the
piece is the obstacle, since "de la Cruz Juan Carlos" groups as [de]
[la Cruz Juan Carlos] once the ambiguous particle chains, so the stop
must cut INSIDE a piece. post_rules can: roles are per token, and
nothing downstream reads pieces (measured -- only _assign, which runs
before it). Grouping stays order-independent.
The order is read, not re-derived. assign records the order it used on
ParseState.order and the fold keys on that; policy.name_order would
disagree with the roles assign already wrote whenever a script_orders
entry overrides it.
The run counts UNITS: a conjunction join (P3) and a bound given-name
pair (P5) each count once, so "de la Vega y Santos Juan" cannot stop
between Vega and Santos, and "abdul Rahman" cannot be halved. Both are
read off the tags -- the prefix chain has already merged the joined
piece away by then.
Measured: one differential corpus name moves, "de Mesnil Garcia",
under each family-first order; all 751 are byte-identical in the
default order. The corpus cannot see more than that -- it runs under
the default policy against 1.4.0, which has no name_order -- so the
verification that counts is the two-leftover case rows, which
mutation-checking confirms are the only thing in the suite that fails
when name_order is discarded from the leftover placement.
Closes #395
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A never-given particle opening the name took every remaining word into
the family in all three orders. Under a declared family-first order it
now takes one name word and leaves the rest to the order:
FAMILY_FIRST "de Mesnil Juan" -> family 'de Mesnil',
given 'Juan'
FAMILY_FIRST_GIVEN_LAST "de la Cruz Juan Carlos" -> middle 'Juan',
given 'Carlos'
Declaring a family-first order asserts that what follows the family is
not more surname, which is the question the stopping point asks. The
DEFAULT order is unchanged and that is the accepted cost: with nothing
declared, "de Mesnil Juan" has the shape of "pennie von bergen
wessels", whose whole text is the surname. Callers who mean otherwise
write the comma, which already parses that way.
Where it lives, and why not the two sites that failed before: the fold
in post_rules. Grouping was PR #394 and assignment PR #391 -- and the
piece is the obstacle, since "de la Cruz Juan Carlos" groups as [de]
[la Cruz Juan Carlos] once the ambiguous particle chains, so the stop
must cut INSIDE a piece. post_rules can: roles are per token, and
nothing downstream reads pieces (measured -- only _assign, which runs
before it). Grouping stays order-independent.
The order is read, not re-derived. assign records the order it used on
ParseState.order and the fold keys on that; policy.name_order would
disagree with the roles assign already wrote whenever a script_orders
entry overrides it.
The run counts UNITS: a conjunction join (P3) and a bound given-name
pair (P5) each count once, so "de la Vega y Santos Juan" cannot stop
between Vega and Santos, and "abdul Rahman" cannot be halved. Both are
read off the tags -- the prefix chain has already merged the joined
piece away by then.
Measured: one differential corpus name moves, "de Mesnil Garcia",
under each family-first order; all 751 are byte-identical in the
default order. The corpus cannot see more than that -- it runs under
the default policy against 1.4.0, which has no name_order -- so the
verification that counts is the two-leftover case rows, which
mutation-checking confirms are the only thing in the suite that fails
when name_order is discarded from the leftover placement.
Closes #395
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A never-given particle opening the name took every remaining word into
the family in all three orders. Under a declared family-first order it
now takes one name word and leaves the rest to the order:
FAMILY_FIRST "de Mesnil Juan" -> family 'de Mesnil',
given 'Juan'
FAMILY_FIRST_GIVEN_LAST "de la Cruz Juan Carlos" -> middle 'Juan',
given 'Carlos'
Declaring a family-first order asserts that what follows the family is
not more surname, which is the question the stopping point asks. The
DEFAULT order is unchanged and that is the accepted cost: with nothing
declared, "de Mesnil Juan" has the shape of "pennie von bergen
wessels", whose whole text is the surname. Callers who mean otherwise
write the comma, which already parses that way.
Where it lives, and why not the two sites that failed before: the fold
in post_rules. Grouping was PR #394 and assignment PR #391 -- and the
piece is the obstacle, since "de la Cruz Juan Carlos" groups as [de]
[la Cruz Juan Carlos] once the ambiguous particle chains, so the stop
must cut INSIDE a piece. post_rules can: roles are per token, and
nothing downstream reads pieces (measured -- only _assign, which runs
before it). Grouping stays order-independent.
The order is read, not re-derived. assign records the order it used on
ParseState.order and the fold keys on that; policy.name_order would
disagree with the roles assign already wrote whenever a script_orders
entry overrides it.
The run counts UNITS: a conjunction join (P3) and a bound given-name
pair (P5) each count once, so "de la Vega y Santos Juan" cannot stop
between Vega and Santos, and "abdul Rahman" cannot be halved. Both are
read off the tags -- the prefix chain has already merged the joined
piece away by then.
Measured: one differential corpus name moves, "de Mesnil Garcia",
under each family-first order; all 751 are byte-identical in the
default order. The corpus cannot see more than that -- it runs under
the default policy against 1.4.0, which has no name_order -- so the
verification that counts is the two-leftover case rows, which
mutation-checking confirms are the only thing in the suite that fails
when name_order is discarded from the leftover placement.
Closes #395
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
A never-given particle opening the name took every remaining word into
the family in all three orders. Under a declared family-first order it
now takes one name word and leaves the rest to the order:
FAMILY_FIRST "de Mesnil Juan" -> family 'de Mesnil',
given 'Juan'
FAMILY_FIRST_GIVEN_LAST "de la Cruz Juan Carlos" -> middle 'Juan',
given 'Carlos'
Declaring a family-first order asserts that what follows the family is
not more surname, which is the question the stopping point asks. The
DEFAULT order is unchanged and that is the accepted cost: with nothing
declared, "de Mesnil Juan" has the shape of "pennie von bergen
wessels", whose whole text is the surname. Callers who mean otherwise
write the comma, which already parses that way.
Where it lives, and why not the two sites that failed before: the fold
in post_rules. Grouping was PR #394 and assignment PR #391 -- and the
piece is the obstacle, since "de la Cruz Juan Carlos" groups as [de]
[la Cruz Juan Carlos] once the ambiguous particle chains, so the stop
must cut INSIDE a piece. post_rules can: roles are per token, and
nothing downstream reads pieces (measured -- only _assign, which runs
before it). Grouping stays order-independent.
The order is read, not re-derived. assign records the order it used on
ParseState.order and the fold keys on that; policy.name_order would
disagree with the roles assign already wrote whenever a script_orders
entry overrides it.
The run counts UNITS: a conjunction join (P3) and a bound given-name
pair (P5) each count once, so "de la Vega y Santos Juan" cannot stop
between Vega and Santos, and "abdul Rahman" cannot be halved. Both are
read off the tags -- the prefix chain has already merged the joined
piece away by then.
Measured: one differential corpus name moves, "de Mesnil Garcia",
under each family-first order; all 751 are byte-identical in the
default order. The corpus cannot see more than that -- it runs under
the default policy against 1.4.0, which has no name_order -- so the
verification that counts is the two-leftover case rows, which
mutation-checking confirms are the only thing in the suite that fails
when name_order is discarded from the leftover placement.
Closes #395
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Closes #390. Second attempt — #391 was closed unmerged with its findings recorded on the issue.
Why this one works: the claim lives in grouping
The first attempt put it in
assignand couldn't reach three routes — a chained piece can't be split there (de la Vega Juangroups as[de][la Vega Juan], so taking two pieces takes the whole name), theFAMILY_COMMAbranch is never entered, andde los Santosregressed togiven='Santos'because the particle vocabulary had gaps.#360 fixed the third by landing first, and it holds:
de los Santosstill readsfamily='de los Santos'.P4 is amended, not worked around
A never-given particle leading the name now chains, through its run onto one word. An ambiguous one still chains nothing, so
Van Johnsonsurvives. A run inside the name still joins greedily — P2 is untouched.The asymmetry is the two positions meaning different things:
Identical shape, and only position tells them apart. That's why P1 and P2 stay separate rules.
The comma path changed deliberately
Smith, de Mesnilwasfamily='Smith de Mesnil'in v1. Nobody writes a comma to mean "all of this is the family name", so the comma stays the primary order signal and the post-comma run reads as given text. A v1 parity break; the three tests that pinned the old reading now pin this one.The guard was wrong twice, both times by testing a negative
"vocab:particle-ambiguous" not in tagspasses vacuously for a conjunction-merged piece headed byand— which swallowedand van Buren. And a both-vocabulary word (st,do,freiherr) led the chain untilnot titlewas added, which is the trapdecisions.md#P1already records under Declined. The head token must positively be a never-given particle.Ledger
The new diff was again absorbed by
fix(suffix-routing), the fields-only catch-all whose own comment says its prose fits all four of its names —1.4.0exited 0 while attributingde Mesnil Garciato a rule about trailing suffixes. It gets its own rule in all three ledgers,suffix-routingis back to four, claims are recorded, and a_CROSS_RULE_WINNERSrow now pins that this name keeps the #390 rule — without it the name falls back to the catch-all with the gate still at 0 unexplained. That row is what attempt 1's review flagged as missing.Verification
tools/differentialexit 0 at 1.4.0, 2.0.0 and 2.1.0deviates: #364markers removed fromrules.md#P1; P4's statement and examples amended; P1'simplemented:now names_group.py,_assign.pyand_post_rules.pyde Mesnil Garcia, the v1 parity break Shouldde Mesnil Juanbe all surname, or familyde Mesnilplus givenJuan? #364 weighed and accepted🤖 Generated with Claude Code