Context
Local mutation-testing run against main at 3c1fa01bcf4c26dac79975c18b74c01d577dcf95 (mutmut 3.6.0, committed [tool.mutmut] configuration: source_paths = ["workflow_scripts/"], test selection workflow_scripts/tests/, act-gated workflow tests excluded). Run totals: 1463 mutants — 979 killed, 478 survived, 5 no-tests, 1 timeout.
These scripts power the estate's CI, so mutation gaps here matter most. This issue covers one coherent area; sibling issues cover the rest. Equivalent mutants are recorded in the triage worklist and deliberately omitted here. Inspect any survivor with uv run --with mutmut==3.6.0 mutmut show <name>; names below are workflow_scripts.<module>.x_<function>__mutmut_<n> with the numbers listed per line.
Analysis
mutation_run_mutmut.py is the helper that runs mutmut inside caller repositories — a gap here weakens mutation testing across the whole estate. The uv run --with mutmut==<version> mutmut ... command construction is asserted only loosely (individual flag mutants such as --WITH, --ALL, and TRUE survive, each of which would break the real invocation), the failure path's stderr routing and diagnostics are unasserted, and the job-summary Markdown is not snapshot-tested. count_statuses survives an accumulation bug (+= 1 → = 1) because no fixture has two mutants sharing a status. 50 survivors are real test gaps; 6 are accepted (below).
Suggested tests
- Assert the exact argv for both invocations (cmd-mox or the emitted
mutation_mutmut_command line): uv run --with mutmut==<version> mutmut run <extra> <globs> and ... mutmut results --all true. One equality assertion per command kills every flag-token mutant, including _mutmut_command variants.
- The failing-run path: a stubbed non-zero
mutmut run must emit mutation_mutmut_exit_code=<code> on stdout, the mutation_mutmut_error=... diagnostic on stderr (assert the stream and the exact message including the code), and raise SystemExit with the same code.
- Snapshot (syrupy) tests of
render_summary and _render_survivor_table covering: no results, results with survivors and no tests entries, and results without survivors — pinning the heading, count lines, and table markup kills all Markdown-string mutants.
count_statuses with two mutants sharing a status, asserting the count is 2.
_parse_result_line with a space-containing name (must return None) to kill the mangled-separator guard.
_publish_results: assert the results artefact file content equals the captured output and that mutation_mutmut_counts= is emitted with the exact JSON payload.
Accepted survivors (no test to write)
_publish_results mutants 12, 14, 21, 23 (workflow_scripts/mutation_run_mutmut.py:273,275): locale-dependent encoding=None/omitted-encoding variants, equivalent on UTF-8 CI runners. Candidate # pragma: no mutate.
_run_mutation_testing mutants 18 and 19 (workflow_scripts/mutation_run_mutmut.py:257): RETCODE(FG=...) only toggles plumbum's console streaming; the captured exit code is identical, so no in-process test can observe the change. Candidate # pragma: no mutate.
Surviving mutants
workflow_scripts/mutation_run_mutmut.py:145 in _parse_result_line (mutants 3; 2-equivalent)
- original:
name, separator, status = line.partition(": ")
- 3:
name, separator, status = line.rpartition(": ") — mutmut result lines contain a single ': ' separator; rpartition matches
workflow_scripts/mutation_run_mutmut.py:148 in _parse_result_line (mutants 8; 1-test-gap)
- original:
is_mutant_name = " " not in name and "__mutmut_" in name
- 8:
is_mutant_name = "XX XX" not in name and "__mutmut_" in name
workflow_scripts/mutation_run_mutmut.py:189 in count_statuses (mutants 2; 1-test-gap)
- original:
counts[result.status] += 1
- 2:
counts[result.status] = 1
workflow_scripts/mutation_run_mutmut.py:198 in _render_survivor_table (mutants 3; 1-test-gap)
- original:
### Surviving mutants",
- 3:
XX### Surviving mutantsXX",
workflow_scripts/mutation_run_mutmut.py:199 in _render_survivor_table (mutants 6, 10; 1-test-gap)
- original:
,
- 6:
XXXX",
- 10:
XXXX",
workflow_scripts/mutation_run_mutmut.py:200 in _render_survivor_table (mutants 7, 8, 9; 1-test-gap)
- original:
Inspect a survivor with uv run mutmut show .",
- 7:
XXInspect a survivor with uv run mutmut show .XX",
- 8:
inspect a survivor with uv run mutmut show .",
- 9:
INSPECT A SURVIVOR WITH UV RUN MUTMUT SHOW .",
workflow_scripts/mutation_run_mutmut.py:202 in _render_survivor_table (mutants 11, 12, 13; 1-test-gap)
- original:
| Mutant | Status |",
- 11:
XX| Mutant | Status |XX",
- 12:
| mutant | status |",
- 13:
| MUTANT | STATUS |",
workflow_scripts/mutation_run_mutmut.py:203 in _render_survivor_table (mutants 14; 1-test-gap)
- original:
| ------ | ------ |",
- 14:
XX| ------ | ------ |XX",
workflow_scripts/mutation_run_mutmut.py:206 in _render_survivor_table (mutants 16; 1-test-gap)
- original:
return [*header, *rows, ""]
- 16:
return [*header, *rows, "XXXX"]
workflow_scripts/mutation_run_mutmut.py:225 in render_summary (mutants 2, 5; 1-test-gap)
- original:
lines = ["## Mutation testing results (mutmut)", ""]
- 2:
lines = ["XX## Mutation testing results (mutmut)XX", ""]
- 5:
lines = ["## Mutation testing results (mutmut)", "XXXX"]
workflow_scripts/mutation_run_mutmut.py:227 in render_summary (mutants 8, 9, 12; 1-test-gap)
- original:
return "\\n".join((*lines, "No mutants were tested.", ""))
- 8:
return "XX\\nXX".join((*lines, "No mutants were tested.", ""))
- 9:
return "\\n".join((*lines, "XXNo mutants were tested.XX", ""))
- 12:
return "\\n".join((*lines, "No mutants were tested.", "XXXX"))
workflow_scripts/mutation_run_mutmut.py:230 in render_summary (mutants 18; 1-test-gap)
- original:
lines.append("")
- 18:
lines.append("XXXX")
workflow_scripts/mutation_run_mutmut.py:233 in render_summary (mutants 24; 1-test-gap)
- original:
return "\\n".join(lines)
- 24:
return "XX\\nXX".join(lines)
workflow_scripts/mutation_run_mutmut.py:238 in _mutmut_command (mutants 1, 3, 4; 1-test-gap)
- original:
return ["run", "--with", f"mutmut=={version}", "mutmut"]
- 1:
return ["XXrunXX", "--with", f"mutmut=={version}", "mutmut"]
- 3:
return ["run", "XX--withXX", f"mutmut=={version}", "mutmut"]
- 4:
return ["run", "--WITH", f"mutmut=={version}", "mutmut"]
workflow_scripts/mutation_run_mutmut.py:251 in _run_mutation_testing (mutants 2; 1-test-gap)
- original:
*_mutmut_command(mutmut_version),
- 2:
*_mutmut_command(None),
workflow_scripts/mutation_run_mutmut.py:256 in _run_mutation_testing (mutants 6, 7, 10, 11, 12, 13; 1-test-gap)
- original:
emit("mutation_mutmut_command", ["uv", *run_arguments])
- 6:
emit(None, ["uv", *run_arguments])
- 7:
emit("mutation_mutmut_command", None)
- 10:
emit("XXmutation_mutmut_commandXX", ["uv", *run_arguments])
- 11:
emit("MUTATION_MUTMUT_COMMAND", ["uv", *run_arguments])
- 12:
emit("mutation_mutmut_command", ["XXuvXX", *run_arguments])
- 13:
emit("mutation_mutmut_command", ["UV", *run_arguments])
workflow_scripts/mutation_run_mutmut.py:257 in _run_mutation_testing (mutants 18, 19; 4-untestable)
- original:
code = local["uv"][run_arguments] & RETCODE(FG=True)
- 18:
code = local["uv"][run_arguments] & RETCODE(FG=None) — plumbum RETCODE(FG=...) only toggles console streaming; exit code identical
- 19:
code = local["uv"][run_arguments] & RETCODE(FG=False) — plumbum RETCODE(FG=...) only toggles console streaming; exit code identical
workflow_scripts/mutation_run_mutmut.py:258 in _run_mutation_testing (mutants 20, 21, 24, 25; 1-test-gap)
- original:
emit("mutation_mutmut_exit_code", code)
- 20:
emit(None, code)
- 21:
emit("mutation_mutmut_exit_code", None)
- 24:
emit("XXmutation_mutmut_exit_codeXX", code)
- 25:
emit("MUTATION_MUTMUT_EXIT_CODE", code)
workflow_scripts/mutation_run_mutmut.py:261 in _run_mutation_testing (mutants 28, 34, 35; 1-test-gap)
- original:
mutation_mutmut_error",
- 28:
None,
- 34:
XXmutation_mutmut_errorXX",
- 35:
MUTATION_MUTMUT_ERROR",
workflow_scripts/mutation_run_mutmut.py:262 in _run_mutation_testing (mutants 29; 1-test-gap)
- original:
f"mutmut run failed with exit code {code} (failing baseline?)",
- 29:
None,
workflow_scripts/mutation_run_mutmut.py:263 in _run_mutation_testing (mutants 30; 1-test-gap)
- original:
stream=sys.stderr,
- 30:
stream=None,
workflow_scripts/mutation_run_mutmut.py:263 in _run_mutation_testing (mutants 33; 1-test-gap)
- original:
stream=sys.stderr, / )
- 33:
)
workflow_scripts/mutation_run_mutmut.py:271 in _publish_results (mutants 4, 5, 7, 8, 9, 10; 1-test-gap)
- original:
*_mutmut_command(mutmut_version), "results", "--all", "true
- 4:
*_mutmut_command(None), "results", "--all", "true
- 5:
*_mutmut_command(mutmut_version), "XXresultsXX", "--all", "true
- 7:
*_mutmut_command(mutmut_version), "results", "XX--allXX", "true
- 8:
*_mutmut_command(mutmut_version), "results", "--ALL", "true
- 9:
*_mutmut_command(mutmut_version), "results", "--all", "XXtrueXX
- 10:
*_mutmut_command(mutmut_version), "results", "--all", "TRUE
workflow_scripts/mutation_run_mutmut.py:273 in _publish_results (mutants 12, 14, 17; 2-equivalent/4-untestable)
- original:
Path(results_file).write_text(results_text, encoding="utf-8")
- 12:
Path(results_file).write_text(results_text, encoding=None) — encoding=None locale-dependent
- 14:
Path(results_file).write_text(results_text, ) — encoding omitted, locale-dependent
- 17:
Path(results_file).write_text(results_text, encoding="UTF-8") — UTF-8 codec alias
workflow_scripts/mutation_run_mutmut.py:275 in _publish_results (mutants 21, 23, 28; 2-equivalent/4-untestable)
- original:
with Path(summary_path).open("a", encoding="utf-8") as handle:
- 21:
with Path(summary_path).open("a", encoding=None) as handle: — encoding=None locale-dependent
- 23:
with Path(summary_path).open("a", ) as handle: — encoding omitted, locale-dependent
- 28:
with Path(summary_path).open("a", encoding="UTF-8") as handle: — UTF-8 codec alias
workflow_scripts/mutation_run_mutmut.py:277 in _publish_results (mutants 31, 32, 35, 36; 1-test-gap)
- original:
emit("mutation_mutmut_counts", count_statuses(results))
- 31:
emit(None, count_statuses(results))
- 32:
emit("mutation_mutmut_counts", None)
- 35:
emit("XXmutation_mutmut_countsXX", count_statuses(results))
- 36:
emit("MUTATION_MUTMUT_COUNTS", count_statuses(results))
Context
Local mutation-testing run against
mainat3c1fa01bcf4c26dac79975c18b74c01d577dcf95(mutmut 3.6.0, committed[tool.mutmut]configuration:source_paths = ["workflow_scripts/"], test selectionworkflow_scripts/tests/, act-gated workflow tests excluded). Run totals: 1463 mutants — 979 killed, 478 survived, 5 no-tests, 1 timeout.These scripts power the estate's CI, so mutation gaps here matter most. This issue covers one coherent area; sibling issues cover the rest. Equivalent mutants are recorded in the triage worklist and deliberately omitted here. Inspect any survivor with
uv run --with mutmut==3.6.0 mutmut show <name>; names below areworkflow_scripts.<module>.x_<function>__mutmut_<n>with the numbers listed per line.Analysis
mutation_run_mutmut.pyis the helper that runs mutmut inside caller repositories — a gap here weakens mutation testing across the whole estate. Theuv run --with mutmut==<version> mutmut ...command construction is asserted only loosely (individual flag mutants such as--WITH,--ALL, andTRUEsurvive, each of which would break the real invocation), the failure path's stderr routing and diagnostics are unasserted, and the job-summary Markdown is not snapshot-tested.count_statusessurvives an accumulation bug (+= 1→= 1) because no fixture has two mutants sharing a status. 50 survivors are real test gaps; 6 are accepted (below).Suggested tests
mutation_mutmut_commandline):uv run --with mutmut==<version> mutmut run <extra> <globs>and... mutmut results --all true. One equality assertion per command kills every flag-token mutant, including_mutmut_commandvariants.mutmut runmust emitmutation_mutmut_exit_code=<code>on stdout, themutation_mutmut_error=...diagnostic on stderr (assert the stream and the exact message including the code), and raiseSystemExitwith the same code.render_summaryand_render_survivor_tablecovering: no results, results with survivors andno testsentries, and results without survivors — pinning the heading, count lines, and table markup kills all Markdown-string mutants.count_statuseswith two mutants sharing a status, asserting the count is 2._parse_result_linewith a space-containing name (must returnNone) to kill the mangled-separator guard._publish_results: assert the results artefact file content equals the captured output and thatmutation_mutmut_counts=is emitted with the exact JSON payload.Accepted survivors (no test to write)
_publish_resultsmutants 12, 14, 21, 23 (workflow_scripts/mutation_run_mutmut.py:273,275): locale-dependentencoding=None/omitted-encoding variants, equivalent on UTF-8 CI runners. Candidate# pragma: no mutate._run_mutation_testingmutants 18 and 19 (workflow_scripts/mutation_run_mutmut.py:257):RETCODE(FG=...)only toggles plumbum's console streaming; the captured exit code is identical, so no in-process test can observe the change. Candidate# pragma: no mutate.Surviving mutants
workflow_scripts/mutation_run_mutmut.py:145in_parse_result_line(mutants 3; 2-equivalent)name, separator, status = line.partition(": ")name, separator, status = line.rpartition(": ")— mutmut result lines contain a single ': ' separator; rpartition matchesworkflow_scripts/mutation_run_mutmut.py:148in_parse_result_line(mutants 8; 1-test-gap)is_mutant_name = " " not in name and "__mutmut_" in nameis_mutant_name = "XX XX" not in name and "__mutmut_" in nameworkflow_scripts/mutation_run_mutmut.py:189incount_statuses(mutants 2; 1-test-gap)counts[result.status] += 1counts[result.status] = 1workflow_scripts/mutation_run_mutmut.py:198in_render_survivor_table(mutants 3; 1-test-gap)### Surviving mutants",XX### Surviving mutantsXX",workflow_scripts/mutation_run_mutmut.py:199in_render_survivor_table(mutants 6, 10; 1-test-gap),XXXX",XXXX",workflow_scripts/mutation_run_mutmut.py:200in_render_survivor_table(mutants 7, 8, 9; 1-test-gap)Inspect a survivor withuv run mutmut show.",XXInspect a survivor withuv run mutmut show.XX",inspect a survivor withuv run mutmut show.",INSPECT A SURVIVOR WITHUV RUN MUTMUT SHOW.",workflow_scripts/mutation_run_mutmut.py:202in_render_survivor_table(mutants 11, 12, 13; 1-test-gap)| Mutant | Status |",XX| Mutant | Status |XX",| mutant | status |",| MUTANT | STATUS |",workflow_scripts/mutation_run_mutmut.py:203in_render_survivor_table(mutants 14; 1-test-gap)| ------ | ------ |",XX| ------ | ------ |XX",workflow_scripts/mutation_run_mutmut.py:206in_render_survivor_table(mutants 16; 1-test-gap)return [*header, *rows, ""]return [*header, *rows, "XXXX"]workflow_scripts/mutation_run_mutmut.py:225inrender_summary(mutants 2, 5; 1-test-gap)lines = ["## Mutation testing results (mutmut)", ""]lines = ["XX## Mutation testing results (mutmut)XX", ""]lines = ["## Mutation testing results (mutmut)", "XXXX"]workflow_scripts/mutation_run_mutmut.py:227inrender_summary(mutants 8, 9, 12; 1-test-gap)return "\\n".join((*lines, "No mutants were tested.", ""))return "XX\\nXX".join((*lines, "No mutants were tested.", ""))return "\\n".join((*lines, "XXNo mutants were tested.XX", ""))return "\\n".join((*lines, "No mutants were tested.", "XXXX"))workflow_scripts/mutation_run_mutmut.py:230inrender_summary(mutants 18; 1-test-gap)lines.append("")lines.append("XXXX")workflow_scripts/mutation_run_mutmut.py:233inrender_summary(mutants 24; 1-test-gap)return "\\n".join(lines)return "XX\\nXX".join(lines)workflow_scripts/mutation_run_mutmut.py:238in_mutmut_command(mutants 1, 3, 4; 1-test-gap)return ["run", "--with", f"mutmut=={version}", "mutmut"]return ["XXrunXX", "--with", f"mutmut=={version}", "mutmut"]return ["run", "XX--withXX", f"mutmut=={version}", "mutmut"]return ["run", "--WITH", f"mutmut=={version}", "mutmut"]workflow_scripts/mutation_run_mutmut.py:251in_run_mutation_testing(mutants 2; 1-test-gap)*_mutmut_command(mutmut_version),*_mutmut_command(None),workflow_scripts/mutation_run_mutmut.py:256in_run_mutation_testing(mutants 6, 7, 10, 11, 12, 13; 1-test-gap)emit("mutation_mutmut_command", ["uv", *run_arguments])emit(None, ["uv", *run_arguments])emit("mutation_mutmut_command", None)emit("XXmutation_mutmut_commandXX", ["uv", *run_arguments])emit("MUTATION_MUTMUT_COMMAND", ["uv", *run_arguments])emit("mutation_mutmut_command", ["XXuvXX", *run_arguments])emit("mutation_mutmut_command", ["UV", *run_arguments])workflow_scripts/mutation_run_mutmut.py:257in_run_mutation_testing(mutants 18, 19; 4-untestable)code = local["uv"][run_arguments] & RETCODE(FG=True)code = local["uv"][run_arguments] & RETCODE(FG=None)— plumbum RETCODE(FG=...) only toggles console streaming; exit code identicalcode = local["uv"][run_arguments] & RETCODE(FG=False)— plumbum RETCODE(FG=...) only toggles console streaming; exit code identicalworkflow_scripts/mutation_run_mutmut.py:258in_run_mutation_testing(mutants 20, 21, 24, 25; 1-test-gap)emit("mutation_mutmut_exit_code", code)emit(None, code)emit("mutation_mutmut_exit_code", None)emit("XXmutation_mutmut_exit_codeXX", code)emit("MUTATION_MUTMUT_EXIT_CODE", code)workflow_scripts/mutation_run_mutmut.py:261in_run_mutation_testing(mutants 28, 34, 35; 1-test-gap)mutation_mutmut_error",None,XXmutation_mutmut_errorXX",MUTATION_MUTMUT_ERROR",workflow_scripts/mutation_run_mutmut.py:262in_run_mutation_testing(mutants 29; 1-test-gap)f"mutmut run failed with exit code {code} (failing baseline?)",None,workflow_scripts/mutation_run_mutmut.py:263in_run_mutation_testing(mutants 30; 1-test-gap)stream=sys.stderr,stream=None,workflow_scripts/mutation_run_mutmut.py:263in_run_mutation_testing(mutants 33; 1-test-gap)stream=sys.stderr, / ))workflow_scripts/mutation_run_mutmut.py:271in_publish_results(mutants 4, 5, 7, 8, 9, 10; 1-test-gap)*_mutmut_command(mutmut_version), "results", "--all", "true*_mutmut_command(None), "results", "--all", "true*_mutmut_command(mutmut_version), "XXresultsXX", "--all", "true*_mutmut_command(mutmut_version), "results", "XX--allXX", "true*_mutmut_command(mutmut_version), "results", "--ALL", "true*_mutmut_command(mutmut_version), "results", "--all", "XXtrueXX*_mutmut_command(mutmut_version), "results", "--all", "TRUEworkflow_scripts/mutation_run_mutmut.py:273in_publish_results(mutants 12, 14, 17; 2-equivalent/4-untestable)Path(results_file).write_text(results_text, encoding="utf-8")Path(results_file).write_text(results_text, encoding=None)— encoding=None locale-dependentPath(results_file).write_text(results_text, )— encoding omitted, locale-dependentPath(results_file).write_text(results_text, encoding="UTF-8")— UTF-8 codec aliasworkflow_scripts/mutation_run_mutmut.py:275in_publish_results(mutants 21, 23, 28; 2-equivalent/4-untestable)with Path(summary_path).open("a", encoding="utf-8") as handle:with Path(summary_path).open("a", encoding=None) as handle:— encoding=None locale-dependentwith Path(summary_path).open("a", ) as handle:— encoding omitted, locale-dependentwith Path(summary_path).open("a", encoding="UTF-8") as handle:— UTF-8 codec aliasworkflow_scripts/mutation_run_mutmut.py:277in_publish_results(mutants 31, 32, 35, 36; 1-test-gap)emit("mutation_mutmut_counts", count_statuses(results))emit(None, count_statuses(results))emit("mutation_mutmut_counts", None)emit("XXmutation_mutmut_countsXX", count_statuses(results))emit("MUTATION_MUTMUT_COUNTS", count_statuses(results))