Convention: Python Ruff Standard
Convention: Python Ruff Standard
Every active Python repo uses Ruff with identical settings:
line-length=88, select=["E","F","I","W"]. Parent issue: pal-e-platform#29.Rule
All active Python repos must configure Ruff with
line-length = 88, target-version = "py312", and select = ["E", "F", "I", "W"] in pyproject.toml. No repo-specific line-length overrides or additional rule categories without a convention amendment.Rationale
Without a single enforced standard, repos drift. Today basketball-api uses
line-length=100 with an extra N rule, minio-sdk/minio-api/pal-e-mcp use line-length=120, and pal-e-docs/pal-e-docs-sdk use the correct 88. Agents switching between repos produce inconsistent formatting. CI fails on style in some repos and not others. The 88-character default matches Ruff/Black upstream, the ["E","F","I","W"] set is minimal and high-signal, and the Claude Code hooks enforce mechanically so no review nit is ever about formatting again.Examples
| Correct | Incorrect | Why |
|---|---|---|
| <code>line-length = 88</code> in pyproject.toml | <code>line-length = 120</code> in pyproject.toml | 88 is the platform standard. No per-repo overrides. |
| <code>select = ["E", "F", "I", "W"]</code> | <code>select = ["E", "F", "I", "N", "W"]</code> | N (pep8-naming) is not in the standard set. Adding rules requires a convention amendment. |
| <code>extend-exclude = ["alembic/versions"]</code> for repos with Alembic | <code>extend-exclude = ["tests"]</code> to skip test linting | Only Alembic auto-generated migrations are excluded. Tests must pass lint. |
| Both <code>ruff-format</code> and <code>ruff</code> hooks in <code>.pre-commit-config.yaml</code> | Only <code>ruff-format</code> without <code>ruff</code> lint hook | Format and lint are both required. Format without lint misses logical errors. |
| Excluded repo (<code>mcd-tracker-api</code>) left as-is | Updating excluded repo to match the standard | Archive candidates get no new work. Do not waste tickets on deprecated repos. |
Enforcement
Hook-enforced. Two Claude Code hooks in
claude-custom fire on every git commit:| Hook | File | Trigger | Behavior |
|---|---|---|---|
| Auto-format | <code>hooks/auto-ruff-format.sh</code> | PreToolUse on <code>git commit</code> | Finds staged <code>.py</code> files, runs <code>ruff format</code>, re-stages. Always exits 0 (never blocks). |
| Lint gate | <code>hooks/check-ruff-before-commit.sh</code> | PreToolUse on <code>git commit</code> | Runs <code>ruff check .</code> from repo root. Blocks commit with <code>permissionDecision: deny</code> if violations found. Fails open if ruff unavailable or repo is not Python. |
Additionally, Woodpecker CI pipelines run
ruff check . as a lint step (failure blocks merge), and repos with .pre-commit-config.yaml run ruff on human commits.pyproject.toml Template
Add this section to every in-scope repo's
pyproject.toml:
Optional per-repo addition:
extend-exclude = ["alembic/versions"] for repos with Alembic migrations. No other overrides.pre-commit-config.yaml Template
Pin
rev to the latest stable release at adoption time. Bump as a batch across all repos.Repos In Scope
| Repo | Current line-length | Current select | Conformant |
|---|---|---|---|
| <code>pal-e-docs</code> (API) | 88 | E, F, I, W | Yes |
| <code>pal-e-docs-sdk</code> | 88 | E, F, I, W | Yes |
| <code>basketball-api</code> | 100 | E, F, I, N, W | No — line-length 100, extra N rule |
| <code>minio-sdk</code> | 120 | E, F, W, I | No — line-length 120 |
| <code>minio-api</code> | 120 | E, F, W, I | No — line-length 120 |
| <code>pal-e-mcp</code> | 120 | E, F, W, I | No — line-length 120 |
Four repos require alignment tickets: update
pyproject.toml, run ruff format ., fix lint violations, commit.Repos Excluded
| Repo | Reason |
|---|---|
| <code>mcd-tracker-api</code> | Archive candidate. No new work. |
| <code>mcd-tracker-app</code> | Archive candidate. No new work. |
| <code>pal-e-mail</code> | Deprecated. No new work. |
Related
ci-rules— CI conventions including lint stepsbranch-protection— merge gates that CI lint feeds intoagent-spawn-conventions— agent dispatch patterns (hooks fire on every agent commit)convention-validation-pipeline— validation tiers where lint is the first gate