Stability & versioning¶
What you can rely on, how mklang is versioned, and how breaking changes are made. The normative version of this policy is ADR 0026; this page is the user-facing summary. The language contract itself is SPEC.
Two version lines¶
mklang carries two independent version numbers:
- Spec version — the language, declared per file via the
mklang:field (currently"0.3";"0.2"documents remain valid). It changes only when the language changes. - Package version — the reference interpreter and tooling, SemVer in
pyproject.toml(1.x — strict SemVer since 1.0.0). It changes when the interpreter or tooling changes.
The two move independently: a package release often ships with the spec version unchanged. Both lines are recorded in CHANGELOG.
What 1.0 promises¶
At 1.0.0 the 0.3 language surface is frozen and the package adopts strict SemVer:
- MAJOR — incompatible change to the stable surface.
- MINOR — additive, backward-compatible (new opt-in features, tooling, docs).
- PATCH — backward-compatible fixes.
The stable surface is the 0.3 language (machines, states, the four core faces
plus the optional faces, capability tiers, code-hook gates, the gate judge
protocol, and the trace shape — SPEC §1–§8) together with the
documented host contracts (the mklang.tools / mklang.hooks /
mklang.providers / mklang.machines entry-point registries, the run(...)
embedding API, and the §6 untrusted-data delimiting). Pin a major version and
rely on no breaking language changes.
Explicitly outside the stable surface (free to change):
- The SPEC §9 non-goals — formal types, provider/model pinning,
the
.mklextension, caching, dual-channel control. - Host-side, non-normative behavior — CLI presentation, console UX, prompt assembly text, provider parameters.
Deprecation cycle¶
A breaking change to the stable surface is never silent:
- Deprecate in a MINOR — the old surface keeps working; the change is
signalled by a CHANGELOG "Deprecated" entry, a
mklang check/lintnotice where statically detectable, and a runtime warning where observable. - Remove no sooner than the next MAJOR, and only after the deprecation has been documented for at least one full minor cycle.
Pre-1.0 behavior is not covered by this forward promise — the commitment runs from 1.0.0 onward.
Spec vs reference interpreter¶
SPEC is the normative contract; src/mklang/ is one conformant
reference implementation. A behavior change that is a valid reading of the 0.3
spec is a package change (SemVer), not a spec change. A change that needs new
spec text is a spec change (0.4+) and carries the conformance work the change
checklist requires. What would actually force a 0.4 — rather than another
deferral — is written down as falsifiable conditions in
ADR 0031; a 0.4 proposal cites
the evidence row that met one.
The .mkl extension¶
Machine files use the .mkl suffix (mklang), renamed from .mk to shed the
Makefile / Linguist collision
(ADR 0027). The suffix is a discovery
convention, not part of the language contract: the document is YAML, and a
machine loads by explicit path regardless of suffix. Directory discovery
(load_registry, the CLI project scan) matches *.mkl.