Removing a word from particles_ambiguous — the customization docs/customize.rst documents — changes no field at all under a non-default name order:
van LISTED default given='van' family='Gogh' amb=[particle-or-given]
van REMOVED default given='' family='van Gogh' amb=[] <- knob applies
van LISTED FAMILY_FIRST given='Gogh' family='van' amb=[particle-or-given]
van REMOVED FAMILY_FIRST given='Gogh' family='van' amb=[] <- identical fields
Only the ambiguity report moves. The same asymmetry read from the other end: a name opening with a never-given particle stops folding into the surname.
default FAMILY_FIRST
de Mesnil family='de Mesnil' family='de', given='Mesnil'
de la Vega family='de la Vega' family='de', given='la Vega'
Compare "Juan de la Vega", where the chain does survive the order change and only the destination flips (family='de la Vega' -> given='de la Vega') — that case works as intended.
Cause
nameparser/_pipeline/_post_rules.py:80-92 keys on roles, not position:
if len(givens) == 1 and (middles or families):
gtags = tokens[givens[0]].tags
if "particle" in gtags and "vocab:particle-ambiguous" not in gtags:
It fires only when the leading particle was assigned GIVEN, which happens under given-first ordering. Under FAMILY_FIRST that token is already FAMILY and the following piece is GIVEN, so the tag test inspects the wrong token and declines. The rule's intent — "a leading never-given particle means the whole name is a surname" — is order-agnostic; its implementation is not.
The decision, not just the fix
Worth settling before touching it: what should name_order=FAMILY_FIRST mean for a Latin-script name opening with a particle? Reading "de Mesnil" as family de plus given Mesnil is defensible if the caller has declared family-first and means it. If the answer is "the particle still chains", the rule needs to key on position rather than role.
Docs that must move with the behaviour
Both written in #354, both accurate today, both stale the moment this changes:
nameparser/config/particles.py — the PARTICLES docstring asserts Policy(name_order=FAMILY_FIRST) gives family de, given Mesnil
AGENTS.md:136 — the same claim
#358 deliberately scoped its documentation sweep to the default order and asserts nothing about non-default orders for never-given particles, precisely so it would not bless this output.
Found while sweeping #355. Any fix needs a differential run — it changes parse output for a shipped policy.
Removing a word from
particles_ambiguous— the customizationdocs/customize.rstdocuments — changes no field at all under a non-default name order:Only the ambiguity report moves. The same asymmetry read from the other end: a name opening with a never-given particle stops folding into the surname.
Compare
"Juan de la Vega", where the chain does survive the order change and only the destination flips (family='de la Vega'->given='de la Vega') — that case works as intended.Cause
nameparser/_pipeline/_post_rules.py:80-92keys on roles, not position:It fires only when the leading particle was assigned
GIVEN, which happens under given-first ordering. UnderFAMILY_FIRSTthat token is alreadyFAMILYand the following piece isGIVEN, so the tag test inspects the wrong token and declines. The rule's intent — "a leading never-given particle means the whole name is a surname" — is order-agnostic; its implementation is not.The decision, not just the fix
Worth settling before touching it: what should
name_order=FAMILY_FIRSTmean for a Latin-script name opening with a particle? Reading"de Mesnil"as familydeplus givenMesnilis defensible if the caller has declared family-first and means it. If the answer is "the particle still chains", the rule needs to key on position rather than role.Docs that must move with the behaviour
Both written in #354, both accurate today, both stale the moment this changes:
nameparser/config/particles.py— thePARTICLESdocstring assertsPolicy(name_order=FAMILY_FIRST)gives familyde, givenMesnilAGENTS.md:136— the same claim#358 deliberately scoped its documentation sweep to the default order and asserts nothing about non-default orders for never-given particles, precisely so it would not bless this output.
Found while sweeping #355. Any fix needs a differential run — it changes parse output for a shipped policy.