Skip to content

Compare string-literal operands by raw text, not masked text (#31)#32

Merged
yavorpanayotov merged 1 commit into
mainfrom
fix/masked-string-value-comparisons
Jun 11, 2026
Merged

Compare string-literal operands by raw text, not masked text (#31)#32
yavorpanayotov merged 1 commit into
mainfrom
fix/masked-string-value-comparisons

Conversation

@yavorpanayotov

Copy link
Copy Markdown
Collaborator

Closes #31. Fixes the regression introduced by #29 (the #28 masking fix), found by post-merge adversarial review.

Problem

#29 made the regex lanes match on a masked view of the source where string content is blanked to spaces. Two lanes compare string-literal values textually, and masking collapses distinct same-length literals into identical text ("a" and "b" both become " "):

  • False positive: requires: order.state = "a" + requires: order.state != "b" (satisfiable) emitted a spurious allium.rule.neverFires — a TS-only warning allium check never emits, i.e. the parity class TypeScript regex lanes lack comment/string awareness (false positives on keyword-shaped text) #28 was about, reintroduced via a different lane.
  • False negatives: = "aa" + = "bb" (genuine contradiction) was no longer flagged by rule.neverFires, and when mode = "aa" and mode = "bb" no longer flagged by surface.impossibleWhen.

Fix

Detection stays on masked text. When a captured operand starts with ", findNeverFireRuleIssues and findSurfaceImpossibleWhenIssues re-read the operand's text from the raw source at the same offsets via a new rawStringOperand helper — the mask preserves length and offsets, and the value group is anchored at the end of each match, so its raw position is matchStart + matchLength − valueLength.

Tests

Four new regression tests covering all three confirmed reproducers plus a distinct-expressions control. All workspaces green (313 extension + 8 LSP), npm run lint clean. Also re-verified the three reproducers directly against the built dist.

🤖 Generated with Claude Code

The #28 masking fix (bd22350) blanked string content to spaces in the
text the regex lanes match on. Two lanes compare string-literal values
textually, and masking collapses distinct same-length literals into
identical text ("a" and "b" both become " "), breaking value-equality
reasoning both ways: a spurious rule.neverFires on satisfiable
requires pairs ("a" vs != "b"), and missed genuine contradictions
("aa" = "bb" no longer flagged by neverFires or impossibleWhen).

Detection stays on masked text; when a captured operand starts with a
quote, findNeverFireRuleIssues and findSurfaceImpossibleWhenIssues now
re-read the operand from the raw source at the same offsets via
rawStringOperand — the mask preserves length and offsets, and the value
group is anchored at the end of each match.

Found by post-merge adversarial review of #29.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@yavorpanayotov yavorpanayotov merged commit 9517560 into main Jun 11, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Regression from #28 masking: string-literal value comparisons break (spurious/missed neverFires, missed impossibleWhen)

1 participant