ViolationDiff identifies violations by (property, code, valuePartIndex) and ignores args, so replacing one offending value with a different offending value at the same position is classified as pre-existing rather than new.
Consequence: guards that rely on "only new violations block" do not fire on an in-place swap. This includes the always-blocking relation-target-unresolvable-source violation from #1265: an existing unresolvable relation target can be edited into a different unresolvable target without the write being blocked, even though writing that target fresh would be refused.
Fix direction: include args (or the offending value) in the violation identity, while keeping genuinely unchanged statements non-blocking.
AI-authored — Claude Code, Fable 5 (max); found during the #1265 code review, filed on Jeroen's behalf; issue text not human-reviewed.
ViolationDiffidentifies violations by (property, code, valuePartIndex) and ignoresargs, so replacing one offending value with a different offending value at the same position is classified as pre-existing rather than new.Consequence: guards that rely on "only new violations block" do not fire on an in-place swap. This includes the always-blocking
relation-target-unresolvable-sourceviolation from #1265: an existing unresolvable relation target can be edited into a different unresolvable target without the write being blocked, even though writing that target fresh would be refused.Fix direction: include
args(or the offending value) in the violation identity, while keeping genuinely unchanged statements non-blocking.