diff --git a/repo-config/configure.sh b/repo-config/configure.sh index 2af0f165..d655314f 100755 --- a/repo-config/configure.sh +++ b/repo-config/configure.sh @@ -71,14 +71,15 @@ if [ -f "$registry" ]; then # Resolved here, not near the top, so a run with no registry (an explicit model, no hub checkout) never needs Python at all. # The name python3 is not universal: native Windows can register a Microsoft Store stub under that name that resolves on PATH but fails when actually run, so this runs it rather than just checking PATH (docs/host-setup.md). # The probe checks 3.7+ (PEP 563, from __future__ import annotations) because that is the oldest interpreter resolve_description.py happens to parse and run on, not because 3.7 is this repo's supported floor. - # The repository floor is 3.13 (spec/host-tools.json's python3 target, enforced on the host by scripts/host_gate.py); resolve_description.py's own from __future__ import annotations is what lets it stay parseable below that, not a license for any other spec/ code to hedge for anything older. + # The repository floor is 3.13 (spec/host-tools.json's python3 target, enforced on the host by scripts/host_gate.py). + # Its own from __future__ import annotations is what lets resolve_description.py stay parseable below that, not a license for any other spec/ code to hedge for anything older. # A too-old interpreter fails here with a clear message instead of a bare traceback from the script. if python3 -c "from __future__ import annotations" >/dev/null 2>&1; then py_cmd=(python3) elif py -3 -c "from __future__ import annotations" >/dev/null 2>&1; then py_cmd=(py -3) else - echo "No Python interpreter found (python3 or py -3) able to run resolve_description.py. This repo targets Python 3.13; see docs/host-setup.md." >&2 + echo "No Python interpreter found (python3 or py -3) able to run resolve_description.py. This repo targets Python 3.13 (see docs/host-setup.md)." >&2 exit 1 fi # Delegates to spec/resolve_description.py rather than a third hand-rolled copy of description_errors(). diff --git a/spec/host-tools.json b/spec/host-tools.json index 30356d3e..f79d2fd6 100644 --- a/spec/host-tools.json +++ b/spec/host-tools.json @@ -87,7 +87,7 @@ "probes": [["python3", "--version"], ["py", "-3", "--version"]], "pattern": "Python (\\d+(?:\\.\\d+)*)", "minimum": "3.13", - "why": "Every script here is standard library only, so a bare interpreter is enough and no package floor exists. The floor is the toolchain target rather than a measured breakage one version below it, which is the one entry here that reads that way and says so rather than implying a defect nobody found. pyproject.toml sets ruff target-version to py313 and mypy python_version to 3.13, so what those tools report describes 3.13 and describes no other interpreter, and a run below the floor is unverified rather than known broken. Both tools run in CI through uvx at their latest releases, beside the doc linters, the registry and spec validation, the script self-tests under coverage, and the repo and prose gates. That run judges the code rather than any host, so this floor is still a configuration choice rather than an enforced result, and a host failing it has no CI failure to point at. Two hard requirements are measured, both sit lower, and they fail differently. str.removeprefix and str.removesuffix need 3.9, and each is called where the tree actually calls it: removeprefix in scripts/prose_lint.py and spec/audit.py, removesuffix in spec/audit.py alone. An older interpreter starts, runs, and raises AttributeError when it reaches one. datetime.UTC needs 3.11 and arrives through a module-level from datetime import UTC in spec/audit.py, scripts/pr_review.py and its tests, so an older interpreter raises ImportError before any of those modules run at all. Which mode a host sees is decided by the script it runs rather than by the interpreter alone: spec/audit.py carries both and fails at import, scripts/pr_review.py carries only the import and fails the same way, and scripts/prose_lint.py carries only the call and therefore starts, runs, and fails partway through. The name rather than the version is what differs per platform, which the second probe covers. Two scripts outside this gate probe a lower number on purpose rather than by drift: repo-config/configure.sh accepts 3.7+ because that is the oldest interpreter resolve_description.py happens to run on (PEP 563), not a second floor for this repo, and scripts/skills_install.sh / host-setup/*/install-skills.* accept 3.7+ because they must run on whatever a host already has before this floor's own toolchain exists to install one; neither is evidence that spec/ or scripts/ code should hedge for anything older than 3.13.", + "why": "Every script here is standard library only, so a bare interpreter is enough and no package floor exists. The floor is the toolchain target rather than a measured breakage one version below it, which is the one entry here that reads that way and says so rather than implying a defect nobody found. pyproject.toml sets ruff target-version to py313 and mypy python_version to 3.13, so what those tools report describes 3.13 and describes no other interpreter, and a run below the floor is unverified rather than known broken. Both tools run in CI through uvx at their latest releases, beside the doc linters, the registry and spec validation, the script self-tests under coverage, and the repo and prose gates. That run judges the code rather than any host, so this floor is still a configuration choice rather than an enforced result, and a host failing it has no CI failure to point at. Two hard requirements are measured, both sit lower, and they fail differently. str.removeprefix and str.removesuffix need 3.9, and each is called where the tree actually calls it: removeprefix in scripts/prose_lint.py and spec/audit.py, removesuffix in spec/audit.py alone. An older interpreter starts, runs, and raises AttributeError when it reaches one. datetime.UTC needs 3.11 and arrives through a module-level from datetime import UTC in spec/audit.py, scripts/pr_review.py and its tests, so an older interpreter raises ImportError before any of those modules run at all. Which mode a host sees is decided by the script it runs rather than by the interpreter alone: spec/audit.py carries both and fails at import, scripts/pr_review.py carries only the import and fails the same way, and scripts/prose_lint.py carries only the call and therefore starts, runs, and fails partway through. The name rather than the version is what differs per platform, which the second probe covers. Two scripts outside this gate probe a lower number on purpose rather than by drift: repo-config/configure.sh accepts 3.7+ because that is the oldest interpreter resolve_description.py happens to run on (PEP 563), not a second floor for this repo, and scripts/skills_install.sh / host-setup/*/install-skills.* accept 3.7+ because they must run on whatever a host already has before this floor's own toolchain exists to install one. Neither is evidence that spec/ or scripts/ code should hedge for anything older than 3.13.", "source": { "linux": "Whatever the platform provides at or above the floor, since the scripts need an interpreter and no packages, so no distribution or build is pinned here.", "macos": "Whatever the platform provides at or above the floor, on the same reasoning as Linux.",