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
These two scripts run cargo-mutants and merge its shard reports; like the mutmut runner, gaps here weaken mutation testing estate-wide. In mutation_run_cargo.py, the --shard emission boundary survives (shard_count > 1 → > 2, so two-shard runs would silently run unsharded) and the exit-code meaning strings are unasserted. In mutation_summarize_cargo.py, the malformed-scenario fallbacks (_survivor_from placeholders, _start_line default), the loop robustness (continue → break skips all artefacts after one bad entry), the merged timeout/unviable counts, the root-first report ordering, the diagnostic emit keys, and the summary Markdown all escape. All 49 survivors are real test gaps except one accepted encoding mutant (below).
Suggested tests
build_arguments with shard_count=2: assert --shard 0/2 is present (kills the boundary mutant).
interpret_exit_code: parametrise over 0, 1, 2, 3, 4, 70, and an unknown code, asserting both the success flag and the exact meaning string.
parse_outcomes with a non-dict outcome entry followed by a valid missed mutant: the survivor must still be collected (kills continue → break).
_survivor_from with a scenario whose Mutant is missing or not a dict, and with a mutant missing file/name/span: assert the exact ("?", 0, "?") placeholders (kills the dozen placeholder mutants and the str(None) defaults); _start_line with a missing span asserts 0.
collect_reports over a fixture tree containing an unmatched directory name, a directory without outcomes.json, an invalid JSON file, and two shards of one slug plus a second slug sorting before root: assert the skipped/missing/invalid emit diagnostics via capsys (exact keys and values), the summed caught/missed/timeout/unviable counts, and root-first ordering.
- A snapshot (syrupy) test of
render_summary for reports with and without survivors, including a mutation name containing | (pins headings, count lines, table markup, and the cell escaping); plus the empty-reports message.
main: assert mutation_summary_targets= is emitted with the exact slug-to-missed JSON mapping.
Accepted survivors (no test to write)
collect_reports mutant 27 (workflow_scripts/mutation_summarize_cargo.py:187): locale-dependent encoding=None, equivalent on UTF-8 CI runners. Candidate # pragma: no mutate.
Surviving mutants
workflow_scripts/mutation_run_cargo.py:134 in build_arguments (mutants 14; 1-test-gap)
- original:
if invocation.shard_count > 1:
- 14:
if invocation.shard_count > 2:
workflow_scripts/mutation_run_cargo.py:158 in interpret_exit_code (mutants 2, 6, 7; 1-test-gap)
- original:
meaning = EXIT_CODE_MEANINGS.get(code, "unexpected exit code")
- 2:
meaning = EXIT_CODE_MEANINGS.get(None, "unexpected exit code")
- 6:
meaning = EXIT_CODE_MEANINGS.get(code, "XXunexpected exit codeXX")
- 7:
meaning = EXIT_CODE_MEANINGS.get(code, "UNEXPECTED EXIT CODE")
workflow_scripts/mutation_summarize_cargo.py:130 in collect_reports (mutants 12; 1-test-gap)
- original:
continue
- 12:
break
workflow_scripts/mutation_summarize_cargo.py:130 in parse_outcomes (mutants 14; 1-test-gap)
- original:
continue
- 14:
break
workflow_scripts/mutation_summarize_cargo.py:146 in _survivor_from (mutants 7, 8, 9, 10, 11, 12, 13, 14, 15; 1-test-gap)
- original:
return SurvivingMutant(file="?", line=0, name="?")
- 7:
return SurvivingMutant(file=None, line=0, name="?")
- 8:
return SurvivingMutant(file="?", line=None, name="?")
- 9:
return SurvivingMutant(file="?", line=0, name=None)
- 10:
return SurvivingMutant(line=0, name="?")
- 11:
return SurvivingMutant(file="?", name="?")
- 12:
return SurvivingMutant(file="?", line=0, )
- 13:
return SurvivingMutant(file="XX?XX", line=0, name="?")
- 14:
return SurvivingMutant(file="?", line=1, name="?")
- 15:
return SurvivingMutant(file="?", line=0, name="XX?XX")
workflow_scripts/mutation_summarize_cargo.py:148 in _survivor_from (mutants 24, 26, 29; 1-test-gap)
- original:
file=str(mutant.get("file", "?")),
- 24:
file=str(mutant.get("file", None)),
- 26:
file=str(mutant.get("file", )),
- 29:
file=str(mutant.get("file", "XX?XX")),
workflow_scripts/mutation_summarize_cargo.py:150 in _survivor_from (mutants 33, 35, 38; 1-test-gap)
- original:
name=str(mutant.get("name", "?")),
- 33:
name=str(mutant.get("name", None)),
- 35:
name=str(mutant.get("name", )),
- 38:
name=str(mutant.get("name", "XX?XX")),
workflow_scripts/mutation_summarize_cargo.py:159 in _start_line (mutants 13; 1-test-gap)
- original:
return line if isinstance(line, int) else 0
- 13:
return line if isinstance(line, int) else 1
workflow_scripts/mutation_summarize_cargo.py:180 in collect_reports (mutants 6, 7, 10, 11; 1-test-gap)
- original:
emit("mutation_summary_skipped_dir", artefact_dir.name)
- 6:
emit(None, artefact_dir.name)
- 7:
emit("mutation_summary_skipped_dir", None)
- 10:
emit("XXmutation_summary_skipped_dirXX", artefact_dir.name)
- 11:
emit("MUTATION_SUMMARY_SKIPPED_DIR", artefact_dir.name)
workflow_scripts/mutation_summarize_cargo.py:184 in collect_reports (mutants 18, 19, 22, 23; 1-test-gap)
- original:
emit("mutation_summary_missing_outcomes", artefact_dir.name)
- 18:
emit(None, artefact_dir.name)
- 19:
emit("mutation_summary_missing_outcomes", None)
- 22:
emit("XXmutation_summary_missing_outcomesXX", artefact_dir.name)
- 23:
emit("MUTATION_SUMMARY_MISSING_OUTCOMES", artefact_dir.name)
workflow_scripts/mutation_summarize_cargo.py:187 in collect_reports (mutants 27, 29; 2-equivalent/4-untestable)
- original:
payload = json.loads(outcomes_path.read_text(encoding="utf-8"))
- 27:
payload = json.loads(outcomes_path.read_text(encoding=None)) — encoding=None locale-dependent
- 29:
payload = json.loads(outcomes_path.read_text(encoding="UTF-8")) — UTF-8 codec alias
workflow_scripts/mutation_summarize_cargo.py:189 in collect_reports (mutants 30, 31, 34, 35; 1-test-gap)
- original:
emit("mutation_summary_invalid_outcomes", f"{artefact_dir.name}: {error}")
- 30:
emit(None, f"{artefact_dir.name}: {error}")
- 31:
emit("mutation_summary_invalid_outcomes", None)
- 34:
emit("XXmutation_summary_invalid_outcomesXX", f"{artefact_dir.name}: {error}")
- 35:
emit("MUTATION_SUMMARY_INVALID_OUTCOMES", f"{artefact_dir.name}: {error}")
workflow_scripts/mutation_summarize_cargo.py:205 in collect_reports (mutants 59; 1-test-gap)
- original:
timeout=totals["Timeout"],
- 59:
timeout=None,
workflow_scripts/mutation_summarize_cargo.py:206 in collect_reports (mutants 60; 1-test-gap)
- original:
unviable=totals["Unviable"],
- 60:
unviable=None,
workflow_scripts/mutation_summarize_cargo.py:211 in collect_reports (mutants 87, 88; 1-test-gap)
- original:
return sorted(reports, key=lambda report: (report.slug != "root", report.slug))
- 87:
return sorted(reports, key=lambda report: (report.slug != "XXrootXX", report.slug))
- 88:
return sorted(reports, key=lambda report: (report.slug != "ROOT", report.slug))
workflow_scripts/mutation_summarize_cargo.py:235 in render_summary (mutants 2; 1-test-gap)
- original:
return "## Mutation testing results\\n\\nNo reports were produced.\\n
- 2:
return "XX## Mutation testing results\\n\\nNo reports were produced.\\nXX
workflow_scripts/mutation_summarize_cargo.py:241 in render_summary (mutants 7, 8, 13; 1-test-gap)
- original:
,
- 7:
XXXX",
- 8:
XXXX",
- 13:
XXXX",
workflow_scripts/mutation_summarize_cargo.py:252 in render_summary (mutants 10; 1-test-gap)
- original:
### Surviving mutants",
- 10:
XX### Surviving mutantsXX",
workflow_scripts/mutation_summarize_cargo.py:254 in render_summary (mutants 14, 15, 16; 1-test-gap)
- original:
| File | Line | Mutation |",
- 14:
XX| File | Line | Mutation |XX",
- 15:
| file | line | mutation |",
- 16:
| FILE | LINE | MUTATION |",
workflow_scripts/mutation_summarize_cargo.py:255 in render_summary (mutants 17; 1-test-gap)
- original:
| ---- | ---- | -------- |",
- 17:
XX| ---- | ---- | -------- |XX",
workflow_scripts/mutation_summarize_cargo.py:262 in render_summary (mutants 22; 1-test-gap)
- original:
lines.append("")
- 22:
lines.append("XXXX")
workflow_scripts/mutation_summarize_cargo.py:263 in render_summary (mutants 24; 1-test-gap)
- original:
return "\\n".join(lines)
- 24:
return "XX\\nXX".join(lines)
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
These two scripts run cargo-mutants and merge its shard reports; like the mutmut runner, gaps here weaken mutation testing estate-wide. In
mutation_run_cargo.py, the--shardemission boundary survives (shard_count > 1→> 2, so two-shard runs would silently run unsharded) and the exit-code meaning strings are unasserted. Inmutation_summarize_cargo.py, the malformed-scenario fallbacks (_survivor_fromplaceholders,_start_linedefault), the loop robustness (continue→breakskips all artefacts after one bad entry), the mergedtimeout/unviablecounts, the root-first report ordering, the diagnosticemitkeys, and the summary Markdown all escape. All 49 survivors are real test gaps except one accepted encoding mutant (below).Suggested tests
build_argumentswithshard_count=2: assert--shard 0/2is present (kills the boundary mutant).interpret_exit_code: parametrise over 0, 1, 2, 3, 4, 70, and an unknown code, asserting both the success flag and the exact meaning string.parse_outcomeswith a non-dict outcome entry followed by a valid missed mutant: the survivor must still be collected (killscontinue→break)._survivor_fromwith a scenario whoseMutantis missing or not a dict, and with a mutant missingfile/name/span: assert the exact("?", 0, "?")placeholders (kills the dozen placeholder mutants and thestr(None)defaults);_start_linewith a missing span asserts 0.collect_reportsover a fixture tree containing an unmatched directory name, a directory withoutoutcomes.json, an invalid JSON file, and two shards of one slug plus a second slug sorting beforeroot: assert the skipped/missing/invalidemitdiagnostics viacapsys(exact keys and values), the summedcaught/missed/timeout/unviablecounts, and root-first ordering.render_summaryfor reports with and without survivors, including a mutation name containing|(pins headings, count lines, table markup, and the cell escaping); plus the empty-reports message.main: assertmutation_summary_targets=is emitted with the exact slug-to-missed JSON mapping.Accepted survivors (no test to write)
collect_reportsmutant 27 (workflow_scripts/mutation_summarize_cargo.py:187): locale-dependentencoding=None, equivalent on UTF-8 CI runners. Candidate# pragma: no mutate.Surviving mutants
workflow_scripts/mutation_run_cargo.py:134inbuild_arguments(mutants 14; 1-test-gap)if invocation.shard_count > 1:if invocation.shard_count > 2:workflow_scripts/mutation_run_cargo.py:158ininterpret_exit_code(mutants 2, 6, 7; 1-test-gap)meaning = EXIT_CODE_MEANINGS.get(code, "unexpected exit code")meaning = EXIT_CODE_MEANINGS.get(None, "unexpected exit code")meaning = EXIT_CODE_MEANINGS.get(code, "XXunexpected exit codeXX")meaning = EXIT_CODE_MEANINGS.get(code, "UNEXPECTED EXIT CODE")workflow_scripts/mutation_summarize_cargo.py:130incollect_reports(mutants 12; 1-test-gap)continuebreakworkflow_scripts/mutation_summarize_cargo.py:130inparse_outcomes(mutants 14; 1-test-gap)continuebreakworkflow_scripts/mutation_summarize_cargo.py:146in_survivor_from(mutants 7, 8, 9, 10, 11, 12, 13, 14, 15; 1-test-gap)return SurvivingMutant(file="?", line=0, name="?")return SurvivingMutant(file=None, line=0, name="?")return SurvivingMutant(file="?", line=None, name="?")return SurvivingMutant(file="?", line=0, name=None)return SurvivingMutant(line=0, name="?")return SurvivingMutant(file="?", name="?")return SurvivingMutant(file="?", line=0, )return SurvivingMutant(file="XX?XX", line=0, name="?")return SurvivingMutant(file="?", line=1, name="?")return SurvivingMutant(file="?", line=0, name="XX?XX")workflow_scripts/mutation_summarize_cargo.py:148in_survivor_from(mutants 24, 26, 29; 1-test-gap)file=str(mutant.get("file", "?")),file=str(mutant.get("file", None)),file=str(mutant.get("file", )),file=str(mutant.get("file", "XX?XX")),workflow_scripts/mutation_summarize_cargo.py:150in_survivor_from(mutants 33, 35, 38; 1-test-gap)name=str(mutant.get("name", "?")),name=str(mutant.get("name", None)),name=str(mutant.get("name", )),name=str(mutant.get("name", "XX?XX")),workflow_scripts/mutation_summarize_cargo.py:159in_start_line(mutants 13; 1-test-gap)return line if isinstance(line, int) else 0return line if isinstance(line, int) else 1workflow_scripts/mutation_summarize_cargo.py:180incollect_reports(mutants 6, 7, 10, 11; 1-test-gap)emit("mutation_summary_skipped_dir", artefact_dir.name)emit(None, artefact_dir.name)emit("mutation_summary_skipped_dir", None)emit("XXmutation_summary_skipped_dirXX", artefact_dir.name)emit("MUTATION_SUMMARY_SKIPPED_DIR", artefact_dir.name)workflow_scripts/mutation_summarize_cargo.py:184incollect_reports(mutants 18, 19, 22, 23; 1-test-gap)emit("mutation_summary_missing_outcomes", artefact_dir.name)emit(None, artefact_dir.name)emit("mutation_summary_missing_outcomes", None)emit("XXmutation_summary_missing_outcomesXX", artefact_dir.name)emit("MUTATION_SUMMARY_MISSING_OUTCOMES", artefact_dir.name)workflow_scripts/mutation_summarize_cargo.py:187incollect_reports(mutants 27, 29; 2-equivalent/4-untestable)payload = json.loads(outcomes_path.read_text(encoding="utf-8"))payload = json.loads(outcomes_path.read_text(encoding=None))— encoding=None locale-dependentpayload = json.loads(outcomes_path.read_text(encoding="UTF-8"))— UTF-8 codec aliasworkflow_scripts/mutation_summarize_cargo.py:189incollect_reports(mutants 30, 31, 34, 35; 1-test-gap)emit("mutation_summary_invalid_outcomes", f"{artefact_dir.name}: {error}")emit(None, f"{artefact_dir.name}: {error}")emit("mutation_summary_invalid_outcomes", None)emit("XXmutation_summary_invalid_outcomesXX", f"{artefact_dir.name}: {error}")emit("MUTATION_SUMMARY_INVALID_OUTCOMES", f"{artefact_dir.name}: {error}")workflow_scripts/mutation_summarize_cargo.py:205incollect_reports(mutants 59; 1-test-gap)timeout=totals["Timeout"],timeout=None,workflow_scripts/mutation_summarize_cargo.py:206incollect_reports(mutants 60; 1-test-gap)unviable=totals["Unviable"],unviable=None,workflow_scripts/mutation_summarize_cargo.py:211incollect_reports(mutants 87, 88; 1-test-gap)return sorted(reports, key=lambda report: (report.slug != "root", report.slug))return sorted(reports, key=lambda report: (report.slug != "XXrootXX", report.slug))return sorted(reports, key=lambda report: (report.slug != "ROOT", report.slug))workflow_scripts/mutation_summarize_cargo.py:235inrender_summary(mutants 2; 1-test-gap)return "## Mutation testing results\\n\\nNo reports were produced.\\nreturn "XX## Mutation testing results\\n\\nNo reports were produced.\\nXXworkflow_scripts/mutation_summarize_cargo.py:241inrender_summary(mutants 7, 8, 13; 1-test-gap),XXXX",XXXX",XXXX",workflow_scripts/mutation_summarize_cargo.py:252inrender_summary(mutants 10; 1-test-gap)### Surviving mutants",XX### Surviving mutantsXX",workflow_scripts/mutation_summarize_cargo.py:254inrender_summary(mutants 14, 15, 16; 1-test-gap)| File | Line | Mutation |",XX| File | Line | Mutation |XX",| file | line | mutation |",| FILE | LINE | MUTATION |",workflow_scripts/mutation_summarize_cargo.py:255inrender_summary(mutants 17; 1-test-gap)| ---- | ---- | -------- |",XX| ---- | ---- | -------- |XX",workflow_scripts/mutation_summarize_cargo.py:262inrender_summary(mutants 22; 1-test-gap)lines.append("")lines.append("XXXX")workflow_scripts/mutation_summarize_cargo.py:263inrender_summary(mutants 24; 1-test-gap)return "\\n".join(lines)return "XX\\nXX".join(lines)