Differential harness: CJK corpus generated from the case table - #304
Merged
Conversation
The fix(#271/#272) rule in expected_changes.toml had never classified a name in a real run: corpus.jsonl regenerates from v1's test banks (no reason to test CJK) and build_issues_corpus.py requires an internal space, which unspaced names -- the exact shape the rule explains -- never have. The rule was verified once against a throwaway synthetic corpus during #294 and was otherwise dead weight the harness could not distinguish from coverage. corpus_cjk.jsonl is the third corpus with the third provenance: generated by build_cjk_corpus.py from every distinct case-table text bearing a codepoint the script table classifies, through the same _script_matcher the parser uses. Row context is deliberately ignored -- the corpus carries name STRINGS and the harness parses them with the default facade, so a zh-scoped row's text is simply one more CJK name to diff. The selection self-extends: a case row added for future CJK work enters the corpus at the next regeneration, and test_regex_sync.py pins the checked-in file against the generator's selection so a stale corpus fails the suite. First real run: 685 names, 44 intentional diffs, 0 unexplained, with the CJK rule claiming 23 names. It also immediately surfaced a shape no rule covered -- a name where delimiter recognition (corner brackets, the nakaguro nickname join) and the CJK family-first flip change fields in the SAME diff, which neither single-change rule may claim because each excludes the other's fields on purpose. The new fix(cjk-delimited-nickname) rule takes exactly that union, scoped to the CJK-typographic delimiters so it cannot absorb a Latin delimiter diff; its issue slug avoids the literal #271/#272 substrings the sync test uses to select the one canonical CJK rule. Closes #295 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #304 +/- ##
=======================================
Coverage 98.43% 98.43%
=======================================
Files 41 41
Lines 2750 2750
=======================================
Hits 2707 2707
Misses 43 43 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
Review found the delimiter-only regex claiming more than its comment said: 「」『』 sit in CJK Symbols and Punctuation, OUTSIDE every classified span, so 'John 「Jack」 Kennedy' matched and a bare first/last regression on a Latin name classified as intended. The rule now requires a classified codepoint alongside the delimiter (both lookaheads), drops the unearned middle field (all three claimed diffs touch exactly first/last/nickname), and its comment owns the one absorption subset-matching cannot avoid -- a nickname-only diff on a nakaguro name -- instead of claiming 'cannot absorb'. The second lookahead is the toml's second hand copy of the script spans, so it gets the same sync pin as the first, which also pins the delimiter set and records the #271/#272-substring taboo where a rule author will look. Plus the smaller review items: the provenance comment now credits the parity rows (the corpus members that pin NON-diffs), the positional note within the name_regex tier is stated, test_regex_sync's module docstring counts its outside-the-package tests correctly, and the README comma splice is mended. Noted, not changed: the Latin probes the review used do not fall to UNEXPLAINED without the compound rule -- the fields-only fix(suffix-routing) rule absorbs any bare first/last diff on any name, and always has. Pre-existing fields-tier looseness, outside this change. Co-Authored-By: Claude Fable 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.
Summary
Closes #295. The
fix(#271/#272)rule inexpected_changes.tomlhad never classified a name in a real run — both existing corpora are structurally blind to unspaced CJK (v1's banks never tested it;build_issues_corpus.pyrequires an internal space). This adds the third corpus with a third provenance:corpus_cjk.jsonl, generated bybuild_cjk_corpus.pyfrom every case-table text bearing a codepoint the script table classifies, selected through the same_script_matcherthe parser uses. A no-network pin intest_regex_sync.pyasserts the checked-in file equals the generator's selection, so a CJK case row added without regenerating fails the suite — and #298's future rows enter the corpus automatically.First real run: 685 names, 44 intentional diffs, 0 unexplained, the CJK rule claiming 23 names — and the corpus immediately earned its place by surfacing a shape no rule covered: names where delimiter recognition (corner brackets / the nakaguro nickname join) and the CJK family-first flip land in the same diff. Neither single-change rule may claim that union (each excludes the other's fields on purpose, so lone regressions stay loud); the new narrow
fix(cjk-delimited-nickname)rule takes exactly it, scoped to CJK-typographic delimiters, with an issue slug that deliberately avoids the#271/#272substrings the sync test keys on.Test plan
compare.py: exit 0, 685/44/0, CJK rule fires (23), compound rule fires (3)🤖 Generated with Claude Code