with one click
mutation-hitlist
Work the weekly mutation-testing hit list (issue
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Menu
Work the weekly mutation-testing hit list (issue
Install with Codex or Claude Copy this prompt, paste it into Codex, Claude, or another assistant, and let it review the skill page and install it for you.
Based on SOC occupation classification
| name | mutation-hitlist |
| description | Work the weekly mutation-testing hit list (issue |
Issue #591 is the auto-updated tracking issue (workflow:
.github/workflows/mutation.yml, weekly schedule). Its body holds the score,
per-shard table, and a truncated top-50 hit list. Work happens in comments;
never edit the body.
gh issue view 591 --repo sleepypod/core --json body -q .body | head -80
gh issue view 591 --comments — prior weeks' work is recorded there).Each shard uploads mutation-report-<shard> containing mutation.json:
cd $(mktemp -d)
gh run download <RUN_ID> --repo sleepypod/core -n mutation-report-<shard>
python3 <repo>/.claude/skills/mutation-hitlist/survivors.py mutation.json <fileBasename>
Shard names: hardware-lib, homekit, hooks, server,
services-scheduler, streaming (see the matrix in mutation.yml).
origin/dev (test/<file>-mutants-591).git diff <trigger-commit> origin/dev --stat -- <file> <its test file> —
if the source changed since the run, line numbers are stale; re-run scoped
Stryker first instead of trusting the artifact.A killing test must FAIL when the mutation is applied. Expected test file is
<dir>/tests/<name>.test.ts. Prefer no source changes; if internals are
unreachable, extending an existing __test__ export with pure functions is
the accepted pattern (see piezoStream.ts).
Playbook by mutator:
StringLiteral in thrown errors / WS error messages → assert exact message
content, not just /some regex/ that an empty string can't fail.StringLiteral in console.log/warn → vi.spyOn(console, ...) and assert
expect.stringContaining(...) plus exact numeric args where deterministic.EqualityOperator (< vs <=) → test the exact boundary value.ConditionalExpression true/false → one test per branch, asserting the
branch-specific observable (message text, count, absence of a frame).BlockStatement {} on guards → assert the guarded side effect happened
(port refuses connections after shutdown, no duplicate frames, etc.).ArithmeticOperator on buffer offsets → multi-tick scenarios (partial
append, then seek) with exactly-once + content assertions.new Decoder({...}) options): activate at import; the vitest runner's
module cache makes them false survivors. Unkillable without per-mutant
process restart.setTimeout delays, yield cadence like
recordsSinceYield >= 500, read-chunk sizes that only change speed).Math.random() entropy, >= 0 on sizes iterated with
for..of over an empty set.Do NOT run Stryker locally — mutation runs happen in CI only.
pnpm exec vitest run src/<path>/tests/<file>.test.ts
Then let CI produce the mutation numbers:
mutation-test label to the PR —
mutation.yml runs on it and comments a summary.scope
input set to the target file glob (blank = all shard defaults).Pull the run's mutation-report-<shard> artifact and re-run survivors.py
on its mutation.json for the post-change survivor list.
dev, title test(<area>): kill <file> surviving mutants (#591 hit list),
with a test plan section.