lint(ruff): clean up 80 pre-existing violations + wire ruff into CI as required check (closes #33) - #34
Merged
Conversation
…s required check (closes #33) Dual scope per dev directive: cleanup + CI gate + verify-release.sh step. ## Cleanup (80 violations addressed) Original discovery enumerated 82; host ruff 0.15.7 against on-disk source counted 80 (small drift likely from a ruff version difference between the api container and host). All 80 addressed. - 70 auto-fixed via `python -m ruff check . --fix`. 47 files modified, mostly unused-import removals. - 6 manually fixed: - 4x E402 import-order: app/exemptions/router.py L17 stray `import re` + L143 `BaseModel` hoisted to top; app/main.py L31-33 `engine` + `User`/`UserRole` + `AdminUserCreate` hoisted alongside other app.* imports; tests/test_base_connector.py L29 `get_connector` hoisted. - 1x F841: scripts/generate_pdf.py L218 unused `cx` removed (grep confirmed single-occurrence dead code, no shadowing risk). - 4 retained as inline `# noqa: E402 <justification>`: - app/connectors/file_system.py L16: module logger configured at L14 before base imports trigger their own logging. - tests/test_bootstrap_integration.py L65: explicit T6/ENG-001 doc-block above mandates module-constant tie (`_VALID_ENCRYPTION_KEY`). - tests/test_manual_drop.py L250: section-local import for the "Pipeline Dispatch Tests" group. - tests/test_rest_connector.py L497: section-local import for the "P7 adversarial Retry-After" group. No bare `# noqa`; every suppression carries rule-ID + one-line justification. Final: `python -m ruff check .` from backend/ → exit 0, "All checks passed!" ## CI gate (.github/workflows/ci.yml) Adds new job `ruff (lint)`. Mirrors the `--no-deps` pattern from the bootstrap-failure job. Runs on every push to master + every PR. Lightweight: 5min timeout, no postgres needed. CAVEAT: making this a REQUIRED check (i.e. blocks merges, not just runs) needs the branch-protection setting (Settings -> Branches -> master -> Require status checks -> add `ruff (lint)`). Workflow change in this PR makes the job RUN; the protection setting makes it BLOCK. Repo admin must flip the setting after this merges and the job has at least one successful run on master. ## verify-release.sh Adds step 4 ("ruff lint") between section 3 (required docs) and the summary. Uses host-side ruff (`pip install --user ruff`) with `python -m ruff` fallback. Comment in the script explains why host ruff (scans on-disk source directly) over container ruff (would see image-baked source, potentially stale relative to current working tree). CI uses container ruff because CI always builds a fresh api image first. ## CHANGELOG.md [Unreleased] > Changed entry referencing this PR's dual scope. ## Local verification - `python -m ruff check .` from backend/: exit 0, "All checks passed!" - `bash scripts/verify-release.sh`: exit 0, all 4 sections PASS: - sovereignty: 8 PASS / 1 WARN / 0 FAIL (pre-existing telemetry-pattern match, carried from prior runs) - version lockstep: `1.3.0` across all 4 surfaces (this PR doesn't bump version; v1.4.0 cut is Phase 2 Step 6) - required docs: all 6 present - ruff: 0 violations - Evidence captured in `sprint-phase2-evidence/local/2026-04-25-*-{ruff,verify-release}*.log` ## Sprint context This PR is pre-flight Bug fix #1 of the Phase 2 sprint. Closes #33. After merge: live-fire test the new ruff CI gate via a throwaway PR with one synthetic violation; confirm CI fails; delete the throwaway. Then the sprint proceeds to #30 + #31 in parallel. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The ruff job in PR #34 failed CI on first run because docker-compose.yml's service-level `env_file: .env` directive requires the .env file to exist even when `--no-deps` skips bringing up postgres/redis. The other CI jobs (backend, bootstrap-failure) synthesize a per-job .env as their first step; the ruff job missed that pattern. Adds a hermetic .env synthesis step before `docker compose build api`, matching the existing convention. Values are placeholders — ruff never reads them; the file just needs to exist for compose to load. Per dev directive's bug-discipline rule: bugs encountered mid-PR are fixed in the same PR (no file-and-defer). Logged as a sprint surprise. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
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.
Closes #33
Pre-flight Bug fix #1 of the Phase 2 sprint. Dual scope per dev directive: ruff cleanup + wire ruff into CI as a required check + add ruff step to
scripts/verify-release.sh.What's in this PR
Cleanup — 80 violations addressed (was 82 in earlier discovery; host ruff 0.15.7 against on-disk source counted 80)
python -m ruff check . --fix. 47 files modified, mostly unused-import removals.app/exemptions/router.pyL17 strayimport re+ L143BaseModelhoisted;app/main.pyL31-33engine+User/UserRole+AdminUserCreatehoisted;tests/test_base_connector.pyL29get_connectorhoisted.scripts/generate_pdf.pyL218cxremoved (single-occurrence dead code, no shadowing risk).# noqa: E402with rule-ID + one-line justification:app/connectors/file_system.pyL16 — module logger configured at L14 before base imports trigger their own loggingtests/test_bootstrap_integration.pyL65 — explicit T6/ENG-001 doc-block above mandates module-constant tie (_VALID_ENCRYPTION_KEY)tests/test_manual_drop.pyL250 — section-local import for "Pipeline Dispatch Tests" grouptests/test_rest_connector.pyL497 — section-local import for "P7 adversarial Retry-After" groupNo bare
# noqa. Final state:python -m ruff check .frombackend/→ exit 0, "All checks passed!"CI gate (
.github/workflows/ci.yml)Adds new job
ruff (lint). Mirrors the--no-depspattern from the bootstrap-failure job. Runs on every push to master + every PR. 5 min timeout, no postgres needed.ruff (lint)). After this PR merges and the job has at least one successful run on master, that flip should happen.scripts/verify-release.shAdds step 4 (
ruff lint) between section 3 (required docs) and the summary. Uses host-side ruff (pip install --user ruff) withpython -m rufffallback. Comment in the script explains why host ruff (scans on-disk source directly) over container ruff (would see image-baked source, potentially stale relative to current working tree). CI uses container ruff because CI always builds a fresh api image first.CHANGELOG
[Unreleased]> Changed entry referencing this PR's dual scope.Local verification
python -m ruff check .frombackend/: exit 0, "All checks passed!"bash scripts/verify-release.sh: exit 0, all 4 sections PASS1.3.0across all 4 surfaces (no version bump in this PR — v1.4.0 cut is Phase 2 Step 6)sprint-phase2-evidence/local/2026-04-25-*-{ruff,verify-release}*.logDiff summary
[LARGE-CHANGE]tag needed)Sprint context
sprint-phase2-log.mdat workspace root tracks all sprint work. This is pre-flight Step 1 of 8.Refs
sprint-phase2-log.md(workspace root)🤖 Generated with Claude Code