Skip to content

feat(dashboard): per-finding "runtime-blind on this node" caveat (JEF-424)#242

Merged
thejefflarson merged 2 commits into
mainfrom
thejefflarson/jef-424-per-finding-runtime-blind-on-this-node-caveat-where-a
Jul 18, 2026
Merged

feat(dashboard): per-finding "runtime-blind on this node" caveat (JEF-424)#242
thejefflarson merged 2 commits into
mainfrom
thejefflarson/jef-424-per-finding-runtime-blind-on-this-node-caveat-where-a

Conversation

@thejefflarson

Copy link
Copy Markdown
Owner

What & why

A finding whose workload sits on a node the agent can't see (no live eBPF sensor) reads as calm / propose-only — but that calm is dishonest there: absence of a corroborating signal is not evidence of safety, so blind ≠ green. This threads the existing per-node blind_node_set() into the findings snapshot so such a finding carries a finding-level caveat that leads with the crisp "runtime-blind on <node>" framing and NAMES the node.

What changed

  • engine/src/engine/dashboard/view_model/findings.rs — the finding-level blind_node_caveat now reads "runtime-blind on <node> — no live sensor here, so absence of a signal is not evidence of safety", keeping the honest tail and naming the node.
  • The caveat is presentation metadata only (ADR-0016 — a view, never a gate): an additive Option<String> on FindingProps (already #[serde(default)]-shaped), derived from the same blind_node_set the Readiness runtime-corroboration row reads, so the two can never disagree. It never touches the verdict, the proposed action (cut), or the report — the decision is unchanged.
  • Client renders it via the existing .verdict-caveat / role="note" precedent in detail.jsx; the node name is untrusted and auto-escaped at render (Preact).

Honesty invariants

  • VERDICT UNCHANGED — the caveat alters nothing but its own field.
  • Derived from the SAME blind_node_set the Readiness row uses (they never disagree).
  • Untrusted node name escaped at render.

Tests

  • Rust (view_model/findings/tests.rs): a finding on a blind node carries the caveat naming the node (runtime-blind on <node>); a finding on a healthy/sensored node — and a corroborated one — does not; and a new honesty test asserts the caveat changes NOTHING else (same posture/live-tag/verdict-summary, same cut, same disposition, byte-for-byte-equal report body).
  • JS (test/blind-caveat.test.jsx): the caveat renders as a role="note"; none renders when the server ships null; an XSS-laden node name renders as escaped text, never a live element.

Checks (all green)

  • cargo fmt, cargo clippy -p protector --all-targets (clean), cargo test -p protector (775 lib + integration + guards pass).
  • Web bundle built from source (npm run build); npm test (72 pass, incl. 3 new).

Scope note

Overlaps with JEF-421 — both touch the dashboard view-model props + client, but different files. Flagged for the architect.

Closes JEF-424

🤖 Generated with Claude Code

https://claude.ai/code/session_01VtjoJttCvBY4dzCoE4f9vP

thejefflarson and others added 2 commits July 17, 2026 23:22
…-424)

A finding whose workload sits on a node the agent can't see (no live eBPF
sensor) reads as calm/propose-only — but that calm is dishonest there: we
can't tell whether the path is being exploited, so blind ≠ green. The
finding-level blind-node caveat (shipped as coverage under JEF-308) now leads
with the crisp "runtime-blind on <node>" framing the ticket names, keeping the
honest tail ("absence of a signal is not evidence of safety") and NAMING the
node.

METADATA ONLY (ADR-0016 — presentation is a view, never a gate): the caveat is
an additive `Option<String>` on `FindingProps`, derived from the SAME
`blind_node_set` the Readiness runtime-corroboration row reads (so the two can
never disagree). It never touches the verdict, the proposed action (cut), or
the report — the finding's decision is unchanged. The client renders it via the
existing `.verdict-caveat` / `role="note"` precedent; the node name is UNTRUSTED
and auto-escaped at render (Preact).

Tests: Rust — a finding on a blind node carries the caveat NAMING the node
("runtime-blind on <node>"); a finding on a healthy/sensored node (and a
corroborated one) does not; and a new honesty test asserts the caveat changes
NOTHING but that one field — same verdict/posture/live-tag, same cut, same
disposition, byte-for-byte-equal report body. JS — the caveat renders as a
`role="note"` and an XSS-laden node name renders as escaped text, never a live
element. Web bundle built from source; `cargo fmt`/`clippy`/`cargo test -p
protector` and `npm test` all green.

Closes JEF-424

Claude-Session: https://claude.ai/code/session_01VtjoJttCvBY4dzCoE4f9vP

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
@thejefflarson
thejefflarson enabled auto-merge (squash) July 18, 2026 07:10
@thejefflarson
thejefflarson merged commit b3aa963 into main Jul 18, 2026
5 checks passed
@thejefflarson
thejefflarson deleted the thejefflarson/jef-424-per-finding-runtime-blind-on-this-node-caveat-where-a branch July 18, 2026 07:18
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant