Skip to content

de Mesnil Juan should read family de Mesnil plus given Juan — the fold takes the particle run, not the rest of the name #390

Description

@derek73

rules.md#P1 states that a leading never-given particle makes the
particle run and the one name word it attaches to the family, with any
further name words read by position. The parser still folds every
remaining name word in, so the rule and the code disagree.

Behavior, all three orders

                today                       intended
GIVEN_FIRST     family='de Mesnil Juan'     family='de Mesnil'  given='Juan'
FAMILY_FIRST    family='de Mesnil Juan'     family='de Mesnil'  given='Juan'
FF_GIVEN_LAST   family='de Mesnil Juan'     family='de Mesnil'  given='Juan'

name_order deliberately has no effect on this input class, and
that is the decision rather than an oversight. A leading never-given
particle is evidence about how the name is written — the Latin-script
analogue of rules.md#W4, where a wholly-hangul name reads
family-first under every declared order because the script settles it.
decisions.md#O4 draws the line the same way: "Words no vocabulary
has claimed read by position"
, so the declared order governs the
unclaimed remainder, which is most inputs but not this one.

The alternative — particle group takes position one, name_order
names the position — is Declined at decisions.md#P1: it makes
de la Vega read given='de la Vega' with no family under
GIVEN_FIRST, breaking a corpus name and v1 parity, unless a further
rule forces a particle-headed lone group into the family, at which
point it produces this issue's reading anyway.

Where the decision lives

Decided 2026-08-16 in #386 as part of the order-precedence keystone,
recorded at decisions.md#P1 (the 2026-08-16 #364 entry). #364
asked the question and closed once it was answered; this issue is the
implementation, so the two deviates: #364 markers on rules.md#P1
have a live target.

"Takes everything" was never argued for — it was the shape of v1's
handle_non_first_name_prefix, not a decision.

Measured scope

One corpus name moves, over all 782 names of the three differential
corpora with no prefilter:

de Mesnil Garcia   family='de Mesnil Garcia'  →  family='de Mesnil', given='Garcia'

Two lookalikes do not move: de la Vega is one group start to
finish, and de Mesnil Jr. has two name words because Jr. is a
suffix.

Measurement trap, from mechanisms.md: the particle run chains
through any particle, not only the never-given ones. A detector
walking only the never-given run splits de la Vega after de la and
reports 50 false movers.

Implementation note

The fold is in nameparser/_pipeline/_post_rules.py and today reads
for i in givens + middles: _retag(tokens, i, Role.FAMILY) — every
remaining name word. It needs the particle's own group instead, which
state.pieces already carries. The DEVIATION #364 comment above it
comes out in the same diff.

Sibling

#365 is the same rule reached under FAMILY_FIRST, where the particle
strands in middle. Both close together: once grouping is
order-independent, the middle position needs no third fold site.

Verification

Metadata

Metadata

Assignees

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions