Correct the stale prose left by the #293 vocabulary rename - #377
Merged
Conversation
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>
Codecov Report✅ All modified and coverable lines are covered by tests. 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. 🚀 New features to boost your workflow:
|
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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
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
AGENTS.mdparticle noteabu bakr ahmed→first='abu bakr';mohammed abu bakr→last='abu bakr'AGENTS.mdinternal-usage guardinternal_reader.py:1thenreal_caller.py:1→ 2 warningsAGENTS.mdesq paragraphSUFFIX_ACRONYMS − {esq}"changes many"E.S.Q./E.S.Q5/7 frames,Esq/Esq./ESQ/esq0/7AGENTS.mddelimiter gotchadocs/customize.rstTITLES,PARTICLESand the rest ofnameparser.configare frozen"REGEXESandCAPITALIZATION_EXCEPTIONSare stilldictnameparser/config/__init__.pyTwo 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 = ...raisesTypeError, a custom delimiter key is refused rather than accepted as a compiled pattern, andHumanName.parse_nicknamesis gone. But thepop()+ assign routing advice is still correct and still the only way to move a built-in on the v1 API: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 §Ninto gitignoreddocs/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.
customize.rstsaidTITLES"and the rest kept the names they already had" — false forNON_FIRST_NAME_PREFIXES,BOUND_FIRST_NAMES,SUFFIX_NOT_ACRONYMSAGENTS.md"the CJK packs took it to eleven" — the eight keys came from one commit (7ee6e3a, #273), and five of eight are Western pairsAGENTS.md"the bridge warns per read location" — credits the bridge with__warningregistry__'s behaviorwarnings.warnemit 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 warningcustomize.rst"still plain dicts" read as an exemption from the freezeAGENTS.md"there is noparse_nicknames()left" — the name is live in_facade.py's_V1_HOOKS, where overriding it warns (#280)AGENTS.mdesq single-token claim was a universal quantified over sampled framesThe dict finding got worse on re-measurement. The review comment said mutating
CAPITALIZATION_EXCEPTIONSwas a silent no-op. Through the correct API: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.pyhad two comments callingSUFFIX_ACRONYMS_AMBIGUOUS"consulted only byparse_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-ambiguoustag).Still open on #356 (the API/test half)
__all__onparticles.py/bound_given_names.py;particles.pyre-exportsBOUND_GIVEN_NAMES__dir__raisesKeyErrorrather thanAttributeErroroff the read pathinspect.getmembers()/help()ontitles/suffixesresolves retired names and emits their warnings (confirmed incidentally —dir()on those modules warns)_RETIRED_NAMESduplicates what's derivable fromALIASES;ALIASESis a positionally-indexed bare 4-tuplefrom X import Yattribution tested for one alias of fiveThe natural bundle for whatever next touches
nameparser/config/— plausibly #342, which editssuffixes.py.Verification
Part of #356.
🤖 Generated with Claude Code