Skip to content

chore(cli): mutate only the lines a branch changed - #848

Merged
blafourcade merged 1 commit into
nextfrom
chore/mutate-only-changed-lines
Sep 11, 2026
Merged

chore(cli): mutate only the lines a branch changed#848
blafourcade merged 1 commit into
nextfrom
chore/mutate-only-changed-lines

Conversation

@blafourcade

Copy link
Copy Markdown
Contributor

🎯 What & why

Mutation-testing a change before pushing meant running a whole scope. The alternative was turning git diff -U0 into --mutate file:start-end ranges by hand, which was done five times in one session (#842).

🛠️ How it works

node scripts/run-mutation.mjs --changed [<base>]:

  1. It diffs the working tree against its merge base with <base> (default origin/next). Uncommitted edits count.
  2. It keeps only the lines added or changed under src/, as file:start-end ranges. A pure deletion adds no line, and a file outside src/ belongs to no scope.
  3. It runs Stryker on those ranges only, and names each survivor with its file, line and mutator.

It holds no floor and passes no --incremental file, so it never moves a scope's gate or its cached results. Its reports go to reports/mutation/changed/.

Three pure functions carry the logic, and each has a test in mutation-covers-source.arch.test.ts's "the guard itself":

  • changedRanges(diff);
  • changedArgs(ranges);
  • survivorsOf(report).

The report filing both modes share moved into fileReports. cli/aidd_docs/memory/testing.md has one line for the new mode.

🧪 How to verify

  • Red first: the two new tests failed with changedRanges is not a function and survivorsOf is not a function.
  • Real runs, with a throwaway HOME:
Command Result
--changed HEAD No line under src/ changed since HEAD: nothing to mutate.
--changed origin/next~1 (#836, a rename and one import) no mutant on those lines, 1 changed range(s)
--changed origin/next~2 (adds #835) score 97.6, 16 changed range(s); one survivor named: marketplace-sync-settings-use-case.ts:577 StringLiteral (the equivalent mutant #835 documents)
after all three no incremental.json written

Local gates: typecheck, lint, knip, architecture 17/17 in the touched file.

⚠️ Heads-up

  • No package script is added: mutation-covers-source.arch.test.ts requires every test:mutation:* script to be a declared scope, and --changed is not one.
  • Untracked new files are not in git diff, so --changed does not see them until they are added.

🔗 Linked issue

Fixes #842

✅ I certify

  • I DO CERTIFY I READ EACH LINE OF THE PULL REQUEST BECAUSE I AM A SOFTWARE ENGINEER, NOT A AI PUPPY.

🤖 Generated with Claude Code

https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb

@blafourcade
blafourcade requested a review from a team as a code owner September 11, 2026 04:18
Checking a change with mutation meant running a whole scope, or turning
`git diff -U0` into `--mutate file:start-end` ranges by hand. That was done
five times in one session.

`node scripts/run-mutation.mjs --changed [<base>]` diffs the working tree
against its merge base with `<base>` (default `origin/next`), mutates only
the lines added or changed under `src/`, and names each survivor with its
file and line. It holds no floor and passes no incremental file, so it
never moves a scope's gate or its cached results.

Fixes #842

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011x4ms5qcGuZgYhCxfdHMUb
AIDD-Session-Id: 4acc9a1c-19bc-4468-b8b6-e86644bcba60
@blafourcade
blafourcade force-pushed the chore/mutate-only-changed-lines branch from d996068 to a173094 Compare September 11, 2026 05:28
@blafourcade
blafourcade merged commit 8da878f into next Sep 11, 2026
36 checks passed
@blafourcade
blafourcade deleted the chore/mutate-only-changed-lines branch September 11, 2026 07:42
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