Skip to content

Add scheduled mutation testing to generated repos - #24

Open
leynos wants to merge 8 commits into
mainfrom
add-mutation-testing-template
Open

Add scheduled mutation testing to generated repos#24
leynos wants to merge 8 commits into
mainfrom
add-mutation-testing-template

Conversation

@leynos

@leynos leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner

Summary

This branch rolls the estate-wide scheduled mutation-testing pattern into the Copier template so newly generated repositories receive the applicable shared workflow by default.

Python projects with a 3.13 or newer baseline receive mutmut configuration and a scheduled mutmut job. Rust-enabled projects receive cargo-mutants independently of the Python baseline. Projects with neither capability do not render a mutation-testing workflow. The default Python baseline moves from 3.10 to 3.12, and malformed baseline answers now fail at the Copier boundary before the hidden mutation-support answer is derived.

Review walkthrough

Gating and scheduling

  • The mutmut job and [tool.mutmut] section render only for Python 3.13 or newer because the shared workflow helpers require Python 3.13 or newer.
  • The cargo-mutants job remains gated independently by use_rust and targets rust_extension/ through extra-crate-dirs because generated repositories have no root Cargo.toml.
  • When both gates are off, Copier omits the workflow file by rendering its conditional filename as empty.
  • The generated schedule is 30 9 * * * (09:30 UTC), with guidance to stagger it per repository.
  • Manual cargo dispatch retains a known shared-workflow limitation: full runs create one root-target leg despite the absent root crate. shard-count: 1 confines the failing root target to one leg while the extension target still runs.

Validation

  • make check-fmt: passed; 19 files checked.
  • make lint: passed; Ruff clean and interrogate coverage 100%.
  • make typecheck: passed.
  • make test: passed; 41 passed, 2 skipped and 3 snapshots passed.
  • Focused mutation-gating and malformed-version tests: 8 passed.
  • Rendered workflow variants YAML-parse and pass actionlint; rendered project metadata TOML-parses with the expected Python and Ruff baselines.
  • Rendered Rust variant: cargo test --manifest-path rust_extension/Cargo.toml passed with 1 test.

References

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @leynos, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

Walkthrough

Raise the Python baseline to 3.12, validate Python version answers, and add conditional mutmut and Rust mutation-testing workflows, project configuration, documentation, and rendered-template contract tests.

Changes

Mutation testing setup

Layer / File(s) Summary
Python version and mutation capability contract
copier.yml, tests/helpers/rendering.py, tests/helpers/pyproject_contracts.py
Set Python defaults to 3.12, validate 3.X values, compute mutmut_supported for Python 3.13+, and update rendering and packaging contracts.
Mutation workflow and project configuration
template/.github/workflows/..., template/pyproject.toml.jinja
Generate scheduled/manual mutation workflows with independent mutmut and Rust jobs, and emit [tool.mutmut] only when supported.
Mutation workflow documentation
docs/developers-guide.md, template/docs/developers-guide.md.jinja, template/docs/users-guide.md.jinja
Document workflow rendering, schedules, reusable workflows, and Python and Rust job gates.
Rendered mutation gating tests
tests/test_template.py
Test documentation, configuration, workflow jobs, reusable-workflow SHA formats, Python minor gating, and invalid version rejection.
Reusable action pin test fixtures
tests/test_helpers.py
Replace hardcoded action SHAs in coverage workflow fixtures and rewrite assertions with shared test constants.

Sequence Diagram(s)

sequenceDiagram
  participant Scheduler
  participant MutationWorkflow
  participant MutmutWorkflow
  participant CargoWorkflow
  Scheduler->>MutationWorkflow: Trigger daily schedule or manual dispatch
  MutationWorkflow->>MutmutWorkflow: Call mutation-mutmut.yml when Python is 3.13+
  MutationWorkflow->>CargoWorkflow: Call mutation-cargo.yml when Rust is enabled
Loading

Possibly related PRs

Poem

Set Python’s course to three-twelve,
Let mutation gates decide.
Schedule tests beneath the moon,
Pin shared workflows side by side.
Rust and mutmut march in tune.


Caution

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

  • Ignore

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error Gating and malformed-input tests are substantive, but the new workflow’s cron, permissions, concurrency, and Rust job inputs remain unchecked, so plausible regressions would still pass. Assert the mutation workflow cron, permissions, concurrency, and job inputs (module-prefix-strip, paths, extra-crate-dirs, shard-count); parameterise any shared pyproject helper for non-default renders.
Performance And Resource Use ⚠️ Warning Cap the Hypothesis property test: it renders a full project with the default 100 examples and has no max_examples bound. Set max_examples to a low, explicit value (for example 25) for test_python_version_minor_controls_mutmut_generation, or replace it with a smaller bounded matrix.
✅ Passed checks (18 passed)
Check name Status Explanation
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
User-Facing Documentation ✅ Passed Document the new scheduled mutation-testing workflow in the users’ guide; the template covers daily/manual runs plus Python 3.13+ and Rust gating.
Developer Documentation ✅ Passed PASS: docs/developers-guide.md and template/docs/developers-guide.md.jinja document the new mutation-testing gates; no roadmap/execplan artefacts or alternate locales exist.
Module-Level Documentation ✅ Passed All touched Python modules include clear top-level docstrings that explain purpose and relationships; no module-level docstring gaps were found.
Testing (Unit And Behavioural) ✅ Passed PASS: Tests render real Copier projects, cover malformed python_version rejection, and assert generated docs, pyproject, and workflow gating across 3.12–3.14 plus Rust variants.
Testing (Property / Proof) ✅ Passed Hypothesis now covers the 3.x minor-version invariant for mutmut gating, and malformed baseline formats are rejected before derivation.
Testing (Compile-Time / Ui) ✅ Passed No Rust/TS compile-time path changed, so trybuild is unnecessary; the new workflow/docs tests use focused YAML/TOML parsing and semantic assertions, with existing snapshots already covering stable...
Unit Architecture ✅ Passed PASS: Rendering/parsing helpers keep I/O and failures explicit, and the new mutation-gating tests exercise one feature boundary without hidden side effects.
Domain Architecture ✅ Passed No domain model was altered; the PR only changes template, docs, and tests, and keeps mutation-testing/version gating at the Copier boundary.
Observability ✅ Passed Template-only workflow changes add no runtime observability hooks; GitHub Actions logs and comments already cover the new scheduled jobs.
Security And Privacy ✅ Passed PASS: the new workflow keeps least-privilege permissions, validates python_version before use, and adds no new secrets, credentials, or sensitive-data exposures.
Concurrency And State ✅ Passed PASS: the only parallelism is declarative workflow concurrency with an explicit group and cancel-in-progress=false; no shared mutable state or task lifetime changes were added.
Architectural Complexity And Maintainability ✅ Passed The new mutmut gate is a thin, documented seam around a real 3.13 invariant; no generic abstraction or hidden dependency graph was introduced.
Rust Compiler Lint Integrity ✅ Passed No Rust sources changed, and the diff adds no broad lint suppressions or clone-heavy Rust edits.
Title check ✅ Passed The title clearly summarises the main change: adding scheduled mutation testing to generated repositories.
Description check ✅ Passed The description is directly related to the changeset and explains the mutation-testing workflow, gating, validation, and docs updates.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch add-mutation-testing-template

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 862e80152e

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@leynos

leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos

leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai review

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
✅ Action performed

Review finished.

Note: CodeRabbit is an incremental review system and does not re-review already reviewed commits. This command is applicable only when automatic reviews are paused.

@leynos
leynos force-pushed the add-mutation-testing-template branch from 57d3ac7 to 3a34cba Compare July 7, 2026 10:46
@leynos

leynos commented Jul 7, 2026

Copy link
Copy Markdown
Owner Author

Reworked per review and maintainer direction. Credit to the review for catching that the caller passed the template's default python-version (3.10) into the shared mutmut workflow, where setup-uv exports UV_PYTHON job-wide and the helper scripts require >= 3.13 — change detection failed before any mutation testing ran.

Changes in the latest push:

  • copier.yml python_version default bumped 3.10 → 3.12 (estate baseline for libraries; applications and internal work sit at 3.14). Derived content (requires-python, ruff target-version, test helpers, contract assertions) follows the answer.
  • New hidden computed answer mutmut_supported (baseline minor >= 13, numeric comparison): the mutmut job and [tool.mutmut] render only when it holds; cargo-mutants stays gated on use_rust independently. When both gates are off the workflow filename renders empty and copier skips the file entirely — no empty workflow is ever generated.
  • Caller pin bumped 2b09d10859416a90eb3987b46a57682c5d6b8964ad3f0a6 (sub-3.13 fail-fast guard + setup-commands input).
  • python-version: "{{ python_version }}" retained — now >= 3.13 by construction whenever the job exists.
  • Four new contract-test cases cover the gating combinations (3.12 pure: no file; 3.12 + Rust: cargo-only; 3.13 pure; 3.14 + Rust: both jobs).

