R-291: assert that a tag one reader accepts stays visible to the other
c0 asked whether R-290's widening of tagsIn reaches past outcome-coverage's loose counter, which would zero its unparsed count for the wrong reason and retire a canary. It does not -- 22 beats from each reader on CLEAN_GROUND.md, nothing that tagsIn accepts invisible to the other guard -- but "does not today" decays quietly, so it is now a test importing both real functions rather than a copy of either pattern. Mutation-checked: widening tagsIn to accept [CUS Spot] turns it red. Measuring it found something the question did not ask about, recorded in the log: for [cus: ...], [CUS : ...] and [ CUS: ...] the two guards disagree -- tagsIn reads the tag, beatLikeIn calls it unparseable -- because beatsIn's strict half kept the case-sensitive literal. The build stops, which is the safe direction, but names the wrong thing. outcome-coverage.mjs is c0's file and the call is theirs. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
ae8179bd9b
commit
ed851b76e3
@@ -6840,3 +6840,29 @@ starts from a clean corpus rather than from an exception list.
|
||||
pattern**: widen the reader for the spellings you thought of, and add a looser counter that
|
||||
names the one you did not. A marker nothing reads is worse than no marker, because whoever
|
||||
wrote it believes the thing is declared.
|
||||
|
||||
## R-291 — the canary c0 asked about, asserted rather than remembered
|
||||
|
||||
R-290 widened `tagsIn`. c0 asked the right question about it: `outcome-coverage`'s
|
||||
`beatLikeIn` names the tags its own reader cannot parse, and if the widened `tagsIn` reaches
|
||||
past that loose pattern, the unparsed count drops to zero for the wrong reason and stops
|
||||
being a canary.
|
||||
|
||||
**It does not.** Measured on both real readers rather than by copying either pattern:
|
||||
CLEAN_GROUND.md gives 22 beats from `tagsIn`, 22 from `beatsIn`, 0 unparsed. Across spellings,
|
||||
everything `tagsIn` accepts is seen by the other guard — parsed, or named. `[CUS Spot]` and
|
||||
`[CUS= Spot]` are refused by both strict readers and still named by the counter.
|
||||
|
||||
"Does not today" is exactly the kind of claim that decays without anyone noticing, so it is a
|
||||
test: **a tag one reader accepts is never invisible to the other.** It imports both real
|
||||
functions, so neither pattern is duplicated and the test cannot agree with a stale copy.
|
||||
Mutation-checked — widening `tagsIn` to accept `[CUS Spot]`, past the counter, turns it red.
|
||||
|
||||
**What the measurement found that the question did not ask about.** For `[cus: …]`,
|
||||
`[CUS : …]` and `[ CUS: …]` the two guards now *disagree*: `tagsIn` reads the tag and checks
|
||||
it for reachability, while `beatLikeIn` reports it unparseable and fails the build, because
|
||||
`beatsIn`'s own strict half kept the case-sensitive literal R-290 removed from `tagsIn`. Not
|
||||
silence — the build stops, which is the safe direction — but the message names the wrong
|
||||
thing, and the fix is the one check-rollable already made for the cast: read through the other
|
||||
guard's function rather than a second regex. That file is c0's and the call is theirs; it is
|
||||
recorded here so it is a decision rather than something nobody wrote down.
|
||||
|
||||
Reference in New Issue
Block a user