Skip to main content

mutation-night-watch

Launch, schedule, and hand off an unattended, LLM-free overnight mutation night-watch run. Use when the user wants a mutation-score baseline waiting each morning without paying LLM cost or blocking a session overnight, says "run mutation testing overnight", "schedule a nightly mutation scan", "set up a mutation night watch", or asks how to get an unattended mutation baseline. Wraps mutation_nightwatch.py — report-only measurement, never generation.

Source facts

Repository
bdfinst/agentic-dev-team
Last source activity
August 5, 2026 at 19:33
Detected SKILL.md language
English
Stars
302
Forks
35

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

File Explorer
2 files

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
mutation-night-watch
description
Launch, schedule, and hand off an unattended, LLM-free overnight mutation night-watch run. Use when the user wants a mutation-score baseline waiting each morning without paying LLM cost or blocking a session overnight, says "run mutation testing overnight", "schedule a nightly mutation scan", "set up a mutation night watch", or asks how to get an unattended mutation baseline. Wraps mutation_nightwatch.py — report-only measurement, never generation.
role
worker
user-invocable
true
allowed-tools
Read, Write, Bash(python3 *), Bash(launchctl *), Bash(crontab *), Bash(schtasks *)
# Mutation Night-Watch Role: worker. Launches and schedules a report-only measurement run. It never generates a test, never invokes an LLM, and never commits — that is the `mutation-kill` agent's job, the next morning, reading this skill's output. > **Naming note.** The skill is named `mutation-night-watch`; its underlying > scripts, output directory (`reports/mutation-nightwatch/`), and launchd > label use `mutation_nightwatch`/`mutation-nightwatch` — this is an > intentional, stable naming split; do not rename the on-disk paths without a > migration plan (#1856). ## Why this exists, and how it differs from `mutation-kill` `mutation-kill` already has two modes: **interactive** (an agent generates tests turn by turn) and **`--headless`** (unattended, but every round still shells out to `claude --print` — LLM cost and API availability are both in the loop). Neither mode is meant to run **overnight with nobody watching**: a multi-hour unattended `claude --print` loop is expensive and, on a flaky network, silently stalls. Night-watch is a **third, LLM-free mode**: measurement only. It runs the real mutation tool for each detected stack, scores the result with the same [`mutation_report.py`](../mutation-testing/scripts/mutation_report.py) the rest of the mutation-testing skill family uses, and writes the result where `mutation-kill` (or a human) picks it up the next day. It does not replace `mutation-kill`'s fixing modes — see [`mutation-testing/SKILL.md`](../mutation-testing/SKILL.md) for those. ## Constraints - **Report-only. Never generation.** The script ([`../mutation-testing/scripts/mutation_nightwatch.py`](../mutation-testing/scripts/mutation_nightwatch.py)) has no code path that shells to an LLM. If a stack's tool run mutates a survivor count, that is the mutation tool itself running normally — nothing here writes a test. - **Mechanical repair only, never code.** Before measuring, the script runs each stack's package-pin-sync step (`npm ci` when `node_modules` is missing, `dotnet restore`) so a stale dependency tree doesn't fail the whole run on a mechanical break. It never edits a production or test file, and never commits — see the script's `mechanical_repair`. - **Detected-but-unscored stacks are reported, not guessed.** pitest (Java) and go-mutesting (Go) are detected but have no `mutation_report.py` parser yet; they show up in the summary as `skipped_no_parser`, never a fabricated score. - **Always confirm scope before scheduling a recurring run.** A single ad hoc `--detach` launch needs no extra confirmation beyond what the user already asked for; wiring a scheduler entry (Task Scheduler / launchd / cron) that runs unattended on a recurring cadence is a standing change to the user's machine — confirm the schedule and scope before writing the scheduler config. ## Step 1: Detect and preview scope Run once without `--detach` on a small scope, or just read the detection output, before committing to an overnight run: ```bash python3 "${CLAUDE_PLUGIN_ROOT}/skills/mutation-testing/scripts/mutation_nightwatch.py" --repo-root . --no-sleep-inhibit ``` This prints the run directory and writes `MORNING-SUMMARY.md` + `SURVIVORS.json` there and into `reports/mutation-nightwatch/LATEST/`. Read the summary's stack table before scheduling a longer, detached run — a stack reporting `skipped` (no unique `.sln`, no `stryker-config.json`) or `skipped_no_parser` needs attention first, not a repeat overnight run that will report the same gap every time. ## Step 2: Launch detached (survives closing the terminal/session) ```bash python3 "${CLAUDE_PLUGIN_ROOT}/skills/mutation-testing/scripts/mutation_nightwatch.py" --repo-root . --detach ``` `--detach` re-execs the script into a new session/process group (POSIX `setsid`-equivalent; Windows `DETACHED_PROCESS`) and returns immediately, printing the child's PID and its `detached-launch.log` path. The run continues after the launching terminal or Claude Code session closes. While running, the script holds the OS awake for the run's duration: `caffeinate -dims` on macOS, `systemd-inhibit --what=sleep:idle` on Linux, `SetThreadExecutionState` directly on Windows. When none of those are available, the run still proceeds — but `MORNING-SUMMARY.md`'s Notes section always carries an explicit `NOTE: sleep inhibition unavailable on <platform>` line rather than silently risking a sleep-interrupted run. Treat that NOTE as actionable: install the missing tool, or accept the machine may sleep mid-run. ## Step 3: Schedule a recurring run (optional) Per-OS recipes — Task Scheduler, launchd, and cron — live in [`references/scheduling.md`](references/scheduling.md). Confirm the cadence and scope with the user before writing any of these (see Constraints above); they run unattended, indefinitely, until removed. ## Step 4: Morning hand-off Read `reports/mutation-nightwatch/LATEST/MORNING-SUMMARY.md` first — it carries per-stack status, the honest score, and any Notes (sleep inhibition, mechanical-repair failures) from the most recent run, regardless of that run's timestamped folder name. Both files are refreshed after every module completes, not only when the run finishes cleanly — a mid-run kill or timeout still leaves whatever finished so far, never nothing. `SURVIVORS.json` alongside it is the machine-readable list (`{stack, module, file, line, mutator, change, status}` per survivor) — hand it to the `mutation-kill` agent (or triage it per [`mutation-testing/SKILL.md`](../mutation-testing/SKILL.md) Step 4) rather than re-running the scan to rediscover the same survivors. A stack reporting `error` in the summary table did not produce a report at all this run (tool missing, timed out, or crashed before writing its native report) — its prior night's `SURVIVORS.json` entries (if any) are stale, not confirmed-fixed; re-run that stack before trusting a "clean" reading. **Exclude-policy proposal, if present.** When the summary's Notes mention no committed `mutation-exclude-policy.json` was found, review `reports/mutation-nightwatch/LATEST/EXCLUDE-POLICY-PROPOSAL.json` — its `always` entries carry a filename-convention hint (DI wiring, middleware, generated code), its `propose_and_ask` entries are signal-only and need a human look. Approve what you agree with: ```bash python3 "${CLAUDE_PLUGIN_ROOT}/skills/mutation-testing/scripts/mutation_exclude_policy.py" --approve reports/mutation-nightwatch/LATEST/EXCLUDE-POLICY-PROPOSAL.json --repo-root . ``` This is the only code path that writes the committed policy file — the night-watch run itself only ever drafts a proposal, never approves one. ## When not to apply - No mutation tool is set up yet for any stack → run [`mutation-testing`](../mutation-testing/SKILL.md) interactively first to get one configured and smoke-gated; night-watch only measures, it does not install or configure a tool. - The repo is small enough that a mutation run finishes in a few minutes → just run `mutation-testing` directly; detach/sleep-inhibition/scheduling are overhead a short run doesn't need. - Java (pitest) or Go (go-mutesting) is the *only* detected stack → night- watch will report `skipped_no_parser`/never invoke the tool; use `mutation-testing` directly for those ecosystems today.
View on GitHub