Loading and pinning
An answer without a pinned version is not reproducible. This chapter says how a spec becomes bytes: the required form, the sources each facade tries in order, the hash check on installed canons, the lock file that pins dependencies, and the offline flag.
The spec is always name and version
Section titled “The spec is always name and version”export function parseSpec(spec: string): { name: string; version: string };def parse_spec(spec: str | None) -> dict[str, str]:Both facades split name@version and refuse anything else. There is
no latest in reproducible code: the version in the spec selects the
exact bytes that answer, and the answer’s program hash names those
bytes back. The deadline app keeps the
spec in one place so a version change is a single deliberate edit.
Installed canons are checked by hash
Section titled “Installed canons are checked by hash”An installed canon is trusted by its hash, not its name. Before the
bytes are parsed, the facade digests them and compares the digest with
contentHash in the canon’s manifest; a mismatch raises
IntegrityError with the expected and actual digests and the path.
The TypeScript resolution tries the installed package whose name follows the dotted rule, then the published aliases:
export const CANON_ALIASES = { 'de.bgb.fristen': '@arxo/canon-bgb-fristen', 'kz.corpus.ogpovts': '@arxo/canon-ogpo-vts', 'unidroit.picc': '@arxo/canon-unidroit-picc',};The manifest of the periods canon names its own version, the linked world the engine runs, the calendar, and the hashes:
{ "name": "de.bgb.fristen", "version": "0.1.0", "namespace": "urn:de:corpus:clir:bgb-fristen", "clir": "world.lawir.json", "calendar": "resources/de-feiertage-bundesweit.calendar.json", "contentHash": "sha256:07b0ccc7…", "packageContentHash": "sha256:4a78d774…"}contentHash covers the linked world — this canon plus its compiled
import — and is what open checks. packageContentHash covers the
canon’s own compiled model and is the hash a lock file pins. Python
resolves the same way through its installed arxo_canon_* packages,
with the same digest-then-parse check.
The lock file pins the dependencies
Section titled “The lock file pins the dependencies”The canon ships a lock file with the exact pins it was linked against: the dependency edges, each dependency’s content hash, the calendar resource with its hash, and the resolution hash of the whole.
{ "lockVersion": "0.2", "languageSemantics": "law.core/0.2.0", "packages": [ { "name": "de.bgb.core", "version": "0.1.0", "contentHash": "sha256:35d07b51…" } ], "resources": [ { "id": "urn:de:corpus:clir:bgb-fristen#KALENDER_BUNDESWEIT", "contentHash": "sha256:aa310583…" } ], "resolutionHash": "sha256:3b8f07b7…"}The manifest also lists where the compiled import lives inside the
package (imports/de-bgb-core.lawir.json), so the linked world is
complete without fetching anything.
Checkout trees
Section titled “Checkout trees”When the canon is not installed — while its author iterates on it —
both facades accept a checkout tree through local:
local?: { root?: string; map?: Record<string, { clir: string; calendar?: string; passport?: string }>; packages?: Record<string, { ir: unknown; calendar?: string; meta?: unknown }>; };open("de.bgb.fristen@0.1.0", {"local": { "root": "/path/to/checkout", "map": {"de.bgb.fristen": {"clir": "world.lawir.json"}},}})packages carries already-parsed models keyed by name@version;
root with map points at files on disk, resolved against the root
when relative. A model whose declared version differs from the spec is
skipped, and resolution continues to the next source. In the browser
entry, only the in-memory packages form exists.
Resolution order in TypeScript is: installed canon, checkout tree, disk cache, then the public registry unless offline. Python tries the installed canon, the checkout tree, and the cache; registry fetch is not in the Python release.
The offline flag
Section titled “The offline flag”open('de.bgb.fristen@0.1.0', { offline: true });open("de.bgb.fristen@0.1.0", {"offline": True})Offline keeps the facade off the network: TypeScript skips the
registry source, and Python refuses to create the host client, so
explain raises TransportError. Installed canons and checkout trees
keep working — offline never meant “no canons”, only “no network”.
The program hash
Section titled “The program hash”Every answer carries hashes.program: the digest of the canon build
that answered. Keep it with the archived document and the answer is
replayable: the same spec resolves the same build, and the replay
chapter of the deadline app re-runs the stored
query and compares the result hash. The checksum step separately
verifies the stored bytes. Four different checks, never to be
merged: the stored-document checksum ≠ the result-hash comparison
≠ byte-equality of old and new documents ≠ authentication of the
whole capture.
One limit: the two facades do not produce byte-identical documents for the same question, so a replay must use the same facade that recorded the answer.
Contract
Section titled “Contract”- The spec is
name@version; anything else is refused. - Installed bytes are digested and compared with the manifest hash
before parsing; a mismatch is an
IntegrityError, not an answer. - The lock file pins every dependency and resource by hash.
localloads a checkout tree or in-memory models; a version mismatch skips the entry.offlinedisables the registry and the host client; local sources keep working.hashes.programnames the build that answered; archive it with the document.
Documentation for Arxo. Writings — blog.arxo.io.
Anonymous visit counts on stats.arxo.io, no cookies.