tests(differential): a pin names exactly one rule (#508) - #509
Merged
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #509 +/- ##
=======================================
Coverage 98.66% 98.66%
=======================================
Files 45 45
Lines 3219 3219
=======================================
Hits 3176 3176
Misses 43 43 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
test_the_recorded_rule_still_wins_each_contested_name compared
classify()'s answer to the pinned winner with `startswith`, so a pin
was satisfied by any rule whose issue extended it. Measured 2026-09-05
over the 51 rows: 17 pins are short family prefixes that reach one
rule, 31 are full issue strings reaching only themselves, two are full
strings that are also a strict prefix of a sibling's ('Bob Jones,
author' and 'Bob Jones, compositeur', whose winner's issue the C1
rule's extends), and one is a short prefix reaching three rules
('Andrews, M.D.' on the bare `fix(comma-family)`). All three are at
1.4.0 and latent -- classify() returns the intended rule today -- but
a pin that names a family pins nothing, and the #498 completeness
check reads a _RECORDED_DIFFS key as "a winner is pinned" on this
guard's word.
_pinned_rule resolves a pin to one rule -- exact where a rule's issue
equals it, else the single rule whose issue starts with it, refused
otherwise -- and the winner guard compares exactly against the
resolved issue. test_every_pinned_winner_names_exactly_one_rule refuses
an ambiguous pin on its own, at pytest speed, naming the pin and the
rules it reached. 'Andrews, M.D.' is spelled out to the lone-post-comma
rule that wins it; the Bob Jones rows keep their full-string pins, now
compared exactly, and their comment says so. Control: pinning the
all-titles string and forcing classify() to answer the C1 string fails
the guard, where `startswith` would have passed.
Gate 352 / 247 / 155 / 14 byte-identical -- nothing the gate reads
changed. Refs #508.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
A dated decisions entry for #508: the 31 / 17 / 2 / 1 breakdown of the 51 pins with its recipe, the decision that a pin resolves to exactly one rule and is compared exactly, the three declined shapes (exact everywhere, an allowlist, a word-boundary prefix), and the finding that #498's borrowed "a key means a winner" was hollow for three rows. One sentence in mechanisms.md#CROSS-RULE-OUTCOME-PINS states the resolution rule. Closes #508. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
derek73
force-pushed
the
claude/508-pin-one-rule
branch
from
September 6, 2026 06:26
7f22e6d to
9444269
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A
_CROSS_RULE_WINNERSpin now names exactly one rule. The winner guard resolves each pin to one rule's issue — exact where a rule's issue equals the pin, else the single rule whose issue starts with it, refused otherwise — and comparesclassify()'s answer to it exactly instead of by prefix. Closes #508.What was wrong
The guard compared with
startswith, so a pin was satisfied by any rule whose issue extended it. Measured 2026-09-05 over the 51 rows on master:Bob Jones, authorandBob Jones, compositeur, whose winner's issue the…, the C1 examplerule extends. Their comment rested the pin on the C1 regex being unable to reach the string, an argument nothing executed.Andrews, M.D.on the barefix(comma-family).All three are at 1.4.0 and were latent. What the prefix could not do was fail when it stopped holding: forcing
classify()to answer the C1 string forBob Jones, compositeurpassed the old guard and fails the new one (the mutation control in the first commit).The two commits
tests(differential): a pin names exactly one rule—_pinned_rule(exact, else unique prefix, else refused naming the rules it reached), the winner guard compares exactly against the resolved rule, a new pytest-speed guard refuses an ambiguous pin on its own so the failure names the pin rather than a classification, the resolver's control table on hand-built issue lists (exact over prefix, a family prefix, the two refusals, literal case),Andrews, M.D.spelled out to the lone-post-comma rule that wins it (measured: the only rule admitting its recorded shape), and the Bob Jones comment corrected to what now holds.docs(design): a pin names one rule— the dated decisions entry with the 31 / 17 / 2 / 1 breakdown and recipe, the decision, four declined shapes (exact everywhere, an allowlist, a word-boundary prefix, refusing shared prefixes at the ledger), and the finding that Should file order decide between rules whosefieldsoverlap without nesting? (マイケル・ジャクソンgoes to whichever of two rules comes first, and the contest check never sees the pair) #498's "a key means a winner is pinned" was hollow for three rows; one sentence inmechanisms.md#CROSS-RULE-OUTCOME-PINS.Verification
Nothing the gate reads changed: intentional 352 / 247 / 155 / 14 byte-identical at both commits. Full suite green; ruff and mypy clean. Hand-corrupted pins in memory (a bare family prefix; a nonexistent rule) fail both guards naming the pin; resolver mutations (drop the exact branch; accept several) each fail the negative control. One reviewer over both commits, then a three-reviewer pass over the PR; every finding is fixed in place. The most useful: no committed test had pinned exact-versus-prefix, so a revert to
startswithsurvived the suite.test_the_winner_guard_refuses_a_longer_sibling_of_the_pinnow forcesclassify()to answer the C1 string forBob Jones, compositeurand is the one test that fails under that revert. The resolver also refuses an empty pin, quotes case literally, and tells a reader whose pin reaches no rule that the rule was reworded rather than pointing them at the several-rules case.🤖 Generated with Claude Code