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

nordisk/holger

.nornir/common-framework-design.md

holger on the shared common framework — About + a jera-backed Tools demo

Class: design. Companion guides: common-framework-guide.md (how to use it) and common-framework-for-idiots.md (plain language). Extends the suite-wide mandate (workspace_nordisk/prompt line 65): every app shares — not duplicates — lifecycle management, an About, and a Tools menu whose demos start containers through the shared jera job manager, "a bit like JetBrains has a common framework".

This is additive parity work — no working path removed, no behaviour changed for an unconfigured caller. It brings holger's operator GUI onto the same shared surfaces the other suite apps present, consuming shared crates rather than twinning them (Law 5).


What holger already consumed (verified, not re-done)

The survey found holger already on the shared spine — these are named here so the reuse story is one place:

What this slice added (the gaps)

1. The About identity surface (about.rs) — ADOPTED the shared widget

holger's About now consumes the shared facett_about card (LAW #5 — ADOPTION): the hand-rolled egui draw_about_window twin was DELETED and the ONE render body lives in facett-about, which renders a nornir_appshell::Identity. about.rs keeps only holger's data — the embedded logo, an about::identity() builder, and the headless oracle — all egui-free:

2. Tools · Demo appliance — start a container THROUGH jera (infra.rs)

server/ui/src/infra.rs mirrors korp's infra.rs: the demo is a plain jera::container::ContainerSpec (which maps onto draupnir's ONE OCI engine via ContainerSpec::to_draupnir), and its bring-up is recorded as a durable jera::jobs job — never a thread::spawn or a bespoke docker call.

3. Tools-pane render-time introspection (app.rs)

The server-side gRPC surfaces and RBAC gates already self-report a functional_status row on every real check (GREEN on success, RED on the failure path). This slice closes the remaining §B gap: the five operator Tools panes (#1 holger-ds · #2 migrate · #3 security · #4 deploy · #5 airgap) now self-report the moment they render, mirroring that server-side pattern and reusing holger's own emit bridge (app::functional_status → nornir_testmatrix::functional_status, no twin).

4. The tabbed shell — ADOPTED the shared pane/scene host (app.rs)

holger's operator shell now consumes the shared facett_app::scene layer (LAW #5 — ADOPTION), the same declarative pane/scene host dwarves' tabbed shell adopted. The hand-rolled tab host was DELETED:

5. The sign-in tab — ADOPTED the shared facett-auth-ui LoginPane (app.rs)

holger's operator shell mounts the shared facett_auth_ui::LoginPane as a first-class Tab::SignIn (slot "signin", header Sign in, in TAB_ORDER; the command palette maps "signin" → Tab::SignIn) — the SAME reusable device-code pane korp mounts (LAW #5 — ADOPTION, no twin):

Testing (Law 4 — observe from outside, ≥1 RED-when-broken)

Alternatives (why not) — see reasoning

Extracting the About window into a shared facett component was once deferred as a "move candidate" — that extraction has since landed: the About render body now lives ONCE in the shared facett-about crate and holger (like korp) consumes it (§1); the local about.rs egui twin was deleted, keeping only holger's data + headless oracle. The same ADOPTION applies to the pane/scene host, now the shared facett_app::scene (§4). So this slice is no longer a one-repo hold-out — holger is a REFERENCE consumer of the shared facett UI widgets, not a carrier of twins.