Your browser sucks, JavaScript disabled! Gunnar's console needs JavaScript and WebAssembly. Git over SSH on port 2222 does not.

nordisk/Skidbladnir

.nornir/archive-design.md

archive — design

Class: design · Function axis: f2. States only the shape we ship; the why and the znippy-consolidation plan are in archive-reasoning.md.

The Archive trait — the engine seam

pub trait Archive (archive.rs:86) is the one seam every caller uses; the engine behind it is swappable without touching the pipeline.

method signature what it does
pack pack(staging, version, out) -> BundleManifest (archive.rs:88) seal a staging tree into a bundle, return the manifest
list list(bundle) -> Vec<String> (archive.rs:91) list relative entry paths
extract_one extract_one(bundle, entry, dest) (archive.rs:94) extract one entry atomically (temp → rename)
extract_all extract_all(bundle, dest_dir) (archive.rs:96) extract the whole bundle, tree preserved
read_entry read_entry(bundle, entry) -> Vec<u8> (archive.rs:102) read one entry's bytes (znippy overrides for O(1))
verify_entries verify_entries(bundle, manifest) -> Vec<String> (archive.rs:117) return the bad-entry paths (missing and extra both count)
delta delta(old, new_staging, version) -> Patch (archive.rs:143) binary delta against a prior manifest (znippy)
apply apply(old_bundle, patch, new_bundle) -> BundleManifest (archive.rs:151) reconstruct a new bundle from an old one + a patch (znippy)

The content-addressed manifest

Every bundle carries a sidecar <bundle>.manifest.json (archive::manifest_path, archive.rs:338; load_manifest, archive.rs:343):

This manifest is what fetch::verify_on_receipt (f3) gates the unpack on.

TarZstd — the always-on default

pub struct TarZstd { level } (archive.rs:192; new() → zstd level 3, archive.rs:198). Pure Rust (tar + zstd), always builds and runs offline. impl Archive (archive.rs:203):

ZnippyArchive — feature znippy (REAL znippy-core, one canonical format)

pub struct ZnippyArchive { level } (#[cfg(feature = "znippy")]) is a thin adapter over the real znippy stack (../znippy) — L5 dedup: there is now ONE archive format in the constellation, not a Skidbladnir look-alike twin. A bundle sealed here IS a genuine .znippy archive, readable by the znippy CLI / DuckDB / Polars. On-disk format (the real znippy layout):

[ zstd/OpenZL chunk blob region ][ Arrow-IPC sub-index(es) ][ manifest + global footer (ZNPYMIDX) ]

Security guards

Contract (inject-assert tests)

pack_then_extract_roundtrip_with_manifest_checksums, tampered_manifest_fails_root_verify, verify_rejects_extra_entry_absent_from_manifest (TarZstd); and over REAL znippy-core: znippy_seal_verify_unpack_roundtrip_over_znippy_core, znippy_tampered_byte_fails_verification (RED-when-broken), znippy_content_addressing_identical_entries_round_trip, znippy_selective_read_returns_one_entry, znippy_delta_round_trip_reproduces_target_and_ships_only_changes, znippy_extract_rejects_zip_slip_paths, znippy_full_extract_round_trips.