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

mikronova/modgunn

.nornir/framework-guide.md

framework — guide (About · 🧰 Tools · lifecycle, from the CLI)

Class: guide · Function axis: framework. What the surfaces do and how to drive them. Shape + rationale: framework-design.md.

modgunn shares the constellation-wide common framework (the same About + Tools + lifecycle every suite app has). Because modgunn is a CLI, the surfaces are four verbs.

About — who is this?

$ modgunn about
Móðguðr — modgunn  v0.0.5
  the nordisk security + SCIP world-delta gatekeeper (Gjallarbrú)
  Guards the bridge: scrutinizes what passes (CVE / license / provenance verdict) …
  · Engine A — artifact security VERDICT (scan: multi-ecosystem CVE / license / provenance)
  · Engine B — SCIP whole-world dep-tree BEHAVIOUR-DELTA (scip: tripwires / graph-algs / anomaly)
  repository: git@codeberg.org:nordisk/modgunn.git

$ modgunn about --json   # the stable oracle a robot asserts
{ "name": "modgunn", "display_name": "Móðguðr", "version": "0.0.5", "subtitle": "…gatekeeper…", "engines": [ … ], "framework": [ … ] }

about needs no extra feature — it works in the lean scan build too.

🧰 Tools — one-click demo data through jera

$ modgunn tools                     # list the menu (needs --features framework)
modgunn 🧰 Tools (jera-backed demo actions):
  🩺 Demo advisory feed — generate + scan  [starts: modgunn-demo-feed → view: `modgunn warehouse scan`]
      Start a pinned demo container (jera) that writes a demo OSV advisory …

$ modgunn tools --json              # the roster oracle

# run the demo: start the container (jera) → it writes a demo OSV doc into --out
$ modgunn demo advisory-feed --out ./demo-advisories
demo advisory-feed → jera ContainerSpec: image=docker.io/library/alpine:3.20.3 name=modgunn-demo-feed mount=./demo-advisories:/out
(plan only) rebuild with `--features framework-oci` to start the container live; then `modgunn warehouse import --osv ./demo-advisories`

Building with --features framework-oci makes demo advisory-feed actually start the container (routed THROUGH draupnir's ONE OCI engine, as a tracked jera job) and write the demo OSV file. Then fold + view it:

$ modgunn warehouse import --warehouse /wh --rev demo --osv ./demo-advisories
$ modgunn warehouse scan   --warehouse /wh

In Rust (consuming the same seam):

let spec = modgunn::tools::demo_feed_spec("./demo-advisories"); // a jera ContainerSpec
# #[cfg(feature = "framework-oci")]
let outcome = modgunn::tools::run_demo_feed("./demo-advisories")?; // run THROUGH jera as a job

Service lifecycle — through the ship (skidbladnir)

modgunn declares its world-delta service through the SHARED ship, not a hand-written unit:

$ modgunn service --unit
[Unit]
Description=Móðguðr — the nordisk security + SCIP world-delta gatekeeper
…
[Service]
User=modgunn                                   # its OWN dedicated system user (L5)
Environment=MODGUNN_WORLDDELTA_ADDR=127.0.0.1:50071
ExecStart=/usr/local/bin/modgunn world-delta watch
Restart=on-failure
…

$ modgunn service --json                       # unit · user · port · fat/thin posture
$ modgunn service --unit --user-scope          # a `systemctl --user` dev unit (runs as YOU, no User=)

The dedicated modgunn user is provisioned at install time via skidbladnir::systemd::ensure_system_user("modgunn", …) — the SAME code nornir→nornir, holger→holger use. (The watcher daemon the unit runs is future work.)

Feature matrix — what to compile in

you want build with
about only (lean) default (scan) — nothing extra
tools / demo plan + service --unit --features framework
the demo container to actually run --features framework-oci
the binary (all verbs) --features "warehouse framework"

Build atoms — kind × linkage (cargo xtask build)

The feature flags above are the raw cargo axis; the named builds modgunn ships are declared once as data in build-variants.toml and resolved by the ONE build verb, cargo xtask build (nornir-build-thing's suite_cli). ONE atom, and it is a row of the constellation build matrix:

suite atom role linkage bin
ORIGINAL modgunn ⭐ client fat modgunn

The CLI: Engine A+B + the skade warehouse seam compiled IN (warehouse = ["dep:skade", …]), so it works with no server running — which is what the matrix means by a fat client. A batch CLI that does one job and exits.

$ cargo xtask build --suite ORIGINAL                      # every cargo atom of the delivery
$ cargo xtask build --suite ORIGINAL --atom modgunn       # cargo build -p modgunn --bin modgunn --features scan,scip,warehouse,rustsec,provenance-verify --no-default-features --profile release
$ cargo xtask build --suite ORIGINAL --list               # resolve and print; build nothing
$ dwarves buildthing modgunn --suite ORIGINAL             # the same resolver, from outside the repo

modgunn is NOT a server, has no wire and has no UI. The matrix gives every member five shapes (<x>-server · <x> · <x>-cli · <x>-ui · <x>-solo); modgunn fills exactly ONE, and the other four are declared GAPS rather than phantom atoms — because carrying the suites tag is what claims Build-Thing status, and an atom that claims it while building nothing is a promise the repo cannot keep. The service --unit verb above renders a systemd unit; it does not start one, the module behind it is not even compiled into the shipped modgunn atom, and the unit's ExecStart names modgunn world-delta watch, a verb the CLI does not have. Full measurements: suite-atoms-design.md.

The asymmetry guard. modgunn is the cycle-breaker holger + nornir both depend on, so they are upstream: a fat variant may embed only skade (downstream). A variant that tried embeds = ["nornir"] is rejected by BuildVariantSet::validate.