sigildocs

(sigil deps registry)

(sigil deps registry) - Content-addressed package registry client

The client half of the Sigil package registry (WS-1.4). Resolves a from-pkg dependency {name, version-range} against the frozen v1 registry contract — see [[topics/sigil-registry-contract-v1]]:

  1. GET /v1/index/<name>.json (per-package index, §2)
  2. resolve the range against the index's version keys with the EXISTING (sigil deps semver) resolve-version (§2.3)
  3. GET /v1/cas/sha256/<hash> (the version's source tarball, §3)
  4. MANDATORY: recompute sha256, compare to the requested address (§3 — mismatch is a HARD error; never use unverified bytes)
  5. verify size; unpack; SHOULD verify the unpacked tree against the index tree hash (§2.5, defense-in-depth)

Integrity comes from HASHES, never from the transport or the host name (§1.2). The registry base URL is client configuration (SIGIL_REGISTRY env / config, default baked in) — it never appears in a manifest or a lockfile, so package identity never couples to a host.

Heavy modules — (sigil http), (sigil json), (sigil store) — are loaded LAZILY (module-exists? / load-module / module-ref) rather than imported at the top, so this module adds no hard dependency to bootstrap-critical sigil-deps. They resolve at CLI runtime (where the registry path is actually exercised) and in the workspace test runtime. This mirrors the runtime (sigil store) load in sigil-cli's build-cmds.

Exports

The one hardcoded default registry, overridable per client. Any mirror serving the same bytes at the same paths is fully conforming (§1.1). Positive-sovereignty framing only: the registry exists so package availability is a property of bytes, not of any host.

The index schema version this client understands (§1.4). A document whose schema differs is refused loudly with an upgrade hint — never guessed at.

Strip trailing slashes from a base URL so path joins are clean.

The active registry base URL: SIGIL_REGISTRY env var when set and non-empty, else the baked-in default. (A config-file layer can feed this later; env is the concrete v1 override.)

cas-urlprocedure

CAS objects live at a FLAT path keyed by the raw sha256 hex (§3).

cas-ref-hexprocedure

The 64-hex-char body of a CAS ref, or #f if the ref is malformed.

Validate a decoded index dict against this client's capabilities. Returns (cons 'ok doc), (cons 'bad-schema <schema-value>) when the schema is unsupported (§1.4), or (cons 'parse-error msg) when the document is not an object or its name disagrees with the path (§2.1). expected-name may be #f to skip the name cross-check.

All published version keys as strings (yanked included).

Version keys eligible for NEW range resolutions: yanked entries are skipped (§2.2 — a yanked entry stays fetchable via an explicit lockfile/exact pin, which bypasses the index entirely).

The version entry for a version-key string, or #f.

Resolve a semver range against the index's (unyanked) version keys, reusing the EXISTING (sigil deps semver) resolve-version — the sigil-deps range language is frozen by reference (§2.3), never reimplemented here. A #f range means "highest published version". Returns the resolved version-key string, or #f when nothing matches.

Byte-faithful streaming download to a FILE. NOTE: sigil-http's string-body fetchers round-trip through utf8 and corrupt binary, so CAS objects (raw tarball bytes) MUST come down via http-download.

fetch-indexprocedure

Fetch and parse a per-package index. Returns one of: (cons 'ok <doc>) — parsed, schema-supported index 'not-present — HTTP 404 (authoritative, §1.3) (cons 'outage <msg>) — 5xx / non-2xx / network failure (cons 'bad-schema <value>) — schema we don't support (§1.4) (cons 'parse-error <msg>) — not valid JSON / not an object / name mismatch (§2.1) The index is downloaded to tmp-path (a caller-chosen scratch file) and removed before returning.

Download a CAS object to dest. Returns: (cons 'ok <status>) — 2xx, bytes on disk (NOT yet verified) 'not-present — HTTP 404 (cons 'outage <msg>) — non-2xx / network failure The caller MUST verify the bytes (verify-cas-file!) before use.

Pure predicate: do the bytes at path hash to the CAS ref ref? #f for a malformed ref or a missing file. This is the seam the corrupt-tarball test exercises red/green.

Enforce the mandatory CAS verification. Raises a loud error on any failure (malformed ref, missing file, or hash mismatch); returns #t only when the bytes provably match the requested content address.

verify-size!procedure

Verify the byte length matches the index's size (a cheap DoS guard, §2.2). Raises on mismatch; a #f expectation is a no-op.

verify-treeprocedure

Defense-in-depth (§2.5): after unpacking, verify the tree against the index tree hash (Sigil tree-hash v1 = the store's hash-directory). Catches unpacker bugs / tampering between tar and disk. Returns #t on match or when there is no tree to check against; #f on mismatch. source is the authority; tree is a cross-check, so the caller treats a #f as a warning-or-error policy choice rather than the primary integrity gate.

Unpack a canonical source tarball into dest (which must already exist). The canonical tarball root-prefixes every member with <name>-<version>/ (§5.2), so one component is stripped to land the tree directly under dest. Returns #t iff tar exits 0. Shelling to tar mirrors the toolchain-fetch unpack in sigil-cli.

index-urlvariable

(No description)

(No description)

index-namevariable

(No description)

(No description)

entry-sourcevariable

(No description)

entry-sizevariable

(No description)

entry-treevariable

(No description)

entry-depsvariable

(No description)

(No description)