You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Three review agents on the whole PR. The order Background is narrowed
to what the code can implement -- a declared FAMILY-FIRST order
outranks the shape; an explicit GIVEN_FIRST is the default and cannot
be told apart from it -- and the two decisions.md restatements become
citations. The #470 citation is corrected (closed not-planned
2026-09-02, and it decided that prose in an Accepted clause is the
right home, not a workaround); the option-3 decline is scoped to
listings carrying the trace; the capability-claim lesson is
attributed to AGENTS.md axis 10; the zero-movers reason covers the
Turkic trigger too; the gate's unwitnessable conditions are recorded
as such.
The gate becomes a module-level helper so a reachability probe can
patch it back to the ungated condition and demand the 2.2.0 readings
return -- without it a refactor that stops the rotation reaching
family-first placement leaves all five stand-down rows green while
asserting nothing. O2's Accepted clause gains its pin; a peeled-title
parameter joins the East Slavic stand-down test. The #384 gate gets
its release-note bullet: it changes what 2.2.0 does for a supported
configuration, and corpus movement is not the house exemption.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Copy file name to clipboardExpand all lines: docs/design/rules.md
+23-22Lines changed: 23 additions & 22 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -140,17 +140,17 @@ P1. Rationale: a particle OPENING a name has the whole rest of the
140
140
and no declaration has said this one ends before the string
141
141
does. So `de Mesnil Jean` reports the whole string as the
142
142
family, which is 1.4.0's reach as well (#471, declined by
143
-
design). One name
144
-
word means one UNIT — a particle chain (P2), a conjunction join
145
-
(P3) or a bound given-name pair (P5) is taken whole or not at
146
-
all. A title does not move the opening position (P4), but a
147
-
family comma does end the question: the comma has already fixed
148
-
the surname, so there is no positional read left for an order to
149
-
narrow, and a particle opening the part AFTER it takes the rest
150
-
of that part whatever order is declared. What is left over is not read by O4's rule for a whole name,
151
-
which would make the first leftover a second family name; it is
152
-
laid out as the positions AFTER the family in the declared order,
153
-
the family slot being already filled.
143
+
design). One name word means one UNIT — a particle chain (P2),
144
+
a conjunction join (P3) or a bound given-name pair (P5) is
145
+
taken whole or not at all. A title does not move the opening
146
+
position (P4), but a family comma does end the question: the
147
+
comma has already fixed the surname, so there is no positional
148
+
read left for an order to narrow, and a particle opening the
149
+
part AFTER it takes the rest of that part whatever order is
150
+
declared. What is left over is not read by O4's rule for a
151
+
whole name, which would make the first leftover a second family
152
+
name; it is laid out as the positions AFTER the family in the
153
+
declared order, the family slot being already filled.
154
154
"de la Vega" → family="de la Vega"
155
155
"Sir de Mesnil" → family="de Mesnil"
156
156
"Mesnil de" family-first → given="de"
@@ -966,7 +966,7 @@ C2. Rationale: text beyond the recognized comma parts should be
966
966
## Name order (O)
967
967
968
968
Background: written name order varies by convention: given-first (the library's default reading), family-first, and family-first with the given name last (Vietnamese, where the person is called by the last element, given names are frequently two syllables — the given_names view stays correct wherever the internal boundary falls — and quốc ngữ is Latin script, so no native-script signal exists at all). The order is declared by the caller or a locale pack, never detected — but a few conventions leave a recognizable trace in the name itself. Patronymics are one: East Slavic names carry a father's-name derivative with distinctive endings between given and family, and Turkic names use a standalone marker word ("oglu" son-of, "qizi" daughter-of) after the father's name. Where such a trace is present and unambiguous, an opted-in parser can restore the intended reading from a family-first listing.
969
-
A declared order is a property of the DATA SOURCE rather than of any one string: the caller sets it to match how their records are written, and it governs what no vocabulary and no script license has already claimed (O4) — it outranks what the parser could infer from the shape of a particular name, and yields where a name's own script settles the order instead (W4, where a name written wholly in an East Asian script reads family-first whatever order the caller declared). Two consequences run through this document. Under the default given-first order a string opening with a never-given particle is a surname whose given name is simply absent, so the fold takes the rest of it (P1). Under a declared family-first order the caller has already said that what follows the family is not more surname — so the fold stops there, and the rotations below, whose whole job is to RESTORE the default reading from a family-first listing, have nothing left to restore. A shape neither order settles is the family comma's job, and the parser does not guess at it.
969
+
A declared order is a property of the DATA SOURCE rather than of any one string: the caller sets it to match how their records are written, and it governs what no vocabulary and no script license has already claimed (O4). A declared FAMILY-FIRST order outranks what the parser could infer from the shape of a particular name; the given-first reading is the parser's DEFAULT rather than a declaration it can tell apart from one, and the traces above are what refine it (O1, O2). And the declaration yields where a name's own script settles the order instead (W4, where a name written wholly in an East Asian script reads family-first whatever order the caller declared). Two consequences run through this document. Under the default given-first order a string opening with a never-given particle is a surname whose given name is simply absent, so the fold takes the rest of it (P1). Under a declared family-first order the caller has already said that what follows the family is not more surname — so the fold stops there, and the rotations below, whose whole job is to RESTORE the default reading from a family-first listing, have nothing left to restore. A shape neither order settles is the family comma's job, and the parser does not guess at it.
970
970
971
971
O1. Rationale: an East Slavic name written family-first still shows
972
972
its patronymic — the distinctive ending identifies which word is
@@ -987,16 +987,17 @@ O1. Rationale: an East Slavic name written family-first still shows
987
987
"Иван Петрович Абрамович" [ru] → family="Абрамович" · boundary
988
988
Accepted: under a declared family-first order the readings part
989
989
on natural-order input, and the declaration wins. A family-first
990
-
listing reads the same either way — the first example above is
991
-
that same parse with FAMILY_FIRST declared — while with East
992
-
Slavic handling active and FAMILY_FIRST declared the
993
-
natural-order Иван Петрович Сидоров reads family Иван, given
994
-
Петрович, middle Сидоров. That is the caller's declaration being
995
-
honored on input they said was written family-first, not a
996
-
defect (#384). The example grammar takes one annotation, so a
997
-
pack and an order cannot share an example line; the parse is
998
-
pinned in tests/v2/test_locales.py and decisions.md#O1 records
999
-
why options 2 and 3 were declined.
990
+
listing reads the same either way under FAMILY_FIRST — the first
991
+
example above is that same parse with FAMILY_FIRST declared,
992
+
and under FAMILY_FIRST_GIVEN_LAST the listing's given and middle
993
+
swap, so only the family is invariant — while with East Slavic
994
+
handling active and FAMILY_FIRST declared the natural-order
995
+
Иван Петрович Сидоров reads family Иван, given Петрович, middle
996
+
Сидоров. That is the caller's declaration being honored on input
997
+
they said was written family-first, not a defect (#384). No
998
+
registered example annotation combines a pack with an order, so
999
+
the parse is pinned in tests/v2/test_locales.py instead, and
1000
+
decisions.md#O1 records why options 2 and 3 were declined.
Copy file name to clipboardExpand all lines: docs/release_log.rst
+2Lines changed: 2 additions & 0 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -18,6 +18,8 @@ Release Log
18
18
19
19
- **Mark ba as an acronym that is also an ordinary name, so a bare trailing Ba keeps the family name.** ``HumanName("Anna Ba")`` gives last ``Ba`` and reports a suffix-or-name ambiguity, where 2.0.0 through 2.2.0 gave suffix ``Ba`` and no last name. The SPACED full-name form keeps the credential reading: ``John Smith BA`` still gives suffix ``BA``, now flagged, and the dotted ``John Smith B.A.`` is an unflagged suffix, the periods settling it. The COMMA forms move, and this is the marking's real cost: ``Smith, BA`` gives first ``BA``, and ``John Smith, BA`` gives first ``BA``, last ``John Smith``, where 2.0.0 through 2.2.0 gave suffix ``BA`` for both -- what ``Smith, Ed`` costs, which S2 already accepted for the other ambiguous acronyms. A bracketed or quoted ``John Smith (BA)`` falls through to nickname parsing, as the 2.0 note for ``ma``/``do`` below recorded for that pair. Write ``B.A.`` to keep the credential reading. BA is a common credential and Ba a real surname in Vietnamese and Senegalese Fula, which is the ``ma``/``Ma`` shape exactly. No corpus name moves (#342)
20
20
21
+
- **Fix the East Slavic and Turkic patronymic rotations overriding a declared family-first name order.** With ``patronymic_rules`` opted in and ``Policy(name_order=FAMILY_FIRST)``, ``Мицкевич Адам Юзеф`` gave last ``Адам`` through 2.2.0 and now gives last ``Мицкевич`` -- the reading the declaration asks for -- and ``oglu Ahmad Vali Ali`` with Turkic handling gave last ``Ahmad`` and now ``oglu``. The rotations exist to restore the given-first reading a family-first listing hides, so under a declared family-first order the declaration decides. No corpus name moves. See the ``O1`` entry of ``docs/design/decisions.md`` (closes #384)
22
+
21
23
**Additions**
22
24
23
25
- **Add the renunciate titles to the given-name title list, so a renunciate's one name is a given name.** ``HumanName("Swami Vivekananda")`` gives first ``Vivekananda`` with an empty last name, where every release since 1.4.0 gave last ``Vivekananda``; ``Guru Nanak``, ``Baba Ramdev`` and ``Lama Zopa`` move the same way, and so do the Devanagari and Bengali spellings added below. Two name words behind the title are unchanged -- ``Swami Vivekananda Saraswati`` keeps last ``Saraswati`` -- and a surname-retaining title is untouched: ``Rabbi Cohen`` still gives last ``Cohen``. ``venerable`` is deliberately not in the list, the traditions using it splitting on whether the family name survives. See the ``indic-honorifics`` entry of ``docs/design/decisions.md`` (closes #346)
0 commit comments