Skip to content

Correct the stale prose left by the #293 vocabulary rename - #377

Merged
derek73 merged 9 commits into
masterfrom
claude/2-2-work-prioritization-7fa036
Aug 14, 2026
Merged

Correct the stale prose left by the #293 vocabulary rename#377
derek73 merged 9 commits into
masterfrom
claude/2-2-work-prioritization-7fa036

Conversation

@derek73

@derek73 derek73 commented Aug 14, 2026

Copy link
Copy Markdown
Owner

The documentation half of #356. Every claim was measured against this tree before rewriting — several had drifted further than the issue recorded, and two needed a different fix than it prescribed.

Then reviewed, which turned up six defects in this branch's own corrections; those are fixed in the last three commits and described below.

Deliberately not closing #356: the bridge/API and test-hygiene half is untouched (see the end).

Round 1 — the sweep

Site Was Measured
AGENTS.md particle note "leading token → first-name join, mid-name → last-name join" abu bakr ahmedfirst='abu bakr'; mohammed abu bakrlast='abu bakr'
AGENTS.md internal-usage guard an internal read "would consume the once-per-process warning" internal_reader.py:1 then real_caller.py:12 warnings
AGENTS.md esq paragraph SUFFIX_ACRONYMS − {esq} "changes many" only multi-dot spellings move: E.S.Q./E.S.Q 5/7 frames, Esq/Esq./ESQ/esq 0/7
AGENTS.md delimiter gotcha live 2.x guidance half the mechanism is deleted — see below
docs/customize.rst "TITLES, PARTICLES and the rest of nameparser.config are frozen" REGEXES and CAPITALIZATION_EXCEPTIONS are still dict
nameparser/config/__init__.py cites migration spec §3 the removal list is §4; §3 is the shim

Two places this diverges from the issue.

The delimiter gotcha isn't just v1 history. #356 reads it as a stale paragraph in a section not marked as such. Half is stale — CONSTANTS.regexes.parenthesis = ... raises TypeError, a custom delimiter key is refused rather than accepted as a compiled pattern, and HumanName.parse_nicknames is gone. But the pop() + assign routing advice is still correct and still the only way to move a built-in on the v1 API:

maiden_delimiters['parenthesis'] = nickname_delimiters.pop('parenthesis')
Jane (Jones) Smith    default -> nickname='Jones'
                      routed  -> maiden='Jones'

Retiring the whole bullet would have deleted working guidance, so it's split instead.

The spec-citation problem is repo-wide. Eight shipped modules cite migration spec §N / locales spec §N into gitignored docs/superpowers/. This PR fixes the wrong section number and makes that one note self-contained; the convention is left alone elsewhere, as changing it is a separate call.

Round 2 — review of the above

Six defects, five confirmed by measurement. Three are the same class of error the branch exists to fix.

