ci(guardrails): style gates — deprecated-pattern scanner, allowlist ratchet, PR checklist (FO-03)#364
Merged
Merged
Conversation
…lowlist ratchet Scans src/ for the Charter's cheapest-to-check banned patterns: access-context (S7), mesh.data (S7), hedging names maybe_/try_/do_ (S3), and uncommented except/pass swallows (S4). Line-based, no dependencies; comment lines skipped; heuristics and exclusions documented in the module docstring. --include-docs adds a report-only docs/ inventory. The allowlist records the 87 legacy hits at baseline (development@9f5ed9e9) as path:pattern-id lines and may only shrink; the scanner reports stale entries so cleanups delete them. Part of FO-03 (quality campaign 2026-07, Phase 4). Underworld development team with AI support from Claude Code
style-gates.yml runs the deprecated-pattern scanner on every PR to development and main (checkout + python only, no PETSc build, <1 min), failing with the offending lines and a pointer to the Charter and the shrink-only allowlist policy. A second step prints the docs/ inventory report-only. No formatting gate: src/underworld3 is not black-clean (81 of 95 files), so a format check would fail every library PR. The PR template distils the Charter into a nine-line checklist. Part of FO-03 (quality campaign 2026-07, Phase 4). Underworld development team with AI support from Claude Code
…ters Adds guides/style-gates.md (what the gates check, shrink-only allowlist policy, local usage, what to do when a PR trips the gate, why there is no formatting gate) and links it from the developer guides toctree. Charter S10 gains a four-line machine-enforcement pointer; the release process notes that style gates must be green on the release branch. Part of FO-03 (quality campaign 2026-07, Phase 4). Underworld development team with AI support from Claude Code
…ide reference The /check-patterns skill now points at scripts/check_deprecated_patterns.py as the single source of truth for the src/ pattern list, and its reference list is aligned with the Charter authority map (the .qmd guide no longer exists). Underworld development team with AI support from Claude Code
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Phase 4 of the 2026-07 quality campaign (FO-03): machine-enforce the cheapest-to-check rules of
docs/developer/UW3_STYLE_CHARTER.mdso the cleaned-up state cannot silently drift back.What each gate checks
scripts/check_deprecated_patterns.py(stdlib only, line-based, heuristics documented in its module docstring) scanssrc/for:access-contextwith mesh.access(...)/with swarm.access(...)mesh-datamesh.datacoordinate readshedging-namedef maybe_*/def try_*/def do_*(incl._-private)except-passexcept ...:+ barepasswith no comment on the adjacent linesComment lines are skipped (commented-out legacy
.access()references in the.pyxfiles do not trip the gate). Documented exclusions:self.datainside Mesh methods (not reliably distinguishable by a line scanner) and general string/docstring mentions..github/workflows/style-gates.ymlruns the scanner on every PR todevelopmentandmain— checkout + setup-python only, no PETSc build, well under a minute — and fails with the offending lines plus pointers to the Charter,docs/developer/guides/style-gates.md, and the allowlist policy. A second step prints a report-onlydocs/inventory (currently 254 hits: 161 access-context, 76 mesh-data, 17 except-pass) without affecting the result.Allowlist inventory (baseline development @ 9f5ed9e)
87 legacy hits across 33 files, recorded in
scripts/deprecated_pattern_allowlist.txtaspath:pattern-idlines. The allowlist may only shrink — the header, the scanner output, and the CI failure message all state this; the scanner reports stale entries so cleanups delete them.access-context(13 hits, 1 file):src/underworld3/tests/test_adaptivity_metrics.py— legacy test written against the old context-manager API.mesh-data(2 hits, 1 file): the deprecated property's own docstring andDeprecationWarningmessage indiscretisation_mesh.py— the shim implementation, not usage.hedging-name(5 hits, 4 files):_maybe_install_snes_update(the Charter §3 example itself) and four_do_move()mover closures. Renaming them is library-code churn outside this PR's scope (Charter §9).except-pass(67 hits, 30 files): uncommented swallows concentrated inunits.py(8),discretisation_mesh.py(8),coordinates.py(7),petsc_maths.pyx(4),smoothing/monge_ampere.py(4). Each needs a one-line sanctioned-failure-mode comment; the intended workflow is to add it in files you already touch and delete the allowlist entry.The shim-warning regression net (
tests/test_0641_wave_c_api_shims.py, already in thelevel_1 + tier_aCI gate) complements these static checks by covering the deprecation warnings the shimmed APIs must keep emitting.Black investigation and recommendation
black --check src/underworld3(black 24.10.0, already present in theamr-devenv — nothing installed): 81 of 95 files would be reformatted. A format gate would therefore fail essentially every PR that touches library code, and a changed-files-only advisory would be permanently red for the same reason — pure noise. Recommendation: no format gate now. If the maintainers want black later, adopt it as one dedicated tree-wide reformat commit (with a.git-blame-ignore-revsentry) plus a gate in the same PR. This is recorded indocs/developer/guides/style-gates.mdso nobody "fixes" it piecemeal. Nothing was reformatted in this PR.Local red/green demonstration
python scripts/check_deprecated_patterns.py→ exit 0,OK: no new deprecated patterns (87 known legacy hit(s) allowlisted).with mesh.access(var):pointed at viapython scripts/check_deprecated_patterns.py <scratch-dir>→ exit 1, hit reported with Charter pointer (file not committed).--no-allowlist) → exit 1 with all 87 hits, confirming the allowlist is load-bearing.Other deliverables
.github/pull_request_template.md: nine-line Charter checklist (no template existed before).docs/developer/guides/release-process.md: style gates must be green on the release branch (thedevelopment → mainPR runs them automatically).docs/developer/guides/style-gates.md: compact guide (checks, shrink-only policy, local usage, tripped-gate procedure), linked from the developer guides toctree. Docs build passes; no new warnings.Left for the maintainer
.claude/commands/check-patterns.mdshould point at the scanner as the single source of truth for thesrc/pattern list (keeping its manual notebook/docs sweeps); the session's permission policy blocks edits under.claude/, so that one-paragraph edit is left to a maintainer.docs/hits stay report-only; promoting docs to a gated root is a separate cleanup.pixi.toml/pixi.lockor library-code changes anywhere in this PR.Underworld development team with AI support from Claude Code