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
18 changes: 9 additions & 9 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -205,15 +205,15 @@ asyncio_mode = "auto"
# tests/unit/test_mutmut_policy.py (paths exist, define real logic, cover the
# security-critical surfaces). It is a superset of what the CI gate actually
# mutates: scripts/mutation_report.py drives the gate from its own
# MODULE_TARGETS, which now mutates sdk/agentflow/retry.py AND
# src/serving/semantic_layer/sql_guard.py live. sql_guard is mutated as a
# top-level `serving` package against a duckdb-free narrow test: mutmut's
# trampoline rejects a module name starting with `src.`, which (not duckdb) was
# the real blocker. The remaining serving modules below stay declared-only for
# now -- their unit tests pull the duckdb-backed query engine, so mutating them
# in isolation needs a duckdb-free test per module (the pattern sql_guard now
# uses); the blocker is the test import chain, not the module. See
# scripts/mutation_report.py.
# MODULE_TARGETS, which now mutates sdk/agentflow/retry.py,
# src/serving/semantic_layer/sql_guard.py AND src/serving/masking.py live. The
# serving modules are mutated as a top-level `serving` package against duckdb-free
# narrow tests: mutmut's trampoline rejects a module name starting with `src.`,
# which (not duckdb) was the real blocker. The remaining serving modules below
# stay declared-only for now -- their unit tests pull the duckdb-backed query
# engine, so mutating them in isolation needs a duckdb-free test per module (the
# pattern sql_guard and masking now use); the blocker is the test import chain,
# not the module. See scripts/mutation_report.py.
paths_to_mutate = [
"src/serving/api/auth/manager.py",
"src/serving/api/auth/key_rotation.py",
Expand Down
16 changes: 11 additions & 5 deletions scripts/mutation_report.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,13 @@ class ModuleTarget:
# that, not duckdb, was the real blocker for the serving modules. The fix is to
# (a) copy the module so it imports as a top-level package and (b) pair it with a
# NARROW test that does not pull the duckdb-backed engine import chain. So
# retry.py mutates as agentflow.retry (from sdk/agentflow), and sql_guard mutates
# as serving.semantic_layer.sql_guard (from src/serving) against a duckdb-free
# test. Serving modules whose tests still need the duckdb engine (the
# query/masking/auth surfaces) remain harder to isolate and stay declared-only in
# the [tool.mutmut] policy until they get duckdb-free unit tests of their own.
# retry.py mutates as agentflow.retry (from sdk/agentflow), and sql_guard and
# masking mutate as serving.* (from src/serving) against duckdb-free tests. Each
# duckdb-free test also avoids fixtures and calls the module's methods directly:
# under mutate_only_covered_lines a fixture-built object left every method line
# uncovered, so only __init__ got mutated. The remaining serving modules whose
# tests still need the duckdb engine (the query/auth surfaces) stay declared-only
# in the [tool.mutmut] policy until they get duckdb-free unit tests of their own.
MODULE_TARGETS = {
Path("agentflow/retry.py"): ModuleTarget(
threshold=0.75,
Expand All @@ -43,6 +45,10 @@ class ModuleTarget:
threshold=0.90,
tests=("tests/unit/test_sql_guard_mutation.py",),
),
Path("serving/masking.py"): ModuleTarget(
threshold=0.90,
tests=("tests/unit/test_masking_mutation.py",),
),
}

STATUS_BY_EXIT_CODE = {
Expand Down
Loading