Architecture¶
How it works¶
- Resolve: emulate the
ld.sosearch order from the ELF itself (RPATH is transitive, RUNPATH is not,$ORIGINis per-object). It never scrapes the host'sldd,ld.so.cache, orLD_LIBRARY_PATH, so the result is deterministic. - Stage: copy the interpreter to its verbatim path, mirror the libraries, recreate
versioned-soname symlinks, regenerate
ld.so.cache, and add the glibc NSS pieces. - Assemble: build a non-root image with reproducible layers (sorted entries, zeroed
mtime/uid/gid). The uncompressed
diff_idand the gzip layer digest are computed separately, which avoids the classic unpullable-image bug.
Stability¶
Scratchsmith follows Semantic Versioning. As of 1.0, these surfaces are a stable contract. A breaking change to any of them requires a new major version:
- CLI flags: the names and meaning of
pack/lint/doctor/index/graph/diff/unpackflags, and the top-level--completions. New flags arrive in minor releases. A removed or renamed flag, or a changed default, is a major change. scratchsmith.toml: the configuration keys and their types (the Configuration reference).--format json: the field names and types of thepack,index,graph,diff, andunpackreports (the schema CI gates consume). Each is pinned by a golden test, so a change is always deliberate.- Exit codes:
0on success,2on an argument-parse error, and non-zero on any other failure.
Not frozen (these can change in any release): human-readable text and warning wording, log
output, doctor's exact phrasing, the Rust library API, and the exact bytes of the produced
image. The crate's pub items exist for its own tests, not as a supported API. Layers stay
reproducible for identical inputs, but that is a property, not a frozen API.
COMPATIBILITY.md covers how the contract changes over time. It describes the deprecation cycle (keep it working, warn on stderr, remove only in the next major), and how a test guards each surface.