Compatibility¶
RLMesh documents compatibility at the workflow level rather than freezing every internal type. The project is released and pre-1.0: the stability labels below describe the support level today. See Versioning for the version contract.
Note
This documents 0.1.0-rc.2, a release candidate. The active workflow cohort is
2026.06-0.1.0-rc.2; the stable cutover (sealing the bare 2026.06 edition and
the Production/Stable trove status) lands at the final 0.1.0. The labels below
describe that release. Install the candidate with
pip install rlmesh==0.1.0rc2.
Note
RLMesh is pre-1.0 (0.x). “Stable” means the surface we intend to keep and will change carefully, with a migration note in the Changelog, not an API frozen until 1.0. “Experimental” may change or disappear. A 0.x minor release may break a stable API, so pin a minor range for active projects.
Stable¶
Stable workflows include documented public APIs, supported CLI flows, and supported remote environment/model interactions.
Imports, signatures, and documented behavior follow the version contract: a breaking change to a stable symbol ships in a minor release with a migration note in the Changelog.
Peers must currently run the same release. Cross-version acceptance, where newer runtimes keep accepting older stable clients and packages, is on the roadmap below, not a guarantee today.
New features may require newer packages or capabilities, but older stable workflows either keep working or fail clearly.
Preview and Experimental¶
Preview APIs are intended to become stable but may still change with migration notes. Experimental APIs may change or disappear. Preview is reserved for the intended-stable-but-still-moving case and is currently unused; today’s labels are only Stable and Experimental.
Torch and JAX backends and sandbox helpers are experimental. The MultiBinary, MultiDiscrete, Text, and Tuple space wrappers are also experimental; see Gymnasium Compatibility for the per-space stability labels, which track the API surface policy in api_metadata.json.
Warning
The dtype values int8/16 and uint16/32/64 are not negotiated. A peer from an
earlier release fails with a decode error naming the unknown dtype when it meets an environment
that uses them, so run both ends on the same release. An edition-gated dtype negotiation floor is
on the roadmap below.
Warning
The rlmesh.protocol.v1 wire format stabilizes at 0.1.0. The earlier 0.1.0 beta releases are not
wire-compatible with it; rebuild both peers when upgrading from a beta.
The supported-generation window currently holds a single generation. A future incompatible wire
change mints a new generation rather than mutating v1; a cross-version generation window is on the
roadmap below. Until 2026.06 seals at 0.1.0, prerelease and local builds use exact cohort suffixes
so mismatched moving builds fail loudly instead of guessing they are compatible.
Rust crates¶
Most Rust crates are internal implementation detail with no stability promise: they are published to crates.io so the Python extension can build, but their Rust API may change at any time and there is no plan to stabilize it. The exceptions are the rlmesh facade crate and the CLI commands, the Rust-side surfaces we intend to stabilize. Stabilizing the facade API is a near-term goal (see the roadmap below); until then, build on the Python package. See Versioning.
Framework Version Floors¶
The optional framework backends declare the lowest versions their conversion paths actually require. Each floor has a concrete reason:
Package |
Floor |
Why |
|---|---|---|
Python |
|
Ecosystem baseline; all framework floors below ship |
numpy |
|
First release with complete Python 3.10 wheel coverage. |
torch |
|
First release with full |
jax |
|
First release with DLPack |
The floor harness runs via mise run test:python:floors, which builds a cp310 wheel and runs the framework test suites against exactly these versions. Versions below a floor may work but are unsupported. Within a framework, some features need newer releases: rlmesh.numpy itself converts through the buffer protocol on any supported numpy, but consuming RLMesh tensors with np.from_dlpack needs numpy 1.23 (bool needs 1.25). Torch bool over DLPack needs 2.2 (older versions fall back to a copy), and Torch uint16/32/64 need 2.3.
Value Semantics and Caveats¶
rlmesh.Tensor is a validated transport container with DLPack and buffer-protocol edges. It is not an ndarray. Compute, slicing, and broadcasting belong to the frameworks; RLMesh moves bytes and metadata between them and the wire.
Zero-copy is asymmetric: exporting (
memoryview,__dlpack__, framework views) is zero-copy; importing (constructingTensor,Tensor.from_dlpack) currently always copies. Zero-copy import is planned.Integer precision: Box bounds carry dtype-typed bytes for integer/boolean dtypes (a single scalar for uniform bounds, one per element otherwise, little-endian in the space’s dtype), and containment compares in the dtype’s native domain, so
int64/uint64bounds and values are exact to the full range (includingi64::MIN,i64::MAX, andu64::MAX). Float dtypes keep thedouble-based bounds. The legacy scalar-list wire encoding still stores integers in a signed 64-bit slot, souint64values above 2^63 wrap on that path (the raw byte encoding used by modern clients is exact).Mutation: in-place preprocessing on a decoded observation never corrupts the wire buffer. NumPy and Torch decode to owned, writable copies; JAX decodes to an immutable array. The explicit zero-copy views (
from_dlpack, the buffer protocol,torch.as_tensor(copy=False)) are read-only; NumPy enforces this, Torch does not (see the Torch backend page).
Workflow Editions¶
Workflow semantics are governed by a negotiated workflow edition. Each base edition names a behavioral contract documented in Workflow Editions; prerelease and local builds append exact cohort suffixes. The handshake selects the highest edition supported by both peers. Editions change only on deliberate semantic redesigns; new features and new APIs do not mint editions. The 2026.06 edition seals at 0.1.0; this release candidate advertises 2026.06-0.1.0-rc.2.
Versioning and forward-compatibility roadmap¶
Today, peers must run the same release. Forward-compatibility guarantees become binding only once the code enforces them and a cross-version path is proven. The planned work, with target windows:
v0.1.0 (upcoming). First stable release. It seals the
2026.06workflow edition, freezing its spec checksum. The 0.1.0-rc.2 candidate ships first as the exact2026.06-0.1.0-rc.2cohort.Hardening, around July 2026. A cross-version test harness and a shared compatibility helper, stricter protocol checks, and the workflow edition made load-bearing in the runtime. This enables edition-driven behavior and a cross-version path once a second edition exists.
Forward tolerance, around late July 2026. Edition retention guarantees, a dtype negotiation floor, and adapter forward-tolerance.
Second edition, around August 2026. Mint a second workflow edition to exercise negotiation against a real semantic change.
Rust facade API, near term. Stabilize the
rlmeshfacade crate and the CLI commands once they settle; the other crates stay internal with no stability promise.v1.0, date not set. Forward-compatibility guarantees become binding: newer runtimes accept older stable clients, and sealed editions are never pruned. Gated on the hardening above and a proven cross-version path.
Value conformance¶
The 2026.06 edition defines how observation and action values are checked against their declared spaces (full contract: Edition 2026.06). Two points matter in practice:
Out-of-bounds values warn; they do not fail. A
Boxvalue outside its bounds, or aTextvalue outside its charset or length, is delivered and reported once in thereset/stepinfo map under therlmesh.conformance.warningkey. This keeps the many Gymnasium environments whose values drift past their declared bounds usable out of the box. SetRLMESH_VALIDATION_POLICY=strictto reject such values instead, oroffto skip the checks. Structural problems (wrong shape, dtype, arity, or domain, a missing key) andNaNare always rejected, regardless of the policy.Dtypes are coerced, not passed through. A value is always converted to its declared dtype before transport, so a peer reading the negotiated space never sees a per-message dtype. This is a deliberate difference from Gymnasium, which warns but forwards the mismatched dtype (see Gymnasium Compatibility). A float supplied for an integer dtype is rejected unless every element is exactly integral.
Artifact Versions¶
Core feature releases move together. Patch releases may be artifact-specific when the fix is isolated.
Enforcement¶
rlmesh.toml records the current package family, artifacts, protocol generation, workflow edition, and API surface policy:
python scripts/check_rlmesh_policy.py
mise run check includes mise run policy:check. Protobuf breaking-change checks are disabled while the protocol contract is being reset before the final 0.1.0 cut.