Validated by rendering all five variants (YAML + actionlint + TOML parses clean) and running the full contract suite: 37 passed, 2 skipped. PR body updated with the new gating semantics.

@coderabbitai coderabbitai Bot added the Roadmap label Jul 7, 2026
coderabbitai[bot]

This comment was marked as resolved.

@lodyai
lodyai Bot force-pushed the add-mutation-testing-template branch from 60074b8 to ae21e1a Compare July 13, 2026 21:58
@leynos

leynos commented Jul 18, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai resume

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
✅ Action performed

Reviews resumed.

@lodyai
lodyai Bot force-pushed the add-mutation-testing-template branch from cdd909e to 79de645 Compare July 18, 2026 19:27
@coderabbitai coderabbitai Bot removed the Roadmap label Jul 18, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@template/docs/developers-guide.md`:
- Around line 62-63: Update the sentence in the developers guide to remove the
comma before “because,” so it reads “3.13 or newer because” while preserving the
existing en-GB-oxendict wording and meaning.

In `@tests/test_template.py`:
- Around line 558-612: Extend the parametrized mutation workflow test around its
existing gate assertions to read and validate both rendered
docs/developers-guide.md and docs/users-guide.md. Assert neither mutation
section for Python 3.12 without Rust, only Rust wording for Rust-only variants,
only mutmut wording for Python 3.13 without Rust, and both sections when both
gates apply, using stable snapshot-style expectations for the rendered text.
- Around line 610-612: Update the assertion in the test around the shared
mutation workflow pin to split the combined condition into separate assertions:
validate the @ separator independently and validate revision against the
40-character hexadecimal SHA pattern separately, with clear failure messages for
each malformed component.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: e896e4b4-3527-4832-811f-aa0881b1c87d

📥 Commits

Reviewing files that changed from the base of the PR and between 817ac98 and 79de645.

📒 Files selected for processing (10)
  • copier.yml
  • docs/developers-guide.md
  • template/.github/workflows/{% if mutmut_supported or use_rust %}mutation-testing.yml{% endif %}.jinja
  • template/docs/developers-guide.md
  • template/docs/users-guide.md.jinja
  • template/pyproject.toml.jinja
  • tests/helpers/pyproject_contracts.py
  • tests/helpers/rendering.py
  • tests/test_helpers.py
  • tests/test_template.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)
  • leynos/cuprum (auto-detected)
  • leynos/mdtablefix (auto-detected)

Comment thread template/docs/developers-guide.md Outdated
Comment thread tests/test_template.py
Comment thread tests/test_template.py Outdated
@leynos

leynos commented Jul 19, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Has this now been resolved in the latest commit?

Use codegraph analysis to determine your answer.

If this comment is now resolved, please mark it as such using the API. Otherwise, please provide an AI agent prompt for the remaining work to be done to address this comment.

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error Core gating tests are substantive, but the new conditional docs sections are untested; no assertion checks the rendered users/developers guides across gate combinations. Add parametrised rendering assertions or snapshots for docs/users-guide.md and docs/developers-guide.md across the 3.12/3.13/Rust matrix, and fail when the scheduled-mutation sections are missing or present unexpectedly.
Testing (Property / Proof) ⚠️ Warning The PR adds a version-format invariant and derived gate, but it only exercises a few hand-picked cases; no property-based or proof-oriented recommendation appears. Add a Hypothesis/CrossHair-style test for python_version parsing and mutmut_supported derivation, or justify explicitly why example cases suffice.

@coderabbitai

This comment was marked as resolved.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@tests/helpers/pyproject_contracts.py`:
- Around line 23-25: Parameterize _assert_pyproject_contracts with a
python_version argument and compare requires-python against
f">={python_version}" instead of the hard-coded 3.12 value. Update every caller
to pass the same Python version used by render_project for that rendered
project.

In `@tests/test_template.py`:
- Around line 692-701: Set an explicit, bounded max_examples value in the
Hypothesis `@settings` decorator for
test_python_version_minor_controls_mutmut_generation. Keep the existing deadline
and health-check configuration unchanged while reducing the number of full
Copier renders to make CI runtime predictable.
- Around line 552-690: Split test_generated_mutation_testing_gating into focused
tests or helper functions, separating rendered documentation guidance,
pyproject.toml mutmut configuration, workflow presence and job gating, and
shared-workflow SHA validation. Keep each function’s mccabe complexity at or
below 9, reuse shared setup/helpers where appropriate, and preserve all existing
parameter coverage and assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 58bde07b-18a2-48db-9a0d-771487ea881d

