Skip to content

Commit b97ee98

Browse files
authored
SEP-1909: Decide where ty enforcement runs and how it scopes (#1462)
Adds an `## Enforcement` section to `docs/development/ty-policy.md` recording where `ty` enforcement runs and what it reads, and corrects the in-repo claims that the current measurement contradicts. **No gate ships here** — SEP-1680 builds it; this settles what it should build. **The decision: CI, in two layers.** Not pre-commit, not local-only. | Layer | Scope | Reads | Job | |---|---|---|---| | 1 | whole tree | exit status of `make typecheck` | hold error severity at zero | | 2 | lines a change adds | the diagnostics themselves | detect what the `warn` rules report | The two are not alternatives: layer 1 cannot reach a rule held at `warn`, and layer 2 cannot see a regression in a file the branch did not touch. ### Why scoping is the decision that matters Measured at a157c14, which is also this branch's base: ``` ty check -> Found 3287 diagnostics, exit 0 ty check --error-on-warning -> Found 3287 diagnostics, exit 1 ``` Same tree, same count, different exit code — warning-severity diagnostics do not move the default exit status. Split: **0 error, 3287 warning**. All five defects on record as caught by `ty` in this repository were reported by rules held at `warn`, so none of them would have moved the exit status of a whole-tree run. That is the finding the decision turns on, and it is why layer 1 is adopted as a ratchet on an invariant rather than as a defect detector. ## Changed **`docs/development/ty-policy.md`** - New `## Enforcement` section (nine subsections): the decision, why scoping decides what gets caught, why layer 1 is kept anyway, how a scoped invocation re-establishes the checked surface, per-invocation severity, what SEP-1680 inherits, the bound the per-file overrides place on any gate, installing the pinned group in CI, and every placement rejected with the measurement that rejects it. - Opening paragraph: the document records **three** decisions, not two, and `make typecheck` exits **0** — it previously said type checking was "opt-in and local-only" and that the target "exits non-zero today". - § "The recorded baseline": re-measured to **3,287 (0 error / 3,287 warning) at a157c14**, replacing 3,201 at 5f465e1. The document's own re-measure rule updates only this one figure; the per-rule tables and sampling record stay as dated evidence. - Same section: the sentence explaining the two exit codes said "`ty` exits 1 when it finds diagnostics". It exits 1 on an **error-severity** diagnostic — as written it contradicted the 3,287/exit-0 figure three paragraphs above. - § "Tools that invoke ty with explicit paths": said the path-scoping asymmetry "is not an inconsistency to be 'fixed' by making such a tool read `include`". `--force-exclude` does exactly that, so the stance is now scoped to the case it still governs (editors and LSPs, which should answer about the open file) and the flag is documented alongside. - § "`unresolved-attribute` stays reportable": said that rule caught "the **only** confirmed real defect found so far". Five are now on record across three PRs and two rules, so this now points at the catalogue instead. **`Makefile`** — the comment above `typecheck` said a non-zero exit "is expected and must not gate any automated check". It isn't and it doesn't; the comment now says the target is not yet wired and points at the policy doc. The recipe is unchanged. **`CONTRIBUTING.md`** — links the new section. Its "not enforced in CI or pre-commit yet" sentence is kept deliberately: it is still true at this commit, and becomes SEP-1680's to update.
1 parent a157c14 commit b97ee98

3 files changed

Lines changed: 296 additions & 42 deletions

File tree

CONTRIBUTING.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ We enforce code style guidelines using [Ruff](https://docs.astral.sh/ruff/). The
9595

9696
- **Type checking** (opt-in):
9797

98-
Because the project is fully type-annotated, you can check the annotations locally with [`ty`](https://github.com/astral-sh/ty) (Astral's type checker) by running `make typecheck`. It is **not** enforced in CI or pre-commit yet, so it is safe to run on demand and will currently report a backlog of existing diagnostics. Which trees are checked and what severity each diagnostic rule carries are recorded in [docs/development/ty-policy.md](docs/development/ty-policy.md).
98+
Because the project is fully type-annotated, you can check the annotations locally with [`ty`](https://github.com/astral-sh/ty) (Astral's type checker) by running `make typecheck`. It is **not** enforced in CI or pre-commit yet, so it is safe to run on demand and will currently report a backlog of existing warning-severity diagnostics. Where enforcement will run and what it will read is decided and recorded in [docs/development/ty-policy.md](docs/development/ty-policy.md) under [Enforcement](docs/development/ty-policy.md#enforcement), alongside which trees are checked and what severity each diagnostic rule carries.
9999

100100
- **Docstrings**:
101101

Makefile

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,9 @@ ruff: venv
9191
@"${VENV_BIN}"/ruff check .
9292
@"${VENV_BIN}"/ruff format --check .
9393

94-
# Opt-in, local-only static type checking (Astral ty). Deliberately NOT part of `lint`,
95-
# pre-commit, or CI: a non-zero exit from the existing type-error backlog is expected and
96-
# must not gate any automated check.
94+
# Static type checking (Astral ty). Not yet part of `lint`, pre-commit, or CI: where
95+
# enforcement will run and what it will read is decided and recorded in
96+
# docs/development/ty-policy.md under `Enforcement`. Until then, this runs by hand only.
9797
typecheck: venv
9898
@"${VENV_BIN}"/ty check
9999

0 commit comments

Comments
 (0)