Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,18 @@ markers = [
asyncio_mode = "auto"

[tool.mutmut]
# This list is the *declared* mutation-target policy, enforced by
# tests/unit/test_mutmut_policy.py (paths exist, define real logic, cover the
# security-critical surfaces). It is NOT what the CI mutation gate actually
# mutates: scripts/mutation_report.py drives the gate from its own
# MODULE_TARGETS and currently mutates only the duckdb-free
# sdk/agentflow/retry.py. The serving modules below cannot be mutation-tested
# with the current harness -- they transitively import duckdb, whose compiled
# subpackage (_duckdb._sqltypes) fails to import inside mutmut's mutants/
# workspace and crashes the run (reproduced on Linux, so it is a mutmut x
# duckdb limitation, not platform-specific). Extending the gate needs isolated
# mutant execution (subprocess/spawn) or a different mutation tool. See
# scripts/mutation_report.py.
paths_to_mutate = [
"src/serving/api/auth/manager.py",
"src/serving/api/auth/key_rotation.py",
Expand Down
8 changes: 8 additions & 0 deletions scripts/mutation_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,14 @@ class ModuleTarget:
tests: tuple[str, ...]


# The CI mutation gate runs exactly these module/test pairs. It is deliberately
# limited to the duckdb-free SDK surface: every serving module in the
# [tool.mutmut] policy (pyproject.toml) transitively imports duckdb, and
# duckdb's compiled subpackage (_duckdb._sqltypes) fails to import inside
# mutmut's mutants/ workspace ("'_duckdb' is not a package"), crashing the run
# with every mutant left "not checked". This is a mutmut x duckdb harness
# limitation (reproduced on Linux), not a missing test. Adding serving targets
# needs isolated mutant execution (subprocess/spawn) or a different tool.
MODULE_TARGETS = {
Path("agentflow/retry.py"): ModuleTarget(
threshold=0.75,
Expand Down
5 changes: 5 additions & 0 deletions tests/unit/test_mutmut_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
# pagination SQL wrappers built around prevalidated NL SQL.
# - sql_builder: every entity/metric SQL string the engine executes is
# assembled here.
# NOTE: these are the *declared* targets (intent). Actual mutation execution is
# gated by scripts/mutation_report.py (MODULE_TARGETS), which currently runs only
# the duckdb-free retry.py -- the serving modules below break mutmut's mutants/
# workspace via duckdb (see that script's note). These assertions guard the
# declared policy, not live mutation coverage.
REQUIRED_MUTATION_TARGETS = {
"src/serving/semantic_layer/sql_guard.py",
"src/serving/api/auth/manager.py",
Expand Down