Review: Python repo standards: ruff pre-commit hooks + repo setup template
Verdict: NEEDS_REFINEMENT
Third review of board item #55 / Forgejo issue #29. Prior two reviews (2026-03-27) both returned NEEDS_REFINEMENT. Issue body remains unchanged — none of the prior recommendations have been applied. This review re-validates all findings against the current codebase state as of 2026-03-28.
Template Completeness
- [ ] Type — MISSING. Falls back to Feature (acceptable per template-issue-feature)
- [x] Lineage — "New plan needed — Python Repo Standards"
- [x] Repo — "forgejo_admin/pal-e-platform (convention), forgejo_admin/claude-custom (hooks/skills)"
- [x] User Story — "As a platform operator I want all Python repos to enforce code formatting before CI..."
- [x] Context — Explains whack-a-mole CI failures from missing pre-commit hooks
- [ ] File Targets — Says "Needs scoping" with bullet-point categories only, no specific file paths
- [x] Acceptance Criteria — 5 items present
- [x] Test Expectations — Present with run command
- [x] Constraints — "Needs a proper plan" + audit list
- [x] Checklist — Present
- [x] Related — service-onboarding-sop, basketball-api #15
Traceability
- [ ] story:X label — MISSING. Issue body has a user story ("As a platform operator...") but board item #55 has no story label. Foundational tooling — borderline acceptable, but should have story:platform-standards for traceability.
- [ ] arch:X label — MISSING. Work touches CI pipeline config and developer tooling. Recommend arch:ci-pipeline.
- [x] Forgejo issue — forgejo_admin/pal-e-platform#29, OPEN
File Targets
Issue says "Needs scoping." Full codebase audit confirms 8 Python repos with current state:
| Repo | [tool.ruff] | line-length | lint select | .pre-commit-config | .woodpecker.yml (ruff) | Notes |
|---|---|---|---|---|---|---|
| pal-e-docs | YES | 100 | E,F,I,N,W | YES (v0.15.2) | NO | Only repo with pre-commit hooks |
| pal-e-docs-sdk | YES | 120 | E,F,W,I | NO | YES | |
| basketball-api | YES | 100 | E,F,I,N,W | NO | NO | |
| minio-sdk | YES | 120 | E,F,W,I | NO | YES | |
| minio-api | YES | 120 | E,F,W,I | NO | NO | |
| pal-e-mcp | YES | 120 | E,F,W,I | NO | YES | |
| pal-e-mail | YES | 120 | E,F,I,W | NO | NO | Archive candidate |
| mcd-tracker-api | YES | 100 | E,F,I,N,W | NO | NO | Archive candidate |
Config divergence: line-length splits 100 (pal-e-docs, basketball-api, mcd-tracker-api) vs 120 (all others). Lint rules split: 3 repos include "N" (naming), 5 do not. Standardizing line-length will cause mass reformatting diffs in 3+ repos.
Claude hooks already exist:
claude-custom/hooks/auto-ruff-format.sh— auto-formats staged .py files on every agent commit (never blocks)claude-custom/hooks/check-ruff-before-commit.sh— blocks agent commits when ruff check finds violations
These hooks are registered in claude-custom/settings.json as PreToolUse hooks on Bash tool. Agent-side enforcement is already in place.
Repo name discrepancy: Issue references "dora-exporter" but Forgejo repo is
forgejo_admin/pal-e-dora-exporter.Missing from audit list: minio-api, pal-e-mail, mcd-tracker-api, pal-e-mcp are not listed in the Constraints section audit targets.
Repo Placement
Issue filed on pal-e-platform (convention/governance home) — correct for a standards-level issue. Actual remediation touches 8+ separate repos. Each repo remediation needs its own Forgejo issue on its own repo. This is correctly identified in the Constraints section ("Needs a proper plan").
Dependencies
- No blocking items on board-pal-e-platform. Item #55 is in
todocolumn. - No in-progress items conflict (#576, #577 are pal-e-docs phases, #411 is Harbor CI bug).
- basketball-api #15 referenced as "immediate ruff fix" — standalone remediation already tracked.
- service-onboarding-sop needs updating to include ruff/pre-commit as a standard step — currently no mention of ruff or pre-commit in SOP sections.
Acceptance Criteria
5 AC items assessed:
- "Standard ruff config defined" — verifiable but AMBIGUOUS. Must decide: line-length 100 or 120? Include "N" rules or not? No canonical config identified.
- "Pre-commit hook config templated" — verifiable. pal-e-docs/.pre-commit-config.yaml is the de facto template (ruff-format + ruff check, v0.15.2).
- "New Python repos get hooks + config from repo setup" — requires SOP update to service-onboarding-sop. Not verifiable without specifying where template lives and how it gets applied.
- "All existing Python repos remediated" — verifiable via
ruff format --check . && ruff check .per repo. But this is 7+ repos, each needing its own PR. - "CI pipeline patterns standardized" — AMBIGUOUS. 3 of 8 repos have .woodpecker.yml with ruff steps. 5 repos have no CI at all. Does "standardized" mean adding .woodpecker.yml to all 5? The claude-custom hooks already handle agent-side enforcement.
AC are not fully agent-verifiable. Two criteria are ambiguous and require human decisions before scoping.
Blast Radius
- 7 Python repos need .pre-commit-config.yaml added.
- Standardizing line-length will cause mass reformatting diffs in 3-5 repos (depending on which standard is chosen).
- claude-custom hooks (auto-ruff-format.sh, check-ruff-before-commit.sh) already provide agent-side enforcement — issue scope should acknowledge this gap is partially closed.
- service-onboarding-sop needs a new step for ruff/pre-commit in the scaffold section.
- mcd-tracker-api and pal-e-mail are archive candidates per feedback_archive_mcd_palemail — remediation effort may be wasted.
- No downstream consumer breakage — this is additive tooling.
Decomposition Assessment
Apply the three-thing limit and five-minute rule:
- Does the ticket have >3 discrete changes? YES. 8 repos, 2-3 files each (pyproject.toml, .pre-commit-config.yaml, potentially .woodpecker.yml). Far beyond the 3-change limit.
- Would an agent need >5 minutes? YES, significantly. Each repo remediation is its own PR with potential formatting drift to resolve. Convention definition and SOP update are additional subtasks.
- Are there independent subtasks that could be parallelized? YES. Once the convention note is defined, all per-repo remediations are independent and can be parallelized across agents.
- The issue itself says "Needs a proper plan in pal-e-docs before work starts" — it was written as a plan-level tracking issue, not an agent-dispatchable ticket.
NEEDS DECOMPOSITION via template-board into:
- Convention note: Define canonical ruff config (resolve line-length 100 vs 120, resolve lint rule set). Create convention-python-tooling note.
- SOP update: Add ruff/pre-commit to service-onboarding-sop scaffold step.
- Per-repo remediation (5-6 tickets, one per non-archive repo): Add .pre-commit-config.yaml, align pyproject.toml [tool.ruff] to convention, run ruff format to resolve drift.
- CI standardization (if in scope): Add ruff lint step to .woodpecker.yml for the 5 repos that lack it.
Recommendation
[LABEL]Addstory:platform-standardslabel to board item #55[LABEL]Addarch:ci-pipelinelabel to board item #55[BODY]Add### Typeheader with valueFeature[BODY]Replace "Needs scoping" file targets with the audit table from this review (8 repos, their current ruff config state, pre-commit and CI status)[BODY]Fix repo name: "dora-exporter" should be "pal-e-dora-exporter"[BODY]Add missing repos to audit list: minio-api, pal-e-mail, mcd-tracker-api, pal-e-mcp[BODY]Acknowledge existing claude-custom hooks (auto-ruff-format.sh, check-ruff-before-commit.sh) — agent-side enforcement is already in place[BODY]Clarify AC #5 "CI pipeline patterns standardized" — 3 repos have .woodpecker.yml with ruff, 5 do not. Define target state.[SCOPE]Decide: standard line-length 100 or 120? Current split is 3 repos at 100, 5 at 120.[SCOPE]Decide: include "N" (naming) lint rules in standard, or drop to E,F,I,W only?[SCOPE]Clarify: are mcd-tracker-api and pal-e-mail still in scope given they are archive candidates (feedback_archive_mcd_palemail)?[DECOMPOSE]8 repos, 2-3 files each, 5 AC, well beyond 5-minute rule. Split into sub-board via template-board: (1) convention note, (2) SOP update, (3) per-repo remediation tickets, (4) CI standardization.