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

nordisk/holger

.nornir/PLAN.md

Holger — PLAN (the driver)

The big-stroke driver for holger: where it's going and what to build first. Detail lives in the design docs (linked below); this stays at altitude. Features are recorded here as direction, implemented later.

Constellation context (the embedded-holger / nornir-release arc, benches, release gate) is tracked from the outside in workspace_nordisk/PLAN.md §O. This doc is holger's own driver.


RESUME — session 2026-06-25 (read here first)

All changes are UNCOMMITTED on branch feat/plugin-read-api (holger + znippy), building against the local [patch.crates-io] znippy; znippy-zoomies also has uncommitted C1 changes once that agent lands. Nothing published or merged.

Done + verified this session

Caveats / to-do-when-back

Next (priority order — NOT started, per "don't start more")

  1. #8 Batched release (IRREVERSIBLE — needs explicit go): publish znippy crates → drop holger [patch.crates-io] → bump deps → clean cargo test --workspace → merge both branches. Also commit the uncommitted work first.
  2. #9 W2 v2 per-repo ACL — plumb ron_write_roles into FastRoutes/HolgerGrpc.
  3. #10 static/dynamic profile — BackendProvider trait + crate split; airgap = egress isolation (provable from cargo tree).
  4. #11 offline OIDC — JWT signature verify vs offline JWKS (airgap auth path).
  5. #12 container conformance — real package-manager client ⇄ real holger; mannequin = mocked world (light pass in-process).
  6. znippy perf — batch get_many + ordered bulk decompress (design noted).

Design docs (for eval): auth-rbac-design.md, static-dynamic-profile-design.md, end-to-end-conformance-testing.md, znippy/.nornir/perf-batch-and-ordered-decompress.md.


The spine — two binaries, not one with a switch

Decision: crate split (hard boundary) + features for granularity. The crate boundary is the floor — "the dynamic code isn't in this binary" is provable from the dependency tree, not from trusting #[cfg]. Features then tune each side.

Crates protect the strip, features tune it.


The dynamic driver — reach feature level to X, crucial-first

Goal: reach feature level to established artifact servers (X), crucial-first. Not full parity — the useful features first. Bloat (e.g. Groovy scripting) is out; genuinely-needed niche behaviour can be reimplemented to talk to Holger.

Tier 1 — baseline feature level

  1. Import (→ znippy) — ingest existing artifact stores into znippy archives.

    • Nexus — dump import works today (keep current / refresh).
    • Artifactory — add import via znippy.
    • plus bulk ingest direct from a running server.
  2. Proxy / remote repos — pull-through caching from upstreams, per-upstream creds.

  3. Hosted writable repos — ingest for the core formats (Maven, npm, PyPI, Cargo, Docker/OCI, NuGet, Go).

  4. Virtual / group repos — one URL fronting many hosted+remote, ordered resolve. Clients point at a single endpoint.

  5. Auth + per-repo RBAC — who reads/writes which repo.

Tier 2 — operability 6. Search / browse — find an artifact. 7. Retention / cleanup — bound the store. 8. Audit — who did what. 9. Promotion — already designed (promotion-design.md); lands later.

Throughline: import (1) → one front door (2,3,4) → lock it down (5) → run it (6–9).


UI


Design docs (the detail)