chore: reconcile the production Python runtime to a single 3.10 floor (closes #197)#198
Merged
Merged
Conversation
…closes #197) The repo named its Python runtime three disagreeing ways — container python:3.12-slim, deploy-docs prose 3.11, bare-metal PM2 host 3.10 — the documented root cause behind incident #180 (a 3.11-only datetime.UTC that crashed both Python services on deploy because CI/containers ran a different version than the host). The 3.10-3.14 CI matrix from #195 (ADR-029) mitigated the symptom but left the runtime-naming drift open; this closes it. Adopt 3.10 as the authoritative floor and make it enforced, not hand-kept: - Add /.python-version (=3.10) as the single source of truth. - Add scripts/check-python-version.sh: asserts both Dockerfile.dev FROM lines, the image-service ruff floor (py310), and each CI matrix's version-aware minimum all match the anchor. Wired into make check-python-version, the husky pre-push hook, and a new python-version-consistency CI job. - Pin both Python service images python:3.12-slim -> python:3.10-slim, so the container path mirrors the live 3.10 PM2 host (verified: both images build and import the native stack on 3.10 — onnxruntime resolves its 3.10 wheel, 1.23.2, exactly as ADR-029 predicts). - Reconcile every prose surface to 3.10 (constraints, building-block view, docker-compose doc, CLAUDE.md, CONTRIBUTING, runbook, production-deployment, PR/issue templates) and correct the now-ten CI job count across the docs. - Record the reconciliation as done in ADR-029 and the chapter-11 lesson; the historical "named three ways" narrative is left intact (the guard scopes to machine-readable surfaces, so a literal-version grep can't self-trip on it). The matrix stays 3.10-3.14: 3.10 is the floor we ship, not a cap on what the code must tolerate. Requirements pins are untouched — the floated bounds already resolve real wheels on 3.10. See ADR-029 for the floor rationale. Co-Authored-By: Claude Opus 4.8 <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.
Problem
The repo named its Python runtime three disagreeing ways — container
python:3.12-slim, deploy-docs prose3.11, bare-metal PM2 host3.10. That drift is the documented root cause of incident #180 (a 3.11-onlyfrom datetime import UTCreachedmainand crashed both Python services at import time, because CI/containers ran a different interpreter than the host). The 3.10–3.14 CI matrix from #195 / ADR-029 mitigated the symptom but deliberately left the runtime-naming drift open. This PR is for #197 — it closes that gap.Approach
Adopt 3.10 as the authoritative floor and make it enforced, not hand-maintained.
/.python-version(=3.10) — the single source of truth.scripts/check-python-version.sh— a drift guard that asserts bothDockerfile.devFROMlines, the image-service ruff floor (py310), and each CI matrix's version-aware minimum all match the anchor. Wired intomake check-python-version, the husky pre-push hook, and a newpython-version-consistencyCI job (the tenth). Mirrors the existingcheck-citationshouse style.python:3.12-slim→python:3.10-slim, so the container path mirrors the live 3.10 PM2 host — eliminating the test-vs-ship divergence behind feat: live structured server-log console (closes #178) #180. The matrix stays 3.10–3.14: 3.10 is the floor we ship, not a cap on what the code must tolerate.ui-playwright).requirements*.txtare untouched: the floated bounds (numpy>=2.0.0,onnxruntime>=1.23.2,pydantic>=2.12.5) already resolve real wheels on 3.10 (ADR-029 chose each floor for exactly that).duckdb-serviceintentionally keeps no ruff config (ADR-029 documents why).Verification (all run locally, green)
python:3.10-slim— both images build and import the native stack: image-service →py 3.10.20, cv2 4.10.0, onnxruntime 1.23.2; duckdb-service →duckdb 1.4.4, pydantic 2.13.4. The onnxruntime 1.23.2 resolution is exactly what ADR-029 predicts for a 3.10 interpreter.make check-citationsclean; cross-surface grep shows no stray service-runtime version mention.senior-reviewerpasses; all P0/P1 resolved (incl. a P1 where adding the tenth job had stranded "nine jobs" claims).Reviewer note
PR #196 (unmerged) also touches the runbook's Python section, so expect a trivial both-say-3.10 merge conflict there. No behavioral change — same code, and the 3.10 cell is already green in the existing matrix.
🤖 Generated with Claude Code