Skip to content
docs
Arxo ↗

Compatibility: versions and language lines

For LLMs5 sections

Compatibility in this corpus has three independent dimensions: the package version, the language line the package is written against, and the canon profile that pins a releasable set. This page explains each one and how they combine.

Environment: the observed transcript below comes from the public law-v0.1.1 release run over the lab bundle. Status letters follow the legend on the topic index.

Version grammar is wide; selection is narrow

Section titled “Version grammar is wide; selection is narrow”

Example first. Four version strings and what happens to each:

Version stringLegal?Selected automatically as “latest”?
0.2.0yesyes: a structured stable number
0.3.0-rc.1yesno: a pre-release
2026-09yesno: not structured numbering; install it by exact pin
-1no: a version must start with a letter or digit—

The lab shows selection at work. After revision 0.2.0 of labparcels.registry is published next to 0.1.0, the currency check over the fees package reports the newer stable version. Verbatim, from the lab’s versions exercise:

Output
lab ← /tmp/lab-work/registry (--registry)
labparcels.iface@0.1.0 [lab]: up to date
labparcels.registry@0.1.0 [lab]: published 0.2.0

What this result means: 0.2.0 is the version a dependency command would pick for labparcels.registry when no version is named. The pin in the lock still says 0.1.0, and nothing changes until someone moves it with law update. The number alone does not justify the move; the consumer’s scenarios do.

The rule behind the table: a package version must start with a letter or digit, followed by letters, digits, dots, underscores, pluses, or hyphens. Structured major.minor.patch numbers with optional pre-release and build parts are only a selection convenience on top of that grammar. A version outside structured numbering is therefore a legal state, not a manifest error; such a release simply takes no part in automatic latest-version selection. The source comment that states this rule:

Output
/// A package version §10 admits a wider shape (`^[0-9A-Za-z][0-9A-Za-z._+-]*$`),
/// so "not semver" is a legal state, not a manifest error: such a
/// release simply takes no part in automatic latest-version selection.

Consequences for upgrades:

  • A version that is not structured numbering is legal and stays installable by exact pin. It is never auto-selected as “latest”.
  • Pre-releases are excluded from latest-stable selection.
  • Structured numbering is not a promise of compatible behavior. Exact pins in the manifest and lockfile decide what you get; the number never does. Available in the public release (S).

The Versions protocol is the normative reference for this behavior.

The 0.2 language line is frozen: only additive revisions extend it. A world links exactly one semantics line, and closures that mix lines are refused at resolution time. The lockfile records the line of the linked world, so a later run still evaluates under the same semantics. (S)

The semantics line alone replays nothing. Repeating a saved result years later needs three more things beside it:

  • the saved toolchain: the exact build tools, pinned by hash;
  • the input artifacts: the release bytes plus the saved evaluations;
  • the replay mechanism, which re-runs those evaluations and compares the result bytes.

Lose any of the four and the outcome is a fresh computation, not a replay. When you record a result, record the full law version output with it; the block this page was written against is under Reproduction details.

A canon profile (law.profile/0.1) pins a named set of packages with exact versions, content hashes, calendars, and the required semantics revision. It is one reviewable unit: a manifest adopts it through its profile slot, and the lockfile then carries it under its resolution hash. The observed top-level fields are:

Output
Arxo canon profile 0.1 | schemaVersion, id, version, kind, title, asOf,
language, semanticsRevision, packages, calendars, contentHash

calendars appears only where a calendar is pinned; the remaining fields are present on every observed profile.

The kind value (jurisdiction, discipline, tradition, or custom) is descriptive only. Profiles nest transitively. Registry descriptors carry a signed profile form, so graphs can be checked before any bytes download. (S)

A worked example over the lab fixtures (labparcels.iface, labparcels.registry, labparcels.fees, labparcels.appeals, labparcels.case1) shows how a locked world keeps every member on one line; the lab tour walks through it.

Toolchain, hashes, and full transcripts

The pinned toolchain at the time of writing reports itself as follows (stdout of the version command; build warnings on standard error omitted):

Output
$ law version
law 0.1.1
semantics: law.core/0.2
std for language 0.2: 0.2.0
lawql: lawql/1 (queryResult 0.1)
binary hash: sha256:cfa7c17232f2dc594e665dbbf2ad3c154675797ef4be07ef7d758c9abfb80a28

Quote these five lines when recording what a result was computed with.

Documentation for Arxo. Writings — blog.arxo.io.

Anonymous visit counts on stats.arxo.io, no cookies.