Licensing and trust

Artifacts and verification

The eight files in a package, the manifest, the ed25519 signature over its sha256, and how to check it yourself.

View as Markdown

Every version is one uncompressed tar file with exactly eight files and no executable content. You can check all of it yourself without trusting the registry.

Package layout

File Contents
adapter_model.safetensors The LoRA weights. Safetensors only, never pickle.
adapter_config.json PEFT configuration: base model, rank, alpha, target modules.
retoque.manifest.json Canonical JSON describing the version. See The manifest.
signature.json ed25519 signature over the manifest's sha256, with the publisher public key.
eval-report.json The held-out evaluation report the version cites.
checksums.txt sha256sum-style list of the other seven files.
README.md What the patch does, how to load it, and where the evidence is.
LICENSE.txt The license terms. Its sha256 is the terms digest.

The tar is built reproducibly: files in sorted order, PAX format, owner and group 0 with empty names, modification time 0 and mode 0644. The file is named <slug>-<version>.tar. Anything else in an archive, including links, directories and unknown names, is a reason to refuse it.

The manifest

retoque.manifest.json is written as canonical JSON: keys sorted, no spaces, UTF-8. Its sha256 is the manifest digest the signature covers, the registry stores and retoque.lock pins.

Field Contents
schemaVersion "1.0"
patchId, patchVersion The slug and semver. The CLI refuses a package whose signed identity differs from the one requested.
publisher Publisher name and key algorithm.
baseModel Repository, full revision, and the sha256 of the weights, tokenizer.json and the chat template, plus the base license.
adapter Format peft-lora-safetensors, file name, sha256, size, rank, alpha, sorted target modules, precision and PEFT type.
runtimeCompatibility Tested runtime and library versions, tested devices and quantization, what is unsupported, and whether special tokens changed.
training Run ID, method, training set digest and size, provenance, seed, hyperparameters, hardware, time and final loss.
evaluation Run ID, task, held-out and regression suite digests, evaluator source digests, decoding, baseline, patched and prompt-only counts, regressions introduced, whether rollback outputs were identical, report sha256 and the thresholds.
license LICENSE.txt, its sha256 as termsDigest, and the license type.
files sha256 and byte size of the five payload files: adapter weights, adapter config, README, license and evaluation report.
knownSideEffects The publisher's note on behaviour changes outside the task.
status The starting evidence state set by the packager.

signature.json

The publisher signs the raw 32-byte sha256 digest of retoque.manifest.json with ed25519. Because the manifest lists the sha256 and size of every payload file, one signature covers the whole package.

json
{
  "algorithm": "ed25519",
  "signedPayload": "sha256(retoque.manifest.json)",
  "manifestSha256": "<64 hex>",
  "publicKey": "<64 hex>",
  "signature": "<128 hex>",
  "role": "publisher"
}

checksums.txt

One line per file in sha256sum format, two spaces between the digest and the name, for the five payload files plus retoque.manifest.json and signature.json. You can check an extracted package with standard tools:

sh
sha256sum -c checksums.txt

Verify a package

The CLI runs every check in What install does:

sh
retoque verify ./<slug>-<version>.tar    # offline
retoque verify <slug>@<version>          # installed copy, offline

Or by hand, from an extracted directory:

python
import hashlib, json
from nacl.signing import VerifyKey

manifest_bytes = open("retoque.manifest.json", "rb").read()
sig = json.load(open("signature.json"))

digest = hashlib.sha256(manifest_bytes).digest()
assert digest.hex() == sig["manifestSha256"]

# Compare sig["publicKey"] with a publisher key you trust before this step.
VerifyKey(bytes.fromhex(sig["publicKey"])).verify(digest, bytes.fromhex(sig["signature"]))

manifest = json.loads(manifest_bytes)
for name, entry in manifest["files"].items():
    data = open(name, "rb").read()
    assert hashlib.sha256(data).hexdigest() == entry["sha256"], name
    assert len(data) == entry["bytes"], name

Where trust comes from

  • The first-party publisher key is pinned in the CLI. Other keys count only if you add them to your own config. The registry can't add trust roots.
  • The registry's digests are cross-checked, but the registry alone can't make a package acceptable. Only a trusted signature over the exact bytes can.
  • A valid signature proves who published these exact bytes. It says nothing about whether the patch works. The evaluation numbers in the manifest are the publisher's claims for the stated held-out suite, and the evidence state says how far they have been checked.
  • Where a version is registered on chain, the registry contract stores its manifest, adapter and terms digests, so you can compare them with your copy. See Robinhood Chain.
  • The base weights' sha256 is recorded but not re-hashed on install. The tokenizer and chat template are checked when the snapshot is cached, and run pins the revision.