Help us improve
Share bugs, ideas, or general feedback.
From jaan-to
Runs mutation testing to validate test suite quality across multiple stacks (Stryker, Infection, go-mutesting, mutmut, Vitest). Use when verifying test effectiveness or after generating tests.
npx claudepluginhub parhumm/jaan-to --plugin jaan-toHow this skill is triggered — by the user, by Claude, or both
Slash command
/jaan-to:qa-test-mutate [test-suite-path | qa-test-generate-output | (interactive)][test-suite-path | qa-test-generate-output | (interactive)]This skill is limited to the following tools:
The summary Claude sees in its skill listing — used to decide when to auto-load this skill
> Mutation testing is the only reliable quality metric for AI-generated test suites.
Performs mutation testing using Claude as the mutation engine: generates code mutants, runs tests, tracks kill/survive rates, identifies test gaps, and recommends test improvements. No external mutation tools required.
Runs mutation testing workflow: mutates source code module-by-module, executes tests per mutation, writes tests for survivors, verifies, commits. Tracks multi-session progress.
Validates test suite quality by introducing deliberate code mutations to expose weak assertions, missing edge cases, and dead test code.
Share bugs, ideas, or general feedback.
Mutation testing is the only reliable quality metric for AI-generated test suites.
$JAAN_CONTEXT_DIR/tech.md - Tech stack context (CRITICAL -- determines mutation framework)
#current-stack, #frameworks, #constraints$JAAN_LEARN_DIR/jaan-to-qa-test-mutate.learn.md - Past lessons (loaded in Pre-Execution)$JAAN_TEMPLATES_DIR/jaan-to-qa-test-mutate.template.md - Output template${CLAUDE_PLUGIN_ROOT}/docs/extending/language-protocol.md - Language resolution protocol${CLAUDE_PLUGIN_ROOT}/docs/research/76-tdd-bdd-ai-orchestration.md (Section 5)Test Suite Source: $ARGUMENTS
Input modes:
/jaan-to:qa-test-generate)IMPORTANT: The input above is your starting point. Determine mode and proceed accordingly.
MANDATORY -- Read and execute ALL steps in: ${CLAUDE_PLUGIN_ROOT}/docs/extending/pre-execution-protocol.md
Skill name: qa-test-mutate
Execute: Step 0 (Init Guard) -> A (Load Lessons) -> B (Resolve Template) -> C (Offer Template Seeding)
Also read context files if available:
$JAAN_CONTEXT_DIR/tech.md -- Know the tech stack for mutation framework selectionIf files do not exist, continue without them.
Read and apply language protocol: ${CLAUDE_PLUGIN_ROOT}/docs/extending/language-protocol.md
Override field for this skill: language_qa-test-mutate
Language exception: Generated code output (config files, JSON reports) is NOT affected by this setting and remains in English/code.
Iterative feedback loop (Steps 5-8 of Phase 2) requires Claude Code
Tasktool for sub-agent delegation. In Codex runtime, run single mutation pass only -- skip iterative feedback loop.
ultrathink
Use extended reasoning for:
Read $JAAN_CONTEXT_DIR/tech.md for stack detection. Select mutation framework:
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/qa-test-mutate-reference.mdsection "Multi-Stack Framework Table" for the supported stacks table (JS/TS, PHP, Go, Python), framework names, key CI features, and config files.
Unsupported stack fallback: If tech.md reports a stack not in the supported table (e.g., Java, Ruby, C#, Rust):
mutation_score: null in output, DO NOT failIf tech.md unavailable, use AskUserQuestion:
**/*.test.ts, **/*.spec.ts, **/*_test.go, **/test_*.py, **/Test*.php)npx --no-install stryker --version (never bare npx)vendor/bin/infection --versiongo-mutesting --versionmutmut --versionPresent discovery summary:
MUTATION TESTING ANALYSIS
-------------------------------------------------------------
Tech Stack: {detected stack}
Mutation Framework: {framework name} ({available/unavailable})
Test Runner: {runner name}
Test Files: {count} files
Test Commands: {detected test command}
Mutation Scope:
Source Files: {count} files to mutate
Test Files: {count} test files
Estimated Time: {rough estimate based on file count}
Based on stack and framework availability:
mutation_score: nullConfigure mutation run parameters:
Scope Decision:
Incremental Mode (apply when scope = incremental):
| Stack | Incremental Flag | Effect |
|---|---|---|
| JS/TS (StrykerJS) | incremental: true, incrementalFile: '.stryker-tmp/incremental.json' | Reuses ~94% of previous results via diff-match-patch |
| PHP (Infection) | --git-diff-lines --git-diff-base=main --only-covering-test-cases | Mutates only touched lines, runs only covering tests (3.3x speedup) |
| Go | N/A | No incremental support -- full runs only |
| Python | N/A | No incremental support -- full runs only |
Concurrency (always apply):
| Stack | Concurrency Flag | Notes |
|---|---|---|
| JS/TS (StrykerJS) | concurrency: N, coverageAnalysis: 'perTest' | Per-test analysis runs only tests covering each mutant |
| PHP (Infection) | --threads=max | Uses all available CPU cores |
| Go | N/A | Sequential execution only |
| Python | N/A | Sequential (community fork only) |
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/qa-test-mutate-reference.mdsections "Mutation Run Commands" and "CI Integration Patterns" for per-stack commands and config examples.
Thresholds (from jaan-to/config/settings.yaml or defaults):
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/qa-test-mutate-reference.mdsection "Scoring Rubric and Thresholds" for configurable threshold table.
Show complete plan before executing:
MUTATION TESTING PLAN
-------------------------------------------------------------
Framework: {mutation framework}
Available: {yes/no}
Scope: {incremental/full}
Source Files: {count} to mutate
Test Files: {count} test files
Test Command: {command}
Thresholds: Break={break}%, Target={target}%, Critical={critical}%
Feedback Loop: {enabled/disabled (Codex: disabled)}
Max Iterations: {2-3}
Output Folder: $JAAN_OUTPUTS_DIR/qa/test-mutate/{id}-{slug}/
Use AskUserQuestion:
Do NOT proceed to Phase 2 without explicit approval.
If mutation framework is unavailable for the detected stack:
mutation_score: null, empty survivors: []Execute the appropriate mutation command:
Reference: See
${CLAUDE_PLUGIN_ROOT}/docs/extending/qa-test-mutate-reference.mdsection "Mutation Run Commands" for per-stack execution commands and configuration.
Extract mutation score from mutation tool output only (never conflate with code coverage):
reports/mutation/mutation.json -> mutationScore fieldinfection-log.json -> stats.msi field (Mutation Score Indicator)killed/total ratio (no native JSON output)mutmut results CLI output -> parse survived/killed/total counts (NOT .mutmut-cache SQLite, which is unstable internal format)Write surviving mutants to handoff contract file:
Path: {output-folder}/{id}-{slug}-survivors.json
{
"schema_version": "1.0",
"tool": "{framework-name}",
"run_timestamp": "{ISO-8601}",
"mutation_score": {score or null},
"total_mutants": {count},
"killed": {count},
"survived": {count},
"survivors": [
{
"id": "mutant-{nnn}",
"file": "{relative/path/to/source.ext}",
"line": {line_number},
"original": "{original code snippet}",
"mutated": "{mutated code snippet}",
"mutator": "{MutatorName}",
"status": "Survived"
}
]
}
Contract rules:
tool field: free-form string (not enum). Known values: "stryker", "infection", "go-mutesting", "mutmut".file, line, original, mutated are REQUIRED per survivor.mutation_score: null (JSON null, not 0).If survivors artifact is empty OR mutation run failed:
Codex runtime: Skip this entire section. Single mutation pass only.
For each iteration (max 2-3, stop if delta < 5 points or delta < 2 points on iteration 2+):
Use Task tool to spawn sub-agent:
/jaan-to:qa-test-generate --from-mutants {survivors-json-path}original line and asserts behavior the mutated version would breakExecute mutation framework again with new tests added.
Calculate improvement delta:
delta = new_score - previous_scoreTrack iteration history:
Iteration Score Delta Survivors New Tests
--------- ------ ------ --------- ---------
1 72.5% -- 55 --
2 81.3% +8.8 38 17
3 84.1% +2.8 32 6 (stopped: delta < 5)
Compare final mutation score against configured thresholds:
| Threshold | Value | Result |
|---|---|---|
| Break CI | {break}% | {PASS/FAIL} |
| Target (new code) | {target}% | {PASS/FAIL} |
| Critical paths | {critical}% | {PASS/WARN if applicable} |
Before preview, validate:
file, line, original, mutated fieldssource "${CLAUDE_PLUGIN_ROOT}/scripts/lib/id-generator.sh"
SUBDOMAIN_DIR="$JAAN_OUTPUTS_DIR/qa/test-mutate"
mkdir -p "$SUBDOMAIN_DIR"
NEXT_ID=$(generate_next_id "$SUBDOMAIN_DIR")
Generate slug from feature/project name, lowercase-kebab-case, max 50 chars.
Template:
Mutation testing report for {project/feature} using {framework}. Mutation score: {score}%
({killed}/{total} mutants killed, {survived} survivors). {iterations} feedback iterations
performed. Threshold evaluation: Break CI {PASS/FAIL}, Target {PASS/FAIL}.
Top survivor locations: {top 3 file paths}.
MUTATION TESTING RESULTS
-------------------------------------------------------------
ID: {NEXT_ID}
Folder: $JAAN_OUTPUTS_DIR/qa/test-mutate/{NEXT_ID}-{slug}/
Framework: {framework}
Mutation Score: {score}% ({killed}/{total})
Survivors: {count}
Iterations: {count}
Threshold Results:
Break CI (60%): {PASS/FAIL}
Target (80%): {PASS/FAIL}
Critical (90%): {PASS/WARN/N/A}
Top 5 Survivor Locations:
1. {file}:{line} - {mutator}
2. {file}:{line} - {mutator}
...
Files:
{id}-{slug}.md (Mutation report)
{id}-{slug}-survivors.json (Survivors handoff contract)
Use AskUserQuestion:
If approved:
OUTPUT_FOLDER="$JAAN_OUTPUTS_DIR/qa/test-mutate/${NEXT_ID}-${slug}"
mkdir -p "$OUTPUT_FOLDER"
Path: $OUTPUT_FOLDER/${NEXT_ID}-${slug}.md
Sections:
Path: $OUTPUT_FOLDER/${NEXT_ID}-${slug}-survivors.json
Per contract defined in Step 4.3.
source "${CLAUDE_PLUGIN_ROOT}/scripts/lib/index-updater.sh"
add_to_index \
"$SUBDOMAIN_DIR/README.md" \
"$NEXT_ID" \
"${NEXT_ID}-${slug}" \
"{Feature/Project} Mutation Report" \
"{Executive Summary}"
MUTATION TESTING COMPLETE
-------------------------------------------------------------
ID: {NEXT_ID}
Folder: $JAAN_OUTPUTS_DIR/qa/test-mutate/{NEXT_ID}-{slug}/
Index: Updated $JAAN_OUTPUTS_DIR/qa/test-mutate/README.md
Score: {score}%
Survivors: {count}
Iterations: {count}
Next Steps:
- Review survivors and strengthen tests manually
- Run /jaan-to:qa-test-generate --from-mutants {survivors-json-path} for targeted tests
- Integrate mutation CI stage via /jaan-to:devops-infra-scaffold
Use AskUserQuestion:
If "Learn from this": Run /jaan-to:learn-add qa-test-mutate "{feedback}"
tech.md detection with unsupported-stack fallback$JAAN_OUTPUTS_DIR path{id}-{slug}/{id}-{slug}.md{id}-{slug}-survivors.json