You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
tools/differential/expected_since_1.4.0.toml's fix(suffix-routing) two-token name with unambiguous trailing suffix stays suffix is the only rule in any of the three ledgers with no name_regex:
# tomllib over all three ledgersexpected_since_1.4.0.toml: 59rules, 1withNOname_regexexpected_since_2.0.0.toml: 58rules, 0expected_since_2.1.0.toml: 51rules, 0
issue = "fix(suffix-routing) two-token name with unambiguous trailing suffix stays suffix"# 'Johnson PhD' / 'Smith Jr.' / 'John V' / 'QC MP': ... Four corpus names,# and the prose fits all four.fields = ["given", "family", "suffix"]
It explains 14 names today, not four.
Why this shape absorbs silently
compare.py admits a rule when diff_fields <= set(fields). With no name_regex, this rule claims any name whose diff fits {given, family, suffix} — a very common shape — so a newly-moved name lands under it and the gate stays green with nothing to read.
The guard cannot see it either. _CORPUS_CLAIMS records names as "corpus names the name_regex reaches; the whole corpus when a rule has none" — so this rule's entry is _Claim(1090, ('family', 'given', 'suffix'), …), the entire corpus. It is already at its maximum, so arrivals never move it. test_every_rule_claims_the_recorded_share_of_the_corpus passes whether the rule explains 4 names or 40.
fix(post_rules): a maiden name makes the lone name word the family (#445) #450 — after narrowing the fix(#335) rules, a {given, family} regression on Smith (née Jones) is still explained at 1.4.0 by this rule. That PR records the limit rather than closing it, since the catch-all is long-standing and out of its scope.
So the ledger's central promise — that every behaviour change is classified in writing, by the rule that caused it — is not held for any diff of this shape at the 1.4.0 baseline.
Worth deciding
Whether a fields-only rule should be permitted at all. compare.py's validate_rules currently allows it (the docstring calls it "the most unbounded shape validate_rules permits"), and _CORPUS_CLAIMS's comment already names it as the shape "most worth writing down" — the recording exists precisely because the risk was understood.
Forbid fields-only rules in validate_rules. Structural, and there is exactly one to migrate. Would need a rule for any legitimately open-ended class.
Make the guard see reach rather than regex coverage. Record what a rule explains, not what its regex matches, so a growing catch-all fails the guard. Larger change; would make every rule's claim tighter.
Its comment says "Four corpus names, and the prose fits all four" — that has been wrong since at least #414's rules-corpus harvest, and nothing recomputes it. Whatever is decided, that figure should either become a recompute one-liner or go.
Raised from #450's review, where the same shape was found still absorbing after a targeted narrowing.
tools/differential/expected_since_1.4.0.toml'sfix(suffix-routing) two-token name with unambiguous trailing suffix stays suffixis the only rule in any of the three ledgers with noname_regex:It explains 14 names today, not four.
Why this shape absorbs silently
compare.pyadmits a rule whendiff_fields <= set(fields). With noname_regex, this rule claims any name whose diff fits{given, family, suffix}— a very common shape — so a newly-moved name lands under it and the gate stays green with nothing to read.The guard cannot see it either.
_CORPUS_CLAIMSrecordsnamesas "corpus names thename_regexreaches; the whole corpus when a rule has none" — so this rule's entry is_Claim(1090, ('family', 'given', 'suffix'), …), the entire corpus. It is already at its maximum, so arrivals never move it.test_every_rule_claims_the_recorded_share_of_the_corpuspasses whether the rule explains 4 names or 40.It has absorbed real movements twice
Senator "Rick" Edmonds,Xyz. (Bud) Smith) moved and landed here. Detected only because someone compared the rule's heading count before and after: 14 → 17. They were given their own rule, and the ledger records the surgery as the precedent set by Ledger rules classify diffs they do not describe, and a rule that stops explaining anything is invisible #372's names off this same catch-all.fix(#335)rules, a{given, family}regression onSmith (née Jones)is still explained at 1.4.0 by this rule. That PR records the limit rather than closing it, since the catch-all is long-standing and out of its scope.So the ledger's central promise — that every behaviour change is classified in writing, by the rule that caused it — is not held for any diff of this shape at the 1.4.0 baseline.
Worth deciding
Whether a fields-only rule should be permitted at all.
compare.py'svalidate_rulescurrently allows it (the docstring calls it "the most unbounded shape validate_rules permits"), and_CORPUS_CLAIMS's comment already names it as the shape "most worth writing down" — the recording exists precisely because the risk was understood.Options, roughly:
name_regex. It explains 14 names; an anchored alternation would bound it and make_CORPUS_CLAIMSmeaningful. Cheapest, and it matches what fix(post_rules): H1 counts name words, not annotations (#410) #444 and Ledger rules classify diffs they do not describe, and a rule that stops explaining anything is invisible #372 already did piecemeal.validate_rules. Structural, and there is exactly one to migrate. Would need a rule for any legitimately open-ended class.Its comment says "Four corpus names, and the prose fits all four" — that has been wrong since at least #414's rules-corpus harvest, and nothing recomputes it. Whatever is decided, that figure should either become a recompute one-liner or go.
Raised from #450's review, where the same shape was found still absorbing after a targeted narrowing.