@entelekheia/ref-id 0.3.0 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,22 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ //
3
+ // GENERATED FILE — do not edit by hand. Regenerate with:
4
+ // node scripts/gen-spec.mjs
5
+ //
6
+ // The specification, compiled in as a constant, for an environment with no filesystem to read
7
+ // spec/ref-id.json from. Produced by scripts/gen-spec.mjs, which verifies spec/ref-id.json against
8
+ // its sidecar digest BEFORE emitting this file — a spec that fails that check never reaches here.
9
+ // scripts/checks composes the staleness guard that fails when this file no longer matches the spec
10
+ // it was generated from (packages/ref-id/test/spec-browser-staleness.test.ts).
11
+ /**
12
+ * The sidecar digest `spec/ref-id.json.sha256` carried at the moment this file was generated.
13
+ *
14
+ * This is a STATEMENT about provenance, not a verification: nothing in this module recomputes it,
15
+ * and there is no live spec/ref-id.json here to recompute it against. The guarantee that this digest
16
+ * is the one that was actually verified belongs to the generator (scripts/gen-spec.mjs, which refuses
17
+ * to emit from a spec that fails its sidecar) and to the staleness guard that regenerates and diffs
18
+ * this file in CI. Reading this field as a check performed at import time would be a mistake.
19
+ */
20
+ export const SPEC_DIGEST = "5f5109c08f445dfade1e5d368447c294bb70af88bce8a6e616be770e8fd870d6";
21
+ export const SPEC = { "specVersion": "1.3.0", "scheme": "ref", "grammar": { "dialect": "ecmascript-2018", "expression": "^ref:(?:(?<version>[0-9]+):)?(?<type>[a-z][a-z0-9+.-]*):(?<locator>[^;#\\r\\n]+)(?:;(?<state>[^#\\r\\n]*))?(?:#(?<fragment>[^\\r\\n]*))?$", "groups": ["version", "type", "locator", "state", "fragment"], "adaptationsApplyTo": "every pattern in this file — the expression, the pair grammars, the forms, the dispatch and refinement patterns", "anchors": "the canonical dialect ends a pattern with $ meaning end of input; an engine whose $ also matches before a final line break declares the replacement above", "adaptations": { "ecmascript-2018": { "replace": [] }, "pcre2": { "replace": [["$", "\\z"]] }, "rust-regex": { "replace": [] }, "python-re": { "replace": [["(?<", "(?P<"], ["$", "\\Z"]] }, "swift-regex": { "replace": [] } }, "state": { "separator": ";", "pair": "^(?<key>[a-z][a-z0-9-]*)=(?<value>[^\\r\\n]*)$", "unknownKey": "carry-through", "repeatedKey": "malformed" }, "fragment": { "separator": ";", "pair": "^(?<key>[a-z][a-z0-9-]*)=(?<value>[^\\r\\n]*)$", "path": "the text before the first separator, verbatim", "repeatedKey": "malformed" } }, "version": { "default": 1, "supported": [1], "mints": ["normalisation or percent-encoding", "separators or shape"], "note": "A leading digit can only be a version because a type starts with a letter; ref:v2:... is type v2." }, "encoding": { "locator": { "reserved": [], "note": "a locator is handed to its validator verbatim — a format's own percent-encoding is the format's, and a value that needs a reserved character cannot be a locator" }, "nested": { "reserved": [";", "#", "%"], "table": { ";": "%3B", "#": "%23", "%": "%25" }, "strict": "every % in a nested value begins one of the forms in the table; any other % is malformed at the key" } }, "dispatch": { "pkg": { "locator": "package-url", "validator": "package-url", "delegate": "type-prefixed", "versionTail": true, "corpus": "the nearest manifest declaring a name, skipping any ancestor manifest whose own workspace or package configuration excludes the file; unversioned, the Package URL names the living package and state= carries the frozen one. A path inside the package follows the version and leaves for the Package URL as its own subpath component; with no version declared there is no marker separating the name from the path, so a file in an unversioned corpus is named through folder instead.", "reference": "https://github.com/package-url/purl-spec" }, "folder": { "locator": "declared-corpus-name", "validator": "declared-name", "delegate": "verbatim", "versionTail": false, "pattern": "^[A-Za-z0-9][A-Za-z0-9._-]*(/[A-Za-z0-9._-]+)*$", "declaredBy": "one line in the repository configuration, per subtree, nearest ancestor wins", "corpus": "the subtree declared by name in the repository configuration; the locator continues into that subtree, one segment per directory, and ends at the file whose declared names the fragment cuts" }, "url": { "locator": "hostname-path", "validator": "declared-name", "delegate": "verbatim", "pattern": "^(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z][a-z0-9-]{1,62}(?:/[^/@;#:.][^/@;#:]*)*(?:@[A-Za-z0-9][A-Za-z0-9._+-]*)?$", "versionTail": true, "declaredBy": "the owner of the host names what lives under it: each path segment is a declared name, never a URL path, and @version is optional on the last segment. A segment admits every character except the four the grammar reserves and ':', which is excluded so that a name carrying its own version after a colon is refused rather than absorbed whole — an identifier spelled in another format's convention must be converted, and a segment admitting ':' would accept it silently with the version inert inside the name. '~' is admitted alone, because a digest never appears without the colon that introduces it. A segment may not open on '.', which excludes '.' and '..' for the reason the served-model entry gives below: the delegate is verbatim, so a consumer mapping a declared name onto a path would otherwise inherit a traversal from a locator that parsed clean.", "corpus": "a manifest that declares a host names the corpus by that host; the package name stays the identifier of the software", "reference": "RFC 1123 host labels, lowercase, internationalised labels in their punycode form" }, "email": { "locator": "addr-spec", "validator": "declared-name", "delegate": "verbatim", "versionTail": false, "pattern": "^[A-Za-z0-9._%+-]+@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z][a-z0-9-]{1,62}(?:/[A-Za-z0-9._%+@-]+)*$", "declaredBy": "a mailbox identifies a person or a role, and the items served under it are declared by whoever serves them — a message by its RFC 5322 Message-ID, a thread by the id its provider minted. The scheme checks neither who minted an id nor that the item exists, so the locator continues into the mailbox one segment per item. The first segment is the addr-spec and nothing else: an item id carrying an @, which a Message-ID does, sits after the first / and is never mistaken for the mailbox. A Message-ID is carried without the angle brackets RFC 5322 writes it between, which is the form a mail API hands over.", "reference": "RFC 5322 addr-spec, dot-atom local part — describing the first segment of the locator; RFC 5322 msg-id for an item, angle brackets stripped" }, "unknown": { "locator": "deferred-species-name", "validator": "declared-name", "delegate": "verbatim", "versionTail": true, "pattern": "^(?:[a-z][a-z0-9+.-]*:)?[A-Za-z0-9][A-Za-z0-9._-]*(?:/[A-Za-z0-9][A-Za-z0-9._-]*)*(?:@[A-Za-z0-9][A-Za-z0-9._+-]*)?$", "declaredBy": "an authority this registry does not cover. The optional prefix before the first ':' names the species — the naming system the locator belongs to — so that an uncovered authority is still named precisely rather than opaquely; registering that species as a type of its own later leaves the written identifier unchanged and moves only its status. A colon is safe inside this locator and unsafe at the top level for the same reason: here the outer type is fixed, so this grammar owns every colon within it.", "corpus": "whatever the species declares" }, "tel": { "locator": "global-number", "validator": "declared-name", "delegate": "verbatim", "versionTail": false, "pattern": "^\\+[1-9][0-9]{1,14}$", "declaredBy": "the global number of ITU-T E.164, written as RFC 3966 writes it — the leading '+' is required, so one number has one spelling. Visual separators are legal in both standards and are not admitted here: a locator reaches its validator verbatim, so a non-canonical spelling is refused rather than repaired.", "reference": "RFC 3966 tel URI, global-number-digits; ITU-T E.164" }, "isbn": { "locator": "book-number", "validator": "check-digit", "delegate": "verbatim", "versionTail": false, "pattern": "^(?:97[89][0-9]{10}|[0-9]{9}[0-9X])$", "declaredBy": "the International Standard Book Number of ISO 2108, in its canonical digits with no hyphens. Both registered lengths are admitted: the 13-digit form, which is also a GTIN-13 under the 978 and 979 prefixes, and the 10-digit form, whose final character may be 'X' for the value ten. The check digit is computed, so a number of the right shape and the wrong digit is refused.", "reference": "ISO 2108" }, "gtin": { "locator": "trade-item-number", "validator": "check-digit", "delegate": "verbatim", "versionTail": false, "pattern": "^(?:[0-9]{8}|[0-9]{12}|[0-9]{13}|[0-9]{14})$", "declaredBy": "the Global Trade Item Number of GS1 — the number a retail barcode carries. Four lengths are registered and all four are admitted: GTIN-8 (EAN-8), GTIN-12 (UPC-A), GTIN-13 (EAN-13) and GTIN-14 (ITF-14). The check digit is the GS1 weighted sum and is computed, so a number of the right shape and the wrong digit is refused. A 13-digit book number is both a GTIN-13 and an ISBN; the two types overlap there deliberately and diverge at the 10-digit form.", "reference": "GS1 General Specifications, GTIN and its check digit calculation" }, "ai-model": { "locator": "served-model-id", "validator": "declared-name", "delegate": "verbatim", "versionTail": false, "pattern": "^[A-Za-z0-9][A-Za-z0-9._:@-]*(?:/[A-Za-z0-9][A-Za-z0-9._:@-]*)*$", "declaredBy": "the id the model is served under — the exact string a caller sends to the serving process to select it, verbatim. Deliberately permissive: coercing a served name breaks the round-trip that makes it an identifier at all, so ':' (an Ollama tag), '/' (a hub-style namespace) and '@' (an LM Studio quantisation key, a revision pin) are all admitted, because a serving process accepts each of them today and rejecting one would be a defect rather than a safeguard. Every '/'-separated segment must open on an alphanumeric, which admits each of those and excludes '..', '//' and a trailing '/': the delegate is verbatim, so a consumer mapping a served id onto a path — a local weights cache — would otherwise inherit a traversal from a locator that parsed clean. Case is significant and there is no normalisation, which is a decision with no way back: two callers naming one model in two casings mint two identifiers, and adding a fold later would be a change to normalisation, which mints identifier version 2.", "reference": "no published grammar names a hosted API model: Package URL registers artifact-registry namespaces only (huggingface, mlflow), CycloneDX carries the category as a component type and identifies with an ordinary purl, SPDX 3.0's AIPackage identifies by free-text name and delegates to packageUrl, and OpenTelemetry's gen_ai.request.model is explicitly free text — so this type is this specification's own, not a delegation." } }, "typeRegistry": "a type names the naming system that owns the locator grammar; an unregistered type parses to uncovered, never to malformed, and registering its validator here is what promotes it — the registry is this table. A type name MUST be one an unrelated party solving the same problem would have chosen identically: a product name fails, because claiming it is the point of it, and a short desirable word naming a general activity fails for the opposite reason, because several parties would choose it and none owns a grammar. The test refuses the fight before it starts — a registry that admits a contested name is settled by whoever is larger rather than by whoever is right. An authority the registry does not cover is named through 'unknown' with its species declared, which costs nothing and stays precise.", "delegation": { "type-prefixed": "the validator receives <type>:<locator> verbatim — the type token is also the delegated format's own scheme", "verbatim": "the validator receives the locator alone" }, "statuses": ["ok", "malformed", "uncovered", "unsupported"], "parts": ["grammar", "type", "state", "fragment", "locator", "member", "<qualifier key>", "<refinement key>"], "unknownType": "uncovered", "roles": { "identity": ["type", "locator", "fragment.path"], "cut": "the locator names the item and the fragment names one level inside it. What that level is depends on the kind of item — a folder cuts to a file, a file to a declared name inside it. Descending a level moves the previous one into the locator, so an identifier carries exactly one cut and choosing where to cut is choosing what is named.", "scope": "a path inside the locator is the scope a declared name was declared in, not where the bytes sit. The scope of a heading in a document IS that document, which is why it belongs to identity; a language that gives a symbol a qualified name needs no path for the same reason.", "location": ["a filesystem path on one machine", "a byte offset into one copy", "a mirror serving the same bytes"], "freeze": ["state"], "moment": ["when"], "note": "location is how a reader reaches the bytes from OUTSIDE the identifier, and it never enters one. A refinement such as `lines=` is not location: it narrows within the cut, and it is declared, not measured." }, "qualifiers": { "state": { "role": "freeze", "forms": ["swhid", "git", "content-hash", "none"] }, "by": { "role": "instrument", "forms": ["ref", "sha256"] }, "over": { "role": "population", "forms": ["ref", "sha256", "unknown"] }, "when": { "role": "moment", "forms": ["rfc3339"] } }, "forms": { "swhid": { "pattern": "^swh:1:(cnt|dir|rev|rel|snp):[0-9a-f]{40}$", "reference": "ISO/IEC 18670 core identifier, no SWHID qualifiers" }, "sha256": { "pattern": "^sha256:[0-9a-f]{64}$", "digest": true }, "git": { "pattern": "^git:[0-9a-f]{7,40}$", "reference": "a commit object name, abbreviated or full — a freeze the repository can resolve, weaker than a SWHID only in that it names no archive" }, "content-hash": { "pattern": "^(sha256|blake3):[0-9a-f]{64}$", "reference": "a hash of the content itself, for what no version control holds; never a digest of members, so it declares no digest: true" }, "none": { "pattern": "^none$", "reference": "the declared level for a state nobody captured — an unknown state recorded honestly, worth more than a properties hash presented as proof of content" }, "rfc3339": { "pattern": "^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9]{2}:[0-9]{2}:[0-9]{2}(\\.[0-9]+)?Z$", "reference": "RFC 3339, UTC only — a moment, never a state" }, "ref": { "nested": true, "depth": 1, "encoding": "nested" }, "unknown": { "pattern": "^unknown$", "reference": "the declared level for a population nobody established. Deliberately not `none`, which `state` uses: a state cannot be empty, so `none` is unambiguous there, while a population over zero members is a real and different thing from a population nobody recorded — and an identifier must not let the two read alike. It is a floor, never a destination: a producer that can enumerate its population says so with `sha256`, which names which population rather than admitting there was one" } }, "refinements": { "lines": { "pattern": "^[0-9]+(,[0-9]+)?$", "range": "ascending", "boundSeparator": ",", "reference": "RFC 5147 placement" }, "item": { "pattern": "^[0-9]+$" }, "para": { "pattern": "^[0-9]+$" } }, "unknownRefinement": "carry-through", "resolutionStates": ["resolved", "unresolved", "uncovered", "archival"], "stateLevels": ["properties", "content-hash", "none"], "digest": { "algorithm": "sha256", "over": "identifier-strings", "order": "declared", "join": "\n", "encoding": "utf-8", "dedupe": false, "output": "sha256:<64 lowercase hex>" }, "identifierEquivalence": { "qualifierOrder": "insignificant", "refinementOrder": "significant", "canonicalForm": "re-serialise the parsed identifier with its qualifiers sorted by key in UTF-16 code unit order; every other part verbatim, refinements included", "comparison": "two identifiers name one thing when their canonical forms are equal byte for byte", "reserialisation": "SHOULD preserve the order written; MUST NOT be relied on to tell two identifiers apart", "note": "distinct from `canonicalisation`, which is the form of THIS FILE for its own digest" }, "comparison": { "note": "two relations equality cannot express. Both are computed on the parsed parts, never on the bytes, and both refuse an identifier this grammar did not decompose: `malformed` has no parts, and a version of the scheme an implementation does not support has parts read by the wrong expression. An `uncovered` type is compared like any other — its locator's grammar is unknown, its shape is not.", "dimensions": ["type", "version", "locator stem", "locator version", "fragment path", "fragment refinements", "qualifiers"], "samePackage": { "symmetry": "symmetric", "rule": "every dimension is compared identically except the locator version, which is ignored. A locator carries a version only where its type declares `versionTail`; elsewhere an @ belongs to the format and is part of the stem. Where a version is carried, an @ that opens a segment is a namespace and an @ inside a segment closes the name — the version runs to the next /, and the path after it stays in the stem, because one file at two releases is one file.", "purpose": "whether two identifiers name the same released thing at whatever version each declares. Only a type declaring `versionTail` has a version dimension at all — three of the nine do — so for every other type this relation is equality, and its name is borrowed from the type that motivated it." }, "covers": { "symmetry": "asymmetric — the general covers the specific, and the specific does not cover the general", "rule": "the type and the scheme version must be equal, and the general locator stem must reach the specific one — equal, or a whole segment prefix of it, so a corpus reaches the files under it and never a sibling whose name merely begins with the same characters. For the locator version, the fragment path, each fragment refinement and each qualifier: what the first leaves undeclared, the second may declare freely; what the first declares, the second must declare identically.", "purpose": "a partial identifier is a query — a store keyed by identifier answers a family by asking which of its keys the partial one covers", "reflexive": "every identifier this relation accepts covers itself" } }, "canonicalisation": { "form": "json-sorted-keys-compact", "rules": ["object keys sorted by UTF-16 code unit order", "no whitespace outside strings", "strings escaped as JSON.stringify does", "numbers are integers only", "UTF-8 bytes of the result are what the digest covers"], "sidecar": "ref-id.json.sha256 holds the digest of this file; the file never contains its own digest" }, "envelope": { "fields": { "id": "required", "sets": "required when the identifier carries a digest", "alsoKnownAs": "optional, a declaration never a similarity match", "data": "opaque" }, "selfReference": "id", "setsField": "sets", "digestForms": "every form declaring digest: true", "invariant": "for every qualifier whose value is a digest, sets[qualifier] exists and digest(sets[qualifier]) equals it; and id equals the identifier the envelope was requested under", "onFailure": "refuse at ingestion" }, "vectors": { "parse": [{ "name": "pkg with declared name", "input": "ref:pkg:npm/@acme/scanner-core@0.1.0#Observation", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "Observation", "refinements": [] }, "type": "pkg", "locator": "npm/@acme/scanner-core@0.1.0", "delegated": "pkg:npm/@acme/scanner-core@0.1.0" } }, { "name": "pkg with versioned declared-name path", "input": "ref:pkg:npm/@acme/trait-citation-fidelity@0.0.1#citation-fidelity@1/not-invented", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "citation-fidelity@1/not-invented", "refinements": [] }, "type": "pkg", "locator": "npm/@acme/trait-citation-fidelity@0.0.1" } }, { "name": "folder corpus with declared name", "input": "ref:folder:acme-governance#learnings/a-chunk-carrying-no-answer-means-death-or-health", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "learnings/a-chunk-carrying-no-answer-means-death-or-health", "refinements": [] }, "type": "folder", "locator": "acme-governance" } }, { "name": "folder with state and by digest", "input": "ref:folder:acme-tools;state=swh:1:rev:7e29bb6000000000000000000000000000000000;by=sha256:41b9caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "expect": { "status": "ok", "version": 1, "qualifiers": [["state", "swh:1:rev:7e29bb6000000000000000000000000000000000"], ["by", "sha256:41b9caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]], "fragment": null, "type": "folder", "locator": "acme-tools" } }, { "name": "explicit version 1 is version 1", "input": "ref:1:pkg:npm/x@1.0.0", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "pkg", "locator": "npm/x@1.0.0", "delegated": "pkg:npm/x@1.0.0", "explicitVersion": true } }, { "name": "version outside the supported range is unsupported, not malformed", "input": "ref:2:pkg:npm/x@1.0.0", "expect": { "status": "unsupported", "version": 2, "type": "pkg", "locator": "npm/x@1.0.0" } }, { "name": "letter-led token is a type, not a version", "input": "ref:v2:pkg:npm/x", "expect": { "status": "uncovered", "version": 1, "type": "v2", "locator": "pkg:npm/x" } }, { "name": "unknown type is uncovered, never an exception", "input": "ref:doi:10.1000/182", "expect": { "status": "uncovered", "version": 1, "type": "doi", "locator": "10.1000/182" } }, { "name": "unknown qualifier key is carried through", "input": "ref:folder:acme-tools;zz=1;state=swh:1:rev:7e29bb6000000000000000000000000000000000", "expect": { "status": "ok", "version": 1, "qualifiers": [["zz", "1"], ["state", "swh:1:rev:7e29bb6000000000000000000000000000000000"]], "fragment": null, "type": "folder", "locator": "acme-tools" } }, { "name": "nested by carrying a fragment", "input": "ref:folder:acme-tools;by=ref:pkg:npm/@acme/profiles@0.1.0%23profile/conformance@1", "expect": { "status": "ok", "version": 1, "qualifiers": [["by", "ref:pkg:npm/@acme/profiles@0.1.0%23profile/conformance@1"]], "fragment": null, "type": "folder", "locator": "acme-tools", "nested": { "by": "ref:pkg:npm/@acme/profiles@0.1.0#profile/conformance@1" } } }, { "name": "nested by carrying its own qualifier", "input": "ref:folder:acme-tools;by=ref:pkg:npm/x@1.0.0%3Bstate=swh:1:rev:7e29bb6000000000000000000000000000000000%23S", "expect": { "status": "ok", "version": 1, "qualifiers": [["by", "ref:pkg:npm/x@1.0.0%3Bstate=swh:1:rev:7e29bb6000000000000000000000000000000000%23S"]], "fragment": null, "type": "folder", "locator": "acme-tools", "nested": { "by": "ref:pkg:npm/x@1.0.0;state=swh:1:rev:7e29bb6000000000000000000000000000000000#S" } } }, { "name": "two different nested values are two different identifiers", "input": "ref:folder:acme-tools;by=ref:pkg:npm/x@1.0.0%3Bstate=swh:1:rev:7e29bb6000000000000000000000000000000000", "expect": { "status": "ok", "version": 1, "qualifiers": [["by", "ref:pkg:npm/x@1.0.0%3Bstate=swh:1:rev:7e29bb6000000000000000000000000000000000"]], "fragment": null, "type": "folder", "locator": "acme-tools", "nested": { "by": "ref:pkg:npm/x@1.0.0;state=swh:1:rev:7e29bb6000000000000000000000000000000000" } } }, { "name": "a purl keeps its own percent-encoding intact", "input": "ref:pkg:npm/%40acme/x@1.0.0#S", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "S", "refinements": [] }, "type": "pkg", "locator": "npm/%40acme/x@1.0.0", "delegated": "pkg:npm/%40acme/x@1.0.0" } }, { "name": "an identifier is one line", "input": "ref:folder:acme-tools\nx", "expect": { "status": "malformed", "part": "grammar" } }, { "name": "nesting deeper than one level is malformed", "input": "ref:folder:b;by=ref:folder:a%3Bby=ref:pkg:npm/x@1.0.0%2523S", "expect": { "status": "malformed", "part": "by" } }, { "name": "a reversed line range is malformed", "input": "ref:folder:acme-tools#AGENTS.md;lines=20,10", "expect": { "status": "malformed", "part": "lines" } }, { "name": "an unknown key keeps an encoded separator in its value", "input": "ref:folder:acme-tools;zz=a%3Bb;state=swh:1:rev:7e29bb6000000000000000000000000000000000", "expect": { "status": "ok", "version": 1, "qualifiers": [["zz", "a%3Bb"], ["state", "swh:1:rev:7e29bb6000000000000000000000000000000000"]], "fragment": null, "type": "folder", "locator": "acme-tools" } }, { "name": "refinement after the declared-name path", "input": "ref:folder:acme-tools#AGENTS.md;lines=10,20", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "AGENTS.md", "refinements": [["lines", "10,20"]] }, "type": "folder", "locator": "acme-tools" } }, { "name": "qualifier before the hash, refinement after it", "input": "ref:folder:acme-tools;state=swh:1:cnt:3404a00f00000000000000000000000000000000#AGENTS.md;lines=1", "expect": { "status": "ok", "version": 1, "qualifiers": [["state", "swh:1:cnt:3404a00f00000000000000000000000000000000"]], "fragment": { "path": "AGENTS.md", "refinements": [["lines", "1"]] }, "type": "folder", "locator": "acme-tools" } }, { "name": "unknown refinement key is carried through", "input": "ref:folder:acme-tools#AGENTS.md;zz=q", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "AGENTS.md", "refinements": [["zz", "q"]] }, "type": "folder", "locator": "acme-tools" } }, { "name": "over as a digest", "input": "ref:folder:acme-tools;over=sha256:41b9caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", "expect": { "status": "ok", "version": 1, "qualifiers": [["over", "sha256:41b9caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]], "fragment": null, "type": "folder", "locator": "acme-tools" } }, { "name": "a validator failure outranks an unknown type", "input": "ref:doi:10.1000/182;state=swh:1:rev:7e29bb6", "expect": { "status": "malformed", "part": "state" } }, { "name": "an unsupported version is not validated further", "input": "ref:2:pkg:npm/x@1.0.0;state=swh:1:rev:7e29bb6", "expect": { "status": "unsupported", "version": 2, "type": "pkg", "locator": "npm/x@1.0.0", "qualifiers": [["state", "swh:1:rev:7e29bb6"]] } }, { "name": "an uncovered type still carries its qualifiers and fragment", "input": "ref:doi:10.1000/182;state=swh:1:rev:7e29bb6000000000000000000000000000000000#S", "expect": { "status": "uncovered", "version": 1, "type": "doi", "locator": "10.1000/182", "qualifiers": [["state", "swh:1:rev:7e29bb6000000000000000000000000000000000"]], "fragment": { "path": "S", "refinements": [] } } }, { "name": "percent in a nested value is itself encoded", "input": "ref:folder:acme-tools;by=ref:pkg:npm/x@1.0.0%2523src/y", "expect": { "status": "ok", "version": 1, "qualifiers": [["by", "ref:pkg:npm/x@1.0.0%2523src/y"]], "fragment": null, "type": "folder", "locator": "acme-tools", "nested": { "by": "ref:pkg:npm/x@1.0.0%23src/y" } } }, { "name": "empty fragment is malformed", "input": "ref:folder:acme-tools#", "expect": { "status": "malformed", "part": "fragment" } }, { "name": "empty qualifier is malformed", "input": "ref:folder:acme-tools;", "expect": { "status": "malformed", "part": "state" } }, { "name": "qualifier without a value separator is malformed", "input": "ref:folder:acme-tools;at", "expect": { "status": "malformed", "part": "state" } }, { "name": "a nested value that is not a ref and not a digest fails the by validator", "input": "ref:folder:acme-tools;by=rumdl", "expect": { "status": "malformed", "part": "by" } }, { "name": "a refinement key on the qualifier side is malformed", "input": "ref:folder:acme-tools;lines=1#AGENTS.md", "expect": { "status": "malformed", "part": "lines" } }, { "name": "a qualifier key on the fragment side is malformed", "input": "ref:folder:acme-tools#AGENTS.md;state=swh:1:rev:7e29bb6000000000000000000000000000000000", "expect": { "status": "malformed", "part": "state" } }, { "name": "an empty path before a refinement is malformed", "input": "ref:folder:acme-tools#;lines=1", "expect": { "status": "malformed", "part": "fragment" } }, { "name": "a nested identifier of an unsupported version is carried, not rejected", "input": "ref:folder:acme-tools;by=ref:2:pkg:npm/x@1.0.0", "expect": { "status": "ok", "version": 1, "qualifiers": [["by", "ref:2:pkg:npm/x@1.0.0"]], "fragment": null, "type": "folder", "locator": "acme-tools", "nested": { "by": "ref:2:pkg:npm/x@1.0.0" } } }, { "name": "a version token round-trips as written", "input": "ref:01:pkg:npm/x@1.0.0", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "pkg", "locator": "npm/x@1.0.0", "explicitVersion": true, "versionText": "01" } }, { "name": "a trailing line break is malformed in every engine", "input": "ref:folder:acme-tools\n", "expect": { "status": "malformed", "part": "grammar" } }, { "name": "a repeated qualifier key is malformed at that key", "input": "ref:folder:acme-tools;state=swh:1:rev:7e29bb6000000000000000000000000000000000;state=swh:1:rev:7e29bb6000000000000000000000000000000000", "expect": { "status": "malformed", "part": "state" } }, { "name": "a repeated refinement key is malformed at that key", "input": "ref:folder:acme-tools#AGENTS.md;lines=1;lines=2", "expect": { "status": "malformed", "part": "lines" } }, { "name": "a raw percent in a nested value is malformed at the key", "input": "ref:folder:acme-tools;by=ref:pkg:npm/%40acme/x@1.0.0", "expect": { "status": "malformed", "part": "by" } }, { "name": "a nested value carries the inner percent-encoding doubled", "input": "ref:folder:acme-tools;by=ref:pkg:npm/%2540acme/x@1.0.0", "expect": { "status": "ok", "version": 1, "qualifiers": [["by", "ref:pkg:npm/%2540acme/x@1.0.0"]], "fragment": null, "type": "folder", "locator": "acme-tools", "nested": { "by": "ref:pkg:npm/%40acme/x@1.0.0" } } }, { "name": "when carries a moment in UTC", "input": "ref:pkg:npm/@acme/scanner-core;when=2026-08-12T18:55:27.811Z#governance@0.0.1/markdown-link", "expect": { "status": "ok", "version": 1, "qualifiers": [["when", "2026-08-12T18:55:27.811Z"]], "fragment": { "path": "governance@0.0.1/markdown-link", "refinements": [] }, "type": "pkg", "locator": "npm/@acme/scanner-core", "delegated": "pkg:npm/@acme/scanner-core" } }, { "name": "a moment with an offset is malformed at when", "input": "ref:folder:acme-tools;when=2026-08-12T15:55:27-03:00", "expect": { "status": "malformed", "part": "when" } }, { "name": "a typed governed-record fragment on an unversioned package corpus", "input": "ref:pkg:npm/acme-tools#acme/adr@2/0019", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "acme/adr@2/0019", "refinements": [] }, "type": "pkg", "locator": "npm/acme-tools", "delegated": "pkg:npm/acme-tools" } }, { "name": "an agent named by no authority carries the name alone, under unknown", "input": "ref:unknown:MentorUniversitario@1.4.1", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "unknown", "locator": "MentorUniversitario@1.4.1" } }, { "name": "an agent named by its host, its digest carried by state", "input": "ref:url:acme.example/doctor@v1.0;state=git:a1b2c3d4", "expect": { "status": "ok", "version": 1, "qualifiers": [["state", "git:a1b2c3d4"]], "fragment": null, "type": "url", "locator": "acme.example/doctor@v1.0" } }, { "name": "a platform vouching for a user is two segments under the host", "input": "ref:url:github.example/someone/doctor", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "url", "locator": "github.example/someone/doctor" } }, { "name": "a segment refuses the colon, so a name carrying its own version is not absorbed whole", "input": "ref:url:acme.example/doctor:v1.0", "expect": { "status": "malformed", "part": "locator" } }, { "name": "a retired type degrades to uncovered — an identifier written against it keeps its parts", "input": "ref:dot-agent:acme.example/doctor:v1.0", "expect": { "status": "uncovered", "version": 1, "qualifiers": [], "fragment": null, "type": "dot-agent", "locator": "acme.example/doctor:v1.0" } }, { "name": "a dotted host needs no registry to parse — whether it resolves is the ecosystem's check, never the grammar's", "input": "ref:url:mentor.pessoal.agent/MentorUniversitario@1.4.1", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "url", "locator": "mentor.pessoal.agent/MentorUniversitario@1.4.1" } }, { "name": "a tilde opens a segment — a platform whose usernames carry one needs no exception", "input": "ref:url:sr.ht/~reykjalin/fonn@v1.0", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "url", "locator": "sr.ht/~reykjalin/fonn@v1.0" } }, { "name": "an opaque value minted by a product is named by that product, with the value as the declared name", "input": "ref:url:entelekheia.example/app#550e8400-e29b-41d4-a716-446655440000", "expect": { "status": "ok", "version": 1, "qualifiers": [], "type": "url", "locator": "entelekheia.example/app", "fragment": { "path": "550e8400-e29b-41d4-a716-446655440000", "refinements": [] } } }, { "name": "unknown carries its species, so an uncovered authority is still named precisely", "input": "ref:unknown:doi:10.1000/182", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "unknown", "locator": "doi:10.1000/182" } }, { "name": "a species is lowercase, so one naming system has one spelling under unknown", "input": "ref:unknown:DOI:10.1000/182", "expect": { "status": "malformed", "part": "locator" } }, { "name": "a species with nothing under it names no thing", "input": "ref:unknown:doi:", "expect": { "status": "malformed", "part": "locator" } }, { "name": "a species inside unknown may itself be a naming system this registry once carried", "input": "ref:unknown:dot-agent:doctor@v1.0", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "unknown", "locator": "dot-agent:doctor@v1.0" } }, { "name": "a telephone number is the global form of E.164, and the leading + is required", "input": "ref:tel:+5511999999999", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "tel", "locator": "+5511999999999" } }, { "name": "a telephone number without its + is a different spelling of the same number, and only one spelling is an identifier", "input": "ref:tel:5511999999999", "expect": { "status": "malformed", "part": "locator" } }, { "name": "visual separators are legal in the standard and refused here — a locator reaches its validator verbatim", "input": "ref:tel:+1-201-555-0123", "expect": { "status": "malformed", "part": "locator" } }, { "name": "a thirteen-digit book number carries a check digit that is computed, not matched", "input": "ref:isbn:9780262033848", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "isbn", "locator": "9780262033848" } }, { "name": "the ten-digit form admits X for the value ten in its check digit", "input": "ref:isbn:080442957X", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "isbn", "locator": "080442957X" } }, { "name": "a book number of the right shape and the wrong check digit is a typo, which a pattern alone cannot see", "input": "ref:isbn:9780262033847", "expect": { "status": "malformed", "part": "locator" } }, { "name": "a trade item number is the number a retail barcode carries, in any of its four registered lengths", "input": "ref:gtin:036000291452", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "gtin", "locator": "036000291452" } }, { "name": "the eight-digit length is a trade item number too", "input": "ref:gtin:40170725", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "gtin", "locator": "40170725" } }, { "name": "a trade item number with the wrong check digit is refused by the same weighted sum", "input": "ref:gtin:036000291453", "expect": { "status": "malformed", "part": "locator" } }, { "name": "a domain names a corpus", "input": "ref:url:portfolio.example", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "url", "locator": "portfolio.example" } }, { "name": "a declared name under a domain, versioned, with a section fragment", "input": "ref:url:portfolio.example/case-xpto@2#results", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "results", "refinements": [] }, "type": "url", "locator": "portfolio.example/case-xpto@2" } }, { "name": "an uppercase host is malformed at the locator", "input": "ref:url:Portfolio.example/case", "expect": { "status": "malformed", "part": "locator" } }, { "name": "a mailbox identifies a person", "input": "ref:email:someone@mail.example", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "email", "locator": "someone@mail.example" } }, { "name": "an item under a mailbox is named by whoever serves it", "input": "ref:email:someone@mail.example/doctor", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "email", "locator": "someone@mail.example/doctor" } }, { "name": "an unregistered naming system is uncovered", "input": "ref:spotify:track/4uLU6hMCjMI75M1A2tKUQC", "expect": { "status": "uncovered", "version": 1, "type": "spotify", "locator": "track/4uLU6hMCjMI75M1A2tKUQC" } }, { "name": "a content hash freezes what no version control holds", "input": "ref:url:models.example/quant-q4;state=blake3:0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f", "expect": { "status": "ok", "version": 1, "qualifiers": [["state", "blake3:0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"]], "fragment": null, "type": "url", "locator": "models.example/quant-q4" } }, { "name": "none is a declared state level", "input": "ref:url:models.example/quant-q4;state=none", "expect": { "status": "ok", "version": 1, "qualifiers": [["state", "none"]], "fragment": null, "type": "url", "locator": "models.example/quant-q4" } }, { "name": "a state in an undeclared form is malformed at state", "input": "ref:url:models.example/quant-q4;state=sha1:0f0f0f0f", "expect": { "status": "malformed", "part": "state" } }, { "name": "uppercase type is malformed", "input": "ref:Pkg:npm/x@1.0.0", "expect": { "status": "malformed", "part": "grammar" } }, { "name": "missing scheme is malformed", "input": "pkg:npm/x@1.0.0", "expect": { "status": "malformed", "part": "grammar" } }, { "name": "empty locator is malformed", "input": "ref:pkg:", "expect": { "status": "malformed", "part": "grammar" } }, { "name": "abbreviated SWHID fails the state validator", "input": "ref:folder:acme-tools;state=swh:1:rev:7e29bb6", "expect": { "status": "malformed", "part": "state" } }, { "name": "invalid purl fails the locator validator", "input": "ref:pkg:not-a-purl", "expect": { "status": "malformed", "part": "locator" } }, { "name": "malformed refinement value", "input": "ref:folder:acme-tools#AGENTS.md;lines=ten", "expect": { "status": "malformed", "part": "lines" } }, { "name": "a corpus name carries the path to a file inside it", "input": "ref:folder:acme-tools/docs#AGENTS.md", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "AGENTS.md", "refinements": [] }, "type": "folder", "locator": "acme-tools/docs" } }, { "name": "ai-model served id is admitted: Qwen3-4B-Instruct-2507-4bit", "input": "ref:ai-model:Qwen3-4B-Instruct-2507-4bit", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "Qwen3-4B-Instruct-2507-4bit" } }, { "name": "ai-model served id is admitted: gemma-4-26b-a4b-it-4bit", "input": "ref:ai-model:gemma-4-26b-a4b-it-4bit", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "gemma-4-26b-a4b-it-4bit" } }, { "name": "ai-model served id is admitted: Qwen3.5-9B-OptiQ-4bit", "input": "ref:ai-model:Qwen3.5-9B-OptiQ-4bit", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "Qwen3.5-9B-OptiQ-4bit" } }, { "name": "ai-model served id is admitted: gpt-oss-20b-MXFP4-Q8", "input": "ref:ai-model:gpt-oss-20b-MXFP4-Q8", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "gpt-oss-20b-MXFP4-Q8" } }, { "name": "ai-model served id is admitted: Llama-3.2-1B-Instruct-4bit", "input": "ref:ai-model:Llama-3.2-1B-Instruct-4bit", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "Llama-3.2-1B-Instruct-4bit" } }, { "name": "ai-model served id is admitted: Qwen3.5-27B-Claude-4.6-Opus-Distilled-MLX-4bit", "input": "ref:ai-model:Qwen3.5-27B-Claude-4.6-Opus-Distilled-MLX-4bit", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "Qwen3.5-27B-Claude-4.6-Opus-Distilled-MLX-4bit" } }, { "name": "ai-model served id is admitted: SmolLM3-3B-4bit", "input": "ref:ai-model:SmolLM3-3B-4bit", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "SmolLM3-3B-4bit" } }, { "name": "ai-model served id is admitted: T-mixed-gemma-4-12B-it-OptiQ-4bit", "input": "ref:ai-model:T-mixed-gemma-4-12B-it-OptiQ-4bit", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "T-mixed-gemma-4-12B-it-OptiQ-4bit" } }, { "name": "ai-model served id is admitted: claude-opus-5", "input": "ref:ai-model:claude-opus-5", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "claude-opus-5" } }, { "name": "ai-model served id is admitted: Ternary-Bonsai-27B-mlx-2bit", "input": "ref:ai-model:Ternary-Bonsai-27B-mlx-2bit", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "Ternary-Bonsai-27B-mlx-2bit" } }, { "name": "ai-model served id is admitted: gemini-2.5-flash", "input": "ref:ai-model:gemini-2.5-flash", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "gemini-2.5-flash" } }, { "name": "ai-model served id is admitted: llama3:8b", "input": "ref:ai-model:llama3:8b", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "llama3:8b" } }, { "name": "ai-model served id is admitted: gpt-4o-2024-08-06", "input": "ref:ai-model:gpt-4o-2024-08-06", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "gpt-4o-2024-08-06" } }, { "name": "ai-model served id is admitted: mlx-community/Qwen3-1.7B-4bit", "input": "ref:ai-model:mlx-community/Qwen3-1.7B-4bit", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "ai-model", "locator": "mlx-community/Qwen3-1.7B-4bit" } }, { "name": "an ai-model id cannot open on a separator", "input": "ref:ai-model:-Qwen3-4B", "expect": { "status": "malformed", "part": "locator" } }, { "name": "unknown is a declared population level", "input": "ref:folder:acme-tools;over=unknown", "expect": { "status": "ok", "version": 1, "qualifiers": [["over", "unknown"]], "fragment": null, "type": "folder", "locator": "acme-tools" } }, { "name": "none is not a population level — a population of zero is not a population nobody recorded", "input": "ref:folder:acme-tools;over=none", "expect": { "status": "malformed", "part": "over" } }, { "name": "unknown is not a state level — the fence from the other side", "input": "ref:folder:acme-tools;state=unknown", "expect": { "status": "malformed", "part": "state" } }, { "name": "unknown is declared for over alone, never for by", "input": "ref:folder:acme-tools;by=unknown", "expect": { "status": "malformed", "part": "by" } }, { "name": "an ai-model id cannot carry a character outside its declared class", "input": "ref:ai-model:a b", "expect": { "status": "malformed", "part": "locator" } }, { "name": "an ai-model id carries a quantisation key after @", "input": "ref:ai-model:qwen2.5-7b-instruct@q4_k_m", "expect": { "status": "ok", "version": 1, "type": "ai-model", "locator": "qwen2.5-7b-instruct@q4_k_m", "qualifiers": [], "fragment": null } }, { "name": "an ai-model id cannot traverse — every segment opens on an alphanumeric", "input": "ref:ai-model:a/../../etc/passwd", "expect": { "status": "malformed", "part": "locator" } }, { "name": "an ai-model id cannot carry an empty segment", "input": "ref:ai-model:a//b", "expect": { "status": "malformed", "part": "locator" } }, { "name": "a folder locator names a file, and the fragment names what is inside it", "input": "ref:folder:acme-tools/docs/guide.md#Setup", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "Setup", "refinements": [] }, "type": "folder", "locator": "acme-tools/docs/guide.md" } }, { "name": "a trailing separator names no file and is malformed", "input": "ref:folder:acme-tools/docs/", "expect": { "status": "malformed", "part": "locator" } }, { "name": "a per-file state is a claim about the file the locator names", "input": "ref:folder:acme-tools/docs/guide.md;state=sha256:a2153e88000000000000000000000000000000000000000000000000000000ff#Setup", "expect": { "status": "ok", "version": 1, "qualifiers": [["state", "sha256:a2153e88000000000000000000000000000000000000000000000000000000ff"]], "fragment": { "path": "Setup", "refinements": [] }, "type": "folder", "locator": "acme-tools/docs/guide.md" } }, { "name": "a pkg subpath follows the version and reaches purl as its own component", "input": "ref:pkg:npm/x@1.0.0/docs/guide.md#Setup", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "Setup", "refinements": [] }, "type": "pkg", "locator": "npm/x@1.0.0/docs/guide.md", "canonical": "pkg:npm/x@1.0.0#docs/guide.md" } }, { "name": "a namespace @ opens a segment and is not the version that a subpath follows", "input": "ref:pkg:npm/@acme/x@1.0.0/docs/guide.md", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "pkg", "locator": "npm/@acme/x@1.0.0/docs/guide.md", "canonical": "pkg:npm/%40acme/x@1.0.0#docs/guide.md" } }, { "name": "a namespace without a version carries no subpath and canonicalises as the bare purl", "input": "ref:pkg:npm/@acme/x", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "pkg", "locator": "npm/@acme/x", "canonical": "pkg:npm/%40acme/x" } }, { "name": "a mailbox carries the items served under it", "input": "ref:email:alguem@dominio.com/CADx9v7abc123@mail.gmail.com", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "email", "locator": "alguem@dominio.com/CADx9v7abc123@mail.gmail.com" } }, { "name": "a message is the item, and the fragment cuts inside it", "input": "ref:email:alguem@dominio.com/CADx9v7abc123@mail.gmail.com#Assunto;para=3", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "Assunto", "refinements": [["para", "3"]] }, "type": "email", "locator": "alguem@dominio.com/CADx9v7abc123@mail.gmail.com" } }, { "name": "a message is the cut when the mailbox is the item", "input": "ref:email:alguem@dominio.com#CADx9v7abc123@mail.gmail.com", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": { "path": "CADx9v7abc123@mail.gmail.com", "refinements": [] }, "type": "email", "locator": "alguem@dominio.com" } }, { "name": "a trailing separator under a mailbox names no item", "input": "ref:email:alguem@dominio.com/", "expect": { "status": "malformed", "part": "locator" } }, { "name": "a name already percent-encoded is not encoded twice", "input": "ref:pkg:npm/%40acme/x@1.0.0", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "pkg", "locator": "npm/%40acme/x@1.0.0", "canonical": "pkg:npm/%40acme/x@1.0.0" } }, { "name": "a package type canonicalises in lower case", "input": "ref:pkg:NPM/x@1.0.0", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "pkg", "locator": "NPM/x@1.0.0", "canonical": "pkg:npm/x@1.0.0" } }, { "name": "purl qualifiers canonicalise in key order, whatever order they were written", "input": "ref:pkg:npm/x@1.0.0?os=linux&arch=amd64", "expect": { "status": "ok", "version": 1, "qualifiers": [], "fragment": null, "type": "pkg", "locator": "npm/x@1.0.0?os=linux&arch=amd64", "canonical": "pkg:npm/x@1.0.0?arch=amd64&os=linux" } }], "canonical": [{ "name": "one qualifier is already canonical", "input": "ref:eita:structured-output@1/validity;when=2026-08-02T18:31:31.870Z", "expect": "ref:eita:structured-output@1/validity;when=2026-08-02T18:31:31.870Z" }, { "name": "two qualifiers written out of order sort by key", "input": "ref:eita:structured-output@1/validity;when=2026-08-02T18:31:31.870Z;over=unknown", "expect": "ref:eita:structured-output@1/validity;over=unknown;when=2026-08-02T18:31:31.870Z" }, { "name": "the same qualifiers in the other order reach the same form", "input": "ref:eita:structured-output@1/validity;over=unknown;when=2026-08-02T18:31:31.870Z", "expect": "ref:eita:structured-output@1/validity;over=unknown;when=2026-08-02T18:31:31.870Z" }, { "name": "an unknown key sorts beside a declared one, carried through", "input": "ref:eita:citation-fidelity@1/exact;when=2026-08-14T23:38:26.089Z;context-tokens=8000;over=unknown", "expect": "ref:eita:citation-fidelity@1/exact;context-tokens=8000;over=unknown;when=2026-08-14T23:38:26.089Z" }, { "name": "sorting is by UTF-16 code unit, so a hyphen precedes a letter", "input": "ref:eita:t@1/o;alphaone=1;alpha-two=2;alpha=3", "expect": "ref:eita:t@1/o;alpha=3;alpha-two=2;alphaone=1" }, { "name": "a nested value is not decoded by canonicalisation", "input": "ref:eita:t@1/o;when=2026-08-02T18:31:31.870Z;over=ref:ai-model:Qwen3-4B-Instruct-2507-4bit", "expect": "ref:eita:t@1/o;over=ref:ai-model:Qwen3-4B-Instruct-2507-4bit;when=2026-08-02T18:31:31.870Z" }, { "name": "no qualifiers, nothing to sort", "input": "ref:pkg:npm/@acme/scanner-core@0.1.0#Observation", "expect": "ref:pkg:npm/@acme/scanner-core@0.1.0#Observation" }, { "name": "an explicit version survives canonicalisation verbatim", "input": "ref:1:pkg:npm/x@1.0.0;state=none;by=sha256:0000000000000000000000000000000000000000000000000000000000000000", "expect": "ref:1:pkg:npm/x@1.0.0;by=sha256:0000000000000000000000000000000000000000000000000000000000000000;state=none" }, { "name": "refinements are positional and keep the order they were written", "input": "ref:folder:acme-governance;state=none#AGENTS.md;lines=1,20;item=3", "expect": "ref:folder:acme-governance;state=none#AGENTS.md;lines=1,20;item=3" }, { "name": "qualifiers sort while the fragment beside them is untouched", "input": "ref:folder:acme-governance;when=2026-08-02T18:31:31.870Z;state=none#AGENTS.md;lines=1,20", "expect": "ref:folder:acme-governance;state=none;when=2026-08-02T18:31:31.870Z#AGENTS.md;lines=1,20" }, { "name": "a malformed identifier has no canonical form", "input": "ref:eita:t@1/o;state=none;state=none", "expect": { "error": "state" } }], "roundtrip": ["ref:pkg:npm/@acme/scanner-core@0.1.0#Observation", "ref:1:pkg:npm/x@1.0.0", "ref:folder:acme-tools;zz=1;state=swh:1:rev:7e29bb6000000000000000000000000000000000", "ref:folder:acme-tools;by=ref:pkg:npm/@acme/profiles@0.1.0%23profile/conformance@1", "ref:folder:acme-tools;by=ref:pkg:npm/x@1.0.0%3Bstate=swh:1:rev:7e29bb6000000000000000000000000000000000%23S", "ref:pkg:npm/%40acme/x@1.0.0#S", "ref:folder:acme-tools;zz=a%3Bb;state=swh:1:rev:7e29bb6000000000000000000000000000000000", "ref:folder:acme-tools;state=swh:1:cnt:3404a00f00000000000000000000000000000000#AGENTS.md;lines=1", "ref:folder:acme-tools#AGENTS.md;zz=q", "ref:doi:10.1000/182", "ref:dot-agent:unknown/MentorUniversitario:1.4.1", "ref:url:portfolio.example/case-xpto@2;state=none#results", "ref:email:someone@mail.example", "ref:2:pkg:npm/x@1.0.0", "ref:01:pkg:npm/x@1.0.0", "ref:pkg:npm/@acme/scanner-core;when=2026-08-12T18:55:27.811Z#governance@0.0.1/markdown-link", "ref:pkg:npm/acme-tools#acme/adr@2/0019", "ref:folder:acme-tools;by=ref:2:pkg:npm/x@1.0.0", "ref:doi:10.1000/182;state=swh:1:rev:7e29bb6000000000000000000000000000000000#S", "ref:folder:acme-tools;by=ref:pkg:npm/x@1.0.0%2523src/y", "ref:ai-model:mlx-community/Qwen3-1.7B-4bit", "ref:ai-model:llama3:8b", "ref:folder:acme-tools;over=unknown"], "build": [{ "name": "same declared name through two paths is one identifier", "parts": { "type": "pkg", "locator": "npm/x@1.0.0", "fragment": "Observation", "location": { "path": "src/a.ts" } }, "expect": "ref:pkg:npm/x@1.0.0#Observation" }, { "name": "same declared name through two paths is one identifier (other path)", "parts": { "type": "pkg", "locator": "npm/x@1.0.0", "fragment": "Observation", "location": { "path": "lib/b.ts", "lines": "4,9" } }, "expect": "ref:pkg:npm/x@1.0.0#Observation" }, { "name": "nested qualifier value is encoded by the builder", "parts": { "type": "folder", "locator": "acme-tools", "qualifiers": [["by", { "nested": "ref:pkg:npm/x@1.0.0;state=swh:1:rev:7e29bb6000000000000000000000000000000000#S" }]] }, "expect": "ref:folder:acme-tools;by=ref:pkg:npm/x@1.0.0%3Bstate=swh:1:rev:7e29bb6000000000000000000000000000000000%23S" }, { "name": "a pkg locator given as the bare group builds as is", "parts": { "type": "pkg", "locator": "npm/x@1.0.0", "fragment": "Observation" }, "expect": "ref:pkg:npm/x@1.0.0#Observation" }, { "name": "an intact purl given as locator has its scheme folded into the type", "parts": { "type": "pkg", "locator": "pkg:npm/x@1.0.0", "fragment": "S" }, "expect": "ref:pkg:npm/x@1.0.0#S" }, { "name": "a locator carrying a reserved character is refused", "parts": { "type": "pkg", "locator": "pkg:npm/x@1.0.0#src/y", "fragment": "S" }, "expect": { "error": "locator" } }, { "name": "a fragment path carrying the separator is refused", "parts": { "type": "folder", "locator": "acme-tools", "fragment": "a;b" }, "expect": { "error": "fragment" } }, { "name": "a nested identifier passed as a plain string is refused", "parts": { "type": "folder", "locator": "acme-tools", "qualifiers": [["by", "ref:pkg:npm/x@1.0.0#S"]] }, "expect": { "error": "by" } }, { "name": "a type carrying the field separator is refused", "parts": { "type": "1:folder", "locator": "a" }, "expect": { "error": "type" } }, { "name": "a dot-agent identifier builds with its digest in state", "parts": { "type": "dot-agent", "locator": "acme.example/doctor:v1.0", "qualifiers": [["state", "git:a1b2c3d4"]] }, "expect": "ref:dot-agent:acme.example/doctor:v1.0;state=git:a1b2c3d4" }, { "name": "a content hash is accepted as a state", "parts": { "type": "url", "locator": "models.example/quant-q4", "qualifiers": [["state", "sha256:0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f"]] }, "expect": "ref:url:models.example/quant-q4;state=sha256:0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f" }, { "name": "a digest value passes through the builder", "parts": { "type": "folder", "locator": "acme-tools", "qualifiers": [["over", "sha256:41b9caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"]] }, "expect": "ref:folder:acme-tools;over=sha256:41b9caaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" }, { "name": "an ai-model locator with a hub-style separator builds as is", "parts": { "type": "ai-model", "locator": "mlx-community/Qwen3-1.7B-4bit" }, "expect": "ref:ai-model:mlx-community/Qwen3-1.7B-4bit" }, { "name": "an ai-model locator with an Ollama tag builds as is", "parts": { "type": "ai-model", "locator": "llama3:8b" }, "expect": "ref:ai-model:llama3:8b" }, { "name": "over=unknown builds as the declared level for an unestablished population", "parts": { "type": "folder", "locator": "acme-tools", "qualifiers": [["over", "unknown"]] }, "expect": "ref:folder:acme-tools;over=unknown" }], "digest": [{ "name": "two members in declared order", "members": ["ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000", "ref:folder:acme-tools#GOVERNANCE.md;state=swh:1:cnt:48db124700000000000000000000000000000000"], "expect": "sha256:75433bb5329808aa4064084a54173f0328926eb38ddce742f61cbd4f0ebba71e" }, { "name": "same members, other order, different digest", "members": ["ref:folder:acme-tools#GOVERNANCE.md;state=swh:1:cnt:48db124700000000000000000000000000000000", "ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000"], "expect": "sha256:83eee8e9bcff34577a3d305bddebef2685a2e6bb20644e5a2ff29c9a8602a25b" }, { "name": "a repeated member is not deduplicated", "members": ["ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000", "ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000"], "expect": "sha256:32e30e39f2ea3cf01cc2602487229fb097846ba1a9f1037e738f61757eb3e8b6" }, { "name": "a single member", "members": ["ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000"], "expect": "sha256:b89a7d58a6ed779ac53f03eafd0b9cddfac76aad11bfe510688680bfeff45a5f" }, { "name": "a member whose content changed changes the digest", "members": ["ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a01000000000000000000000000000000000", "ref:folder:acme-tools#GOVERNANCE.md;state=swh:1:cnt:48db124700000000000000000000000000000000"], "expect": "sha256:59ecd4cdaa3ffcaf60103a20f555c4b9fa5755a0705c83a3748f60557c2c3518" }, { "name": "empty sequence", "members": [], "expect": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855" }, { "name": "a member carrying the join character is refused", "members": ["ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000\nref:folder:acme-tools#GOVERNANCE.md;state=swh:1:cnt:48db124700000000000000000000000000000000"], "expect": { "error": "member" } }], "envelope": [{ "name": "members recompute to the digest", "requestedId": "ref:folder:acme-tools;over=sha256:75433bb5329808aa4064084a54173f0328926eb38ddce742f61cbd4f0ebba71e", "envelope": { "id": "ref:folder:acme-tools;over=sha256:75433bb5329808aa4064084a54173f0328926eb38ddce742f61cbd4f0ebba71e", "sets": { "over": ["ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000", "ref:folder:acme-tools#GOVERNANCE.md;state=swh:1:cnt:48db124700000000000000000000000000000000"] } }, "expect": "admissible" }, { "name": "a member changed and the digest did not", "requestedId": "ref:folder:acme-tools;over=sha256:75433bb5329808aa4064084a54173f0328926eb38ddce742f61cbd4f0ebba71e", "envelope": { "id": "ref:folder:acme-tools;over=sha256:75433bb5329808aa4064084a54173f0328926eb38ddce742f61cbd4f0ebba71e", "sets": { "over": ["ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a01000000000000000000000000000000000", "ref:folder:acme-tools#GOVERNANCE.md;state=swh:1:cnt:48db124700000000000000000000000000000000"] } }, "expect": "refused" }, { "name": "members reordered", "requestedId": "ref:folder:acme-tools;over=sha256:75433bb5329808aa4064084a54173f0328926eb38ddce742f61cbd4f0ebba71e", "envelope": { "id": "ref:folder:acme-tools;over=sha256:75433bb5329808aa4064084a54173f0328926eb38ddce742f61cbd4f0ebba71e", "sets": { "over": ["ref:folder:acme-tools#GOVERNANCE.md;state=swh:1:cnt:48db124700000000000000000000000000000000", "ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000"] } }, "expect": "refused" }, { "name": "sets missing for a digest-carrying qualifier", "requestedId": "ref:folder:acme-tools;over=sha256:75433bb5329808aa4064084a54173f0328926eb38ddce742f61cbd4f0ebba71e", "envelope": { "id": "ref:folder:acme-tools;over=sha256:75433bb5329808aa4064084a54173f0328926eb38ddce742f61cbd4f0ebba71e" }, "expect": "refused" }, { "name": "served under an identifier that is not its own", "requestedId": "ref:folder:acme-tools#AGENTS.md", "envelope": { "id": "ref:folder:acme-tools#GOVERNANCE.md" }, "expect": "refused" }, { "name": "no digest, no sets required", "requestedId": "ref:folder:acme-tools;state=swh:1:rev:7e29bb6000000000000000000000000000000000", "envelope": { "id": "ref:folder:acme-tools;state=swh:1:rev:7e29bb6000000000000000000000000000000000", "data": { "anything": true } }, "expect": "admissible" }, { "name": "two digest qualifiers, both must recompute", "requestedId": "ref:folder:acme-tools;by=sha256:b89a7d58a6ed779ac53f03eafd0b9cddfac76aad11bfe510688680bfeff45a5f;over=sha256:27c2b1674a091639b11e51152103ce945bcd1edbb34ef36e549befcd8c0ce0a3", "envelope": { "id": "ref:folder:acme-tools;by=sha256:b89a7d58a6ed779ac53f03eafd0b9cddfac76aad11bfe510688680bfeff45a5f;over=sha256:27c2b1674a091639b11e51152103ce945bcd1edbb34ef36e549befcd8c0ce0a3", "sets": { "by": ["ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000"], "over": ["ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000"] } }, "expect": "refused" }, { "name": "a requested identifier that does not parse is refused", "requestedId": "not-a-ref", "envelope": { "id": "not-a-ref" }, "expect": "refused" }, { "name": "a requested identifier that is malformed is refused", "requestedId": "ref:folder:acme-tools;state=swh:1:rev:7e29bb6", "envelope": { "id": "ref:folder:acme-tools;state=swh:1:rev:7e29bb6" }, "expect": "refused" }, { "name": "an uncovered requested identifier is admissible", "requestedId": "ref:doi:10.1000/182", "envelope": { "id": "ref:doi:10.1000/182" }, "expect": "admissible" }, { "name": "alsoKnownAs is opaque to the invariant", "requestedId": "ref:folder:acme-tools;over=sha256:b89a7d58a6ed779ac53f03eafd0b9cddfac76aad11bfe510688680bfeff45a5f", "envelope": { "id": "ref:folder:acme-tools;over=sha256:b89a7d58a6ed779ac53f03eafd0b9cddfac76aad11bfe510688680bfeff45a5f", "sets": { "over": ["ref:folder:acme-tools#AGENTS.md;state=swh:1:cnt:3404a00f00000000000000000000000000000000"] }, "alsoKnownAs": ["ref:pkg:npm/acme-tools@0.6.0"] }, "expect": "admissible" }], "comparison": [{ "name": "identical identifiers are the same package and cover each other", "a": "ref:pkg:npm/x@1.0.0", "b": "ref:pkg:npm/x@1.0.0", "expect": { "samePackage": true, "covers": true, "coversReversed": true } }, { "name": "no version covers a version; the reverse does not hold", "a": "ref:pkg:npm/x", "b": "ref:pkg:npm/x@1.0.0", "expect": { "samePackage": true, "covers": true, "coversReversed": false } }, { "name": "two versions are one package and neither covers the other", "a": "ref:pkg:npm/x@1.0.0", "b": "ref:pkg:npm/x@2.0.0", "expect": { "samePackage": true, "covers": false, "coversReversed": false } }, { "name": "a namespace '@' is not a version — it opens a segment", "a": "ref:pkg:npm/%40acme/x", "b": "ref:pkg:npm/%40acme/x@1.0.0", "expect": { "samePackage": true, "covers": true, "coversReversed": false } }, { "name": "a mailbox '@' is not a version: two mailboxes are two things", "a": "ref:email:someone@mail.example", "b": "ref:email:someone@other.example", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "a served model's '@' keys a quantisation, never a version", "a": "ref:ai-model:mymodel@q4_k_m", "b": "ref:ai-model:mymodel@q8_0", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "no declared name covers one", "a": "ref:pkg:npm/x", "b": "ref:pkg:npm/x@1.0.0#Observation", "expect": { "samePackage": false, "covers": true, "coversReversed": false } }, { "name": "two declared names are neither", "a": "ref:pkg:npm/x#A", "b": "ref:pkg:npm/x#B", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "no refinement covers one", "a": "ref:folder:acme-tools#AGENTS.md", "b": "ref:folder:acme-tools#AGENTS.md;lines=1", "expect": { "samePackage": false, "covers": true, "coversReversed": false } }, { "name": "two refinement values are neither — a range is not a family", "a": "ref:folder:acme-tools#AGENTS.md;lines=1", "b": "ref:folder:acme-tools#AGENTS.md;lines=9", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "no qualifier covers one", "a": "ref:pkg:npm/x", "b": "ref:pkg:npm/x;state=none", "expect": { "samePackage": false, "covers": true, "coversReversed": false } }, { "name": "two qualifier values are neither", "a": "ref:pkg:npm/x;state=none", "b": "ref:pkg:npm/x;state=git:a1b2c3d", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "qualifier order does not distinguish either relation", "a": "ref:pkg:npm/x;state=none;when=2026-01-01T00:00:00Z", "b": "ref:pkg:npm/x;when=2026-01-01T00:00:00Z;state=none", "expect": { "samePackage": true, "covers": true, "coversReversed": true } }, { "name": "two types are never compared", "a": "ref:url:acme.example/x", "b": "ref:pkg:npm/x", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "an uncovered type compares like any other", "a": "ref:eita:trait", "b": "ref:eita:trait@1", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "a malformed identifier names nothing, itself included", "a": "ref:url:NOPE", "b": "ref:url:NOPE", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "an unsupported scheme version has parts read by the wrong grammar", "a": "ref:pkg:npm/x", "b": "ref:2:pkg:npm/x@1.0.0", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "a corpus covers a file under it", "a": "ref:folder:acme-tools", "b": "ref:folder:acme-tools/docs/guide.md", "expect": { "samePackage": false, "covers": true, "coversReversed": false } }, { "name": "a prefix that is not a whole segment covers nothing", "a": "ref:folder:acme-tools", "b": "ref:folder:acme-tools-extra", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "a directory covers what is under it and not its sibling", "a": "ref:folder:acme-tools/docs", "b": "ref:folder:acme-tools/docs/guide.md", "expect": { "samePackage": false, "covers": true, "coversReversed": false } }, { "name": "one file at two versions is one package", "a": "ref:pkg:npm/x@1.0.0/docs/guide.md", "b": "ref:pkg:npm/x@2.0.0/docs/guide.md", "expect": { "samePackage": true, "covers": false, "coversReversed": false } }, { "name": "a package covers a file inside one of its releases", "a": "ref:pkg:npm/x", "b": "ref:pkg:npm/x@1.0.0/docs/guide.md", "expect": { "samePackage": false, "covers": true, "coversReversed": false } }, { "name": "two files in one release are neither", "a": "ref:pkg:npm/x@1.0.0/docs/guide.md", "b": "ref:pkg:npm/x@1.0.0/docs/api.md", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }, { "name": "a mailbox covers an item served under it", "a": "ref:email:alguem@dominio.com", "b": "ref:email:alguem@dominio.com/CADx9v7abc123@mail.gmail.com", "expect": { "samePackage": false, "covers": true, "coversReversed": false } }, { "name": "two mailboxes sharing a prefix cover nothing", "a": "ref:email:alguem@dominio.com", "b": "ref:email:alguemx@dominio.com", "expect": { "samePackage": false, "covers": false, "coversReversed": false } }] } };
22
+ //# sourceMappingURL=spec.browser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.browser.js","sourceRoot":"","sources":["../src/spec.browser.ts"],"names":[],"mappings":"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"}
package/dist/spec.d.ts CHANGED
@@ -1,9 +1,17 @@
1
- /** Thrown when the loaded spec's bytes do not match its sidecar digest. */
2
- export declare class SpecIntegrityError extends Error {
1
+ import { RefIdError } from "./errors.ts";
2
+ /**
3
+ * Thrown when the loaded spec's bytes do not match its sidecar digest.
4
+ *
5
+ * Both spec errors extend `RefIdError` so that one `instanceof` covers everything this package throws.
6
+ * They carry `part: "spec"` because the part that failed is the specification itself rather than any
7
+ * part of an identifier — the field stays meaningful instead of being left undefined for two of the
8
+ * five errors.
9
+ */
10
+ export declare class SpecIntegrityError extends RefIdError {
3
11
  constructor(message: string);
4
12
  }
5
13
  /** Thrown when the loaded spec declares a specVersion major, or a vocabulary, this package does not support. */
6
- export declare class SpecVersionError extends Error {
14
+ export declare class SpecVersionError extends RefIdError {
7
15
  constructor(message: string);
8
16
  }
9
17
  /**
@@ -52,6 +60,7 @@ export interface RefIdSpec {
52
60
  validator: string;
53
61
  delegate: string;
54
62
  pattern?: string;
63
+ versionTail?: boolean;
55
64
  reference?: string;
56
65
  declaredBy?: string;
57
66
  }>;
@@ -81,10 +90,6 @@ export interface RefIdSpec {
81
90
  unknownRefinement: string;
82
91
  resolutionStates: string[];
83
92
  stateLevels: string[];
84
- fragmentGrammars: Record<string, {
85
- declaredName: string;
86
- tieBreak: string;
87
- }>;
88
93
  digest: {
89
94
  algorithm: string;
90
95
  over: string;
@@ -133,10 +138,25 @@ export declare function status(spec: RefIdSpec, name: string): string;
133
138
  * `status()`: naming a part the spec lacks is a version mismatch, reported rather than emitted.
134
139
  */
135
140
  export declare function part(spec: RefIdSpec, name: string): string;
141
+ /** The major version this package was built against. Not spec data — the package's own contract. */
142
+ export declare const SUPPORTED_SPEC_MAJOR = "1";
143
+ /**
144
+ * A source of the specification: a function an entry point installs, which returns a spec that has
145
+ * already been established as the published one.
146
+ *
147
+ * "Already established" is the contract, and it is deliberately not checkable from here. The disk
148
+ * source verifies bytes against the sidecar at the moment it reads them; the browser source carries a
149
+ * constant that `scripts/gen-spec.mjs` refused to emit until that same verification passed, and that
150
+ * the staleness guard re-establishes on every run. Re-hashing the constant here would compare a
151
+ * constant against a digest compiled from it in the same build — a check that cannot fail, which reads
152
+ * as a guarantee and is a tautology (Plan-004's Decision Log).
153
+ */
154
+ export type SpecSource = () => RefIdSpec;
136
155
  /**
137
- * Loads and validates a spec + sidecar pair from an arbitrary directory. Exposed for the
138
- * spec-integrity tests; `loadSpec()` is the entry point every other module uses.
156
+ * Installs the source `loadSpec()` reads from. Called exactly once, by an entry point, before any
157
+ * public function of this package runs — never by a consumer, because the entry point is what encodes
158
+ * which environment this build is for.
139
159
  */
140
- export declare function loadSpecFrom(dir: string): RefIdSpec;
141
- /** The validated spec object, cached after the first successful load. */
160
+ export declare function installSpecSource(load: SpecSource): void;
161
+ /** The spec object, cached after the first successful load. */
142
162
  export declare function loadSpec(): RefIdSpec;
package/dist/spec.js CHANGED
@@ -1,21 +1,32 @@
1
1
  // SPDX-License-Identifier: Apache-2.0
2
2
  //
3
- // Loads spec/ref-id.json, verifies its digest against the sidecar, and checks the specVersion
4
- // major. Behaviour only — the spec's own data is never restated here.
5
- import { readFileSync } from "node:fs";
6
- import { createHash } from "node:crypto";
7
- /** Thrown when the loaded spec's bytes do not match its sidecar digest. */
8
- export class SpecIntegrityError extends Error {
3
+ // The specification's vocabulary and its canonical serialisation, plus the seam through which a spec
4
+ // reaches this package. Behaviour only — the spec's own data is never restated here.
5
+ //
6
+ // THIS MODULE READS NOTHING. It used to open spec/ref-id.json itself through `node:fs` and hash it
7
+ // through `node:crypto`, which made every module that touches the spec which is all of them
8
+ // depend on a filesystem. Where the bytes come from is now the caller's decision, installed once by
9
+ // an entry point: `index.ts` installs the disk loader (`spec.node.ts`), `index.browser.ts` installs
10
+ // the generated constant (`spec.browser.ts`). That is the whole of Plan-004's browser build; nothing
11
+ // below knows which one it got.
12
+ import { RefIdError } from "./errors.js";
13
+ /**
14
+ * Thrown when the loaded spec's bytes do not match its sidecar digest.
15
+ *
16
+ * Both spec errors extend `RefIdError` so that one `instanceof` covers everything this package throws.
17
+ * They carry `part: "spec"` because the part that failed is the specification itself rather than any
18
+ * part of an identifier — the field stays meaningful instead of being left undefined for two of the
19
+ * five errors.
20
+ */
21
+ export class SpecIntegrityError extends RefIdError {
9
22
  constructor(message) {
10
- super(message);
11
- this.name = "SpecIntegrityError";
23
+ super("SpecIntegrityError", "spec", message);
12
24
  }
13
25
  }
14
26
  /** Thrown when the loaded spec declares a specVersion major, or a vocabulary, this package does not support. */
15
- export class SpecVersionError extends Error {
27
+ export class SpecVersionError extends RefIdError {
16
28
  constructor(message) {
17
- super(message);
18
- this.name = "SpecVersionError";
29
+ super("SpecVersionError", "spec", message);
19
30
  }
20
31
  }
21
32
  /**
@@ -49,26 +60,6 @@ export function canonicalise(value) {
49
60
  }
50
61
  throw new Error(`value of type ${typeof value} has no canonical form`);
51
62
  }
52
- /** The major version this package was built against. Not spec data — the package's own contract. */
53
- const SUPPORTED_SPEC_MAJOR = "1";
54
- function readText(location) {
55
- return readFileSync(location, "utf8");
56
- }
57
- function validate(rawJson, rawSidecar) {
58
- const parsed = JSON.parse(rawJson);
59
- const canonical = canonicalise(parsed);
60
- const computed = createHash("sha256").update(canonical, "utf8").digest("hex");
61
- const expected = rawSidecar.trim();
62
- if (computed !== expected) {
63
- throw new SpecIntegrityError(`spec/ref-id.json does not match its sidecar digest (expected ${expected}, computed ${computed})`);
64
- }
65
- const spec = parsed;
66
- const major = String(spec.specVersion).split(".")[0];
67
- if (major !== SUPPORTED_SPEC_MAJOR) {
68
- throw new SpecVersionError(`spec/ref-id.json declares specVersion ${spec.specVersion}; this package supports major ${SUPPORTED_SPEC_MAJOR}`);
69
- }
70
- return spec;
71
- }
72
63
  /**
73
64
  * A status name this code needs, checked against the vocabulary the spec declares. Code names a
74
65
  * status because it has to choose one; the spec owns the list, and naming one the spec lacks is a
@@ -91,26 +82,30 @@ export function part(spec, name) {
91
82
  }
92
83
  throw new SpecVersionError(`this package names the part "${name}", which spec ${spec.specVersion} does not declare`);
93
84
  }
85
+ /** The major version this package was built against. Not spec data — the package's own contract. */
86
+ export const SUPPORTED_SPEC_MAJOR = "1";
87
+ let source;
88
+ let cached;
94
89
  /**
95
- * Loads and validates a spec + sidecar pair from an arbitrary directory. Exposed for the
96
- * spec-integrity tests; `loadSpec()` is the entry point every other module uses.
90
+ * Installs the source `loadSpec()` reads from. Called exactly once, by an entry point, before any
91
+ * public function of this package runs — never by a consumer, because the entry point is what encodes
92
+ * which environment this build is for.
97
93
  */
98
- export function loadSpecFrom(dir) {
99
- const raw = readText(`${dir}/ref-id.json`);
100
- const sidecar = readText(`${dir}/ref-id.json.sha256`);
101
- return validate(raw, sidecar);
94
+ export function installSpecSource(load) {
95
+ source = load;
96
+ cached = undefined;
102
97
  }
103
- let cached;
104
- /** The validated spec object, cached after the first successful load. */
98
+ /** The spec object, cached after the first successful load. */
105
99
  export function loadSpec() {
106
100
  if (cached) {
107
101
  return cached;
108
102
  }
109
- const jsonUrl = new URL("../spec/ref-id.json", import.meta.url);
110
- const sidecarUrl = new URL("../spec/ref-id.json.sha256", import.meta.url);
111
- const raw = readText(jsonUrl);
112
- const sidecar = readText(sidecarUrl);
113
- cached = validate(raw, sidecar);
103
+ if (!source) {
104
+ // Reachable only by importing a module of this package directly rather than through one of its
105
+ // entry points — `exports` publishes no deep path, so a consumer cannot arrive here by accident.
106
+ throw new SpecVersionError("no specification source is installed; import this package through its entry point rather than a module inside it");
107
+ }
108
+ cached = source();
114
109
  return cached;
115
110
  }
116
111
  //# sourceMappingURL=spec.js.map
package/dist/spec.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"spec.js","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"spec.js","sourceRoot":"","sources":["../src/spec.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,11 @@
1
+ import { type RefIdSpec } from "./spec.ts";
2
+ /**
3
+ * Loads and validates a spec + sidecar pair from an arbitrary directory. Exposed for the
4
+ * spec-integrity tests; `loadSpec()` is the entry point every other module uses.
5
+ */
6
+ export declare function loadSpecFrom(dir: string): RefIdSpec;
7
+ /**
8
+ * Reads the spec that ships beside this build and verifies it. Installed as the spec source by
9
+ * `index.ts`; the `../spec/` copy is the one `package.json`'s prebuild step puts there.
10
+ */
11
+ export declare function loadSpecFromDisk(): RefIdSpec;
@@ -0,0 +1,49 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ //
3
+ // The Node source of the specification: reads spec/ref-id.json from disk, verifies its bytes against
4
+ // the sidecar digest, and checks the specVersion major. This is the half of the old spec.ts that
5
+ // needs a filesystem, and it is now the only module in the package that has one.
6
+ //
7
+ // `index.ts` installs `loadSpecFromDisk` as the spec source; `index.browser.ts` installs the
8
+ // generated constant instead and never imports this file, which is what keeps `node:fs` and
9
+ // `node:crypto` out of the browser build's module graph (Plan-004, Track 2).
10
+ import { readFileSync } from "node:fs";
11
+ import { createHash } from "node:crypto";
12
+ import { canonicalise, SpecIntegrityError, SpecVersionError, SUPPORTED_SPEC_MAJOR, } from "./spec.js";
13
+ function readText(location) {
14
+ return readFileSync(location, "utf8");
15
+ }
16
+ function validate(rawJson, rawSidecar) {
17
+ const parsed = JSON.parse(rawJson);
18
+ const canonical = canonicalise(parsed);
19
+ const computed = createHash("sha256").update(canonical, "utf8").digest("hex");
20
+ const expected = rawSidecar.trim();
21
+ if (computed !== expected) {
22
+ throw new SpecIntegrityError(`spec/ref-id.json does not match its sidecar digest (expected ${expected}, computed ${computed})`);
23
+ }
24
+ const spec = parsed;
25
+ const major = String(spec.specVersion).split(".")[0];
26
+ if (major !== SUPPORTED_SPEC_MAJOR) {
27
+ throw new SpecVersionError(`spec/ref-id.json declares specVersion ${spec.specVersion}; this package supports major ${SUPPORTED_SPEC_MAJOR}`);
28
+ }
29
+ return spec;
30
+ }
31
+ /**
32
+ * Loads and validates a spec + sidecar pair from an arbitrary directory. Exposed for the
33
+ * spec-integrity tests; `loadSpec()` is the entry point every other module uses.
34
+ */
35
+ export function loadSpecFrom(dir) {
36
+ const raw = readText(`${dir}/ref-id.json`);
37
+ const sidecar = readText(`${dir}/ref-id.json.sha256`);
38
+ return validate(raw, sidecar);
39
+ }
40
+ /**
41
+ * Reads the spec that ships beside this build and verifies it. Installed as the spec source by
42
+ * `index.ts`; the `../spec/` copy is the one `package.json`'s prebuild step puts there.
43
+ */
44
+ export function loadSpecFromDisk() {
45
+ const jsonUrl = new URL("../spec/ref-id.json", import.meta.url);
46
+ const sidecarUrl = new URL("../spec/ref-id.json.sha256", import.meta.url);
47
+ return validate(readText(jsonUrl), readText(sidecarUrl));
48
+ }
49
+ //# sourceMappingURL=spec.node.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"spec.node.js","sourceRoot":"","sources":["../src/spec.node.ts"],"names":[],"mappings":"AAAA,sCAAsC;AACtC,EAAE;AACF,qGAAqG;AACrG,iGAAiG;AACjG,iFAAiF;AACjF,EAAE;AACF,6FAA6F;AAC7F,4FAA4F;AAC5F,6EAA6E;AAE7E,OAAO,EAAE,YAAY,EAAE,MAAM,SAAS,CAAA;AACtC,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAA;AACxC,OAAO,EACL,YAAY,EACZ,kBAAkB,EAClB,gBAAgB,EAChB,oBAAoB,GAErB,MAAM,WAAW,CAAA;AAElB,SAAS,QAAQ,CAAC,QAAsB;IACtC,OAAO,YAAY,CAAC,QAAQ,EAAE,MAAM,CAAC,CAAA;AACvC,CAAC;AAED,SAAS,QAAQ,CAAC,OAAe,EAAE,UAAkB;IACnD,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,OAAO,CAAY,CAAA;IAC7C,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,CAAC,CAAA;IACtC,MAAM,QAAQ,GAAG,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,SAAS,EAAE,MAAM,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAC7E,MAAM,QAAQ,GAAG,UAAU,CAAC,IAAI,EAAE,CAAA;IAClC,IAAI,QAAQ,KAAK,QAAQ,EAAE,CAAC;QAC1B,MAAM,IAAI,kBAAkB,CAC1B,gEAAgE,QAAQ,cAAc,QAAQ,GAAG,CAClG,CAAA;IACH,CAAC;IACD,MAAM,IAAI,GAAG,MAAmB,CAAA;IAChC,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;IACpD,IAAI,KAAK,KAAK,oBAAoB,EAAE,CAAC;QACnC,MAAM,IAAI,gBAAgB,CACxB,yCAAyC,IAAI,CAAC,WAAW,iCAAiC,oBAAoB,EAAE,CACjH,CAAA;IACH,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,YAAY,CAAC,GAAW;IACtC,MAAM,GAAG,GAAG,QAAQ,CAAC,GAAG,GAAG,cAAc,CAAC,CAAA;IAC1C,MAAM,OAAO,GAAG,QAAQ,CAAC,GAAG,GAAG,qBAAqB,CAAC,CAAA;IACrD,OAAO,QAAQ,CAAC,GAAG,EAAE,OAAO,CAAC,CAAA;AAC/B,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,gBAAgB;IAC9B,MAAM,OAAO,GAAG,IAAI,GAAG,CAAC,qBAAqB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;IAC/D,MAAM,UAAU,GAAG,IAAI,GAAG,CAAC,4BAA4B,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAAA;IACzE,OAAO,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,QAAQ,CAAC,UAAU,CAAC,CAAC,CAAA;AAC1D,CAAC"}