CRUMB a card from devarno-cloud

Pellet Data Model: Framed Format, PID, Signatures, Provenance, Lockfile

nestr intermediate 6 min read

ELI5

A Pellet is a sealed box with a label. The box’s name is a fingerprint of the box and its label, so you cannot swap contents without the name changing. Signatures and the builder’s receipt are stapled to the outside in an envelope; you can add more staples without changing the box’s name. The lockfile is your shopping list of exact box names.

Technical Deep Dive

Source: nestr-tools/engine internal/pellets/format.go:1-74, internal/pellets/footer.go:53-132, internal/pellets/pellets.go:1-16,122-142, internal/pellets/cas.go:1-25, internal/pellets/lockfile/lockfile.go:1-40 @e9180e4, read 2026-10-25. The previous revision described a {id}.pellet + .meta.json pair with a timestamp ID and a sha256 over compressed bytes; all three were replaced at M2.1 (pellets.go:3-7).

Wire layout (PEL-ART-001)

SectionEncoding
MAGICNSTR\0PEL\1 (9 bytes; the spec’s “8 bytes” is a counting error noted in code)
HEADER LENGTHu32 little-endian
HEADERCBOR PelletHeader
PAYLOADzstd(tar(contents))
FOOTERCBOR Footer

PID = pid:blake3:<hex> over MAGIC, HEADER LENGTH, HEADER and PAYLOAD. The footer never contributes (PEL-ART-004), so signatures can be added without changing identity. All hashes are BLAKE3-256; crypto/sha256 is gone from the package.

classDiagram
class PelletHeader {
+uint32 spec_version
+string name
+string version
+string arch
+string platform
+bytes payload_blake3
+uint64 payload_size
+string created_at
+bytes manifest_hash
}
class Footer {
+SignatureBlock[] signature_blocks
+ProvenanceAttestation provenance_attestation
}
class SignatureBlock {
+string pid
+string algorithm
+bytes public_key
+IdentityClaim identity
+bytes signature
+time signed_at
+LogEntry log
}
class ProvenanceAttestation {
+InTotoStatement statement
+SignatureBlock builder_sig
}
class LogEntry {
+string log_id
+uint64 log_index
+bytes leaf_hash
+bytes[] inclusion_proof
+uint64 tree_size
}
Footer --> SignatureBlock
Footer --> ProvenanceAttestation
SignatureBlock --> LogEntry
ProvenanceAttestation --> SignatureBlock

On disk: content-addressed store (PEL-ART-030..032)

flowchart LR
P["pid:blake3:abc123..."] --> D["store/blake3/ab/c1/abc123.../"]
D --> F1["pellet: framed file"]
D --> F2["extracted/: files 0444, dirs 0555"]
D --> F3["meta.json: operator metadata"]
F2 --> W["workspace: hardlinks, symlink fallback, never copies"]

Extraction and materialisation are pure data operations with no exec syscall anywhere in the package.

nest.lock (PEL-LOCK-*)

Canonical, byte-stable YAML; one per workspace. Each entry is name, pid, provenance_hash, sig_blk_hash, source, version (alphabetical field order); name and version are informational, the PID is the reference. A BLAKE3 self-hash under the frozen domain nestr.pellets.lock.v1 makes tampering detectable.

Key Terms

  • PID → content address over everything but the footer.
  • SignatureBlock → PEL-SIG-010 record: algorithm, key, identity claim, signature, time, optional log entry.
  • ProvenanceAttestation → in-toto v1.0 statement with a SLSA v1.0 predicate, signed by the builder.
  • CAS → <store>/blake3/<aa>/<bb>/<hex>/.

Q&A

Q: What bytes does the PID cover, and what does it deliberately exclude? A: MAGIC, the header length, the CBOR header and the zstd payload. It excludes the footer, so signatures and provenance can be attached without changing the Pellet’s identity.

Q: What does the footer carry, and why can it change without changing the PID? A: Signature blocks (each optionally with a transparency-log entry and inclusion proof) and a SLSA provenance attestation signed by the builder. It is outside the PID by spec (PEL-ART-004), so adding a co-signature does not create a new Pellet.

Q: What does each nest.lock entry commit to? A: The PID plus hashes of the signature block and the provenance, with name, version and source as information. The file carries its own BLAKE3 self-hash.

Examples

nestr install reads nest.lock, fetches pid:blake3:..., recomputes the PID and payload_blake3 before anything else, and refuses with E_PID_MISMATCH if a mirror served different bytes under the same name and version.

neighbors on the map