A pyright sweep of the runner clone surfaces 204 errors — mostly a few root causes (the _fn_* DI attrs on WebhookHandler, a bad dict[str, str] annotation in status.py, un-narrowed Popen.stdout/stdin in claude.py/tasks.py, a too-narrow _filter_threads signature in worker.py, a Session.request override mismatch, and MagicMock cast pattern in tests).
Rather than filing and tracking each cluster by hand, wire type-checking into the normal gates:
- Add
pyright to dev dependencies (uv add --dev pyright).
- Add a CI job alongside lint/format/test that runs
uv run pyright and fails the build on any error.
- Pre-commit hook runs the same check and blocks commits on error (same pattern as
ruff + pytest).
- Bring the tree to zero by fixing the existing 204 as part of this ticket (not as separate bucket tickets — the gate itself is the contract).
Once this lands, future type regressions are blocked at commit/CI time and we don't need to document individual violations.
A pyright sweep of the runner clone surfaces 204 errors — mostly a few root causes (the
_fn_*DI attrs onWebhookHandler, a baddict[str, str]annotation instatus.py, un-narrowedPopen.stdout/stdininclaude.py/tasks.py, a too-narrow_filter_threadssignature inworker.py, aSession.requestoverride mismatch, and MagicMock cast pattern in tests).Rather than filing and tracking each cluster by hand, wire type-checking into the normal gates:
pyrightto dev dependencies (uv add --dev pyright).uv run pyrightand fails the build on any error.ruff+pytest).Once this lands, future type regressions are blocked at commit/CI time and we don't need to document individual violations.