Reference
Version Policy
How org policy constrains allowed runtime and tool versions without turning on provisioning.
Recommended next
When to use this page
Use this page when a repo should stay explicit about what it needs, but the org wants to constrain which versions may be declared.
Use version_policy when governance matters even if installs stay manual or come from another bootstrap path.
- the contract says what the repo needs
version_policysays which versions are allowedprovisioningsays where ota may install or select that prerequisiteadapter_bootstraponly bootstraps the installer itself
How policy is interpreted
Think of policy as an approval gate. It validates what the repo declares; it does not rewrite repo requirements.
version_policyis keyed byruntimesandtoolsusing the same names asota.yaml.- Each policy entry may have
approved_versionsand optionalplatformsoverrides. - A policy match is required on the active OS only; if a prerequisite is off on that OS via
only_on, policy is not evaluated for that prerequisite. - Each approval entry is compared against the contract version expression with semver-aware rules; an unapproved expression is a hard policy failure.
- If no matching policy entry exists, there is no version-policy gate for that prerequisite.
- Policy can reject a declaration before provisioning, but it never changes
version,provider, ordistributionin the contract.
Current boundary
Repo contract
Declare runtime and tool intent in ota.yaml, including only_on for OS scope, platforms for per-OS value overrides, and required: false when a prerequisite should warn instead of block.
policies.version_policy
Constrain the versions governed repos may declare without forcing ota-managed installs.
policies.provisioning
Select the approved install source only when ota is also allowed to provision the prerequisite.
policies.adapter_bootstrap
Approve how ota may install the adapter binary if the chosen provisioning backend is missing.
Exact pin example
node: "22"passes andnode: "24"failspnpm: "10.12.4"passes andpnpm: "10.12.5"fails- this is the strictest form because the org is enumerating one accepted contract version
version: 1project: name: exampleruntimes: node: "22"tools: pnpm: "10.12.4"policies: version_policy: runtimes: node: approved_versions: - "22" tools: pnpm: approved_versions: - "10.12.4"Semver-range example
- use ranges when the org wants one compatible version family instead of one exact patch
- keep the policy explicit enough that repo maintainers can still tell which version families are acceptable
- doctor should fail when the repo declares a version outside the approved family
runtimes: node: "22"tools: pnpm: "^10"policies: version_policy: runtimes: node: approved_versions: - "22" tools: pnpm: approved_versions: - "^10"OS-scoped example
Use only_on in the contract for OS scope, keep platforms in the contract or version_policy for per-OS overrides, and use required only for blocking-versus-warning behavior.
- Windows may require
pwsh 7.6.0 - Linux and macOS do not fail readiness or policy checks if
pwshis inactive there - the same contract stays honest across different target OSes instead of pretending one host shape fits every machine
tools: pwsh: version: "7.6.0" only_on: - windowspolicies: version_policy: tools: pwsh: platforms: windows: approved_versions: - "7.6.0"Java distribution example
Java is the clearest case for separating repo intent from org governance, because version, provider, distribution, and install source can all differ without meaning the same thing.
Use the contract to say what the repo expects, then use org policy to constrain the allowed version and approved install path for each target OS.
version: "21"says the repo expects Java 21, not just any installed JDKprovider: sdkmanis repo intent about the runtime manager surface, not the same thing as a provisioning source approvaldistribution: temurinis the default runtime flavor, whileplatforms.windows.distribution: zulunarrows the Windows expectation without changing macOSonly_onsays Java is required on Windows and macOS but not on Linux for this repo- the org policy separately constrains the allowed Java version and the approved install source for each target OS
- if the repo later asks for Java 22, doctor should report a version-policy violation before provisioning is even relevant
- if the repo asks for
zulubut policy only permits an OpenJDK provisioning path, that mismatch should stay explicit instead of being silently rewritten
runtimes: java: version: "21" provider: sdkman distribution: temurin only_on: - windows - macos platforms: windows: distribution: zulupolicies: version_policy: runtimes: java: approved_versions: - "21" platforms: windows: approved_versions: - "21" provisioning: java: source: sdkman approved_versions: - "21" platforms: windows: source: winget package: Microsoft.OpenJDK.21 approved_versions: - "21"With provisioning
Use both layers when the org wants to govern the allowed contract versions and also govern where ota may install them from.
version_policyis the contract governance layerprovisioningis the install-source selection layer- keep them separate so doctor can explain whether the repo asked for the wrong version or whether the approved source path is missing or blocked
policies: version_policy: runtimes: node: approved_versions: - "22" tools: pnpm: approved_versions: - "10.12.4" provisioning: node: source: choco package: nodejs approved_versions: - "22" pnpm: source: npm approved_versions: - "10.12.4"How doctor explains a failure
- a version-policy failure is a contract-versus-policy mismatch
- it is not the same thing as missing provisioning or a broken package manager
- the next step should point maintainers to change the repo contract version or intentionally widen policy
◉ ERROR Repo does not satisfy org policy packWhy: `.ota/org-policy.yaml` requires version policy violations: runtime `node` version `24` is not approved by policy; expected one of: 22Next: update the repo contract versions or widen `.ota/org-policy.yaml`When this is the right boundary
- use
version_policywhen you want the org to control what versions are acceptable - use
provisioningseparately when the org must also control where missing prerequisites come from - skip both if your repo policy is purely convention and not a mandatory compliance control
- when both are present, keep version-policy checks in front of provisioning decisions so failures stay explainable