Finding Fix
customize.rst said TITLES "and the rest kept the names they already had" — false for NON_FIRST_NAME_PREFIXES, BOUND_FIRST_NAMES, SUFFIX_NOT_ACRONYMS all five renames named, so the negative claim is now true
AGENTS.md "the CJK packs took it to eleven" — the eight keys came from one commit (7ee6e3a, #273), and five of eight are Western pairs attributed to #273, counts split 5 Western / 3 CJK
AGENTS.md "the bridge warns per read location" — credits the bridge with __warningregistry__'s behavior control: two files issuing a plain warnings.warn emit the same two warnings under -W once/default/module. Now credits the warnings module, and names the bridge's real contribution (no write-back caching) with a don't-optimize-it warning
customize.rst "still plain dicts" read as an exemption from the freeze see below — the measurement changed the finding
AGENTS.md "there is no parse_nicknames() left" — the name is live in _facade.py's _V1_HOOKS, where overriding it warns (#280) marked gone-as-a-method, live-as-a-hook
AGENTS.md esq single-token claim was a universal quantified over sampled frames reframed as the proof it is; the 26-frame sweep demoted to corroboration

The dict finding got worse on re-measurement. The review comment said mutating CAPITALIZATION_EXCEPTIONS was a silent no-op. Through the correct API:

v1 shared CONSTANTS    unchanged
v1 fresh Constants()   CHANGED
v2 Lexicon.default()   unchanged

Not a no-op — the inconsistent reach the freeze was introduced to remove for the word lists. The committed text says that.

Also fixed, outside #356's list

nameparser/config/suffixes.py had two comments calling SUFFIX_ACRONYMS_AMBIGUOUS "consulted only by parse_nicknames()". Same staleness class, in a shipped module. Repointed at the three real 2.x readers: _extract.py:60 (delimited-content escape), _vocab.py:127 (period gate), _classify.py:47 (vocab:suffix-ambiguous tag).

Still open on #356 (the API/test half)

  • no __all__ on particles.py / bound_given_names.py; particles.py re-exports BOUND_GIVEN_NAMES
  • __dir__ raises KeyError rather than AttributeError off the read path
  • inspect.getmembers()/help() on titles/suffixes resolves retired names and emits their warnings (confirmed incidentally — dir() on those modules warns)
  • _RETIRED_NAMES duplicates what's derivable from ALIASES; ALIASES is a positionally-indexed bare 4-tuple
  • star-import test asserts names but not values; from X import Y attribution tested for one alias of five

The natural bundle for whatever next touches nameparser/config/ — plausibly #342, which edits suffixes.py.

Verification

pytest              3197 passed, 41 skipped, 11 xfailed
ruff check          All checks passed!
mypy                Success: no issues found in 103 source files
sphinx -W           build succeeded
sphinx -b doctest   225 tests, 0 failures

Part of #356.

🤖 Generated with Claude Code

derek73 and others added 6 commits August 13, 2026 20:39
The #293 rename could sweep the constant names -- a test fails on any
internal .py that still spells PREFIXES -- but not the English around
them. "leading token -> first-name join, mid-name -> last-name join"
describes PARTICLES n BOUND_GIVEN_NAMES in the words 2.0 retired, on
the one line the particle work in this milestone reads first.

Measured, so the direction is not just renamed but right:

  abu bakr ahmed        first='abu bakr'
  mohammed abu bakr     last='abu bakr'

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The guard's stated cost -- an internal read "would also consume the
once-per-process warning and leave the real caller told nothing" --
stopped being true when the bridge moved to per-read-location warnings.
Measured on this tree:

  internal_reader.py:1  then  real_caller.py:1  ->  2 warnings

The guard is still right to exist; what it buys is attribution, not the
caller's one warning. A library read points the caller at a deprecation
inside nameparser/ they cannot act on, and kills any run under
-W error::DeprecationWarning from library code.

docs/release_log.rst already states the new semantics correctly, so this
was the last site carrying the old ones.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"SUFFIX_ACRONYMS - {esq} changes many" is unfalsifiable: every grid
confirms it, which is why it survived review. Measured over 7 frames x
7 spellings, the split is total and grid-independent:

  'E.S.Q.'  5/7 frames change      'Esq'   0/7
  'E.S.Q'   5/7 frames change      'Esq.'  0/7
                                   'ESQ'   0/7
                                   'esq'   0/7

So the checkable claim is which spellings move, not how many rows do.
This grid returns a fourth distinct count (10) for the three the
paragraph already refuses to choose between, which is the argument for
its no-count rule rather than against it.

Relevant now because #342 removes an entry from this same set and will
calibrate its blast radius against this paragraph.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
#356 reads this bullet as v1 history sitting in a live section. Half of
it is: the mechanism the sentinel existed FOR is gone.

  CONSTANTS.regexes.parenthesis = ...   -> TypeError
  nickname_delimiters['brackets'] = re.compile(...)  -> TypeError
  HumanName.parse_nicknames             -> AttributeError

But the other half is current 2.x guidance, so retiring the whole
paragraph would delete advice that still works. Measured:

  maiden_delimiters['parenthesis'] = nickname_delimiters.pop('parenthesis')
  Jane (Jones) Smith   default -> nickname='Jones'
                       routed  -> maiden='Jones'

Also drops the "three default keys" count, which the CJK delimiter packs
took to eleven -- the same failure as the esq line one commit back, so
the replacement says why not to write a count rather than a new one.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
"TITLES, PARTICLES and the rest of nameparser.config are frozen"
overstates the 2.2 headline change in the file a user reads to act on
it. Two public members are still mutable dicts:

  regexes.REGEXES                        dict
  capitalization.CAPITALIZATION_EXCEPTIONS  dict

The following sentence then said "those constants were renamed",
naming TITLES and PARTICLES immediately before it -- TITLES was never
renamed. Split into what froze and what got a new name, and name the
two renames instead of gesturing at them.

These .rst files aren't covered by CI, so this ships silently if 2.2
goes out without it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The maintainer note pointed at the migration spec's §3 for the 3.0
removal list. §3 is "The Constants shim"; the list is in §4, "Warning
inventory & removal schedule".

Both citations resolve to docs/superpowers/, which .gitignore:31
excludes -- so an outside reader could check neither the section number
nor the claim it supports. The note now carries the claim inline (the
list says "nameparser.config in its entirety" while its parenthetical
names only the five shim exports), leaving the section number as
corroboration rather than the only source.

Leaves the "migration spec §N" convention alone in the other seven
shipped modules that use it; that's a convention call, not housekeeping.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@derek73 derek73 added this to the v2.2 milestone Aug 14, 2026
@derek73 derek73 added the docs Documentation fixes and updates label Aug 14, 2026
@derek73 derek73 self-assigned this Aug 14, 2026
@codecov

codecov Bot commented Aug 14, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 98.51%. Comparing base (54c1894) to head (3038cd4).

Additional details and impacted files
@@           Coverage Diff           @@
##           master     #377   +/-   ##
=======================================
  Coverage   98.51%   98.51%           
=======================================
  Files          44       44           
  Lines        2895     2895           
=======================================
  Hits         2852     2852           
  Misses         43       43           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

derek73 and others added 3 commits August 13, 2026 22:07
Two review findings on the previous commit, both in the paragraph it
rewrote.

"TITLES and the rest kept the names they already had" is false for
three of the five renames -- NON_FIRST_NAME_PREFIXES, BOUND_FIRST_NAMES
and SUFFIX_NOT_ACRONYMS all moved. Naming two and generalizing over the
rest was worse than the vague sentence it replaced, which at least
claimed nothing specific. All five are named now, so "names outside
that list are unchanged" is true.

"REGEXES and CAPITALIZATION_EXCEPTIONS are still plain dicts" sat in a
paragraph about why runtime mutation does not work and read as an
exemption. Measured, mutating the module dict:

  v1 shared CONSTANTS   unchanged
  v1 fresh Constants()  CHANGED
  v2 Lexicon.default()  unchanged

That is not a no-op, it is the inconsistent reach the freeze was
introduced to remove -- worth stating rather than implying either way.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Review findings on the three AGENTS.md commits below.

Layer attribution (the #293 bullet): "the bridge warns per read
location" credits the bridge with the warnings module's behavior. A
control -- two files issuing an identical plain warnings.warn -- emits
the same two warnings under -W once, -W default and -W module. Per-
location suppression is __warningregistry__; what the bridge actually
contributes is not caching the resolved value, which config/_deprecated.py
already explains and this file now matches.

Delimiter provenance: the eight added keys came from one commit,
7ee6e3a (#273), not from locale packs, and five of the eight are
Western typographic pairs rather than CJK. Replacing a stale count with
a wrong attribution is the same failure in a new coat.

parse_nicknames: gone as a method, still live in _facade.py's _V1_HOOKS,
where overriding it in a v1 subclass warns (#280). "There is no
parse_nicknames() left" invited deleting a diagnostic.

Also reframes the esq single-token claim as the proof it is -- each
spelling normalizes into the word branch regardless of the acronym set
-- rather than a universal quantified over sampled frames, which is the
support shape this file warns about two sections earlier.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Both comments on this set said it was consulted only by
parse_nicknames(), which has not existed as a method since the M11 swap.
Same staleness class as the rest of this branch, but in a shipped module
rather than in docs -- surfaced by the review of the delimiter bullet,
not by #356's list.

The 2.x readers:

  _pipeline/_extract.py:60   the delimited-content escape
  _pipeline/_vocab.py:127    the period gate for bare recognition
  _pipeline/_classify.py:47  the vocab:suffix-ambiguous tag

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@derek73
derek73 merged commit 5320a42 into master Aug 14, 2026
11 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

docs Documentation fixes and updates

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant