# In-process embedding — design
> **Class:** `design` · **Function:** `embed` (exposes `registry` + `storage` with no
> `serve`; the **embedded** build variant). The whole-system view is [`design.md`](design.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:
```rust
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 a `crates-io` upstream → a transparent
caching crates.io mirror (a write-through fills it on miss);
- **`/sparring`** — a writable-znippy registry → the release-rehearsal target (`seal` later
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`](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`.