Kernel tooling read-through (2026-11-03)
Read-only review of the source as it is on the git server today. No code was changed. Purpose: say what exists, what is connected, what is not, and how it could fit together.
Commits read: edda main 3d8fe66, tunnr main 3953015, heimdall main d747087 (the no-pivot shim lands in 9ac44df..d747087; the shared clone on the build box still sits at f4b5002), holger main a76203a plus branch kern/appliance-lsm 390cb8c, dwarves main c5150d2, nornir main eed4eaf8. Line numbers refer to those commits. "Not verified" means I did not run it.
Status words used for every arrow:
- CONNECTED: code calls it, or a file is read by code (path:line given).
- MANUAL: only a shell script, an environment variable, a shell redirect or a person links it.
- MISSING: planned or implied by docs, but nothing links it.
0. Glossary (for an outside reader)
| Name |
Meaning |
| Build Thing |
Our build system. The engine is the Rust crate nornir-build-thing (repo edda). Each product repo has a thin <repo>-build-thing crate that declares its rows in Rust and emits them as .nornir/build-variants.toml. |
| row |
One declared artifact: [[build.kernel]] (a kernel), [[build.installer]] (an appliance medium), [[build.variant]] (a binary or container). |
| fragment |
A Kconfig fragment (CONFIG_X=y lines). Rows are composed as preset + profile + closures + requirements + user fragment, then olddefconfig. |
| pin |
A content hash that fixes an input: the kernel tarball sha, the toolchain image id, a ledger key. |
| ledger |
A built kernel looked up by its pin before a rebuild (nornir.kernel-ledger-key/1). |
| requires |
A [[build.installer.requires]] row: a consumer says a kernel symbol must be y/n, with a reason. |
| veto |
A row-level CONFIG_X=n decision, allowed only after a coverage run proved the symbol never executed. Written with a receipt. |
| receipt |
A JSON evidence file (nornir.kernel-veto/1, nornir.kernel-coverage/1) that says what was measured, when, with which tools. |
| door |
A CLI verb of a <repo>-build-thing binary (tunnr-build-thing kernel …). |
| suite |
A shell script that boots the row's medium under KVM and prints STAGE n PASS/FAIL lines; the coverage/veto verbs drive it. |
| korp |
The appliance OS layer in tunnr: korp-installer (medium PID 1), korp-start (root of trust that loads a seccomp profile and execs the payload). |
| Heimdall |
Our sandbox: seccomp profiles (probe → generate → check), Landlock, a youki container shim, a broker for file/socket calls, a node signer for Kubernetes (heimdall-k8s). AGPL; always run as a separate binary by MIT code. |
| shim / broker |
heimdall-container-shim creates the job container (youki); the broker answers the job's openat/connect/execve through seccomp USER_NOTIF. |
| profile |
A measured seccomp allow-list per program × arch × libc: .probe.json (evidence), .json (reviewable), .oci.json (what the kernel loads). |
| Rusternetes |
Our Kubernetes node (kubelet + control plane, youki backend) shipped as a tunnr payload. |
| dwarves |
Our forge/operator tool (MIT): dwarves buildthing builds rows; dwarves tune is the Heimdall tuner (probe/gen/check/approve/show/app). |
| Mímir |
Our code graph (repo nornir): source call graph from rustc, binary symbols, a system-call boundary. The owner's engine for "possible syscalls". |
1. System map
BUILD BOX (podman, no KVM) KVM HOST NODE / APPLIANCE
┌──────────────────────────────────────────────────────┐ ┌─────────────────────────┐ ┌─────────────────────────────┐
│ edda: nornir-build-thing (engine) │ │ scripts/kernel-suite.sh │ │ korp-start (PID-1 root of │
│ kernel.rs rows→fragment→container build→pin │ │ rusternetes-kvm.sh │ │ trust) loads seccomp/*.oci │
│ kernel_trim what-if / candidates / coverage / veto │──►│ rusternetes-check.py │ │ node PID-1 (supervise, │
│ syscall_join measured calls → CONFIG options │ C │ memsave snapshots │ │ landlock, filter) │
│ measure.rs heimdall binary → .nornir/profiles │ │ holger tools/ │ │ Rusternetes kubelet (youki) │
└───────────▲────────────────────────▲─────────────────┘ │ kernel-suite.sh │ │ ──► heimdall-k8s signer │
│ path dep (C) │ path dep (C) │ holuse-init.c │ │ Heimdall shim+broker (jobs) │
┌───────────┴────────────┐ ┌────────┴─────────────────┐ └────────────▲────────────┘ └─────────────▲───────────────┘
│ tunnr-build-thing │ │ dwarves │ │ ScriptSuite (C) │ medium (C)
│ 5 kernel rows, pins │ │ buildthing (compose) │ │ │
│ kernel-vetoes/*.list │ │ kernel_ledger │ ┌────────────┴────────────────┐ │
│ door: kernel-probe, │ │ tune probe/gen/check/ │ │ .nornir/kernel-coverage/ │ │
│ kernel what-if…veto, │ │ approve/show/app │ │ <row>/<sha12>.json (C) │ │
│ measure syscalls/gate│ │ dwarves-tune-graph │ │ .nornir/kernel-vetoes/<row>/│ │
│ korp-installer (ISO) │ │ (reads Graph JSON) │ │ protect.list, receipts/ │ │
│ payloads/rusternetes- │ └──────────┬───────────────┘ │ .nornir/profiles/<row>/ │ │
│ node, xtask stage │ │ runs the binary │ measure.toml/json, *.json │ │
└───────────┬────────────┘ ▼ │ kernel-needs.json (MANUAL)│ │
│ emit (C) ┌──────────────────────────┐ └─────────────────────────────┘ │
▼ │ heimdall (AGPL binary) │ │
.nornir/build-variants.toml │ profile probe/gen/check │ ┌─────────────────────────────┐ │
(installer.requires =n │ probe-exec/-container │ │ holger .nornir/kernel-usage/│ │
from the veto list) (C) │ KernelReport (runtime) │ │ needs.json, coverage.json, │ │
│ k8s signer, shim, broker│ │ heimdall-needs.fragment │──MISSING──►│ Holger kernel rows
└──────────────────────────┘ │ (a REPORT; nothing reads │ (rows exist only on branch
│ it back) │ kern/appliance-lsm)
┌──────────────────────────────────────────────────────┐ └─────────────────────────────┘
│ Mímir (nornir): driver CALLS edges, binary symbols, │
│ boundary @syscall nodes (x86_64), libc map, BTF │──MISSING (step 1: walk + Graph JSON)──► dwarves-tune-graph --graph
└──────────────────────────────────────────────────────┘ ──MISSING──► syscall_join / veto
1.1 Pieces and where they run
| Piece |
Repo / path |
Runs on |
Role |
| nornir-build-thing engine |
edda crates/nornir-build-thing/src/{kernel.rs,kernel_trim.rs,kernel_trim/,syscall_join.rs,kernel_requires.rs,kernel_features.rs,measure.rs} |
build box (kernel compile in a podman container via draupnir) |
rows, fragments, pins, ledger key, what-if, coverage model, veto rule, syscall join, measure step |
| tunnr-build-thing |
tunnr crates/tunnr-build-thing/src/{kernel.rs,vetoes.rs,main.rs,plan.rs,rusternetes.rs,recipe.rs} |
build box |
the 5 kernel rows, the toolchain pin, the veto lists, every kernel … door |
| kernel suite |
tunnr scripts/kernel-suite.sh, scripts/rusternetes-kvm.sh, scripts/rusternetes-check.py |
compose on build box, boot on KVM host |
the one suite (bridge, rusternetes-node only) |
| Holger usage report |
holger .nornir/kernel-usage/holger-scan-worker/ (+ tools/kernel-suite.sh, holuse-init.c) |
KVM host |
a measured report: needs.json, coverage, 8 veto candidates, heimdall-needs.fragment |
| dwarves tuner |
dwarves crates/dwarves/src/{tune.rs,tune/review.rs,tune_app.rs,kernel_ledger.rs}, crates/dwarves-tune-graph/ |
build box |
probe/gen/check/approve/show/app; graph cross-check reader; kernel ledger |
| Heimdall |
heimdall crates/* |
build box (probe, tests), node/appliance (shim, broker, k8s signer) |
profiles, runtime kernel-feature report, container jobs |
| Node OS |
tunnr crates/korp-installer, payloads/rusternetes-node/ |
node |
ISO, PID-1, korp-start seccomp floor, Landlock, youki, RuntimeClass heimdall, CNI |
| Mímir |
nornir crates/{mimir-driver,mimir-binary,mimir-ingest/src/boundary,mimir-room} |
build box |
code graph; the future "possible syscalls" producer |
1.2 Every arrow, with its status
| # |
From → To |
Status |
Evidence |
| 1 |
tunnr-build-thing → edda engine |
CONNECTED |
path dep crates/tunnr-build-thing/Cargo.toml:41; main.rs:354-447 calls kernel_trim::run_kernel_verb_in, measure::run_measure_verb |
| 2 |
kernel rows → merged fragment → container build → .kernel-out/<name>/{bzImage,kernel.config,<name>.kernel-pin.json,kernel.why.toml} |
CONNECTED |
edda kernel.rs:1652 (merged_fragment), :4318 (build_kernel_with), :4758-4790 (outputs) |
| 3 |
kernel pin → consumer (installer) |
CONNECTED |
edda kernel.rs:4151 (resolve_kernel_for), korp forge.rs:192-205 |
| 4 |
Rust rows → .nornir/build-variants.toml → parity test |
CONNECTED |
edda emit.rs:65-107; tunnr tests/emitted_toml.rs:24 |
| 5 |
veto list → installer kernel edge (=n requires) → emitted toml |
CONNECTED |
tunnr vetoes.rs:16-18 (include_str!), recipe.rs:533,564, .nornir/build-variants.toml:1226-1231 |
| 6 |
kernel coverage → suite script → KVM → coverage JSON |
CONNECTED to the script, MANUAL inside it |
edda veto.rs:242 (ScriptSuite runs bash <script>), coverage.rs:734 (store); the build-box/KVM split is KS_COMPOSE_ONLY/KS_MEDIA env plus a hand sync of the kernel tree (kernel-suite.sh:49-73) |
| 7 |
coverage JSON + protect.list → kernel candidates / kernel veto |
CONNECTED |
edda coverage.rs:744 (load_for), :763-801 (protect), veto.rs:507-643 (run_veto) |
| 8 |
veto → receipt JSON → anyone |
CONNECTED to write, barely read |
written veto.rs:636; read by list_receipts veto.rs:646 (the vetoes verb) and one unit test tunnr vetoes.rs:55-69. The build trusts the .list line, never the receipt. |
| 9 |
heimdall probe → .nornir/profiles/<row>/… (measure.json, *.probe.json, *.json, *.oci.json) |
CONNECTED |
edda measure.rs (module doc + run_measure_verb :1096) runs the heimdall binary; dwarves tune.rs:18-21 calls edda measure |
| 10 |
profiles → kernel needs (syscall → CONFIG join) |
CONNECTED |
edda syscall_join.rs:602 (MeasuredRow::load), :721 (needs) |
| 11 |
profiles → veto refusal (a measured call protects its option) |
CONNECTED |
edda kernel_trim.rs:160 (join_syscalls), syscall_join.rs:850 (vetoes_for), veto.rs what-if clean check |
| 12 |
kernel needs --json → .nornir/profiles/<row>/kernel-needs.json → dwarves tune show |
MANUAL |
reader exists: dwarves tune/review.rs:224; writer is a shell redirect in dwarves/README.md:162. needs() writes nothing (syscall_join.rs:721). No row in any repo has the file (only a dwarves test fixture). |
| 13 |
heimdall-needs.fragment (Holger report) → Holger kernel rows |
MISSING on main |
fragment holger/.nornir/kernel-usage/holger-scan-worker/heimdall-needs.fragment; main a76203a has no CONFIG_SECURITY/LANDLOCK/LSM requires; branch kern/appliance-lsm 390cb8c has them hand-typed as [[build.installer.requires]] (CONFIG_SECURITY, CONFIG_SECURITY_LANDLOCK, CONFIG_LSM="landlock,lockdown,yama", CONFIG_CROSS_MEMORY_ATTACH). |
| 14 |
Heimdall runtime needs → any machine-readable kernel need |
MISSING |
heimdall container/src/kernel.rs:118 (missing_for_strict) returns prose; the only CONFIG string is a message (:127). No needs output, no fragment. |
| 15 |
Holger tools/kernel-suite.sh → tunnr-build-thing kernel-probe |
MANUAL (script) |
holger/.nornir/kernel-usage/holger-scan-worker/tools/kernel-suite.sh:37; nothing in tunnr calls kernel-probe (tunnr's own suite composes via dwarves buildthing, kernel-suite.sh:60) |
| 16 |
measured node profile → packed seccomp profile on the node |
MISSING |
the packed approved-x86_64.oci.json (361 calls) is hand-written (tunnr rusternetes.rs:984-1011); the measured node-pid1 profile (17 calls) is not packed; korp-start, rusternetes, rusternetes-youki-shim are needs_vm, never measured (.nornir/profiles/rusternetes-node/measure.toml) |
| 17 |
korp-start → seccomp/<entry>.oci.json → payload |
CONNECTED |
tunnr crates/korp-installer/src/seccomp.rs:1-95, src/bin/korp-start.rs:674-685 |
| 18 |
Rusternetes kubelet → heimdall-k8s signer (RuntimeClass heimdall) |
CONNECTED |
tunnr payloads/rusternetes-node/src/heimdall.rs:1-50, handlers/heimdall.json; heimdall k8s/src/lib.rs:100,336 |
| 19 |
Heimdall runtime kernel report → signed result |
CONNECTED |
heimdall container/src/kernel.rs:94, core/src/types.rs:573 |
| 20 |
dwarves kernel ledger → edda resolve_built_kernel_with |
CONNECTED when configured |
dwarves kernel_ledger.rs:263; needs DWARVES_HOLGER_DIR; edda's own public resolve_built_kernel (kernel.rs:3630) always uses NoLedger |
| 21 |
Build Thing kernel data → AI / MCP / llms / nornir graph |
MISSING |
no kernel module mentions MCP, llms or nornir-introspect; the only machine faces are the --json schemas (nornir.kernel-what-if/1, -candidates/1, -needs/1, -coverage/1, -veto/1) |
| 22 |
Mímir → Graph JSON → dwarves-tune-graph --graph |
MISSING |
reader exists: dwarves dwarves-tune-graph/src/lib.rs:218 (read_graph), xcheck.rs:39; producer: none in nornir (no code writes unresolved_sites/syscalls Graph; mimir-room/src/query.rs:219 refuses SYSCALLS edges until the universe is folded). walk.rs:6 and srcgraph/mod.rs:36-41 are owner-reserved stubs; tests #[ignore]. |
| 23 |
Graph JSON → syscall_join / veto |
MISSING |
MeasuredRow (syscall_join.rs:602) reads only measured profiles; no "possible" field |
| 24 |
drift gate (measure gate) → forge/CI |
CONNECTED as a verb, pipeline not verified |
tunnr main.rs:227; edda measure.rs (parse_gate_verb, run_gate); tunnr xtask has no drift verb (xtask/src/*.rs) |
2. Inventory
2.1 Build Thing kernel side (edda crates/nornir-build-thing)
| Item |
path:line |
Does |
In → Out |
Called by |
KernelBuild row |
kernel.rs:641-847 |
one [[build.kernel]]: version, tarball_sha256, preset, profile, toolchain_image(_sha256), lto, solver, cpus, mem |
Rust decl → .nornir/build-variants.toml |
<repo>-build-thing |
| fragments |
kernel.rs:116-154, src/kconfig/{base,hardened,k8s-hardened,profile,minimal,deps-tinyconfig,nuked}.config |
preset/profile layers (include_str!) |
— |
merge |
| merge |
kernel.rs:1601-1708 |
preset → profile → minimal → LTO → consumer requires → user fragment → probe fragment; later line wins; a contradicted requirement is refused |
fragments → one .config input |
build, ledger_key_of, kernel_trim |
| toolchain image |
kernel.rs:161-255,958-982,1060,2213,4913 |
nordisk-kernel-toolchain@sha256:<pin>; reproducible mint; re-pin hint |
Containerfile src/containerfiles/kernel-toolchain.Containerfile |
build |
| build |
kernel.rs:4318-4790 |
preflight disk, fetch tarball (sha), merge_config+olddefconfig+canary in a bounded airgapped container (draupnir/bollard), collect |
→ .kernel-out/<name>/{bzImage,kernel.config,kernel.base.config,<name>.kernel-pin.json,kernel.why.toml}, pins/<ledger_key>/ |
dwarves buildthing <donor> --variant <kernel> |
| pin receipt |
kernel.rs:3430-3523 |
nornir.kernel-pin/1: shas of fragment, bzImage, config, toolchain id |
file |
slot_holds :3577, resolve_kernel_for :4151 |
| ledger key |
kernel.rs:3668-3683 |
nornir.kernel-ledger-key/1 over version · tarball · toolchain ref · profile · fragment sha |
→ StepPin.ledger_key (build_dag.rs:492) |
consumers, dwarves ledger |
| probe boot (TCG) |
kernel.rs:2867-3231 |
QEMU TCG boot in the toolchain container, serial markers |
bzImage → KernelProbe result |
tests/kernel_probe_live.rs |
| what-if / candidates |
kernel_trim.rs:228-660 |
TrimModel::what_if (olddefconfig-style settle), candidates ranked by bytes leaving, InverseCheck |
.config, Kconfig graph, TreeSizes → nornir.kernel-what-if/1, -candidates/1 |
run_kernel_verb_in :1332 |
| gcov coverage |
kernel_trim/coverage.rs:45-801 |
DEV-only gcov probe kernel; read counters from vmlinux + QEMU memsave dumps; per-symbol Executed/NeverExecuted/Unmeasured; protect.list |
suite output → .nornir/kernel-coverage/<row>/<sha12>.json (nornir.kernel-coverage/1) |
kernel coverage |
| veto |
kernel_trim/veto.rs:92-646 |
ScriptSuite protocol; run_veto: one symbol, refused unless never-executed, unprotected, what-if clean, inverse holds; rerun suite without probe; append .list; receipt |
→ <store>/<row>.list, .nornir/kernel-vetoes/<row>/receipts/<date>-CONFIG_X.json (nornir.kernel-veto/1) |
kernel veto |
| syscall join |
syscall_join.rs:138-868 |
SyscallMap read off the kernel tree (syscall_64.tbl, SYSCALL_DEFINE, Makefile gates, sys_ni.c), cached nornir.syscall-map/1; MeasuredRow from measure.json + *.probe.json; needs, vetoes_for, join_candidates |
profiles + kernel tree → nornir.kernel-needs/1 (stdout only) |
kernel needs, what-if |
| requires closure |
kernel_requires.rs:216-1417 |
feature → KconfigReq; union; contradictions; WhyIndex → kernel.why.toml |
rows → fragment lines |
build, plan |
| feature model |
kernel_features.rs:190-730 |
decision layer: `--opt kernel.preset |
profile |
=on |
| measure step |
measure.rs |
`measure syscalls [--check |
--gen |
--workload], measure gate; runs the external pinned heimdall` binary |
| live tests |
tests/{kernel_build_live,kernel_probe_live,kernel_offline_live,pinned_recipe_reproduces,toolchain_images_live}.rs |
all #[ignore], need podman socket, network or unshare --net; none need KVM |
|
by hand |
2.2 tunnr (node OS, media, kernel rows, doors, suite)
| Item |
path:line |
Does |
In → Out |
Runs on |
| kernel rows |
crates/tunnr-build-thing/src/kernel.rs:330-467, recipe.rs:839-845 |
tunnr-kernel (nuked/hardened), -scsi, -nvme, -hyperv (slim/hardened) = the lean appliance kernels; tunnr-kernel-k8s (slim/k8s-hardened, Landlock+BPF) |
6.12.104, tarball sha 949d166a…, closures variants/kernel/tunnr-hardening.config, tunnr-k8s-hardening.config |
build box |
| toolchain pin |
kernel.rs:302-308 |
TOOLCHAIN_IMAGE_SHA256 = 3f632569… = the image id (changed 2026-11-03 from a manifest digest) |
checked by unit tests :818-823,:880-960; fail-closed check in edda toolchain_archive.rs:104-122 |
|
| lean-pin gate |
tests/rusternetes_node_kernel.rs:188-256 |
pins the standalone fragment sha and the lean consumer ledger key per row; k8s has Landlock, lean rows keep # CONFIG_SECURITY is not set |
|
|
| parity gates |
tests/emitted_toml.rs:24, tests/kernel_toolchain_edge.rs:45-51, kernel.rs:1228,1078 |
toml = code; Containerfile = edda's; k8s closure = shared closure except the LSM block; derived rows differ only by preset |
|
|
| veto lists |
crates/tunnr-build-thing/kernel-vetoes/{rusternetes-node,rusternetes-node-aya}.list, src/vetoes.rs |
one applied veto: CONFIG_MOUSE_PS2_BYD (receipt 2026-11-03T144637Z, suite bridge 8/8 PASS, 10 NOTRUN, bzImage −65536 B); aya list empty |
include_str! → requires =n (recipe.rs:533,564) |
|
| protect / coverage / receipts |
.nornir/kernel-vetoes/rusternetes-node/{protect.list,receipts/}, .nornir/kernel-coverage/rusternetes-node/{380dcfbd46e9,58a245df9d77}.json |
52 protect globs; two coverage reports (one stale fragment); no report for the post-veto fragment 333150ec… |
|
|
| doors |
src/main.rs:102-463 |
--list, toml, emit, facts, plan, preflight, `measure syscalls |
gate, kernel-probe [--repo] [--probe gcov |
off] [--fragment-extra f](:301-377),kernel what-if |
| suite |
scripts/kernel-suite.sh |
` <probe |
off> ; compose cp+worker via dwarves buildthing … --build kernel(:58-64);KS_COMPOSE_ONLY=1stops after compose;KS_MEDIA=boots given ISOs; KVM slot flockKS_KVM_LOCK(:101-103);rusternetes-kvm.sh+rusternetes-check.pystages;memsave` after each stage (:82-90); 10 fixed NOTRUN lines (:129-133) |
only suite bridge, only rusternetes-node (:43-46) |
| xtask |
xtask/src/{main.rs,rusternetes.rs,rusternetes_upgrade.rs,rusternetes_secrets.rs,rusternetes_kek.rs} |
rusternetes stage (Rusternetes commit 2ed5e700, heimdall-k8s at f4b5002, tunnr-etcd, CNI 1.9.1, all sha-checked) → .rusternetes-out/ + manifest.sha256; stage-aya; `pki |
token |
revoke |
| korp-installer |
crates/korp-installer/src/{isocompose.rs,forge.rs,kernel.rs,seccomp.rs,bin/korp-start.rs} |
ISO = korp-boot + static-musl PID-1s + initramfs + kernel; kernel from the row's kernel_donor (proved against the pin, forge.rs:192-205), or $KORP_KERNEL, or host /boot/vmlinuz; korp-kernel.blake3 is still all zeros |
|
build box |
| node PID-1 |
payloads/rusternetes-node/src/{main.rs:120-204,supervise.rs,landlock.rs,filter.rs,heimdall.rs,lay.rs} |
seed → stage → filter → tmpfs root → lay → seccomp self-test → Landlock (CSI only; PID-1 and Rusternetes none, landlock.rs:35 "waiting on the shim door") → network → join → upgrade door → VIP → supervise (KUBELET_CONTAINER_BACKEND=youki, supervise.rs:453-460) |
|
node |
| seccomp floor |
crates/korp-installer/src/seccomp.rs, payloads/rusternetes-node/filter.rs:314-319 |
seccomp/<entry>.oci.json from the signed archive; default deny, KILL_PROCESS; korp.seccomp=strict refuses unprofiled payloads; the 361-call hand-written approved-x86_64.oci.json packed for rusternetes-node and rusternetes/bin/rusternetes |
|
node |
| measured profiles |
.nornir/profiles/rusternetes-node/{measure.toml,measure.json,node-pid1/*}, .nornir/profiles/rusternetes-node-aya/{node-pid1,tunnr-cni}/* |
tool pin nordisk-heimdall-cli 0.2.0 + sha; node-pid1 17 calls; korp-start, rusternetes, youki shim = needs_vm |
|
build box |
| RuntimeClass heimdall |
payloads/rusternetes-node/src/heimdall.rs, handlers/heimdall.json, .nornir/heimdall-runtimeclass.md |
spawns heimdall-k8s, publishes its key as an annotation, handler = RO root, no caps, no net, digest-only images |
doc says step 2 PARKED; code ships it |
node |
| CNI |
payloads/rusternetes-node/Cargo.toml:28-38, src/lay.rs, src/datapath/*, payloads/tunnr-net-ebpf |
bridge/host-local/loopback; cni-cilium; cni-aya (eBPF) with Kconfig requirement sets rusternetes.rs:674,730,786,809 |
|
node |
| proof scripts |
scripts/rusternetes-aya.py, scripts/rusternetes-ha.py, scripts/rusternetes-ha/*.sh |
aya: WG keys, DNS, ClusterIP, NodePort, pod-to-pod; HA: 6-VM Raft, leader, writer/verify, VIP, join-once, rollout; stdout only |
not reachable from the kernel suite (they are its NOTRUN lines) |
KVM host |
2.3 Heimdall
| Crate |
Does |
Kernel-relevant outputs |
| core |
Job/Policy/SignedResult types; KernelFeatures (types.rs:573); SeccompProfileRef (:320) |
every signed result names the kernel features seen |
| seccomp |
profiles, BPF builder, OCI writer/reader (oci.rs:33,93), tables x86_64 + aarch64 (tables/, scripts/gen-syscall-tables.sh) |
.oci.json sha = the pin |
| probe |
learn (learn.rs:97, live.rs:108), merge (observe.rs:81), minimise (minimise.rs:99), codegen, check (check.rs:41) |
.probe.json, .json, .oci.json, .rs |
| container |
HeimdallRunner: youki, Landlock, seccomp, cgroups, broker, learn; KernelReport (kernel.rs:23), missing_for_strict (:118); shim with no_pivot when / is the initial rootfs (shim.rs at d747087; heimdall-plain/src/rootfs.rs:23,41) |
runtime report only; no fragment |
| broker |
USER_NOTIF+ADDFD supervisor; its own kernel probe Support (support.rs:18); creates files as the caller (setfsuid guard, 9ac44df) |
|
| k8s |
node signer for RuntimeClass heimdall (lib.rs:100,167,221,336); Landlock-confined (:484-490); reports what the kubelet says it applied |
|
| cli |
`heimdall run |
verify-result |
| profiles/ |
one checked-in workload heimdall-wasm-host (x86_64 glibc+musl) |
|
| scan, wasm, run, trace, plain |
static-scan contract for Holger, wasm host, run, dynamic trace, plain youki runner |
trace gives per-program syscall facts (trace/doc.rs:125) |
No approve verb, no review UI, no "heimdall-tune" exists in Heimdall. Approval lives in dwarves (tune approve → approved.toml, tune app approve, RowApprover in dwarves-server) and edda measure (approval_status, approve).
2.4 Holger kernel usage report (.nornir/kernel-usage/holger-scan-worker/)
| File |
What |
README.md |
the report: two halves, findings, reproduce |
measure.json, syscalls-{scan,job}.probe.json |
the worker's measured calls in scan mode (23) and job mode (30) |
needs.json |
nornir.kernel-needs/1 from tunnr-build-thing kernel needs holger-installer-metered --repo <holger> --json: only CONFIG_FUTEX and CONFIG_MMU gate a worker call; 17 enabled gating options have no worker caller (a trim hint, not a veto) |
coverage.json, coverage.txt |
nornir.kernel-coverage/1, GREEN, suite scan-worker: 859 live symbols, 220 executed, 61 never, 578 unmeasured; 3 not run (server, clamd, boot path) |
candidates.txt |
219 candidates, 8 veto-ready with coverage |
heimdall-needs.fragment |
CONFIG_SECURITY=y, CONFIG_SECURITY_LANDLOCK=y, CONFIG_LSM="landlock", CONFIG_CROSS_MEMORY_ATTACH=y — hand-written from the measured refusal; merged via --fragment-extra for the run |
tools/kernel-suite.sh, holuse-init.c, prep-jobs.py, probe-jobs.sh, cpio.py |
the Holger-specific suite (9 required env vars, kernel-probe compose, direct kernel boot, tmpfs root) |
Finding 1 of that report (the shipped Holger kernel cannot run Heimdall strict) is addressed on holger branch kern/appliance-lsm by hand-typed requires rows, and in heimdall d747087 by the no-pivot shim. Nothing reads needs.json, coverage.json or the fragment back by code.
2.5 dwarves
| Item |
path:line |
Does |
| `dwarves tune probe |
gen |
check |
| `dwarves tune app run |
approve` |
tune_app.rs:381 |
dwarves-tune-graph |
crates/dwarves-tune-graph/src/{lib.rs,xcheck.rs,profile.rs,main.rs} |
`--graph <graph.json> --profile <probe |
| kernel ledger |
crates/dwarves/src/kernel_ledger.rs |
index = action cache, bytes = artifact store; record, resolve_built_kernel(_for); honest no-op when DWARVES_HOLGER_DIR unset |
--opt kernel.* |
buildthing.rs:536-574 |
the operator decision door, resolved against the donor's declaration |
2.6 Mímir (nornir) — the possible-syscalls engine
| Exists |
path |
Does |
| source call graph |
crates/mimir-driver |
CALLS edges from rustc HIR/MIR, #[cfg] gating |
| binary layer |
crates/mimir-binary/src/lib.rs |
linked symbols joined onto the same node ids (v0 demangle, mono instances, FFI border) |
| boundary |
crates/mimir-ingest/src/boundary/{mod.rs,x86_64.rs,libc_map.rs,class.rs,btf.rs} |
@syscall nodes per x86_64 table entry + <indirect> (mod.rs:51); libc map (open64 → openat); raw doors → <indirect> UNCERTAIN; kernel types from BTF; SYSCALLS edge kind (mimir-schema/src/lib.rs:290) |
| room |
crates/mimir-room/src/{path.rs,export.rs,query.rs} |
shortest path A→B over chosen edge kinds (path.rs:45), edge export (export.rs:187); SYSCALLS edges only when the dependency universe is folded in (query.rs:219) |
| plan |
.nornir/mimir-syscalls-plan.md |
steps 1–6; 1–4 unassigned; 6 points at Holger 3.2 |
Missing (plan steps): 1 walk from entry points to SYSCALLS and export the Graph JSON dwarves-tune-graph reads; 2 unresolved edges for dyn Trait / fn pointers / Box<dyn Fn>; 3 dependency sources from Holger's crates.io mirror; 4 aarch64 table; 5 bench on rusternetes-node + tunnr-cni against their approved profiles.
Consumers of Mímir's output (who reads what, once step 1 exists):
| Output |
Consumer |
Repo of the consumer change |
Effect |
graph.json per program (Graph type: syscalls{name→Reach}, unresolved_sites, dlopen, …) |
dwarves-tune-graph cross_check (exists, xcheck.rs:39) via dwarves tune app and tune show |
dwarves: none for the reader; tune show should look for .nornir/profiles/<row>/<program>/graph.json |
possible-but-unseen = warn before approve; seen-but-not-possible = red |
the same graph.json |
edda syscall_join::MeasuredRow gains an optional possible set per program |
edda syscall_join.rs:602,721,850 |
kernel needs lists options needed by possible calls too (class "possible, unexercised"); vetoes_for refuses a veto whose option gates a possible call (never widens a profile; only protects the kernel) |
| the same |
Build Thing veto what-if |
edda kernel_trim.rs:160 |
a possible call becomes a protect reason with a path, so a trim cannot drop what the code can reach |
| the same |
Heimdall profiles |
none |
Heimdall never widens a filter from a graph (dwarves rule, lib.rs:16); only the review warns |
Repo fit per plan step: 1, 2, 4 → nornir (mimir-room export verb writing the Graph JSON from @syscall nodes; the aarch64 table beside boundary/x86_64.rs); 3 → nornir mimir-ingest reading crate sources from Holger (a Holger door if one is missing); 5 → tunnr (.nornir/profiles/<row>/<program>/graph.json + the cross-check report committed beside the row), run through dwarves tune. The walk itself stays the owner's; lanes only add readers of the JSON.
3. Data flow today
[[build.kernel]] row (tunnr kernel.rs) measure.toml (hand-written, per row)
│ preset + profile + closure │
▼ ▼
requires (consumers, incl. veto list =n) ──► merged fragment heimdall profile probe (external binary, privileged podman)
│ (edda kernel.rs:1652) │
▼ ▼
kernel build in container ──► .kernel-out/<name>/ + kernel-pin.json .nornir/profiles/<row>/{measure.json,<prog>/*.probe.json,*.json,*.oci.json}
│ │ ledger key │ │
▼ ▼ ▼ ▼ (MISSING: not packed)
korp-installer ISO (kernel_donor) dwarves kernel ledger kernel needs (syscall_join) korp-start seccomp/<entry>.oci.json
│ │ stdout only (hand-written 361-call file today)
▼ ▼ MANUAL redirect
kernel-suite.sh (KVM): boot, stages, memsave ◄── kernel coverage kernel-needs.json ──► dwarves tune show
│
▼
.nornir/kernel-coverage/<row>/<sha12>.json ──► kernel candidates ──► kernel veto ──► <row>.list + receipt JSON
▲ protect.list ▲ what-if (+ measured-call refusal) │
│ │ ▼
└── PROBE_ALTERED always protected └── syscall_join::vetoes_for include_str! → recipe → emit → build-variants.toml
Holger: tools/kernel-suite.sh ──► tunnr-build-thing kernel-probe --repo <holger> --fragment-extra heimdall-needs.fragment
──► needs.json, coverage.json, candidates.txt, heimdall-needs.fragment (a REPORT; nothing consumes it)
──MISSING──► Holger [[build.installer.requires]] (hand-typed on branch kern/appliance-lsm)
Mímir: driver CALLS + binary symbols + @syscall boundary ──MISSING step 1──► graph.json ──► dwarves-tune-graph (reader exists)
└──MISSING──► syscall_join possible set
4. Overlaps, duplicates, gaps and sharp edges (seen in code)
| # |
Where |
What |
| S1 |
edda kernel.rs:962-977,1087-1106; kernel-guide.md:295-311; kernel-for-idiots.md; tunnr kernel.rs:302-308,916 |
Pin semantics clash. tunnr now pins the image id; edda builds name@sha256:<pin> (a manifest ref) and its comment calls the image-id reading "WRONG"; tunnr's pin_defects still demands @sha256:; the two guides teach the opposite rule. Works today only if the engine resolves the id (not verified at run time). |
| S2 |
edda kernel.rs:3668 vs :1538 |
Ledger key misses axes. ledger_key omits toolchain (gcc/clang), solver, base; canonical_bytes has them. A gcc and a clang build share one pins/<key>/ slot and overwrite each other. |
| S3 |
edda kernel.rs:3630, dwarves kernel_ledger.rs |
Ledger has one implementation, in dwarves, behind DWARVES_HOLGER_DIR. edda's public resolver always uses NoLedger. |
| S4 |
edda kernel.rs:4782, kernel_requires.rs:812, kernel_trim.rs:1420 |
kernel.why.toml is written but never read in production. WhyIndex::from_toml is test-only; kernel_trim recomputes the index. |
| S5 |
edda veto.rs:636,646; tunnr vetoes.rs:55-69; tunnr recipe.rs:533 |
Receipts are not consumed. The build trusts the .list line; the receipt JSON is read only by the vetoes listing verb and one unit test. No check that a list line has a receipt, that it says applied, or that it belongs to the current fragment. |
| S6 |
tunnr main.rs:432-434, vetoes.rs:24-30 |
--repo vetoes land nowhere. A veto for another repo's row is written to <other>/crates/tunnr-build-thing/kernel-vetoes (Holger has no such crate); list_of compiles in only tunnr's two rows. |
| S7 |
tunnr vetoes.rs:16-18, main.rs:50 |
A veto needs a rebuild of the door and a re-emit (include_str!), a manual step after every veto. |
| S8 |
edda syscall_join.rs:721; dwarves tune/review.rs:224, README.md:162 |
kernel-needs.json has a reader and no writer (shell redirect only). No row in any repo has the file. |
| S9 |
heimdall container/src/kernel.rs:118-127 |
Heimdall's kernel needs are prose. No machine-readable list, no fragment. The Holger fragment and the branch rows were typed by hand from a failure message. |
| S10 |
heimdall container/src/kernel.rs:56 vs broker/src/support.rs:18 |
Two kernel probes that can disagree. KernelReport infers ADDFD from the release string; the broker probes it for real. |
| S11 |
heimdall probe/observe.rs, minimise.rs, seccomp/oci.rs, trace/doc.rs:125; dwarves Seen; edda MeasuredRow |
Five syscall-set shapes (probe Observations, Generated profile, OCI JSON, trace facts, dwarves Seen) and three readers of .probe.json (heimdall, edda syscall_join, dwarves-tune-graph), each parsing by field name. |
| S12 |
edda syscall_join.rs:259 (MakeGates) vs coverage.rs:388 (linked_gates) |
Object → CONFIG gate resolution exists twice, with different rules, both over makefile_gates. |
| S13 |
tunnr rusternetes.rs:984-1011; .nornir/profiles/rusternetes-node/measure.toml |
The packed node seccomp profile is hand-written (361 calls) and reused for two entries; the measured node-pid1 profile (17 calls) is not packed; korp-start, rusternetes and the youki shim are never measured (needs_vm). |
| S14 |
tunnr payloads/rusternetes-node/src/landlock.rs:35 |
Landlock is off for Rusternetes and every pod ("waiting on the shim door"). Only CSI has rules. |
| S15 |
tunnr scripts/kernel-suite.sh:43-56,96; .nornir/kernel-coverage/rusternetes-node/ |
One suite, one row. bridge for rusternetes-node only; the aya row has no suite, no coverage, an empty veto list. The applied veto ran with 10 checks NOTRUN. No coverage for the post-veto fragment 333150ec…; 380dcfbd46e9.json is stale. Line 96 has a garbled comment. The build-box/KVM split needs a hand sync of the kernel tree. |
| S16 |
tunnr main.rs:465, xtask/src/main.rs:69 |
Usage strings are stale: kernel-probe, preflight, measure gate missing from the door's usage; xtask lists only `stage |
| S17 |
tunnr .nornir/heimdall-runtimeclass.md; heimdall docs/SPEC.md:146 |
Stale docs. RuntimeClass doc says step 2 PARKED while the code ships it; SPEC says the RuntimeClass "runs pods through heimdall-run" while heimdall-k8s only signs what the kubelet claims (k8s/src/lib.rs:88,167). |
| S18 |
tunnr crates/korp-installer/kernel/korp-kernel.blake3:17 |
A dead pin: all zeros; only the $KORP_KERNEL path reads it. |
| S19 |
edda coverage.rs:730 |
Coverage reports keyed by a 12-char sha prefix; a collision fails load_for's full-sha check instead of finding the right file. |
| S20 |
edda coverage.rs:13 vs kernel.rs:3076 |
"Boots under KVM" is in the row script, not the crate; the in-crate probe boot is TCG. Two structs named KernelProbe (kernel.rs:3231 result; coverage.rs:73 gcov enum). |
| S21 |
tunnr xtask/src/rusternetes.rs:159 |
Cargo toolchain image pinned by tag only (localhost/…:live-tools-ssl-proto), the very prefix kernel.rs:230 warns about. |
| S22 |
edda kernel modules |
No AI/MCP/llms face for kernel data. Only --json schemas. The owner's "visible in AI" is not wired. |
| S23 |
heimdall xtask/src/main.rs:13-29; scripts/*.sh |
xtask accepts --quick/--nightly and ignores them; every real gate is a shell script with privileged podman. Two near-duplicate youki shims (plain/src/shim.rs, container/src/shim.rs). |
| S24 |
heimdall profiles |
Profile digests live in CHANGELOG/docs and callers' SeccompProfileRef, not beside the profile; no corpus hash in a profile; aarch64 has tables but no profile or kernel test. |
5. Dead or orphaned
| Item |
path:line |
State |
kernel.why.toml |
edda kernel.rs:4782,4306; reader kernel_requires.rs:812 |
written; read only by tests |
veto_requirements (edda) |
kernel_trim/veto.rs:92 |
called only by veto/tests.rs:131 inside edda (tunnr calls it through vetoes.rs) |
| veto receipt JSON |
tunnr .nornir/kernel-vetoes/rusternetes-node/receipts/*.json |
read by one unit test and the vetoes list verb; never checked by the build |
kernel-needs.json |
dwarves tune/review.rs:19,224 |
reader with no writer; only a test fixture exists |
kernel-probe door |
tunnr main.rs:301-377 |
called only by Holger's hand-run suite script |
run_kernel_verb in edda |
kernel_trim.rs:~1224/1332 |
no CLI in edda; only syscall_join/tests.rs:331 and the tunnr door |
KernelLedger trait in edda |
kernel.rs:3642 |
NoLedger + test MapLedger only; the real one is in dwarves |
MINIMAL_FRAGMENT |
edda kernel.rs |
minimal is refused on x86_64, the only wired arch |
walk::analyze, srcgraph::* |
dwarves dwarves-tune-graph/src/walk.rs:6, srcgraph/mod.rs:36-46 |
owner-reserved stubs, tests #[ignore] (correct by decision; listed so nobody "fixes" them) |
korp-kernel.blake3 |
tunnr crates/korp-installer/kernel/korp-kernel.blake3 |
all-zeros placeholder |
380dcfbd46e9.json |
tunnr .nornir/kernel-coverage/rusternetes-node/ |
coverage of a fragment no row has |
heimdall-needs.fragment, needs.json, coverage.json (Holger) |
holger/.nornir/kernel-usage/holger-scan-worker/ |
report files; no code reads them |
--quick, --nightly |
heimdall xtask/src/main.rs:13-29 |
parsed, ignored |
offsite::restore_latest |
holger server/lib/src/offsite.rs:1143 |
called only by server/lib/tests/the_offsite_copy_restores_a_fresh_box.rs:114,153 |
| two kernel probes |
heimdall container/src/kernel.rs:56, broker/src/support.rs:18 |
duplicated logic |
MakeGates vs linked_gates |
edda syscall_join.rs:259, coverage.rs:388 |
duplicated logic |
6. How it could work together
The boundary that already holds in code and licence: Build Thing (MIT) never links Heimdall (AGPL); it runs the binary and reads JSON by field name. The owner's engine (Mímir) writes a Graph JSON; lanes only read it. Every option below keeps both.
Homes
| Concern |
Home |
Why |
| rows, fragments, pins, ledger, variants, emit, parity |
Build Thing (edda engine + <repo>-build-thing) |
it is the build |
| what-if, candidates, coverage model, veto rule, receipts |
Build Thing |
they change the kernel artifact |
| syscall → CONFIG join |
Build Thing (edda syscall_join) |
it needs the composed kernel tree; it is a pure reader of profile files |
| measured syscalls, Landlock/LSM needs, profiles, approval, drift |
Heimdall tooling (heimdall binary + dwarves tune + edda measure) |
runtime need, runtime evidence |
| Heimdall's own kernel needs |
Heimdall (emit) → Build Thing (consume as requires) |
the runtime knows what it needs; the build must state it as rows |
| possible syscalls (graph) |
Mímir (owner) → a JSON file beside the row |
the plan's boundary |
| the suite (boot the medium, print stages) |
the product repo (scripts/kernel-suite.sh, Holger tools/) |
only the product knows how to boot and exercise itself |
Interface = files in the row directory, with schemas (no code coupling)
.nornir/profiles/<row>/
measure.toml, measure.json, approved.toml Heimdall tooling (exists)
<program>/<arch>-<libc>.{probe.json,json,oci.json} Heimdall tooling (exists)
<program>/graph.json Mímir (MISSING: plan step 1)
kernel-needs.json nornir.kernel-needs/1 Build Thing join (MISSING writer)
kernel-requires.toml generated requires rows Build Thing from heimdall needs (MISSING)
.nornir/kernel-coverage/<row>/<sha>.json Build Thing (exists)
.nornir/kernel-vetoes/<row>/{protect.list,receipts/} Build Thing (exists); the .list should live here too
Option A — keep the three homes, close the missing writers (smallest)
kernel needs <row> --save writes kernel-needs.json beside the row (closes arrow 12).
heimdall kernel needs --json emits the kconfig lines strict mode requires (from missing_for_strict), and Build Thing turns them into [[build.installer.requires]] rows with Heimdall's reasons (closes arrows 13, 14; the Holger branch rows become generated).
- The veto list moves beside its receipts (
.nornir/kernel-vetoes/<row>/<row>.list); <repo>-build-thing reads it from there and refuses a line with no applied receipt on the current fragment (closes S5, S6, S7).
- Mímir step 1 writes
graph.json; syscall_join reads it as a possible set (arrows 22, 23).
- Trade-off: the join stays in edda although it is "runtime need"; acceptable because it reads the kernel tree. Least motion; each step is one small PR.
Option B — a shared MIT crate nordisk-kernel-evidence
- Move
syscall_join, the coverage/veto report types and dwarves-tune-graph's Graph/Seen types into one crate used by edda, dwarves and <repo>-build-thing; Heimdall stays out (AGPL) and only emits JSON.
- Pro: one definition of every evidence file; the three
.probe.json readers become one. Con: a crate split out of an 8k-line module and a new release line; pays off only after A.
Option C — Heimdall owns the "needs" end to end
- Heimdall emits a signed
kernel-needs statement per program (strict-mode features + the measured calls' options), and Build Thing only verifies and consumes.
- Pro: the runtime is the authority. Con: Heimdall would need the syscall→CONFIG map, which lives in the kernel tree the build has; it would duplicate
syscall_join under AGPL. Not recommended.
7. Recommendation
Option A now, B later. The pieces exist and each file already has a schema; what is missing is four writers and one reader. Keep Mímir's walk the owner's; lanes add only the graph.json reader in syscall_join and the tune show lookup.
Smallest first step: kernel needs <row> --json --save writes .nornir/profiles/<row>/kernel-needs.json (edda kernel_trim.rs verb + tunnr main.rs usage), and the Holger report's needs.json is copied there as the first real file. One PR, one test, and dwarves tune show starts showing the kernel join for a real row.
8. Fix list (smallest first)
| # |
Fix |
Repo |
Files |
| 1 |
kernel needs --save writes kernel-needs.json beside the row; tune show then reads a real file |
edda, tunnr |
edda/crates/nornir-build-thing/src/kernel_trim.rs (verb), src/syscall_join.rs:721; tunnr/crates/tunnr-build-thing/src/main.rs:378-463,465 |
| 2 |
Usage strings: add kernel-probe, preflight, measure gate; xtask verbs |
tunnr |
crates/tunnr-build-thing/src/main.rs:465, xtask/src/main.rs:69 |
| 3 |
Suite script hygiene: fix the garbled comment, document KS_MEDIA tree sync, remove the stale coverage file |
tunnr |
scripts/kernel-suite.sh:49-56,96, .nornir/kernel-coverage/rusternetes-node/380dcfbd46e9.json |
| 4 |
One pin rule: decide image id vs manifest digest, make edda's ref builder, tunnr's pin_defects and both guides agree |
edda, tunnr |
edda/.../src/kernel.rs:958-982,1087-1106, edda/.nornir/kernel-guide.md:295-311, edda/.nornir/kernel-for-idiots.md; tunnr/crates/tunnr-build-thing/src/kernel.rs:302-308,916 |
| 5 |
Heimdall: one kernel probe (KernelReport uses the broker's real probe for ADDFD); fix the stale comment |
heimdall |
crates/heimdall-container/src/kernel.rs:7,56, crates/heimdall-broker/src/support.rs:18 |
| 6 |
Ledger key carries toolchain, solver, base |
edda |
crates/nornir-build-thing/src/kernel.rs:3668,4787 |
| 7 |
heimdall kernel needs --json: kconfig lines strict mode requires, with reasons |
heimdall |
crates/heimdall-container/src/kernel.rs:118-127, crates/heimdall-cli/src/main.rs |
| 8 |
Build Thing consumes 7: kernel requires-from-needs generates [[build.installer.requires]] rows; Holger's hand-typed LSM rows become generated; merge the branch |
edda, holger |
edda/.../src/kernel_requires.rs; holger branch kern/appliance-lsm (.nornir/build-variants.toml rows), holger-build-thing recipe |
| 9 |
Veto list beside its receipts; the build refuses a list line with no applied receipt on the current fragment; --repo vetoes land in the other repo's .nornir/kernel-vetoes/<row>/ |
edda, tunnr |
edda/.../kernel_trim/veto.rs:108,636; tunnr/crates/tunnr-build-thing/src/{vetoes.rs:16-30,main.rs:432-434,recipe.rs:533,564} |
| 10 |
Coverage for the post-veto fragment; a suite for the aya row |
tunnr |
scripts/kernel-suite.sh:43-46, .nornir/kernel-coverage/rusternetes-node-aya/ |
| 11 |
Pack the measured profiles instead of the 361-call hand-written one; a VM leg for korp-start, rusternetes, the youki shim (needs_vm) |
tunnr |
crates/tunnr-build-thing/src/rusternetes.rs:984-1011, .nornir/profiles/rusternetes-node/measure.toml, scripts/kernel-suite.sh |
| 12 |
Landlock for Rusternetes and pods (the "shim door") |
tunnr, heimdall |
payloads/rusternetes-node/src/landlock.rs:35, src/heimdall.rs |
| 13 |
Either read kernel.why.toml (WhyIndex::from_toml) in kernel_trim or stop writing it |
edda |
src/kernel.rs:4782,4306, src/kernel_requires.rs:812, src/kernel_trim.rs:1420 |
| 14 |
One object→gate resolver (MakeGates and linked_gates) |
edda |
src/syscall_join.rs:259, src/kernel_trim/coverage.rs:388 |
| 15 |
Stale docs: RuntimeClass step 2, SPEC §9, kernel minimums |
tunnr, heimdall |
tunnr/.nornir/heimdall-runtimeclass.md; heimdall/docs/SPEC.md:55,146, docs/SECCOMP.md |
| 16 |
Kernel data visible to AI: kernel rows, needs, coverage totals and vetoes in the nornir introspection / llms output |
edda, nornir |
edda/crates/nornir-build-thing/src/{surface.rs,suite_cli.rs}, nornir/crates/nornir-introspect |
| 17 |
Mímir plan steps 1–5 (owner assigns): 1 walk + graph.json export, 2 unresolved edges, 4 aarch64 table → nornir crates/mimir-room (export), crates/mimir-ingest/src/boundary/; 3 sources from Holger → nornir mimir-ingest/src/checkout.rs (+ a Holger door if needed); 5 bench on rusternetes-node, tunnr-cni → tunnr .nornir/profiles/<row>/<program>/graph.json + report |
nornir, holger, tunnr |
as listed |
| 18 |
syscall_join reads graph.json as a possible set: needs class "possible, unexercised"; a veto cannot drop an option a possible call needs |
edda |
src/syscall_join.rs:602,721,850, src/kernel_trim.rs:160 |
| 19 |
Remove the dead korp-kernel.blake3 placeholder path or fill it |
tunnr |
crates/korp-installer/kernel/korp-kernel.blake3, src/kernel.rs:33-42 |
| 20 |
Option B: shared evidence crate (after 1–18) |
edda, dwarves |
new crate; dwarves-tune-graph/src/lib.rs types; syscall_join.rs |