Skip to content

Make CI enforcement trustworthy before the rules registry - #3887

Draft
anth-volk wants to merge 6 commits into
masterfrom
phase-0-enforcement
Draft

anth-volk wants to merge 6 commits into
masterfrom
phase-0-enforcement

Conversation

@anth-volk

@anth-volk anth-volk commented Oct 12, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #3886

Summary

Phase 0 of the rules workstream: make CI enforcement trustworthy before the rules registry (#3884, kept as a draft until this merges). The sim counterpart is PolicyEngine/policyengine-sim-api#754.

  • CODEOWNERS (step 0.2). A deliberately narrow file covering only the rule machinery: rules/, scripts/rules/, scripts/guards/, scripts/run_quality_guards.py and CODEOWNERS itself, owned by @PolicyEngine/core-developers. pyproject.toml and workflow files are not owned, so dependency bots and everyday CI edits aren't blocked. The paths for the registry take effect once Add a rules registry that makes every enforced and unenforced rule visible #3884 creates them.
  • Ruff pin (step 0.3). The lint jobs in pr.yml and push.yml ran pip install ruff>=0.9.0 unquoted, so the shell read > as a redirect and CI installed the latest ruff. They now run .github/scripts/install_locked_ruff.sh, which installs the version pinned in uv.lock (currently 0.15.12) and prints it. Following the workstream's CI rule, the multi-line logic lives in a tested script, and the workflow step is a single line. [tool.ruff.lint] select = ["E4", "E7", "E9", "F"] makes ruff's current defaults explicit. No rules are added or removed. Stricter ruff comes in separate PRs right after the registry lands.
  • CRUD boundary discovery (step 0.5). test_data_crud_boundaries.py discovers modules by filename instead of listing them, so households and user_households (12 modules) are checked for the first time. Discovery fails at collection if a pattern matches nothing, because pytest silently skips an empty parameter list. A new test requires every connector module to be a recognised create, read, update or delete module.
  • PR conventions (step 0.6) and the no-bypass rule. github-prs.md now requires a tracking issue and Fixes #ISSUE_NUMBER on the first line of the PR description, and a new PR template starts with that line. Agents must never bypass branch rules (for example gh pr merge --admin), even with admin credentials; AGENTS.md points to both.

Step 0.1 is not in this PR. It sets the required checks (Lint, Type-check API v2, Quality guards, Test) and turns on code-owner review in the main ruleset. That's a ruleset change, applied separately after merge.

Testing

  • pytest tests/unit/v2/test_data_crud_boundaries.py: 40 tests pass, covering 39 discovered modules (previously 27) plus the classification test.
  • Negative checks, each reverted afterwards:
    • Adding import sqlalchemy to services/v2/households/validators.py makes the households case fail. Before this change, nothing checked that module.
    • Adding a connector named writes.py makes the classification test fail.
  • pytest tests/unit/test_install_locked_ruff_script.py: 4 tests pass, using fake pip and ruff. They cover the locked version, the repository's own lock as the default, a missing pin (fails without installing) and a failing pip. The script also passes shellcheck, and a real run against the repo's lock in a throwaway venv installs ruff 0.15.12.
  • Ruff:
    • The install script reads 0.15.12 from the lock.
    • With that version, ruff format --check . and ruff check . both pass.
    • ruff check . with ruff 0.16.8 and the explicit select also passes. With 0.16.8's own defaults, it would report 867 errors.
  • python scripts/run_quality_guards.py and tests/unit/test_alembic_skill.py pass.
  • actionlint reports nothing on the changed workflows.
  • GitHub's CODEOWNERS validation returns no errors for this branch.

🤖 Generated with Claude Code

anth-volk and others added 5 commits October 12, 2026 22:41
Changes to the rules registry, guard scripts and CODEOWNERS itself need
review from a core developer other than the author. Deliberately narrow:
pyproject.toml and workflow files are not owned.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The lint jobs ran `pip install ruff>=0.9.0` unquoted, so the shell read
`>` as a redirect and CI installed the latest ruff. Install the version
pinned in uv.lock instead, and select ruff's current default rules
explicitly so an upgrade cannot change which rules apply. No rules are
added or removed.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The four boundary checks listed their modules by hand, so the households
and user_households packages (12 modules) were never checked. Discover the
modules by filename instead, fail at collection if a pattern matches
nothing, and require every connector module to be a recognised create,
read, update or delete module so a new name cannot escape the checks.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Every PR needs a tracking issue and `Fixes #ISSUE_NUMBER` as the first
line of its description; a PR template starts with that line. Agents must
never bypass branch rules, even with admin credentials.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Multi-line workflow run blocks become tested shell scripts. The lint jobs
now run .github/scripts/install_locked_ruff.sh, which reads ruff's version
from uv.lock and installs it, and tests cover the lock lookup, the default
lock, a missing pin and a failing pip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@codecov

codecov Bot commented Oct 12, 2026 •

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 87.56%. Comparing base (21ddf34) to head (8cedb09).

Additional details and impacted files
@@             Coverage Diff             @@
##           master    #3887       +/-   ##
===========================================
+ Coverage   45.22%   87.56%   +42.33%     
===========================================
  Files         183      198       +15     
  Lines       11073    12211     +1138     
  Branches     1905     2159      +254     
===========================================
+ Hits         5008    10692     +5684     
+ Misses       5644      922     -4722     
- Partials      421      597      +176     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

This branch was successfully deployed

1 active deployment
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.

Make CI enforcement trustworthy before the rules registry

1 participant