Skip to content

Regex-sync pins only the 1.4 ledger, so the 2.0 ledger's four hand copies can drift silently #333

Description

@derek73

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):

  1. 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.
  2. 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.
  3. 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.

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions