Skip to content

Six contested diffs in the 2.x ledgers have no pin, and the empty rosters read as if none existed (MD, PHD goes to whichever rule comes first) #501

Description

@derek73

Rationale

_CROSS_RULE_WINNERS pins which rule classifies a contested name, because nothing
else in the suite can see a name change hands: per-rule rosters measure a rule
alone, and the gate total is per-corpus
(mechanisms.md#CROSS-RULE-OUTCOME-PINS). A pure file reorder in the 1.4 ledger
fails that roster and nothing else.

Both 2.x ledger sections are empty, and until now that read as "nothing here
is contested". It is not. Measured 2026-09-03 against the real pinned wheels,
six diffs are admitted by more than one rule, with file order alone deciding
the winner and nothing recording it:

ledger name measured diff rules admitting
2.0.0 田中さん 様. {family, given, suffix} 2
2.0.0 김민준 박사님 {family, given, suffix} 2
2.0.0 선생님 {family, given} 2
2.0.0 田中さん, 様. {family, given, suffix} 2
2.0.0 MD, PHD {suffix, title} 2
2.1.0 MD, PHD {suffix, title} 2

For contrast, the 1.4.0 ledger has 48 such diffs and 31 pinned rows; 2.2.0 has
none and is correctly empty.

How this surfaced

#497 moved the recorded diff shapes into tools/differential/compare.py as
_RECORDED_DIFFS so a run could verify them. Verifying them found that all four
2.x rows recorded shapes no run produces — 'Nguyen, Van' diffs at no baseline
at all, and 'Jane née and Jones Smith' diffs four roles where three were
recorded. Both were removable rather than correctable, because neither name is
contested at a shape any run makes, so the rows adjudicated nothing.

Deleting them left both 2.x sections empty, which is what exposed this: the
sections were never a statement that nothing is contested, and nobody had
measured whether anything was.

What pinning these needs

Not mechanical. Each winner has to be checked against the winning rule's prose
before it is recorded — a rule that classifies a diff it does not describe is
#372, and it stays green everywhere else. That is the same per-pair judgement
#382's eleven precedes_narrower exemptions each needed, and the CJK four sit in
the glued-honorific neighbourhood that took several review rounds to get right
there.

Note also that a recorded row is only as good as the shape beside it. #497's
whole finding is that a shape nothing measures agrees with itself forever, so
each of these six should be recorded with a shape taken from a run, and
_RECORDED_DIFFS is now the place that holds it and the run is what checks it.

Recompute

Replay main()'s load for the baseline (glob → tier order → shape-to-order →
dedupe on (name, order) → baseline-minimum skip), run compare._run_worker
over the surviving entries, compute each name's diff the way main() does, then
count the rules whose name_regex reaches the name and whose fields are a
superset of that diff. More than one is a contest.

Not in scope

Whether file order picks the RIGHT winner for these six. That is the question
#382 answered for the 1.4 ledger's pairs, and it is a separate argument from
recording what wins today.

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

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions