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 MarkdownEvery 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.
{
"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:
sha256sum -c checksums.txtVerify a package
The CLI runs every check in What install does:
retoque verify ./<slug>-<version>.tar # offline
retoque verify <slug>@<version> # installed copy, offlineOr by hand, from an extracted directory:
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"], nameWhere 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
runpins the revision.