ci: make the strict typing gate actually run (#42)

r6 Medium: AC4 was measurable only on a developer's machine — no
workflow invoked mypy, so a typing regression in any of the six
allowlist modules reached dev unnoticed while the issue claimed
measurable backend quality. Coverage and lint had continuous gates;
typing had a text comparison of a committed list.

The backend job now runs mypy right after ruff, from the same pinned
dependency file (mypy==2.3.1 — an unpinned checker would redden on code
that never changed). The step derives its module list from the
pyproject.toml strict allowlist instead of duplicating it, because a
drifted duplicate is a green step checking the wrong modules, and it
refuses an empty list rather than passing silently.

Guarded twice: a contract test pins all three facts (pinned checker,
a step that really invokes it, list read from pyproject) and the new
typing-gate-stops-running mutant reddens when the invocation is
neutered.

User-Visible: no
Issue: #42
This commit is contained in:
Codex
2026-08-30 22:00:52 +03:00
parent 01fbb77f3b
commit dddbbe5522
5 changed files with 65 additions and 1 deletions
+11
View File
@@ -757,6 +757,17 @@ const MUTANT_DEFINITIONS = [
replace: ' "invalid_toggle_entity", "invalid_value_badge",',
}],
},
{
id: 'typing-gate-stops-running',
guard: 'python3 -m pytest tests_backend/test_backend_quality.py -q -p no:cacheprovider',
because: 'a strict-typing allowlist that CI never executes is a measurement '
+ 'that measures nothing — the step must be load-bearing (#42 r6 AC4)',
patches: [{
file: '.github/workflows/validate.yml',
find: ' python -m mypy $modules',
replace: ' echo "skip: $modules"',
}],
},
{
id: 'error-scanner-loses-a-class-source',
guard: 'python3 -m pytest tests_backend/test_backend_quality.py -q -p no:cacheprovider',