| FazBrowse GitHub Viewer | Trending | | Home |
| Tools: [Download Repo ZIP] [Original HTTPS Page] |
Sorry, something went wrong.
Pure relocation. No behavior change, no ledger entry, no release-log bullet -- the differential is byte-identical because no parse moves. Ten objects leave _group.py verbatim, comment blocks included: the rules.md citations live in those comments and have to travel with the code they cite. _is_title_piece, _PERIOD_ABBREV, _is_leading_title, _leading_titles, _is_suffix_piece, _segment_holds_no_name, Peel, _peel_walk, _trailing_start, _peel_trailing. _vocab.py was the other candidate and rules itself out in its own docstring -- "Text-level tests used by more than one stage; token/piece-level predicates live with their stage." That contract is deliberate (is_wholly_suffix documents two departures from it), so the piece layer gets its own module rather than bending the text layer's. The split is by what the question TAKES, which is the rule mechanisms.md#ONE-PREDICATE-PER-QUESTION states. _trailing_start travels with the peel although only _peel_walk and _peel_trailing cross a stage boundary: decisions.md describes the S2 peel as those three together, and splitting a documented unit across modules to satisfy a usage rule would be worse than carrying one group-only function along. Five predicates stay in _group, being group's alone: _is_prefix_piece, _is_conj_piece, _is_rootname, _is_maiden_marker_piece, and the local closures. group imports back what it still uses; nothing imports _pieces from below, so there is no cycle. Three couplings the move had to carry, none of which grep would have found from the function names alone: - rules.md H2, H3 and S2 name the module their citation sits in, and test_doc_citations asserts set EQUALITY against citing modules, so their implemented: lines move to _pieces.py. - test_regex_sync tracks _PERIOD_ABBREV by module path in three places (the import, the assertion, and the declared-copy roster). - test_layering iterates ALLOWED.items(), so a module absent from that dict is never checked AT ALL. _pieces.py is registered with a tighter contract than the generic stage allowance -- _state and _vocab only -- which makes the module docstring's claim executable. Verified non-vacuous: the entry rejects an added nameparser._render import on a scratch copy. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The same-PR amendment rule landing on text I merged yesterday. Both statements were true when written and the move makes them false: - _group's docstring said it houses the shared piece predicates and explained why they were there. They are not there now, and what remains is group's own. - mechanisms.md#ONE-PREDICATE-PER-QUESTION said a predicate over pieces and tags goes to _group. It goes to _pieces; group was where they collected BEFORE the module existed, which is the accumulation the entry describes rather than the destination it should recommend. The entry's Lives in gains the layering test, because that is now where each module's contract is written down -- and a piece predicate that grows a dependency on a stage shows up there as a widened entry rather than as a review comment. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. @@ Coverage Diff @@
## master #441 +/- ##
=======================================
Coverage 98.59% 98.59%
=======================================
Files 44 45 +1
Lines 3064 3068 +4
=======================================
+ Hits 3021 3025 +4
Misses 43 43 ☔ View full report in Codecov by Harness.
|
Sorry, something went wrong.
test_layering_contract iterates ALLOWED.items(), so its coverage is whatever someone remembered to key. A module absent from that dict is not checked loosely -- it is not checked at all, and nothing notices: the suite stays green and the new module may import whatever it likes. Registering _pieces.py in the commit before this one fixed that one module and left the mechanism intact for the next. Scoped to _pipeline/ because that is what this contract governs. Package-wide, 16 of 45 modules are unkeyed -- config/ vocabulary data, util.py, _version.py -- and they were never in scope; a whole-package assertion would be asserting the wrong thing. Latent rather than active when closed: all 13 _pipeline modules were keyed, so #439's _pieces.py would have been the first to slip through. That measurement is in the docstring rather than in an assertion, because asserting the count is the constant-content pattern AGENTS.md forbids -- it would fail on every legitimate new module, which is the opposite of what this guard wants. Verified non-vacuous by unregistering _pieces.py on a scratch copy: this test fails and test_layering_contract still PASSES, which is the silent gap it closes, demonstrated. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Four reviewers. The move itself survived every mechanical check: ten objects byte-identical, object sets conserved, no new cycle, and 0 of 1069 corpus names differ across all seven role fields plus str(). All ten are killed by the behavior suite -- zero mutation survivors. The findings are the guards around the move and the prose describing it. THE GUARD I SHIPPED WAS DISARMABLE BY ONE CHARACTER. Path.glob on a missing directory returns empty rather than raising, so a typo in the directory literal or the pattern left test_every_pipeline_module_is_ keyed_in_allowed asserting `set() - keyed` -- true for every possible ALLOWED. A completeness check measuring nothing, which is the shape of the bug it exists to prevent. The directory now comes from the imported subpackage (a typo is an AttributeError) and a known member is asserted, which also covers a mistyped glob. The same registry shape one file over, and this one was ACTIVE rather than latent: test_regex_sync's _MODULES was missing six pipeline modules (_assemble, _classify, _extract, _script_segment, _segment, _state), so they were never scanned for undeclared hand copies of a config regex. Measured on a scratch copy: a new module carrying a wrong copy of the mac pattern passed all 20 tests. Added, and given the symmetric guard -- which catches it now, where before only the layering twin did. Nothing had slipped through; the six carry no hand copies. Three of the five prefixes in the _pieces ALLOWED entry were dead permission carried over from the stage allowance. _lexicon is the sharp one: a title predicate reaching for _title_key is the likeliest next widening, and the entry pre-authorised exactly what its comment claimed to watch for. Narrowed to what the module imports. Prose. Every present-tense "assign imports group" is now FALSE -- that import is precisely what this PR removed; _assign no longer names _group at all. Past-tensed, with the rule that replaced it named instead. Also: _peel_trailing's docstring justified its own placement by that import (the one sentence in the moved block that could not survive verbatim); _assign's two "group's _leading_titles"/"group's _peel_trailing"; _vocab's "piece-level predicates live with their stage", which #439 repealed and which _pieces was quoting AS CORROBORATION; the tags attributed to _vocab when classify and group write them; a "three group sites" count the move made two; group's header claiming H2 and H3 after their citations left; and AGENTS.md's _PERIOD_ABBREV, stale by two hops. S2 regains _group in implemented:, via a citation at the site that acts on it -- group holds thirteen call sites of the peel trio deciding where the family and maiden names stop, and dropping off S2's map because the citation moved was the map getting worse. Counts: mine were falsified three times this session, and my own first correction here said "five predicates" over a list of six. These name the PRs and let the reader count. mechanisms.md's Lives in no longer claims a qualifier that stopped selecting its list, and records that is_trailing_numeral_suffix lost its stage caller to this very move. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
| Back | FazBrowse Home | New Git URL |
Closes #439.
Ten objects leave _group.py for a new nameparser/_pipeline/_pieces.py. No behavior change — the differential is byte-identical at every baseline, because no parse moves.
Why a new module rather than _vocab.py
The issue offered both. _vocab.py rules itself out in its own docstring:
That contract is deliberate — is_wholly_suffix documents two explicit departures from it — so the piece layer gets its own module rather than bending the text layer's. The split is by what the question takes, which is what mechanisms.md#ONE-PREDICATE-PER-QUESTION states: _vocab answers how a word reads, _pieces how a piece reads.
What moved, and what didn't
Moved (10): _is_title_piece, _PERIOD_ABBREV, _is_leading_title, _leading_titles, _is_suffix_piece, _segment_holds_no_name, Peel, _peel_walk, _trailing_start, _peel_trailing — verbatim, comment blocks included, because the rules.md citations live in those comments and have to travel with the code they cite.
Stayed (group's own): _is_prefix_piece, _is_conj_piece, _is_rootname, _is_maiden_marker_piece.
_trailing_start travels with the peel even though only _peel_walk and _peel_trailing cross a stage boundary: decisions.md describes the S2 peel as those three together, and splitting a documented unit across modules to satisfy a usage rule would be worse than carrying one group-only function along.
_group imports back what it still uses. Nothing imports _pieces from below, so there is no cycle.
Three couplings the move had to carry
None of these are findable by grepping the function names, and each would have failed CI on its own:
On (3), _pieces.py is registered with a tighter contract than the generic stage allowance — _state and _vocab only — which makes the module docstring's claim executable rather than merely asserted. Verified non-vacuous: the entry rejects an added nameparser._render import on a scratch copy. (The first probe used _assign and only produced a circular-import error at collection, which proves the cycle but not the assertion; the acyclic probe is the one that shows the guard firing.)
And the gap itself is now closed, not just stepped around. Registering _pieces.py fixed one module and left the mechanism intact for the next, so test_every_pipeline_module_is_keyed_in_allowed asserts that every _pipeline/*.py is keyed. Scoped there because that is what the contract governs — package-wide, 16 of 45 modules are unkeyed (config/ vocabulary data, util.py, _version.py) and were never in scope.
It was latent rather than active: all 13 pipeline modules were keyed, so _pieces.py would have been the first to slip through. That measurement lives in the docstring rather than an assertion, because asserting the count is the constant-content pattern AGENTS.md forbids — it would fail on every legitimate new module.
Verified by unregistering _pieces.py on a scratch copy: the new test fails and test_layering_contract still passes — the silent gap, demonstrated.
Docs the move falsified
The same-PR amendment rule landing on text merged yesterday in #440. Both statements were true when written:
It goes to _pieces now; _group is where they collected before the module existed, which is the accumulation the entry describes rather than the destination it should recommend. The entry's Lives in also gains the layering test, since that is now where each module's contract is written down.
Deliberately not done
No renames. The moved names keep their leading underscore, though _vocab's convention would drop it for a shared module's public surface. That would touch ~60 call sites across three files and dilute a diff whose value is being a verifiable pure move — a follow-up if you want it.
Verification
_group.py goes from 1052 to 843 lines.
🤖 Generated with Claude Code