Skip to content

test(mutation): make anchors resilient and stale-anchor failures self-explaining - #55

Merged
willytop8 merged 2 commits into
mainfrom
wr/mutation-anchor-resilience
Aug 7, 2026
Merged

test(mutation): make anchors resilient and stale-anchor failures self-explaining#55
willytop8 merged 2 commits into
mainfrom
wr/mutation-anchor-resilience

Conversation

@willytop8

Copy link
Copy Markdown
Owner

Makes the mutation contract's anchors survive honest edits, and makes a detached anchor say so.

Why

mutation-contract.mjs locates each of its 67 mutants by exact string match. Any legitimate edit to
an anchored line silently detaches the mutant, and the contract then fails with:

expected exactly one mutation target, found 0

which reads like a safety regression rather than a stale anchor. This happened on #53: widening
REPLAY_SAFE_OPERATIONS to include the read-only children/status operations — a correct change —
broke the build, and the message gave no hint that the fix was a one-line anchor update.

Changes

  • Anchors may be a RegExp, with to as a replacement string or a function of the match.
    Literal anchors still work and remain correct for pinned logic (a comparison, a call), where a
    change to the line genuinely should force someone to re-examine the mutant. Use a RegExp when the
    line carries a value that legitimately grows.
  • REPLAY_SAFE_OPERATIONS is re-anchored on its declaration rather than its members, so the set
    can gain read-only operations without detaching the mutant. Verified against the current form, the
    pre-feat: add noInterruptOnUserMessage and noContinueWhileChildrenActive options #53 form that broke, a hypothetical future widening, and reformatted spacing — all resolve to
    exactly one match and still inject prompt.
  • Stale-anchor failures explain themselves: they now name the file, state that this is a stale
    anchor rather than a failed property, say the guarded property is unverified until fixed, and point
    at the RegExp remedy. The >1 case gets its own distinct message.
  • New guard: an anchor that matches but whose replacement leaves the source unchanged now fails
    loudly. Previously that would run the test against unmutated source and "pass" for the wrong
    reason — the mutant is supposed to make the test fail.

Checks

npm run test:mutation — 67/67 critical mutants killed.

The stale-anchor path was verified by deliberately detaching an anchor and reading the output, then
restoring and re-running to confirm 67/67.

@willytop8 willytop8 closed this Aug 6, 2026
@willytop8 willytop8 reopened this Aug 6, 2026
@willytop8
willytop8 merged commit 62b2a19 into main Aug 7, 2026
10 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.

1 participant