diff --git a/docs/release_log.rst b/docs/release_log.rst
index b34b4c7..2d31ba4 100644
--- a/docs/release_log.rst
+++ b/docs/release_log.rst
@@ -2,44 +2,60 @@ Release Log
===========
* 2.1.0 - Unreleased
+ nameparser 2.1 makes East Asian names work without configuration.
+ A name written wholly in Han or hangul, or in kanji with kana, is
+ read family-first. An unspaced Korean name is split against the
+ census surname list. CJK honorifics are recognized whether they
+ are spaced or written against the name. The two conventions that
+ need you to declare a language, Han segmentation and kana-aware
+ division, ship as the opt-in ``locales.ZH`` and ``locales.JA``
+ packs. See :ref:`east-asian-names` for how it fits together, and
+ :doc:`customize` for the switches that turn it off.
+
+ Most of this is **default-on**, deliberately: wherever nameparser
+ acts unasked, the script itself settles the convention and no
+ language detection is involved. Latin-script names are unaffected.
+ To restore 2.0's reading of CJK text, use ``Parser(policy=Policy(
+ script_orders=(), segment_scripts=frozenset()))``.
+
**East Asian name support**
- - Add the Chinese locale pack ``locales.ZH`` — opt-in Han segmentation for unspaced names like ``毛泽东``, with the surname vocabulary it needs. A pack rather than a default because a Chinese surname list corrupts the Japanese names written in the same characters (``高橋一郎`` would split ``高`` + ``橋一郎``); Japanese data goes through ``locales.JA`` and its segmenter instead. It sets no name order, since native-script Han already reads family-first without it (#271)
- - Add ``Lexicon.surnames``, ``Policy.script_orders``, ``Policy.segment_scripts``, the ``Script`` enum and the ``DEFAULT_SCRIPT_ORDERS`` constant to the public API. This is the first behavior nameparser keys on the script a name is written in; it is allowed only where the script itself settles a convention, never as a proxy for guessing the language (#271)
- - Add ``Lexicon.honorific_tails``, the vocabulary the glued-honorific peel matches: entries that may be split off the END of a name token, matched longest-first. Deliberately a separate, narrower set than the spaced honorific vocabulary — a glued tail has no token boundary to lean on — and every entry is also a ``suffix_words`` entry, since the peeled piece is claimed by ordinary suffix classification. That subset rule is enforced, so extend both fields in the one call — ``Lexicon.default().add(suffix_words={"ちゃま"}, honorific_tails={"ちゃま"})``; adding to ``honorific_tails`` alone raises ``ValueError`` naming the orphan (#308)
- - Add ``AmbiguityKind.SEGMENTATION``, reported when a surname split had a vocabulary-supported alternative: ``"남궁민수"`` is 남궁 + 민수 by the compound surname but 남 + 궁민수 by the single-syllable one, and longest-match had to pick. A name with only one possible split decided nothing and reports nothing (#271)
- - Add the Japanese locale pack ``locales.JA`` and the segmenter factory ``locales.ja_segmenter()``, which together divide an unspaced Japanese name: ``parser_for(locales.JA, segmenter=locales.ja_segmenter())`` reads ``山田太郎`` as family ``山田``, given ``太郎``. The two halves are separate because no surname list can do this job — family and given names draw on the same kanji and the reading, not the spelling, decides most divisions — so the pack activates the stage and a third-party divider performs it. ``ja_segmenter()`` wraps `namedivider-python `_, installed with the new ``nameparser[ja]`` extra; the core stays dependency-free, and ``ja_segmenter(gbdt=True)`` selects namedivider's more accurate gradient-boosted model, which downloads its data on first use. With both packs registered, ``locales.available()`` is now ``('ja', 'ru', 'tr_az', 'zh')`` (closes #272)
- - Add a construction-time ``UserWarning`` for the segmenterless activation gap: ``parser_for(locales.JA)`` without ``segmenter=`` used to build a parser that behaved exactly like a working one minus the division feature — nothing could ever divide the activated scripts, and nothing said so. Building such a parser now warns, naming the dead scripts and the ``segmenter=locales.ja_segmenter()`` call to pass (with the ``nameparser[ja]`` install hint). Any configured segmenter or covering surname vocabulary silences it, so the default parser and the ``zh`` pack never warn — while a from-scratch lexicon with no hangul surnames now warns under the default policy's hangul activation, with ``Policy(segment_scripts=())`` as the offered deactivation
- - Add ``Segmentation`` and the ``Segmenter`` type alias to the public API, plus the keyword-only ``Parser(segmenter=...)`` hook they describe: any callable from a token's text to a ``Segmentation`` (the interior offsets to cut at, and a confidence) or ``None`` to decline. It is consulted only for scripts listed in ``Policy.segment_scripts``, and only where the surname vocabulary declined first, so ``parser_for(locales.ZH, locales.JA, segmenter=...)`` composes — a listed Chinese surname wins, the segmenter takes the rest. Read that composition with the zh pack's own warning still attached: vocabulary-first means a Japanese kanji name opening on a listed Chinese surname never reaches the segmenter, so ``高橋一郎`` still splits ``高`` + ``橋一郎`` under the stack exactly as it does under ``locales.ZH`` alone. The two packs are alternatives, one per corpus; stack them only for genuinely mixed data that accepts that trade (#272)
+ - Add the Chinese locale pack ``locales.ZH``: opt-in Han segmentation for unspaced names like ``毛泽东``, with the surname vocabulary it needs. A pack rather than a default because a Chinese surname list corrupts Japanese names written in the same characters (``高橋一郎`` would split ``高`` + ``橋一郎``). Japanese data goes through ``locales.JA`` instead. See :doc:`locales` (#271)
+ - Add ``Lexicon.surnames``, ``Policy.script_orders``, ``Policy.segment_scripts``, the ``Script`` enum and the ``DEFAULT_SCRIPT_ORDERS`` constant to the public API. This is the first behavior nameparser keys on the script a name is written in, allowed only where the script itself settles a convention and never as a proxy for guessing the language. See :doc:`modules` (#271)
+ - Add ``Lexicon.honorific_tails``, the vocabulary the glued-honorific peel matches: entries that may be split off the end of a name token. It is a narrower set than the spaced honorific vocabulary, since a glued tail has no token boundary to lean on, and every entry must also be a ``suffix_words`` entry. Extend both in one call, or adding to ``honorific_tails`` alone raises ``ValueError``. See :doc:`customize` (#308)
+ - Add ``AmbiguityKind.SEGMENTATION``, reported when a surname split had a vocabulary-supported alternative: ``"남궁민수"`` is 남궁 + 민수 by the compound surname but 남 + 궁민수 by the single-syllable one, and longest-match had to pick. A name with only one possible split reports nothing (#271)
+ - Add the Japanese locale pack ``locales.JA`` and the segmenter factory ``locales.ja_segmenter()``, which together divide an unspaced Japanese name: ``parser_for(locales.JA, segmenter=locales.ja_segmenter())`` reads ``山田太郎`` as family ``山田``, given ``太郎``. They are separate because no surname list can do this job, so the pack activates the stage and a third-party divider performs it. ``ja_segmenter()`` wraps `namedivider-python `_, installed with the new ``nameparser[ja]`` extra; the core stays dependency-free. ``locales.available()`` is now ``('ja', 'ru', 'tr_az', 'zh')``. See :doc:`locales` (closes #272)
+ - Add ``Segmentation`` and the ``Segmenter`` type alias to the public API, plus the keyword-only ``Parser(segmenter=...)`` hook: any callable from a token's text to a ``Segmentation`` or to ``None`` to decline. It is consulted only for scripts in ``Policy.segment_scripts``, and only where the surname vocabulary declined first. Note what that ordering means when packs are stacked: a Japanese name opening on a listed Chinese surname never reaches the segmenter, so ``高橋一郎`` still splits ``高`` + ``橋一郎``. The packs are alternatives, one per corpus. See :ref:`segmenter-contract` (#272)
+ - Add a construction-time ``UserWarning`` when a parser activates segmentation for scripts nothing can divide. ``parser_for(locales.JA)`` without ``segmenter=`` used to build a parser that behaved like a working one minus the feature, silently. It now names the dead scripts and the call to pass. Any configured segmenter or covering surname vocabulary silences it, so the default parser and the ``zh`` pack never warn. A from-scratch lexicon with no hangul surnames warns under the default policy, with ``Policy(segment_scripts=())`` offered as the deactivation. See :ref:`east-asian-names`
- Add the ``Script`` members ``HIRAGANA`` and ``KATAKANA``. Two members rather than one ``KANA`` because the parser treats them differently: hiragana never transcribes a foreign name, while a wholly-katakana name usually is one (#272)
**Breaking Changes**
- - Change the pickle compatibility of the 2.0 API's ``Policy`` and ``Lexicon``: the new fields change the field layout their guarded ``__setstate__`` checks, so a pickle written by 2.0.0 raises ``ValueError`` naming the missing fields instead of loading. Re-pickle after upgrading. ``HumanName`` pickles are unaffected — the facade pickles v1-shaped component state, not these objects
- - Change the pickle compatibility of ``Parser`` in the same way and for the same reason: the new ``segmenter`` field changes the layout its guarded ``__setstate__`` checks, so a ``Parser`` pickled by 2.0.x raises ``ValueError`` naming the missing field rather than loading silently with the field absent. That guard is the design, not a regression — re-pickle after upgrading. A ``Parser`` carrying a segmenter pickles only if that segmenter does, which a module-level function does and a closure or lambda does not (#272)
- - Change one thing about parse totality: ``parse()`` still never raises on any input, but a user-supplied ``Parser(segmenter=...)`` runs inside the parse and its own exceptions propagate rather than being absorbed. A failure there is a bug in your callable, not a fact about the name, and hiding it would only make it harder to find (#272)
+ - Change the pickle compatibility of ``Policy`` and ``Lexicon``: the new fields change the field layout their guarded ``__setstate__`` checks, so a pickle written by 2.0.0 raises ``ValueError`` naming the missing fields instead of loading. Re-pickle after upgrading. ``HumanName`` pickles are unaffected, since the facade pickles v1-shaped component state rather than these objects
+ - Change the pickle compatibility of ``Parser`` the same way, for the new ``segmenter`` field. Re-pickle after upgrading. A ``Parser`` carrying a segmenter pickles only if that segmenter does, which a module-level function does and a closure or lambda does not (#272)
+ - Change one thing about parse totality: ``parse()`` still never raises on any input, but a user-supplied ``Parser(segmenter=...)`` runs inside the parse and its own exceptions propagate rather than being absorbed. A failure there is a bug in your callable, not a fact about the name (#272)
**Behavior Changes**
- - Fix names written wholly in Han or Hangul parsing given-first: native-script CJK now reads family-first by default, through the new ``Policy.script_orders`` table, so ``"毛 泽东"`` gives family ``毛`` where 1.x gave family ``泽东``. A name that is a single unspaced token moves the same way — ``"毛泽东"`` and ``"山田太郎"`` now land in ``family``/``last`` where 1.x put them in ``given``/``first``, with the string itself untouched, which makes it the easiest form of this change to miss — a lone token renders the same whichever field holds it, whereas the spaced form does show up in the output (``str(HumanName("毛 泽东"))`` is now ``"泽东 毛"``). No language detection is involved: Chinese and Japanese both write the family name first in native script, so the script settles the order without anyone having to know which language it is. Latin-script and mixed-script names are never affected, and an explicit comma still wins. **Default-on: changes parse output for wholly-CJK names**, through ``HumanName`` as well as the 2.0 API (closes #271)
- - Fix unspaced Korean names not splitting: the census surname list now ships as default vocabulary (``Lexicon.surnames``) with hangul segmentation on by default (``Policy.segment_scripts``), so ``"김민준"`` parses family ``김``, given ``민준`` where 1.x returned the whole string as ``first``. Rendering follows the split, so ``str(HumanName("김민준"))`` is now ``"민준 김"`` where 1.x echoed the input back unchanged. Nothing but Korean is written in hangul and its surnames are a closed census set, which is what makes the split safe as a default rather than a pack. **Default-on**, and it reaches ``HumanName`` too. ``Policy(segment_scripts=())`` turns the split off; ``Policy(script_orders={})`` separately restores the positional reading; clearing both restores 2.0 behavior exactly (#271)
- - Fix Japanese names carrying kana parsing given-first: the family-first rule above extends to any name whose characters stay within kanji and kana while carrying at least one kana character, so ``"高橋 みなみ"`` gives family ``高橋`` and ``"山田 エミ"`` family ``山田`` where 1.x read both the other way round, and a lone such token (``"高橋みなみ"``, ``"みなみ"``) lands in ``family``/``last`` where 1.x put it in ``given``/``first``. The reasoning is the one hangul already uses: hiragana never transcribes a foreign name, and a transcription is kana ALONE, so kanji-plus-kana is a Japanese person's name written in Japanese order. A name written **wholly in katakana** is deliberately excluded and stays positional — it is predominantly a transcribed foreign name (``"マイケル ジャクソン"``) already in given-first order. **Default-on: changes parse output for kana-bearing Japanese names**, through ``HumanName`` as well as the 2.0 API, and the spaced forms change what the name renders as (``str(HumanName("高橋 みなみ"))`` is now ``"みなみ 高橋"``). ``Policy(script_orders={})`` clears this entry along with the Han and Hangul ones (#272)
- - Fix names containing 〆 (U+3006, the shime mark that opens Japanese surnames like 〆木 and 〆谷) parsing given-first: the script classifier now counts 〆 as Han, extending the 々 entry the table already carries, and going a step further than it — 々 is Script=Han and merely outside the ideograph blocks, while 〆 is Script=Common — so these names take the East Asian family-first reading like any other wholly-Han name. ``Policy(script_orders={})`` restores the positional reading for these names exactly as for other wholly-Han names (#303)
- - Fix the katakana middle dot ``・`` (U+30FB, and its halfwidth twin U+FF65) being read as part of a name rather than as the divider it is: it now separates tokens exactly as a space does. A transcribed foreign name therefore divides into its parts and, being wholly katakana, keeps its source order — ``"マイケル・ジャクソン"`` gives given ``マイケル``, family ``ジャクソン``, where 1.x left the whole string in ``first`` — while a kanji pair written the same way takes the family-first rule (``"高橋・一郎"`` → family ``高橋``). Native Japanese names never contain this character and no other script's names use it, so the separation is unconditional, which also means it is **not** covered by the two policy opt-outs. Rendering follows, the way the Korean split's does: the dot comes back as a space, so ``str(HumanName("マイケル・ジャクソン"))`` is now ``"マイケル ジャクソン"``, and that reaches delimited content too — the nickname in ``"山田 太郎 (マイケル・ジャクソン)"`` renders ``"マイケル ジャクソン"``. The Chinese interpunct ``·`` is not an unconditional separator like these two: U+00B7 is also the Catalan punt volat and appears inside legitimate names (``Gal·la``), so it divides only between classified-script characters — the transcription treatment it marks is #298's (#272)
- - Fix 间隔号-divided transcriptions parsing as one unsplit token: U+00B7 — the interpunct Chinese text divides a transcribed foreign name with, ``威廉·莎士比亚`` for William Shakespeare — is now a token separator between characters of a classified script, and a name it divides keeps its source order and is never segmented: the dot is the transcription marker, playing the role pure katakana plays in the kana license. It divides ONLY between classified-script characters, so the Catalan punt volat interior to names like ``Gal·la`` is untouched. The Japanese nakaguro is deliberately not a transcription marker — ``高橋・一郎`` is roster formatting, 姓・名, and keeps its family-first reading — so a transcription typed with the wrong dot (``威廉・莎士比亚``) reads by the convention of the codepoint it was typed with; like the spaced form, only the Chinese dot rescues it. Rendering stays space-joined (``str(HumanName("威廉·莎士比亚"))`` is ``"威廉 莎士比亚"``); a custom ``string_format`` such as ``"{first}·{last}"`` reinstates the dot (#298)
- - Fix spaced CJK postnominal honorifics parsing as name parts: 씨, 박사, 선생님, 교수님, 군, 양 (Korean — standardly written as their own token), 先生, 女士, 小姐, 博士, 教授 (Chinese, with 先生/博士/教授 shared with Japanese), and 様, 氏 (Japanese) now route to ``suffix``, so ``王小明 先生`` reads family ``王小明`` where the family-first default had confidently made 先生 the given name. Whole-token matching, which also reaches a glued surname+honorific token, since segmentation splits off the surname first (``김씨`` reads family 김, suffix 씨). The glued forms whole-token matching cannot reach are handled by the peel described below (closes #307)
- - Fix glued CJK honorifics parsing as part of the name: an honorific written against the name — ``田中さん``, ``山田太郎様``, ``김민준씨``, ``김민준님``, ``王小明先生`` — is now split off the end of the last name token and routed to ``suffix``, where it had been swallowed by the name (the whole of ``田中さん`` was the family name; ``김민준씨`` gave given 민준씨). The peeled name then goes through the ordinary machinery, so the Korean split still happens (``김민준씨`` → family 김, given 민준, suffix 씨) and the ``田中さん`` case stops misreading as a kana-licensed composite. Only entries that can never END a name peel — 씨, 님, 박사, 박사님, 선생님, 교수님, さん, さま, くん, ちゃん, 様, 先生, 教授, 女士, 小姐 — while 양, 군, 氏, 博士 and 殿 are recognized in their spaced form only, because 김지양 is a given name, 田中博士 is Tanaka Hiroshi as readily as Doctor Tanaka, and some ninety Japanese surnames end in 殿 (鵜殿, 真殿); 君 is recognized in neither form, since 王君 is a complete Chinese name, though its kana spelling くん peels. Seven entries are new vocabulary in this change (さん, さま, くん, ちゃん, 殿, 님, 박사님), so their spaced forms route to ``suffix`` too (``田中 さん``, ``田中 殿``, ``김민준 님``, ``김민준 박사님``). 박사님 closes a gap in the shipped set rather than opening new ground: 선생님 and 교수님 shipped in 2.1 without it, so ``김민준박사님`` stranded 박사 in the given name and the spaced ``김민준 박사님`` came back as two suffixes for one honorific. Exactly one honorific peels off a token, and every entry is a whole honorific rather than a part of one. A token that is nothing but an honorific is no longer taken apart either — ``선생님`` and ``박사`` now stay whole where hangul segmentation had split them 선 + 생님 and 박 + 사, since 선 and 박 are listed surnames — which is **default-on** in its own right, hangul segmentation being a default. A configured segmenter benefits twice over: it is handed the name without the honorific, and the honorific the peel just cut off does not then look to it like a boundary the writer drew — so ``parser_for(locales.JA, segmenter=ja_segmenter())`` reads ``山田太郎様`` as family 山田, given 太郎, suffix 様. Worth knowing before you upgrade: that exemption is what makes a GLUED honorific stop protecting a name from division, so a family name written alone with one — ``田中さん`` — now divides the way bare ``田中`` already did (family 田, given 中, suffix さん). It is exactly and only the peeled tail that is exempt. A SPACED honorific is a token boundary its writer typed, and anything standing beside a name calls the segmenter off, so the name is left as written: ``田中 さん`` and ``佐藤 氏`` keep family 田中 and 佐藤 under the pack — the division the pack gives them without this change, whichever field the honorific itself lands in. That is the conservative reading rather than a claim about intent: a spaced honorific cannot be told apart from a spaced given name by position, and counting it as one keeps four real surnames whole (``佐藤 氏``, ``田中 様``, ``鈴木 先生``, ``中村 教授``) at the price of the one division it then declines to make (``山田太郎 様``). Writing the honorific spaced is therefore an opt-out in its own right on the SEGMENTER path, alongside declining the pack or the segmenter. It is no lever where the VOCABULARY divides the name, the two spellings agreeing exactly there — ``김민준 씨`` and ``김민준씨`` both give family 김, given 민준, suffix 씨, as do ``王小明 先生`` and ``王小明先生`` under the Chinese pack — and Korean data has no pack to decline either, hangul segmentation being on by default. **Default-on: changes parse output for glued CJK honorific forms**, through ``HumanName`` as well as the 2.0 API (closes #308)
- - Fix a comma or a 间隔号 stopping the glued-honorific peel: an honorific written against the name is now split off and routed to ``suffix``, so ``김, 민준씨`` gives family 김, given 민준, suffix 씨 — the same as the spaced ``김 민준씨`` — and likewise ``田中, 太郎さん``, which also matches its spaced form. ``田中さん, PhD`` and ``威廉·莎士比亚さん`` peel too; the first of those does *not* otherwise match its spaced form, since ``田中さん PhD`` leaves PhD in ``suffix`` beside さん while after a comma it reads as a ``title`` — where the credential lands is the comma's business, not the peel's. Previously each of these left the honorific inside the name. A comma no longer switches the peel off; what it does now is say which runs of the name to look in, and those are the two around a family comma, an honorific being as often glued to the given name as to the family. Anything past those two runs is out of reach, which is the one limit worth knowing: ``김, 민준 지훈씨`` peels, while ``김, 민준, 지훈씨`` (a third run) and ``김,, 민준씨`` (a doubled comma, which puts the name in a later run) do not. The second of those two runs counts only where it is name text, which is a question the parser asks rather than reads off the comma — see the next entry. The 间隔号 does not switch the peel off either. Both marks say where a name divides into surname and given, and an honorific is not part of the name in either reading. The surname split still stands down for both, unchanged — a comma still means the writer said where the family name ends, and the 间隔号 still marks a transcription. ``田中さん, 太郎`` is unaffected, because the honorific there is not at the end of the name: 太郎 is. **Default-on**, and it reaches ``HumanName`` too (closes #312)
- - Fix a glued honorific staying inside the name when the whole post-comma remainder is a credential: ``田中さん, V.`` and ``田中さん, Ph. D.`` now give up さん to ``suffix`` the way ``田中さん, PhD`` already did, and so do ``김민준씨, V.``, ``王小明先生, Ph. D.`` and ``山田太郎様, Jr. V.``. The peel looks in the two runs around a family comma (the entry above), and it had been taking the second of those for name text on the strength of the comma alone. A comma does not say that much: the suffix-comma reading also wants more than one word ahead of the comma, so a one-word name followed by nothing but credentials reads as a family comma anyway — which is exactly the shape ``田中さん, V.`` has. The scan then walked into the credentials, took ``V.`` for the honorific's site, found no honorific on the end of it and abandoned the peel without a word. Whether a post-comma run is credentials is now asked with the same test that decides the comma structure itself, and where the answer is yes the run is declined and the scan stays with the name. Declining takes a second condition, because that test is not independent of the peel: every honorific tail is also a suffix word, so a glued honorific is itself part of the evidence that the run it sits in is suffix-shaped. The run is therefore declined only where the part *before* the comma offers a peel site of its own — otherwise declining would throw away the only site there is, and ``이, J.씨`` would lose its given name, where it in fact still reads given ``J.``, family ``이``, suffix ``씨``. Where both parts offer a site the decline stands and the person's own honorific is the one peeled: ``김민준씨, J.씨`` now gives family 김민준 with ``씨, J.씨`` in ``suffix``, where before it peeled the 씨 off the junk ``J.씨`` behind the comma and left 김민준씨 whole. One credential in three spellings, one answer — from the *peel*: where the credential itself lands is the comma's business as before and still differs by spelling, ``PhD`` reading as a ``title``, ``V.`` as a ``given``, and ``Ph. D.`` joining さん in ``suffix``. ``Policy(lenient_comma_suffixes=False)`` keeps the old reading for the initial-shaped credentials the knob is about — with it set, ``V.``, ``V`` and ``I`` are a given name again and the family name is the whole ``田中さん`` — but it is no blanket freeze of the old behavior: ``田中さん, Ph. D.`` peels under the knob too, the credential pair merging to a form the strict test accepts either way. Nothing Latin-script moves, since nothing there had an honorific to peel, and no name that peeled before stops peeling — that second one is what the site condition above buys, and it is measured rather than reasoned. What did change wherever the run *is* declined, answer or no answer, is which runs the peel reads: ``田中さん, PhD`` and ``田中さん, 様.`` reached さん before by stepping over the post-comma token the scan had walked onto, and reach it now by never looking at that run — ``様.`` being a listed honorific rather than a credential, and the second one this name has no use for. **Default-on**, and it reaches ``HumanName`` too (closes #319)
- - Fix an ASCII period after a CJK honorific stopping it being recognized: ``씨.``, ``様.``, ``氏.``, ``님.``, ``군.``, ``양.`` and ``殿.`` now route to ``suffix`` like their periodless spellings, where the trailing period had left them inside the name — the family name in ``"김민준 씨."``, the given name in ``"김민준, 씨."``. The cause was v1's initial regex, ``^(\w\.|[A-Z])?$`` (``REGEXES["initial"]``, still public v1 API), whose ``\w`` is Unicode-aware and so matched a hangul syllable or a Han ideograph as readily as a letter; the strict suffix test applies that as a veto (``V.`` in ``"John V. Smith"`` is a middle initial, not roman five), and a veto written for Latin was being asked of scripts it was never about. The cost ran past the honorific itself: because the vetoed token read as name text, the glued-honorific peel's scan back for its site stopped at it instead of stepping over it, took it as the site, found no honorific at the end of it and gave up — so ``"田中さん 様."`` kept ``さん`` inside the name, reading given ``田中さん`` and family ``様.``, while ``"田中さん 様"`` peeled it. The comma form ``"田中さん, 様."`` reached the same scan when this was written; since the #319 entry above it no longer does — its post-comma run is now declined as suffix-shaped before the scan begins, so ``様.`` gets to ``suffix`` through classification rather than by being stepped over. Measured against 1.4.0, ``"김민준, 씨."`` and ``"田中さん, 様."`` were returning exactly what 1.x returns, so the honorific work earlier in this release had a hole in it wherever the honorific was written with a period. An initial is a single LETTER standing in for a name, and Han ideographs, hangul syllables and kana are morphemes and syllables rather than letters, so the veto now asks its question only of the scripts where it means something. Alphabets keep their initials untouched — ``"А. С. Пушкин"``, ``"م. الفارسي"`` and ``"Ա. Խաչատրյան"`` are unaffected, and so is the Ukrainian conjunction entry below, where a punctuated ``Й.`` still outranks the conjunction ``й``. The public ``initial`` tag follows the same line: ``씨.`` no longer carries it. Read ``period`` strictly here: the fix is scoped to the ASCII full stop U+002E, because that is the only period ``_normalize`` strips. The fullwidth U+FF0E and the ideographic U+3002 (with its halfwidth twin U+FF61) — the stops a CJK writer is likelier to type — leave the honorific unmatchable by the vocabulary lookup, which runs before the veto is ever consulted, so ``"김민준 씨."`` still reads the honorific as the family name. That is a separate, still-open gap in ``_normalize`` rather than in the veto: those spellings parse identically before and after this change, and widening the strip is follow-up work. **Default-on**, and it reaches ``HumanName`` too (#320)
- - Fix NFD-decomposed input missing the East Asian defaults entirely: script classification now normalizes to NFC before deciding, so a Korean or Japanese name typed on macOS — where decomposed text is routine — gets the same order rule as its composed twin, which it silently did not before. Segmentation MATCHING deliberately stays raw, so an unspaced NFD hangul name is ordered correctly but not split, rather than being split in the wrong place. One gotcha worth stating plainly: parse output preserves the encoding it was given, so for NFD input ``name.family == "김"`` is ``False`` even though it is the same name — compare NFC-normalized text when comparing across encodings (#272)
- - Fix the Ukrainian conjunction ``й`` not joining the pieces around it: it is the euphonic alternate of ``і``, the two chosen by the surrounding vowel and consonant rather than by meaning (``"Олесь і Олена"`` but ``"Марія й Петро"``), so real Ukrainian data carries both spellings and shipping only ``і`` recognized just one of them. ``"Олесь й Олена Коваленки"`` now gives given ``"Олесь й Олена"`` where the ``й`` previously landed in ``middle``. Same treatment as the ``и``/``і`` entries added in 2.0.0, single-letter carve-out included: the conjunction joins only once the name has enough pieces, and a punctuated initial still wins, so ``"Й. Сліпий"`` is unaffected. Raised in a comment on #267
- - Add the Japanese maiden-name marker ``旧姓`` to the default vocabulary (#309): ``"山田花子 旧姓 佐藤"`` now gives family ``山田花子`` and maiden ``佐藤``, where 1.4.0 left the marker in the name (first ``山田花子``, middle ``旧姓``, last ``佐藤``). It sits beside the Cyrillic ``урожд.`` and German ``geb.`` entries rather than in ``locales.JA``, on the rule that admitted those: a native-script marker cannot collide with a Latin-script name and matching is whole-token, so it is safe as a default and needs no my-data-is-Japanese declaration -- it can only ever match Han text. **Scope worth knowing before you rely on it:** matching is whole-token, so the marker has to *be* a token — which for Japanese, written without spaces between words, means something has to divide it from the name it marks. A space does, and so does a configured delimiter, the brackets being masked out of the text before it is tokenized: ``"山田(旧姓 佐藤)"`` needs no space in front of ``旧姓``. So the bare ``"山田花子 旧姓 佐藤"`` qualifies, and so does the bracketed ``"山田 花子(旧姓 佐藤)"`` under ``Policy(maiden_delimiters=...)``, once the entry below closed #329. What divides nothing is the fullwidth colon that the spelling Japanese more often uses puts after the marker: ``"山田(旧姓:佐藤)"`` still returns maiden ``"旧姓:佐藤"`` with the marker and its colon attached. Not because delimited content escapes classification — a marker is tagged wherever it is a token — but because that colon is no separator, so marker and name arrive as a single token with nothing to divide; the wholly unspaced ``"山田花子(旧姓佐藤)"`` reads as one token for the same reason. Peeling a marker off the head of a token is #317's job. **Default-on**, and it reaches ``HumanName`` too (#309)
- - Fix a maiden marker inside bracketed content staying in the ``maiden`` value: where a delimiter pair is routed to ``maiden`` by ``Policy(maiden_delimiters=...)``, a marker word at the head of the bracketed clause is now dropped the way it has always been dropped in the bare form, so ``"Jane Smith (née Jones)"`` gives maiden ``Jones`` where it gave ``née Jones`` before — the same answer as the unbracketed ``"Jane Smith née Jones"``. The Japanese spelling moves with it: ``"山田 花子(旧姓 佐藤)"`` gives maiden ``佐藤``. Nothing else about either name changes — the marker leaves the ``maiden`` value without turning up anywhere else, the way it already vanished from the bare form, and every other field reads exactly as before. ``maiden`` is in fact the only field that ever differs, which is measured rather than reasoned. The cause was never that the marker went unrecognized — a maiden marker is classified wherever it stands as a token, inside brackets as anywhere else. What was missing was the *consuming*: bracketed content is claimed as a region before the name is tokenized at all, and the tokens cut inside it are born already holding the maiden role, which keeps them out of the grouped runs the marker rule walks, so that rule could not reach a marker sitting in one. The new pass is scoped to the delimited clause, keyed on the extraction spans rather than on a maiden token's neighbours, and both halves of that are load-bearing. A maiden role is not proof of extraction — the bare rule sets it too — so a neighbour test would fire on the bare path and eat the surname out of ``"Jane Smith nee Nee Jones"``, which still gives maiden ``Nee Jones``. And separate clauses are separate content: ``"Jane Smith (Nee) (Jones)"`` also still gives maiden ``Nee Jones``, because the drop takes a clause's first token only where the clause holds more than one — ``Nee`` is a real surname (Irish Ní/Nee, and a Chinese romanization), so a one-token clause is a name rather than a marker, and ``"Jane Smith (née)"`` keeps its ``née`` for the same reason. Each clause loses its own leading marker, so ``"Jane Smith (née Jones) (geb Braun)"`` gives maiden ``Jones Braun``. One edge deserves naming because what it changes is a name's truthiness rather than a field: where a maiden clause is the entire input and everything in it besides the marker is punctuation, dropping the marker leaves nothing carrying an alphanumeric character, and 2.0's standing rule that such input is not a name empties the parse — ``"(née —)"`` returned maiden ``"née —"`` and is now falsy throughout. That follows from treating the marker as structural, the same reading under which ``"(-)"`` has always come back empty, and it takes a name that is nothing but the clause: ``"Jane Smith (née —)"`` still gives given ``Jane``, family ``Smith``, maiden ``—``. Scope before you count on it: ``Policy.maiden_delimiters`` is **empty by default**, so this reaches only callers who have opted a pair into it — under the default policy brackets route to ``nickname`` and nothing here applies. ``HumanName`` reaches it only through the v1 bucket *move* — ``maiden_delimiters['parenthesis'] = nickname_delimiters.pop('parenthesis')`` — since v1 precedence gives a pair held in both buckets to ``nickname``, and the facade preserves that; with the move, ``HumanName("Jane Smith (née Jones)")`` gives maiden ``Jones`` as well. And the agreement with the bare form is not total: the Japanese form written with a fullwidth colon, ``"山田(旧姓:佐藤)"``, still returns maiden ``"旧姓:佐藤"``, since the colon leaves marker and name a single token with nothing to separate — that one wants the head-peel #317 tracks, and the entry above says the rest of it (closes #329)
+ - Fix names written wholly in Han or hangul parsing given-first. Native-script CJK now reads family-first through the new ``Policy.script_orders`` table, so ``"毛 泽东"`` gives family ``毛`` where 1.x gave family ``泽东``. A single unspaced token moves the same way, which is the easiest form of this to miss: ``"毛泽东"`` renders identically whichever field holds it, while the spaced form shows the change (``str(HumanName("毛 泽东"))`` is now ``"泽东 毛"``). No language detection is involved, and an explicit comma still wins. **Default-on**, and it reaches ``HumanName``. See :ref:`east-asian-names` (closes #271)
+ - Fix unspaced Korean names not splitting. The census surname list now ships as default vocabulary with hangul segmentation on by default, so ``"김민준"`` parses family ``김``, given ``민준`` where 1.x returned the whole string as ``first``. Rendering follows the split. Nothing but Korean is written in hangul and its surnames are a closed set, which is what makes this safe as a default rather than a pack. **Default-on**. See :doc:`customize` for the two switches (#271)
+ - Fix Japanese names carrying kana parsing given-first. The family-first rule extends to any name whose characters stay within kanji and kana while carrying at least one kana character, so ``"高橋 みなみ"`` gives family ``高橋``. The reasoning is the one hangul already uses: hiragana never transcribes a foreign name, and a transcription is kana alone, so kanji-plus-kana is a Japanese name in Japanese order. A name written **wholly in katakana** is excluded and stays positional, being predominantly a transcribed foreign name. **Default-on**. See :ref:`east-asian-names` (#272)
+ - Fix names containing 〆 (U+3006, the shime mark opening Japanese surnames like 〆木) parsing given-first. The script classifier now counts it as Han, so these names take the family-first reading like any other wholly-Han name (#303)
+ - Fix the katakana middle dot ``・`` (U+30FB, and its halfwidth twin U+FF65) being read as part of a name rather than as a divider. It now separates tokens exactly as a space does, so ``"マイケル・ジャクソン"`` gives given ``マイケル``, family ``ジャクソン`` where 1.x left the whole string in ``first``. Native Japanese names never contain this character, so the separation is unconditional and the policy opt-outs do **not** cover it. Rendering returns the dot as a space (#272)
+ - Fix 间隔号-divided transcriptions parsing as one unsplit token. U+00B7, the interpunct Chinese text divides a transcribed foreign name with, is now a token separator between characters of a classified script, and a name it divides keeps its source order and is never segmented. It divides only between classified-script characters, so the Catalan punt volat in ``Gal·la`` is untouched. The Japanese nakaguro is deliberately not a transcription marker, so ``高橋・一郎`` keeps its family-first reading (#298)
+ - Fix spaced CJK postnominal honorifics parsing as name parts. 씨, 박사, 선생님, 교수님, 군, 양, 先生, 女士, 小姐, 博士, 教授, 様 and 氏 now route to ``suffix``, so ``王小明 先生`` reads family ``王小明`` where the family-first default had made 先生 the given name. See :ref:`east-asian-names` (closes #307)
+ - Fix glued CJK honorifics parsing as part of the name. ``田中さん``, ``김민준씨`` and ``王小明先生`` now split the honorific off the end of the name into ``suffix``. Previously it stayed in the name: ``田中さん`` was entirely the family name, and ``김민준씨`` gave given 민준씨. The peel runs before the name is split or ordered, so ``김민준씨`` still divides into family 김, given 민준. Only entries that can never end a name peel; 양, 군, 氏, 博士 and 殿 are recognized in their spaced form only, since 김지양 is a given name and some ninety Japanese surnames end in 殿. **Default-on**, and a lone family name written with a glued honorific now divides where it did not. See :ref:`east-asian-names` for the full set and :doc:`customize` for the off-switch (closes #308)
+ - Fix a comma or a 间隔号 stopping the glued-honorific peel. ``김, 민준씨`` now gives family 김, given 민준, suffix 씨, the same as the spaced ``김 민준씨``, and likewise ``田中, 太郎さん``. Previously each left the honorific inside the name. Both marks say where a name divides into surname and given, and an honorific is not part of the name in either reading. What a comma does instead is say which runs to look in: the two around a family comma. Anything past those is out of reach, so ``김, 민준 지훈씨`` peels while ``김, 민준, 지훈씨`` does not. **Default-on**. See :ref:`east-asian-names` (closes #312)
+ - Fix a glued honorific staying inside the name when the whole post-comma remainder is a credential. ``田中さん, V.`` and ``田中さん, Ph. D.`` now give up さん to ``suffix`` the way ``田中さん, PhD`` already did. The peel had been taking the post-comma run for name text on the strength of the comma alone, walking into the credentials and abandoning the peel there. That run is now tested with the same rule that decides the comma structure, and declined where it is credentials, provided the part before the comma offers a peel site of its own. Where the credential itself lands is still the comma's business and still differs by spelling. **Default-on** (closes #319)
+ - Fix an ASCII period after a CJK honorific stopping it being recognized. ``씨.``, ``様.``, ``氏.``, ``님.``, ``군.``, ``양.`` and ``殿.`` now route to ``suffix`` like their periodless spellings, where the trailing period had left them inside the name. The cause was v1's initial regex, whose ``\w`` is Unicode-aware and matched a hangul syllable or Han ideograph as readily as a letter; a veto written for Latin was being asked of scripts it was never about. Alphabets keep their initials untouched, and ``"А. С. Пушкин"`` is unaffected. Read *period* strictly: only the ASCII full stop is covered, so ``"김민준 씨."`` written with the fullwidth stop still reads the honorific as the family name. **Default-on** (#320)
+ - Fix NFD-decomposed input missing the East Asian defaults entirely. Script classification now normalizes to NFC before deciding, so a Korean or Japanese name typed on macOS, where decomposed text is routine, gets the same order rule as its composed twin. Segmentation matching deliberately stays raw, so an unspaced NFD hangul name is ordered correctly but not split, rather than being split in the wrong place. One gotcha: parse output preserves the encoding it was given, so for NFD input ``name.family == "김"`` is ``False`` even though it is the same name. Compare NFC-normalized text when comparing across encodings. See :ref:`east-asian-names` (#272)
+ - Fix the Ukrainian conjunction ``й`` not joining the pieces around it. It is the euphonic alternate of ``і``, chosen by the surrounding sounds rather than by meaning, so real Ukrainian data carries both spellings. ``"Олесь й Олена Коваленки"`` now gives given ``"Олесь й Олена"`` where the ``й`` previously landed in ``middle``. Same treatment as the ``и``/``і`` entries added in 2.0.0: the conjunction joins only once the name has enough pieces, and a punctuated initial still wins, so ``"Й. Сліпий"`` is unaffected. Raised in a comment on #267
+ - Add the Japanese maiden-name marker ``旧姓`` to the default vocabulary. ``"山田花子 旧姓 佐藤"`` now gives family ``山田花子`` and maiden ``佐藤``, where 1.4.0 left the marker in the name. It sits beside the Cyrillic ``урожд.`` and German ``geb.`` entries rather than in ``locales.JA``, on the rule that admitted those: a native-script marker cannot collide with a Latin-script name, so it is safe as a default. Matching is whole-token, so the marker has to *be* a token, which for Japanese means a space or a configured delimiter must divide it from the name. The fullwidth colon does not, so ``"山田(旧姓:佐藤)"`` still returns maiden ``"旧姓:佐藤"``; that one wants the head-peel #317 tracks. **Default-on**. See :doc:`customize` (#309)
+ - Fix a maiden marker inside bracketed content staying in the ``maiden`` value. Where a delimiter pair is routed to ``maiden`` by ``Policy(maiden_delimiters=...)``, a marker at the head of the clause is now dropped the way it always has been in the bare form, so ``"Jane Smith (née Jones)"`` gives maiden ``Jones``, the same answer as the unbracketed spelling. Each clause loses its own leading marker, and only where the clause holds more than one token, so ``"Jane Smith (Nee) (Jones)"`` still gives maiden ``Nee Jones`` (``Nee`` is a real surname). Scope before you count on it: ``Policy.maiden_delimiters`` is **empty by default**, so under the default policy brackets route to ``nickname`` and none of this applies. See :doc:`customize` (closes #329)
**Documentation**
- - Correct the documented scope of the period-abbreviation title rule. It was described as applying to "a leading word", which was never true of any comma form: the rule runs at the front of the part that carries the given name, which after a family comma is the part *after* the comma — so ``"Morse, Det. Insp. Jane"`` gives title ``Det. Insp.``. Behavior is unchanged and matches 1.4.0; only the description was wrong. The examples now use real abbreviations absent from the shipped vocabulary (``Det. Insp.``) rather than whole words carrying a stray period, so they demonstrate the structural inference instead of merely surviving it
+ - Correct the documented scope of the period-abbreviation title rule. It was described as applying to "a leading word", which was never true of any comma form: the rule runs at the front of the part that carries the given name, which after a family comma is the part *after* the comma, so ``"Morse, Det. Insp. Jane"`` gives title ``Det. Insp.``. Behavior is unchanged and matches 1.4.0; only the description was wrong
* 2.0.0 - July 27, 2026
diff --git a/docs/usage.rst b/docs/usage.rst
index 36b56f1..781a4c2 100644
--- a/docs/usage.rst
+++ b/docs/usage.rst
@@ -268,20 +268,47 @@ dependency installed with the ``ja`` extra:
Both halves are required, and they do different jobs: the ``ja`` pack
activates division for Japanese text, and the segmenter performs it.
+``ja_segmenter()`` wraps namedivider's ``BasicNameDivider``, which
+reads data bundled in the installed package;
+``ja_segmenter(gbdt=True)`` selects its gradient-boosted divider
+instead, which is more accurate and downloads its model and surname
+files from the network on first use, worth knowing before deploying it
+somewhere sandboxed or air-gapped.
+
Forgetting the segmenter is loud: building the parser emits a
``UserWarning`` naming the scripts that could never divide and the
call to pass, because the misconfigured parser would otherwise behave
exactly like a working one minus the feature. The same check guards
-any configuration whose activated scripts nothing can serve — a
+any configuration whose activated scripts nothing can serve. A
from-scratch lexicon with no hangul surnames warns under the default
policy, and ``Policy(segment_scripts=())`` is the deactivation the
message offers.
-``ja_segmenter()`` wraps namedivider's ``BasicNameDivider``, which
-reads data bundled in the installed package;
-``ja_segmenter(gbdt=True)`` selects its gradient-boosted divider
-instead, which is more accurate and downloads its model and surname
-files from the network on first use — worth knowing before deploying
-it somewhere sandboxed or air-gapped.
+
+Decomposed text
+^^^^^^^^^^^^^^^
+
+Korean and Japanese text is sometimes stored decomposed, with a
+syllable held as its separate jamo rather than as one codepoint. macOS
+filenames are the common source. Everything above works on decomposed
+input: script classification normalizes to NFC before deciding, so a
+decomposed name gets the same order rule as its composed twin.
+
+Splitting is the exception. An unspaced decomposed hangul name is
+ordered correctly but not split, because surname matching runs against
+the text as given and a decomposed name matches no entry in the census
+list. That is the deliberate choice: being unsplit is recoverable,
+whereas splitting in the wrong place is not.
+
+One consequence is worth stating outright, because it looks like a
+bug. Parse output preserves the encoding it was given, so a field from
+a decomposed name is decomposed too, and comparing it against a
+composed literal fails even where the parse was correct::
+
+ decomposed = unicodedata.normalize("NFD", "김 민준")
+ parse(decomposed).family == "김" # False
+ unicodedata.normalize("NFC", parse(decomposed).family) # '김'
+
+Normalize both sides before comparing across encodings.
Boundaries
~~~~~~~~~~~