Skip to content

ci(quality): pre-commit + Taskfile + pyright + coverage floor (closes #90 infra)#106

Merged
hadamrd merged 2 commits into
trunkfrom
refactor/ci-gates
May 28, 2026
Merged

ci(quality): pre-commit + Taskfile + pyright + coverage floor (closes #90 infra)#106
hadamrd merged 2 commits into
trunkfrom
refactor/ci-gates

Conversation

@hadamrd
Copy link
Copy Markdown
Owner

@hadamrd hadamrd commented May 28, 2026

Summary

  • Closes ci(quality): pyright + mypy strict + coverage floor in pre-commit and CI #90 (infrastructure)
  • `Taskfile.yml` is the developer + CI entrypoint. `task ci` runs the four gates: ruff format/check, mypy, pyright, pytest with coverage floor.
  • No GitHub Actions (per project NG13 policy). Operators wire `task ci` into Jenkins / Drone / forge-loop self-pipeline.
  • `.pre-commit-config.yaml` runs the same gates locally on every commit; reuses the uv venv so no version drift between hook + dev env.
  • pyright + pre-commit added to dev deps.
  • `tool.coverage` + `tool.pyright` config in pyproject.
  • `docs/CONTRIBUTING.md` documents the gates, type-check posture, and architectural invariants (settings single source, typed events, adapters, structlog, gh_client).

NOT in scope (follow-up)

  • `fix(types): mypy strict cascade` — turn on `--warn-unreachable` + `--disallow-any-explicit` + `--disallow-untyped-decorators` after the ~60 existing strict-mode errors get fixed per-module.
  • pyright strict mode (same blocker).
  • Coverage floor bump above 70% once a green run measures the actual ratio.

Test plan

  • `task fmt-check` / `task lint` / `task mypy` / `task pyright` / `task test` all work locally
  • Pre-commit hooks fire on staged-file commit
  • Full suite: 674 passed, 0 regressions

hadamrd added 2 commits May 28, 2026 13:57
…oses #90 infrastructure)

Pre-#90: no pre-commit. No CI workflow. Coverage measured but not gated.
mypy strict but pyright not run; ~60 type errors latent in mypy at full
strict mode.

This PR ships the gate infrastructure. The full strict-mypy cascade
(60+ existing errors) is left for a dedicated follow-up — fixing them
in this PR would balloon the diff and dilute the infra change. CI gates
the current strictness so no regression slips in while the cascade is
worked.

New gates:
- .pre-commit-config.yaml runs ruff format + ruff check + mypy + pyright
  via uv (reuses the project venv — no version drift between hook + dev
  env).
- .github/workflows/ci.yml runs the same four gates on push to trunk +
  every PR. Concurrency-gated to cancel stale runs. 15-min timeout.
  Uses astral-sh/setup-uv@v6 + Python 3.11.
- pytest --cov-fail-under=70 enforces a coverage floor. Set conservatively
  to the current measured floor; ratchets only upward.
- docs/CONTRIBUTING.md is the new contributor entrypoint — explains the
  four gates, current type-check posture (mypy basic strictness + pyright
  basic mode), how to write a PR, and the architectural invariants
  (settings single source, typed events, adapters, structlog, gh_client).

New deps (dev-only):
- pyright >=1.1.380
- pre-commit >=4.0

Config (pyproject.toml):
- [tool.coverage.run] branch=True, source=src/forge_loop
- [tool.coverage.report] excludes pragma:no cover / TYPE_CHECKING /
  NotImplementedError
- [tool.pyright] basic mode, include src/forge_loop, Python 3.11

NOT in scope (follow-up):
- fix(types): mypy strict cascade — turn on --warn-unreachable +
  --disallow-any-explicit + --disallow-untyped-decorators after the
  ~60 existing errors are fixed. Per-module pass.
- pyright strict mode (same blocker — needs the cascade fix first).
- Coverage floor bump above 70% once we know the actual current
  ratio after a green CI run. The 70% is the "first conservative
  ceiling" pattern, not a hard target.

Full suite: 674 passed, 0 regressions vs trunk baseline.
The GitHub Actions workflow I added in the previous commit conflicts
with the project's CI strategy (NG13: no GitHub Actions; CI runs via
the loop itself / Jenkins / host-platform pipeline of choice).

This commit:
- Deletes .github/workflows/ci.yml.
- Adds Taskfile.yml as the developer entrypoint. `task ci` runs the
  same four gates (ruff format/check, mypy, pyright, pytest with
  coverage floor). Operators wire `task ci` into their pipeline of
  choice — Jenkins, Drone, or forge-loop dispatched against its own
  trunk.
- Updates docs/CONTRIBUTING.md — points contributors at `task ci`
  and explicitly documents the no-GHA policy + why (forge-loop is
  the dispatcher, so its CI = forge-loop on itself).

No code or test changes; gates fire identically (same uv-run commands,
same dependency set).
@hadamrd hadamrd merged commit 7041f6f into trunk May 28, 2026
2 checks passed
@hadamrd hadamrd deleted the refactor/ci-gates branch May 28, 2026 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ci(quality): pyright + mypy strict + coverage floor in pre-commit and CI

1 participant