Version the acceptance oracle and its defaults
Use when: Your unattended coding agent treats a linter, formatter, type checker, or test runner as its acceptance oracle, especially when CI installs “latest” or configuration relies on upstream defaults.
Action: Pin the executable in the project lockfile and make the policy explicit. For Ruff migrations that need the pre-0.16 floor, add:
[tool.ruff.lint] select = ["E4", "E7", "E9", "F"]
Then open an upgrade-only branch and run:
uvx [email protected] check . --statistics uvx [email protected] check . --fix
The second command applies safe fixes only. Review that diff before any agent edits remaining violations; require a separate human-reviewed change for --unsafe-fixes. If Markdown formatting is not intended, explicitly exclude *.md from [tool.ruff.format]. Keep the full test suite as a separate gate.
Acceptance check: From a clean checkout, record ruff --version, the enabled settings (ruff check --show-settings path/to/canary.py), diagnostic counts, diff, and test result. Pass only if CI invokes the locked version, the configured rule set matches the reviewed baseline, safe-fix replay is idempotent, no unplanned Markdown changes appear, and lint plus the full tests exit zero twice. Fail promotion on any version, ruleset, file-scope, count, or exit-code drift.
Caveat: Freezing the old rules forever discards useful bug and runtime checks. Treat the four-rule selection as a temporary compatibility floor, not the target policy. Expand categories deliberately, and remember that Ruff labels unsafe fixes unsafe because they may alter runtime behavior or remove comments.