In-process embedding — design
Class:
design· Function:embed(exposesregistry+storagewith noserve; the embedded build variant). The whole-system view isdesign.md.
The functional API
The parsed RON config is the Holger value (server/lib/src/lib.rs); a linking consumer drives a live registry with no gRPC socket and no serialization, calling straight through Arc<dyn RepositoryBackendTrait>:
| method | does |
Holger::fetch(repo, &ArtifactId) -> Option<Vec<u8>> |
resolve bytes from a named repo's backend |
Holger::put(repo, &ArtifactId, &[u8]) |
store bytes (rejects read-only repos) |
Holger::list_repositories() -> Vec<&str> |
the configured repo names |
A consumer wanting a repo's contents (not just by-id) reaches one level deeper: holger.repositories[i].backend_repository is the same Arc<dyn RepositoryBackendTrait>, and it can call list / archive_files / fetch directly. That is enabled by re-exports from holger-server-lib so the consumer needs no separate holger-traits dep:
pub use traits::RepositoryBackendTrait;
pub use traits::{ArtifactEntry, ArtifactId};
LocalHolger (server/lib/src/object.rs) is the in-process implementation of the HolgerObject facade (the twin of the socket-based RemoteHolger) — one handle, transport chosen at startup.
The dev-pair generator
Holger::dev_pair_ron emits the RON for the dev release pair an embedding consumer launches:
/cache— a writable-znippy primary with acrates-ioupstream → a transparent caching crates.io mirror (a write-through fills it on miss);/sparring— a writable-znippy registry → the release-rehearsal target (seallater freezes it into a static drift snapshot — see the promotion reasoning).
Both are writable backends (ron_writable_archive: Some(...)) — the "dynamic"/development shape, not the read-only drift shape.
The reference consumer
The embed-holger feature that turns this into the embedded tier lives on the nornir side (the linking consumer), not as a holger crate feature — there is no embed* feature in any holger Cargo.toml. nornir's 📦 Holger viz pane lists the crates in the dev mirror by calling list_repositories + backend_repository.list() directly, in-process.
Generalized: the holger-embed adapter (2026-07-12)
nornir's bespoke in-process tab is now generalized into the reusable holger-embed adapter crate — the constellation's <guest>-embed shape — which reads this same functional API into a backend-agnostic model and returns the facett-holger registry-browser pane as a Box<dyn Facet> any egui host drops into a tab (native, no wasm). nornir's existing tab is left working; holger-embed is the clean template it migrates onto next. See consolidation-jera-embed-design.md §2.
The writable-repo enumeration fix (commit 8c9e458)
The dev-pair surfaced a latent bug in znippy-rust (server/repository/znippy-rust/src/lib.rs): list / archive_files read the cached self.reader field, which is None for writable backends (only the static drift mode populates it), so enumerating a writable dev-mode repo (/cache, /sparring) silently returned an empty list even with crates on disk. Fixed by reading through open_reader() (re-opens the live view per call), matching how list_files / get_file / contains already resolved it. Covered by writable_repo_put_then_serve_roundtrip, cargo_publish_stores_and_serves, list_with_no_reader_is_empty, and the server-lib test dev_pair_ron_parses_instantiates_and_wires.