📥 Commits

Reviewing files that changed from the base of the PR and between 79de645 and 70306ca.

📒 Files selected for processing (10)
  • copier.yml
  • docs/developers-guide.md
  • template/.github/workflows/{% if mutmut_supported or use_rust %}mutation-testing.yml{% endif %}.jinja
  • template/docs/developers-guide.md.jinja
  • template/docs/users-guide.md.jinja
  • template/pyproject.toml.jinja
  • tests/helpers/pyproject_contracts.py
  • tests/helpers/rendering.py
  • tests/test_helpers.py
  • tests/test_template.py
🔗 Linked repositories identified

CodeRabbit considers these linked repositories for cross-repo context during reviews:

  • leynos/whitaker (auto-detected)
  • leynos/cuprum (auto-detected)
  • leynos/mdtablefix (auto-detected)

Comment thread tests/helpers/pyproject_contracts.py Outdated
Comment thread tests/test_template.py Outdated
Comment thread tests/test_template.py
@leynos

leynos commented Jul 27, 2026

Copy link
Copy Markdown
Owner Author

@coderabbitai Have the following failed checks now been resolved?

If further work is required, please provide an AI agent prompt for the remaining work to be done to address these failures.

Do not treat warnings as optional or aspirational. Where a change is out of scope for this PR, propose a GitHub issue unless one exists already. (Treat documentation and validation coverage as in scope).

❌ Failed checks (1 error, 1 warning)

Check name Status Explanation Resolution
Testing (Overall) ❌ Error Gating and malformed-input tests are substantive, but the new workflow’s cron, permissions, concurrency, and Rust job inputs remain unchecked, so plausible regressions would still pass. Assert the mutation workflow cron, permissions, concurrency, and job inputs (module-prefix-strip, paths, extra-crate-dirs, shard-count); parameterise any shared pyproject helper for non-default renders.
Performance And Resource Use ⚠️ Warning Cap the Hypothesis property test: it renders a full project with the default 100 examples and has no max_examples bound. Set max_examples to a low, explicit value (for example 25) for test_python_version_minor_controls_mutmut_generation, or replace it with a smaller bounded matrix.

@coderabbitai

coderabbitai Bot commented Jul 27, 2026

Copy link
Copy Markdown

Tip

For best results, initiate chat on the files or code changes.

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== HEAD and latest relevant changes =='
git log --oneline -8
git show --stat --oneline HEAD

printf '%s\n' '== Test module outline =='
ast-grep outline tests/test_template.py --items all --type function --view expanded

printf '%s\n' '== Relevant mutation workflow template =='
workflow=$(fd -t f -a 'mutation-testing.yml' template)
printf '%s\n' "$workflow"
nl -ba "$workflow"

printf '%s\n' '== Relevant test sections and imports =='
rg -n -C 8 \
  'test_generated_mutation_testing_gating|test_python_version_minor_controls_mutmut_generation|`@settings`|hypothesis|mutation-testing\.yml|module-prefix-strip|extra-crate-dirs|shard-count|concurrency|schedule|permissions' \
  tests/test_template.py tests/helpers -g '*.py'

printf '%s\n' '== Parser/helper interfaces used by workflow tests =='
ast-grep outline tests/helpers/generated_files.py --items all --type function --view expanded 2>/dev/null || true

Length of output: 8025


🏁 Script executed:

#!/bin/bash
set -euo pipefail

printf '%s\n' '== Relevant workflow template =='
fd -t f -a 'mutation-testing.yml' template -0 |
  while IFS= read -r -d '' file; do
    printf '\n--- %s ---\n' "$file"
    sed -n '1,180p' "$file"
  done

printf '%s\n' '== Mutation test helpers, integration matrix, and property test =='
sed -n '590,900p' tests/test_template.py

printf '%s\n' '== Imports and test configuration =='
sed -n '1,90p' tests/test_template.py
printf '\n--- pytest.ini ---\n'
sed -n '1,120p' pytest.ini

printf '%s\n' '== Exact latest remediation diff =='
git diff --unified=80 HEAD^ HEAD -- tests/test_template.py tests/helpers/pyproject_contracts.py copier.yml

printf '%s\n' '== Verify required terms occur in assertion code =='
rg -n -C 4 \
  '30 9 \* \* \*|permissions|mutation-testing-\$\{\{ github\.ref \}\}|cancel-in-progress|module-prefix-strip|extra-crate-dirs|shard-count|max_examples|`@settings`' \
  tests/test_template.py

