Mutation testing
A green test suite proves that the tests pass. Mutation testing proves that the tests can fail. Stryker changes the source one small step at a time and runs the same suite. A mutant that survives is either a missing assertion or an equivalent change that no test can observe.
Run it
npm run mutationNarrow the matrix locally:
STRYKER_MUTATE=src/agent/session-swap-queue.ts npm run mutationRun the full matrix on demand with npm run mutation. The matrix is not a scheduled job.
Matrix
The default matrix is the state-machine core:
src/agent/loop-guard.tssrc/agent/session-swap-queue.ts
Add a module only when its test file runs fast and asserts observable behavior. Keep the matrix small; a wide matrix turns the run into noise.
Thresholds
stryker.config.mjs uses:
- high: 85
- low: 75
- break: 70
The break threshold fails the run. The first matrix run scored 72.96% overall: loop-guard.ts 73.65% and session-swap-queue.ts 68.97%. The swap-queue tests were added after the first run and raised it from 55.17%. Review the survivors before raising break. Many are redundant state writes. One survivor is the pending > 0 return-to-queued state; it is observable only in a narrow microtask window, and the direct queue test does not pin it.
Reading a survivor
- Read the mutation. If the changed line cannot affect an observable result, it is equivalent. Say so in the PR or the mutation note.
- If the line can change behavior, write the smallest test that fails without it. Add the test to the module's normal suite, not to the mutator.
- If the test would be slow or flaky, keep the survivor and record why in the escaped-defect log or the PR.
Do not chase 100%. A mutation score is a signal about test strength, not a release goal.
Escaped defects
Use escaped-defects.md when a defect reaches a release. Record the missing test and the mutation that would have caught it, then add the regression test.
Fault tests
Run the focused fault and state-machine set on demand:
npm test -- test/semantic-index.test.ts test/semantic-index-lease.test.ts \
test/session-swap-queue.test.ts test/session-manager.test.ts \
test/session-invariants.test.ts test/session-actions.test.ts \
test/agent-service.test.tsThat lane is the home for slow fault cases: failed writes, delayed reads, ENOENT, aborts at awaits, stale trees, and two-tab races.