Read SPECIFICATION.md on GitHub
Not a standard, and not on a track to becoming one yet.
Nothing in this document is an internet standard and it must not be
presented as one. The murl scheme and the
application/murl+json media type are both unregistered;
the intended path is provisional registration per RFC 7595 §5.2 once the
format stabilizes, which has not happened. Until then the specification
claims only the conventional murl:// string.
What it covers
| Section | Contents |
|---|---|
| §3 Syntax | The ABNF grammar for murl://authority/name[@version][?query][#selector], the constraints every parser must enforce, and the canonical form that defines identity. |
| §4 Authorities | The reserved local namespace and DNS-named authorities — who is allowed to define a name. |
| §5 Manifest | The envelope, top-level members, resource members, and relations between resources (dependsOn, ordering). |
| §6 Resolution | The pipeline, where manifests live (the well-known path), caching, identity binding, recursion, the normative limits, and selector failure semantics. |
| §7 Canonical form | MCF-1, the byte form a signature covers, and the ed25519 signature block. |
| §8 Security | Principles, the three tiers — safe sensitive dangerous — and the baseline policy. Summarized here, detailed in the security model. |
| §9 Versioning | murlVersion, pinned versus @latest name versions, and the rollback window that @latest implies. |
| §10–11 Registration, extensions | Registration status and the extension points: custom:* kinds, unknown-member handling, the reserved query component. |
Changes from 0.1
0.2 is additive over 0.1, and consumers must still accept manifests
declaring "murlVersion": "0.1". Duplicate JSON members are now
explicitly invalid (§5.1); the optional notBefore member bounds
a manifest's validity window; selectors gained multiple items and the
role= / tag= forms; and the mutability contract for
@latest is spelled out rather than implied.
The conformance suite
A specification with one implementation is a description of that implementation. The vector suite exists to make a second implementation cheap to build and cheap to check: run the vectors, and you know whether you agree with the reference implementation on the cases that actually matter.
spec/conformance/
manifests/valid/*.murl.json must parse AND validate with zero errors
manifests/invalid/*.murl.json must fail parsing, OR produce ≥1 error
murls/valid.txt one mURL per line; each must parse
murls/invalid.txt one mURL per line; each must be rejected
canonical/*.input.json exact bytes of *.canonical.json, or fail
signatures/{valid,invalid}/ must verify / fail — optional
Six rules an implementation has to satisfy — the sixth only if it verifies signatures:
Valid manifests parse and produce no validation errors. Warnings are allowed — several valid vectors deliberately carry unknown members, which must warn and never fail.
Invalid manifests are rejected, either at parse time or by validation with at least one error. Which of the two is implementation-defined; failing to reject at all is a conformance failure.
Valid mURLs parse and round-trip — re-parsing the canonical form yields an equal value. Some vectors are deliberately non-canonical on input and must normalize.
Invalid mURLs are rejected. No repair, no guessing.
Canonical form — each input document must canonicalize to the exact bytes of its
.canonical.jsontwin. This rule exists because a second implementation passed the first four while producing different bytes, which would have made every signature it checked or produced incompatible.Signatures (optional) — vectors under
signatures/validmust verify and those undersignatures/invalidmust fail, for the stated reason. One is deliberately hostile to the obvious shortcut: an implementation that re-serializes its typed view before verifying drops an unknown member and fails.
Validation is a static check: it never consults the clock or the network. A
vector whose expires is in the past is still valid if
its format and ordering are correct — time-of-use policy is a resolution
concern, tested separately.
# against the reference implementation
cargo test -p murl-core --test conformance
Against your own implementation, point a harness at the four locations above and apply the four rules. The reference harness is about a hundred lines and is a fine template. Vectors are versioned with the specification: new ones are added freely, existing ones change only when the spec does.
- Conformance suite README The full rules, the layout, and how to contribute a vector.
- Browse the vectors Filenames name the feature, or the rule the vector violates.
- JSON Schema A machine-readable shape check for manifests. The specification, not the schema, is normative.
- The reference harness What running the suite looks like in practice.
What is stable, and what is not
Nothing here is stable yet, and the project says so in the same place it says everything else. The grammar, the manifest format, MCF-1 and the signature block, and the well-known resolution path are all experimental, intended to freeze at 1.0 — the format's grammar specifically once a second implementation passes the conformance suite. The canonical form freezes with the format for a mechanical reason: changing it invalidates every signature already issued.
After 1.0, patch releases are editorial, minor releases are strictly additive, and anything that would make an older consumer unsafe rather than merely less capable is a major change. One exception is stated up front: a change required to fix a vulnerability may break compatibility in any release, because the alternative is a format whose defects are permanent.
| After 1.0 | May contain |
|---|---|
| patch | Editorial changes only. |
| minor | Strictly additive changes; older consumers stay safe, merely less capable. |
| major | Anything that would make an older consumer unsafe. |
| any | A change required to fix a vulnerability may break compatibility. |
Full stability and compatibility policy
Registration considerations
- The
murlscheme is unregistered. Provisional registration per RFC 7595 §5.2 is the intended path once the format stabilizes; the template is drafted in the repository but has not been submitted. application/murl+jsonis likewise unregistered; the+jsonstructured syntax suffix follows RFC 6839.- Unrelated single-URL libraries named "murl" exist on PyPI and crates.io. The name collides; the scheme string itself has no known conflicting deployment. Both are documented in prior art.