Compatibility rules
Package metadata says what a tool claims to support. Compatibility rules record what is known to work — and they take priority when jrt picks a runtime.
Local rules
A rule says: for this package, in this version range, use this runtime. --versions uses the ecosystem’s own range syntax (semver for npm, PEP 440 for PyPI, …).
jrt compat set pypi:black --runtime python@3.13 --versions ">=26,<27"
jrt compat set npm:@wonderwhy-er/desktop-commander --runtime node@22 --versions ">=0.2.0 <0.3.0"
jrt compat list
jrt compat remove pypi:blackRules apply the next time a tool is added, updated or run; jrt why <alias> shows when one was used.
Precedence
- Local rules from
jrt compat set— always win. - Signed bundles from publishers you trust.
- Rules built into jrt.
Sharing rules with signed bundles
Instead of every developer running compat set, a team or publisher can sign a bundle of rules once and distribute it.
Publisher
jrt compat keygen my-team # writes JRT_HOME/keys/my-team.jrt-key, prints the public key
jrt compat sign --key <key-file> --sequence 1 --rules rules.json \
--publisher "My Team" --expires-in 90d --out compat-bundle.jsonrules.json has the same shape as the local compatibility.json. Without --rules, your current local rules are signed. Every new bundle must use a higher --sequence than the last. Keep the key file private.
{
"rules": [
{
"ecosystem": "npm",
"package": "left-pad",
"package_constraint": ">=1.0.0",
"runtime": "node",
"runtime_version": "22"
}
]
}Consumers
jrt compat trust add my-team <public-key>
jrt compat update compat-bundle.json # or an https:// URL
jrt compat list # local rules, then each signed layer
jrt compat trust list
jrt compat trust remove my-team # also removes that publisher's rulesSecurity properties
- ed25519 signatures over the exact payload bytes; bundles from untrusted keys or with modified payloads are rejected.
- Rollback and replay protection: a bundle is only installed if its sequence is newer than the one already installed for that key.
- Expired bundles and bundles issued in the future are rejected; an installed layer that expires keeps working but
jrt doctorflags it. - Every rule is validated before signing and again after verification.
- Only
https://URLs are fetched, bundles are capped at 4 MiB, andJRT_OFFLINEblocks fetching.