tests/v2/test_regex_sync.py pins the differential harness's hand-copied character classes against their sources in nameparser/. Three of those pins name expected_since_1.4.0.toml by hardcoded filename (lines 240, 287, 352), so they do not see expected_since_2.0.0.toml, added in #332.
That file carries four hand copies, none of them checked:
| ledger line |
copied from |
expected_since_2.0.0.toml:68 |
_policy._SCRIPT_RANGES |
expected_since_2.0.0.toml:234 |
_policy._SCRIPT_RANGES again, inside the #298 lookahead |
expected_since_2.0.0.toml:167 |
the CJK members of SUFFIX_NOT_ACRONYMS |
expected_since_2.0.0.toml:121 |
GLUED_HONORIFICS |
All four were verified equal to their sources on 2026-08-05, so this is drift risk rather than a live defect. Note that GLUED_HONORIFICS now has no pinned copy anywhere in the tree.
Why it matters
The direction that matters is removal. A span or vocabulary entry deleted from the source forces the 1.4 ledger's copy to narrow, test-driven — while the 2.0 twin stays wide and starts classifying real regressions as intended. test_regex_sync.py:198 already calls this "the copy whose divergence is quietest, because the harness is run by hand rather than in CI"; #332 doubled the number of copies while leaving the pin at one file.
Do this before authoring expected_since_2.1.0.toml
The gap grows by one ledger per release. When 2.2 opens, the next baseline's ledger will hand-copy the same constants again — so fixing the sweep first means those copies are born pinned, instead of adding a fifth and sixth unguarded one.
Globbing is not a one-line change
Three assertions assume a single ledger, and all three break (measured 2026-08-05):
test_differential_cjk_rule_matches_the_script_ranges selects rules by "#271" in issue or "#272" in issue and asserts len(matched) == 1. The 2.0 ledger has 2 such rules.
test_every_span_bearing_rule_matches_the_script_ranges asserts len(checked) >= 3. With both ledgers swept, that floor becomes 5 — the 2.0 file contributes 2 span-bearing rules.
- The same test asserts exactly one
cjk-delimited-nickname rule. The 2.0 ledger has 0, so the assertion has to become per-file rather than global.
The shape to copy is already in the tree: tests/v2/test_differential.py sweeps expected_since_*.toml for the role-vocabulary guard, and asserts the glob is non-empty so it cannot pass vacuously.
tests/v2/test_regex_sync.pypins the differential harness's hand-copied character classes against their sources innameparser/. Three of those pins nameexpected_since_1.4.0.tomlby hardcoded filename (lines 240, 287, 352), so they do not seeexpected_since_2.0.0.toml, added in #332.That file carries four hand copies, none of them checked:
expected_since_2.0.0.toml:68_policy._SCRIPT_RANGESexpected_since_2.0.0.toml:234_policy._SCRIPT_RANGESagain, inside the #298 lookaheadexpected_since_2.0.0.toml:167SUFFIX_NOT_ACRONYMSexpected_since_2.0.0.toml:121GLUED_HONORIFICSAll four were verified equal to their sources on 2026-08-05, so this is drift risk rather than a live defect. Note that
GLUED_HONORIFICSnow has no pinned copy anywhere in the tree.Why it matters
The direction that matters is removal. A span or vocabulary entry deleted from the source forces the 1.4 ledger's copy to narrow, test-driven — while the 2.0 twin stays wide and starts classifying real regressions as intended.
test_regex_sync.py:198already calls this "the copy whose divergence is quietest, because the harness is run by hand rather than in CI"; #332 doubled the number of copies while leaving the pin at one file.Do this before authoring
expected_since_2.1.0.tomlThe gap grows by one ledger per release. When 2.2 opens, the next baseline's ledger will hand-copy the same constants again — so fixing the sweep first means those copies are born pinned, instead of adding a fifth and sixth unguarded one.
Globbing is not a one-line change
Three assertions assume a single ledger, and all three break (measured 2026-08-05):
test_differential_cjk_rule_matches_the_script_rangesselects rules by"#271" in issue or "#272" in issueand assertslen(matched) == 1. The 2.0 ledger has 2 such rules.test_every_span_bearing_rule_matches_the_script_rangesassertslen(checked) >= 3. With both ledgers swept, that floor becomes 5 — the 2.0 file contributes 2 span-bearing rules.cjk-delimited-nicknamerule. The 2.0 ledger has 0, so the assertion has to become per-file rather than global.The shape to copy is already in the tree:
tests/v2/test_differential.pysweepsexpected_since_*.tomlfor the role-vocabulary guard, and asserts the glob is non-empty so it cannot pass vacuously.