module-eval: pin the severity mapping's direction and the panel

The direction is the part a reviewer cannot check by looking, so it is
asserted at both ends of the table and in both tiers' groups: an inverted
mapping still maps every value to something, and a case that only asks
whether a severity parser exists passes on the exact defect. The reader
that turns a rendered operator list back into a PRIORITY -> name function
lives in lib.nix, since both tiers need it.

The panel is asserted on its query rather than its title, because a panel
that keeps the title and loses the expression renders an empty graph that
looks exactly like zero prioless lines.
This commit is contained in:
atlas 2026-09-20 05:19:06 +02:00 committed by mara
commit 7fa13b592f
4 changed files with 121 additions and 0 deletions

View file

@ -140,6 +140,34 @@ let
agentHarness = machine: machine.systemd.services.hive-agent;
# Reads a journald receiver's rendered operator list back as a plain
# `PRIORITY -> severity-name` function, so a case can ask what a given
# priority actually maps to rather than matching on the shape of the config
# that produces it. Shared because two tiers run that receiver — the agent
# container over its own journal, the swarm collector over the host's — from
# one imported mapping, and the case that says so has to reach both.
# `null` for a receiver carrying no severity parser at all, which is the
# state that mapping replaced.
journaldSeverityOf =
receiver: priority:
let
parser = lib.findFirst (o: o.type or null == "severity_parser") null (receiver.operators or [ ]);
# The mapping is `severity-name -> value or list of values`; invert it
# into `value -> severity-name` so a lookup is by priority.
hits = lib.attrNames (lib.filterAttrs (_: v: lib.elem priority (lib.toList v)) parser.mapping);
in
if parser == null || hits == [ ] then null else lib.head hits;
# Whether that same parser rewrites the severity TEXT. Its own reader,
# because it is a separate way for the mapping to be there and useless: see
# the case that asserts it.
journaldSeverityOverwritesText =
receiver:
let
parser = lib.findFirst (o: o.type or null == "severity_parser") { } (receiver.operators or [ ]);
in
parser.overwrite_text or false;
# The enables that switch owns. ⚠️ `otel` is the per-hive collector's own
# option and is NOT under `deploy` — spelled at the wrong path it would be
# undeclared rather than false, and a roster that quietly loses a member is
@ -197,6 +225,8 @@ in
inherit baoSettings;
inherit otelSettings;
inherit agentHarness;
inherit journaldSeverityOf;
inherit journaldSeverityOverwritesText;
inherit swarmServiceEnables;
inherit runGroup;
}