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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Projects

No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions