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

nordisk/dwarves

.nornir/holger-build-matrix-pane-design.md

holger build-matrix pane — design

Class: design · Function axis: f0 the cockpit pane (the whole) · f1 the ResolveHolgerBuild thin-gRPC fetch · f2 the wire→matrix projection · f3 the reused facett-table render · f4 the honest-state classification Strict: this file states only what the holger build-matrix surface IS — its parts and why.

The holger build-matrix pane is the forge cockpit's "which of holger's deployment executables are wired to build, and are they complete" (separation-spec item B2). holger ships ONE source tree built three ways — the deployment tiers embedded · mini · full, each producing its own distinctly-named binary (holger-embedded / holger-mikro / holger-full). dwarves ORCHESTRATES that build; the ResolveHolgerBuild RPC resolves the 3-tier plan against holger's declared build-space (.nornir/build-variants.toml) WITHOUT compiling holger — each tier mapped onto its build target (bin · package · materialized cargo argv), which resolve, and whether the plan is complete. This pane renders that MATRIX (tier × target × status) so a forge operator sees the build landscape in the dwarves UI.

The system as one — the function map (f0)

part lives in what it is
f0 the pane crates/dwarves-embed/src/holgerbuild.rs HolgerBuildPanel a Facet/Panel: the matrix table + a status line + auto-poll
f1 fetch leg fetch_holger_build thin gRPC ResolveHolgerBuild (Bearer, 3s connect timeout, private current-thread rt) → pb::HolgerBuildReply
f2 projection tiers_from_wire → TierRow pure wire→domain map (order preserved); tier_cells formats each tier to the table's string cells
f3 render table_from_tiers → facett_table::Table the REUSED generic data-table (columns tier·status·bin·package·cargo, one row per tier, keyed on the tier name)
f4 honest states BuildErr + Conn connect ⇒ unreachable, Unauthenticated/PermissionDenied ⇒ auth_failed, Unimplemented ⇒ not_served, found=false ⇒ no_build_space, other ⇒ error/empty

The RPC seam (server side, unchanged — consumed, not edited): crates/dwarves/proto/dwarf.proto rpc ResolveHolgerBuild(HolgerBuildRequest) returns (HolgerBuildReply) → HolgerBuildReply{ tiers[HolgerTier{tier,step,resolved,bin,package,command_line}], resolved, missing, complete, found }, resolved in crates/dwarves/src/holger_build.rs. The embed's proto/dwarf.proto carries a field-number-exact copy of those three messages + the rpc so the thin client talks to a live dwarves-server WITHOUT the dwarves server feature and with NO holger/nornir dep (that would be a cycle — nornir already depends on dwarves).

Why it is shaped this way

The seam (robot-testable, headless)

The pane drives over state_json (out) / update_json (in) — the same channel a nornir-robotui scenario and a thin gRPC client use. state_json publishes {status, tiers[], tier_count, resolved, missing, complete, found, error, auto_poll, table:<facett-table state>}; update_json accepts {refresh}, {poll}, {auto_poll}, {holger_root} (pin the server-side checkout + re-resolve) and forwards anything else onto the inner table. The apply_fetch(Result<HolgerBuildReply, BuildErr>) split lets a test drive every state with NO server.

RED-when-broken

testmatrix cells: dwarves-embed/holger_build_matrix_shows_live_rows_red_when_empty, dwarves-embed/holger_build_matrix_honest_states, dwarves-embed/holger_build_matrix_pane_drivable.