Markdown for LLMs
Loading and pinning
The source Markdown for this article. Copy it into your assistant or download it as a text file.
# 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
```ts
export function parseSpec(spec: string): { name: string; version: string };
```
```python
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](/build/start/) keeps the
spec in one place so a version change is a single deliberate edit.
## 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:
```js
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:
```json
{
"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
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.
```json
{
"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
When the canon is not installed — while its author iterates on it —
both facades accept a checkout tree through `local`:
```ts
local?: {
root?: string;
map?: Record<string, { clir: string; calendar?: string; passport?: string }>;
packages?: Record<string, { ir: unknown; calendar?: string; meta?: unknown }>;
};
```
```python
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
```ts
open('de.bgb.fristen@0.1.0', { offline: true });
```
```python
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
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](/build/start/) 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
- 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.
- `local` loads a checkout tree or in-memory models; a version
mismatch skips the entry.
- `offline` disables the registry and the host client; local sources
keep working.
- `hashes.program` names the build that answered; archive it with the
document.