Moon Python/uv Toolchain Integration Constraint
Context and Problem Statement
The repository now includes a privacy scanning workflow that depends on Python
and uv for Semgrep execution. We need a reproducible, moon-compatible
integration path that preserves deterministic tool versions in maintainer and CI
flows.
Initial attempts to add python/uv directly to .moon/toolchains.yml failed
because this moon version does not expose those IDs as built-in toolchains.
Attempts to force custom plugin locators in moon config also failed with plugin
interface mismatch (register_toolchain function not found).
How should the repository integrate Python and uv cleanly with moon while
avoiding brittle plugin mismatch behavior?
Gate Assessment
- Cross-cutting scope — affects security scanning tasks, local developer setup, CI setup, and future Python-based automation.
- Costly to reverse — changing toolchain integration later would require script updates, docs updates, and workflow migration.
- Contract surface — defines internal tooling contract for moon/proto execution and command wiring.
- Multi-quarter longevity — toolchain bootstrapping model is expected to remain stable across multiple quarters.
- Drift risk — without a codified decision, contributors can reintroduce incompatible moon toolchain IDs or ad-hoc Python installs.
All five gates are true. Intake threshold is met.
Decision Drivers
- Keep privacy scanning reproducible and pinned.
- Preserve
moontask compatibility andmoon setupreliability. - Avoid undocumented global pip workflows.
- Keep local and CI behavior aligned.
- Minimize coupling to unstable plugin internals.
Considered Options
- Add
python/uvdirectly as moon built-ins in.moon/toolchains.yml. - Configure moon with explicit custom plugin locators for Python/uv.
- Use moon unstable toolchains (
python,uv) mapped to proto plugin locators in.prototools. - Avoid moon toolchain integration and run only
proto runfrom scripts.
Decision Outcome
Chosen option: Use moon unstable toolchains with proto plugin mappings.
Implementation Contract
.moon/toolchains.ymlconfigures:pythonwithversionFromPrototools: "python"uvwithversionFromPrototools: "uv"
.prototoolspins canonical versions:python = "3.12.11"uv = "0.9.11"
.prototoolsregisters proto plugin locators:python->python_toolwasmuv->python_uv_toolwasm
scripts/ci/check-privacy.shprefersmoon bin uvwhen available, then falls back toproto run uv, then localuv/semgrepbinaries.
Why this is cleanest now
- Works with current moon (validated with
moon project repo,moon setup, andmoon run repo:check-privacy). - Keeps Python version pinning centralized in
.prototools. - Keeps moon configuration declarative without hardcoding unsupported built-in IDs.
- Avoids direct dependency on potentially incompatible custom moon plugin ABI.
Consequences
- Good, because moon and proto remain aligned with pinned versions.
- Good, because privacy scanning stays reproducible in local and CI contexts.
- Good, because the integration path is explicit and documented.
- Bad, because toolchain IDs include
unstable_*naming, which signals evolving upstream support. - Bad, because dual mapping (
python/uvplusunstable_*plugin locators) adds small configuration overhead.
Confirmation
moon project repovalidates and shows unstable Python/uv toolchains.moon setupcompletes without toolchain config errors.moon run repo:check-privacypasses end-to-end.- Weekly scheduled privacy workflow executes
moon run repo:check-privacy.
More Information
- Related decisions:
- Related docs: