Skip to content

Commit 0a7d965

Browse files
authored
ci(mypy): SR-190 — enforce type-checking (informational phase)
* ci(mypy): SR-190 — add informational mypy step after ruff (#189) Re-applied cleanly on top of merged main (post-#173 path doctrine). - Runs after 'ruff check', before 'pytest'. - Matrix-pinned to Python 3.13 (Issue #189 acceptance criterion). - Non-blocking via '|| true' + '--no-error-summary' -> Phase 1. - Scope: survey-cli/survey/ (production code; tests out-of-scope). - Full doctrine as inline comment in workflow (docs-in-code). Note on operator: GHA runs each 'run:' block with 'bash -e -o pipefail'. Under set -e, 'cmd1; cmd2' aborts after cmd1 if it fails. MUST use '|| true' here. This was the operator-fix lesson from the first revision of this PR (commit af826de on the pre-rebase branch). Ref #189 * docs(agents): SR-190 — append mypy CI doctrine section (#189) Appended at the tail of survey-cli/AGENTS.md (post-#173 path doctrine section, post 'Out-of-scope' subsection): - Phase 1 contract (informational, non-blocking, scope, config). - Operator-gotcha note (|| true vs ; true under bash -e). - Promotion trigger for Phase 2 (count < 50 -> blocking). - Audit trail with date + baseline measurement. - Forbidden list (no --ignore-missing-imports, no per-module overrides without debt issue, no tests/ scope). Ref #189
1 parent ecf45a2 commit 0a7d965

2 files changed

Lines changed: 63 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,31 @@ jobs:
7373
- name: Run ruff check
7474
run: ruff check survey-cli/survey --select E,W,F
7575

76+
# SR-190 (Issue #189) — mypy in CI, Phase 1: INFORMATIONAL ONLY.
77+
# ----------------------------------------------------------------
78+
# Doctrine (full rationale lives at the tail of survey-cli/AGENTS.md
79+
# under "SR-190 - mypy in CI"). Short form here for the next agent:
80+
# - Scope: survey-cli/survey/ (Production-Code). Tests OUT-OF-SCOPE.
81+
# - Config: survey-cli/pyproject.toml has [tool.mypy] strict = true.
82+
# We respect that config; no CLI overrides here.
83+
# - Matrix-Pin: ONLY runs on Python 3.13 (avoids double-counts in CI
84+
# logs and matches Issue #189's Python-3.13-as-baseline requirement).
85+
# - Non-blocking: `|| true` forces exit 0. GitHub Actions runs each
86+
# `run:` block with `bash -e -o pipefail`, so `; true` would NOT
87+
# swallow mypy's non-zero exit — `set -e` aborts after `;`. You
88+
# MUST use `|| true` here.
89+
# - --no-error-summary keeps raw `error:` lines grep-able from logs
90+
# (count via `grep -c "error:"`). Baseline at first run was 1075.
91+
# - Promotion to Phase 2 (blocking): when count drops below 50, drop
92+
# the `|| true` and the `--no-error-summary`, then update the
93+
# AGENTS.md SR-190 block to "Phase 2 ACTIVE".
94+
# - DO NOT add `--ignore-missing-imports` here. DO NOT inline
95+
# per-module overrides — those belong in pyproject.toml and need
96+
# a separate debt issue (precedent: SR-62/SR-63 for ruff/pytest).
97+
- name: Type-check with mypy (SR-190 — informational phase)
98+
if: matrix.python-version == '3.13'
99+
run: cd survey-cli && mypy survey/ --no-error-summary 2>&1 || true
100+
76101
- name: Run survey-cli tests
77102
env:
78103
PYTHONPATH: survey-cli

survey-cli/AGENTS.md

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -265,3 +265,41 @@ content: |
265265
in separate, narrowly-scoped PRs that the guard itself makes safe to
266266
land. Mixing governance and bulk-delete into one PR is exactly how
267267
SR-154 happened.
268+
269+
---
270+
271+
## SR-190 - mypy in CI (gradually enforcing types)
272+
273+
**Status:** Phase 1 ACTIVE — informational only, non-blocking.
274+
275+
**What happens:**
276+
- CI workflow `.github/workflows/ci.yml` runs `mypy survey/` after
277+
`ruff check` and before `pytest`, only on the Python 3.13 matrix leg.
278+
- Scope: `survey-cli/survey/` (production code). Tests OUT-OF-SCOPE.
279+
- Config: `survey-cli/pyproject.toml` -> `[tool.mypy] strict = true`.
280+
- Exit code is forced to 0 via `|| true` (GHA shells run with
281+
`bash -e -o pipefail`, so `; true` would NOT swallow the failure
282+
— `set -e` aborts after `;`. MUST use `|| true`).
283+
- `--no-error-summary` keeps raw `error:` lines grep-able in the log
284+
(count via `grep -c "error:"`).
285+
286+
**Why not blocking yet:**
287+
- Baseline = 1075 errors (PR #193, run 25785123606).
288+
- Hard gate would paint every PR red -> velocity killer.
289+
- Phase 1 = visibility. Real bugs surfaced by mypy (60 attr-defined,
290+
63 union-attr) get fixed as small surgical PRs under SR-194
291+
(#198-#202, #210/#211/#213/#214/#217).
292+
293+
**Promotion trigger to Phase 2 (blocking):**
294+
- When error count < 50: drop the `|| true` and `--no-error-summary`,
295+
then flip this block to "Phase 2 ACTIVE".
296+
297+
**Audit trail:**
298+
- 2026-05-13 (SR-190 / PR #193): step introduced. Baseline 1075 errors.
299+
No local run, no clone — implemented entirely via GitHub API.
300+
301+
**Forbidden:**
302+
- NO `--ignore-missing-imports` CLI flag in the workflow.
303+
- NO per-module `[[tool.mypy.overrides]]` without a separate debt
304+
issue (precedent: SR-62/SR-63 for ruff/pytest).
305+
- NO type-check on `survey-cli/tests/` in this phase.

0 commit comments

Comments
 (0)