Length of output: 16495


@leynos Both checks are resolved in the current revision.

  • Testing (Overall): tests/test_template.py now verifies the mutation workflow’s daily cron, manual dispatch trigger, empty top-level permissions, concurrency group, and non-cancelling behaviour. It also verifies mutmut inputs (python-version, paths, module-prefix-strip) and Rust inputs (paths, extra-crate-dirs, shard-count) across the existing render matrix.
  • Performance And Resource Use: test_python_version_minor_controls_mutmut_generation now explicitly sets @settings(max_examples=25, ...) and retains boundary examples for minors 0, 12, 13, and 14.

Mark both findings resolved. No further AI-agent work or follow-up issue is required.

leynos and others added 8 commits July 27, 2026 14:46
Generated projects now ship a thin mutation-testing caller workflow
pinned to the shared reusable workflows: mutmut for the Python package
and, when the Rust extension is enabled, cargo-mutants for the
rust_extension crate. The templated pyproject gains the matching
[tool.mutmut] configuration, with a note on also_copy for tests that
read repository-root paths.
Review found that the caller passed the template's default
python-version (3.10) into the shared mutmut workflow, whose helper
scripts require 3.13 or greater: setup-uv exported UV_PYTHON job-wide
and change detection failed before any mutation testing ran.

Address this per maintainer direction:

- bump copier.yml's python_version default from 3.10 to 3.12 (the
  estate baselines libraries for external consumption at 3.12), and
  update everything derived from the default (test helpers and the
  requires-python contract assertion);
- add a hidden computed mutmut_supported answer (baseline minor >= 13,
  numeric comparison) and render the mutmut job and the [tool.mutmut]
  pyproject section only when it holds;
- keep the cargo-mutants job gated on use_rust independently, and use
  a conditional filename so the workflow file is not generated at all
  when both gates are off;
- bump the shared workflow pin to
  859416a90eb3987b46a57682c5d6b8964ad3f0a6, which fails fast on
  sub-3.13 python-version values;
- add contract tests covering the four gating combinations.

The mutmut job keeps python-version set to the project's baseline,
which is now 3.13 or greater by construction whenever the job exists.
Validate the Python baseline before deriving mutation support so malformed
answers fail at the Copier boundary. Keep rendering tests on the shared
helper and document the generated scheduled mutation workflows for users
and maintainers.
Restore the shared mutation workflow pin constant used by the
gating test after replaying the branch onto main.

Refresh generated `typos.toml` from the current shared
en-GB-oxendict dictionary so the committed config contract stays
in sync with the generator.
Keep GitHub Actions revisions owned solely by Dependabot in workflow
templates. Validate action identities and commit-pin structure without
duplicating mutable SHA values in tests or documentation.

Refresh the generated spelling configuration from the current shared
dictionary so the repository contract remains current.
Render the generated developer guide as a Jinja template so its mutation
guidance follows the Python and Rust gates instead of shipping template
control tags.

Assert the exact developer and user guide sections across every existing
gate combination, and report malformed workflow separators independently
from malformed commit revisions.
Generate bounded Python 3 minor versions and render each example in an
isolated destination. Assert that the derived gate controls both the
mutation workflow job and `[tool.mutmut]` configuration at the 3.13
boundary.

Retain the explicit malformed-version cases and document the grammar
shape covered by each example.
Address review feedback on the scheduled mutation-testing template tests.

- Parameterise `_assert_pyproject_contracts` with `python_version` and
  thread it through `assert_generated_tooling_contracts` so the
  `requires-python` check matches the version each caller renders, rather
  than a hard-coded `>=3.12`.
- Split `test_generated_mutation_testing_gating` into focused helpers for
  documentation guidance, `[tool.mutmut]` configuration, workflow
  metadata, job gating and inputs, and shared-workflow SHA validation.
- Assert the previously unchecked workflow surface: the `30 9 * * *`
  schedule, empty top-level `permissions`, per-ref `concurrency` with
  `cancel-in-progress: false`, the mutmut job `paths`/`module-prefix-strip`
  inputs, and the cargo-mutants job `paths`/`extra-crate-dirs`/`shard-count`
  inputs.
- Cap the `test_python_version_minor_controls_mutmut_generation` property
  test at `max_examples=25` to keep CI runtime predictable while retaining
  the explicit boundary examples.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@lodyai
lodyai Bot force-pushed the add-mutation-testing-template branch from 1398fa5 to 0896a56 Compare July 27, 2026 12:52
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant