Context
Mutation-testing run against main (b850e2fec11b1966d2b73670ae56b5eff195284e), mutmut 3.6.0, local run 2026-07-10: 1025 mutants, 151 killed, 235 survived, 639 no-tests.
This issue covers the orchestration layer in hooks/post-turn-quality-stop-hook.py: 81 survivors across prepare_run_stop_checks (71) and run_stop_checks (10) — the largest survivor cluster in the module.
Surviving mutants
hooks/post-turn-quality-stop-hook.py:1033-1044 — HookState(base_ref=None), shutil.which(None)/"XXgitXX"/"GIT", the "git not found on PATH" literal and its fail_state wiring, and every RunStopChecksPreparation field on the early-return paths (ok=None/True/removed, exit_code=None, state=None/removed) (x_prepare_run_stop_checks__mutmut_2–26).
hooks/post-turn-quality-stop-hook.py:1046-1073 — argument wiring of ensure_base_ref, merge_base, and changed_files (each argument replaced by None or dropped), state.fetched = None, state.base_commit = None, and the success-path exit_code=0 → None/1 (x_prepare_run_stop_checks__mutmut_33–97).
hooks/post-turn-quality-stop-hook.py:1124 — run_stop_checks signature default compush: bool = False → True (x_run_stop_checks__mutmut_1).
hooks/post-turn-quality-stop-hook.py:1147-1157 — prepare_run_stop_checks(start_cwd, None, …), always_fetch=None, and evaluate_changes argument wiring (x_run_stop_checks__mutmut_4, 5, 14–19).
hooks/post-turn-quality-stop-hook.py:1164 — final return 0 → return 1 (x_run_stop_checks__mutmut_23).
Analysis
TestRunStopChecksCompush patches repo_root, ensure_base_ref, merge_base, changed_files, and evaluate_changes, then asserts only the return code and whether compush_check was called. Nothing observes the state the orchestrator builds, the arguments it forwards, the JSON emitted on failure paths, or the fields of RunStopChecksPreparation, so the whole body mutates freely. prepare_run_stop_checks has no direct tests at all.
Suggested tests
- Direct unit tests on
prepare_run_stop_checks (mocking run or the named collaborators with call-argument assertions) covering: git missing from PATH (assert the blocked JSON reason equals "…git not found on PATH…" via capsys and exit_code == 0 semantics), non-repo cwd (assert ok is False, exit_code == 0, silent), ensure_base_ref/merge_base/changed_files failures (assert blocked JSON), and the success path (assert ok is True, exit_code == 0, repo, state.base_commit, state.changed_files, and state.fetched exactly).
- Assert collaborator call arguments (
ensure_base_ref(repo, base_ref, always_fetch=…), merge_base(repo, base_ref), changed_files(repo, base_commit), evaluate_changes(state, repo, max_out)) rather than only return codes.
- Call
run_stop_checks without the compush keyword and assert compush_check is not invoked (kills the signature-default mutant).
- One end-to-end test in a temporary git repository (clean tree, no changed files) asserting rc 0 and no output (kills the final
return 0 mutant and much of the wiring wholesale).
Full worklist: triage worklist.md; dataset SHA b850e2f.
Context
Mutation-testing run against
main(b850e2fec11b1966d2b73670ae56b5eff195284e), mutmut 3.6.0, local run 2026-07-10: 1025 mutants, 151 killed, 235 survived, 639 no-tests.This issue covers the orchestration layer in
hooks/post-turn-quality-stop-hook.py: 81 survivors acrossprepare_run_stop_checks(71) andrun_stop_checks(10) — the largest survivor cluster in the module.Surviving mutants
hooks/post-turn-quality-stop-hook.py:1033-1044—HookState(base_ref=None),shutil.which(None)/"XXgitXX"/"GIT", the"git not found on PATH"literal and itsfail_statewiring, and everyRunStopChecksPreparationfield on the early-return paths (ok=None/True/removed,exit_code=None,state=None/removed) (x_prepare_run_stop_checks__mutmut_2–26).hooks/post-turn-quality-stop-hook.py:1046-1073— argument wiring ofensure_base_ref,merge_base, andchanged_files(each argument replaced byNoneor dropped),state.fetched = None,state.base_commit = None, and the success-pathexit_code=0→None/1(x_prepare_run_stop_checks__mutmut_33–97).hooks/post-turn-quality-stop-hook.py:1124—run_stop_checkssignature defaultcompush: bool = False→True(x_run_stop_checks__mutmut_1).hooks/post-turn-quality-stop-hook.py:1147-1157—prepare_run_stop_checks(start_cwd, None, …),always_fetch=None, andevaluate_changesargument wiring (x_run_stop_checks__mutmut_4,5,14–19).hooks/post-turn-quality-stop-hook.py:1164— finalreturn 0→return 1(x_run_stop_checks__mutmut_23).Analysis
TestRunStopChecksCompushpatchesrepo_root,ensure_base_ref,merge_base,changed_files, andevaluate_changes, then asserts only the return code and whethercompush_checkwas called. Nothing observes thestatethe orchestrator builds, the arguments it forwards, the JSON emitted on failure paths, or the fields ofRunStopChecksPreparation, so the whole body mutates freely.prepare_run_stop_checkshas no direct tests at all.Suggested tests
prepare_run_stop_checks(mockingrunor the named collaborators with call-argument assertions) covering: git missing from PATH (assert the blocked JSON reason equals"…git not found on PATH…"via capsys andexit_code == 0semantics), non-repo cwd (assertok is False,exit_code == 0, silent),ensure_base_ref/merge_base/changed_filesfailures (assert blocked JSON), and the success path (assertok is True,exit_code == 0,repo,state.base_commit,state.changed_files, andstate.fetchedexactly).ensure_base_ref(repo, base_ref, always_fetch=…),merge_base(repo, base_ref),changed_files(repo, base_commit),evaluate_changes(state, repo, max_out)) rather than only return codes.run_stop_checkswithout thecompushkeyword and assertcompush_checkis not invoked (kills the signature-default mutant).return 0mutant and much of the wiring wholesale).Full worklist: triage
worklist.md; dataset SHAb850e2f.