Skip to content

feat(engine): narrowing-delta counter for uncorroborated notable-exec (ADR-0041 §6) - #330

Open
thejefflarson wants to merge 1 commit into
mainfrom
thejefflarson/jef-770-narrowing-delta-counter-for-uncorroborated-notable-exec
Open

feat(engine): narrowing-delta counter for uncorroborated notable-exec (ADR-0041 §6)#330
thejefflarson wants to merge 1 commit into
mainfrom
thejefflarson/jef-770-narrowing-delta-counter-for-uncorroborated-notable-exec

Conversation

@thejefflarson

Copy link
Copy Markdown
Owner

Summary

Adds a view-only narrowing-delta bake instrument (ADR-0041 §6): a structured log +
OTLP counter that fires when a breach-relevant chain has a notable exec (interactive
shell / package manager, observe::exec_class::notable_exec) present on its entry's on-pod
runtime, but the chain is !corroborated. These are exactly the cases the retiring blanket
notable-exec corroboration arm would have flipped to corroborated — the recall the
Behavior::Alert arm currently backstops. This is the Falco-retirement parity-matrix input
and arm-readiness bake instrument (ADR-0037).

Mirrors the cut_divergence / state::divergence read-only-bake shape already in the repo:
a pure compute() function, an unlabeled OTLP counter beside the existing corroborations
counter, and a per-match structured log line — nothing feeds back into the ledger, actuator,
or arming state (ADR-0016).

Design note / decision: ProvenChain doesn't carry its entry's runtime signals directly
(they're resolved internally inside reason::proof::prove_with), so narrowing_delta::compute
looks the entry's workload node up directly in the graph (mirroring, but not calling, the
pub(super) chain::actively_exploited helper, which is scoped to the broader
is_alarming_now family rather than notable_exec specifically). This keeps the new module
entirely outside reason::proof::corroborate.rs, which a sibling engineer is concurrently
narrowing for JEF-393 — no changes were made to corroborates()/corroborated_for.

What changed

  • engine/src/engine/narrowing_delta.rs (new): pure compute(&SecurityGraph, &[ProvenChain]) -> Vec<NarrowingDeltaRecord> and NarrowingDeltaRecord::emit() (structured log).
  • engine/src/engine/narrowing_delta_tests.rs (new): unit tests building the corroborated/uncorroborated states directly (per the ticket's note — doesn't depend on JEF-393 landing first).
  • engine/src/engine/metrics.rs: new unlabeled protector.engine.narrowing_delta counter.
  • engine/src/engine/mod.rs: wires compute() into the per-pass loop alongside the existing corroborations accounting; module declaration.

Test plan

  • cargo test --workspace — full suite green (1217 passed in the engine crate, plus behavior/dashboard/guard suites), including the new narrowing_delta tests:
    • shell exec present + no in-window egress → uncorroborated chain → counter fires
    • shell exec present + in-window egress → corroborated chain → no fire
    • no notable exec on the entry → never fires
    • notable exec present but chain not breach-relevant → never fires
  • cargo fmt --all -- --check clean
  • cargo clippy -p protector --all-targets -- -D warnings clean
  • file_size_guard / self_containment_guard integration tests pass (no file over the 1,000-line cap; no ticket-ID breadcrumbs in committed source)
  • soundcheck:pr-review self-review: no Critical/High findings (view-only, no user input, unlabeled counter, no new egress)
  • /simplify self-review pass: diff already clean against reuse/simplification/efficiency/altitude

Invariants preserved

  • View-only (ADR-0016): no path back into the ledger/actuator/arming state.
  • Zero-egress: existing in-cluster OTLP sink only, no new outbound call.
  • audit-mode observe-only; no PROTECTOR_*_ENABLE toggle; no wire change.
  • Counter carries zero labels (no free text, no per-node/PII dimension) — the entry name appears only in the accompanying structured log, matching the existing ProvenChain::emit() precedent.
  • Did not touch engine/src/engine/reason/proof/corroborate.rs (JEF-393's scope).

Closes JEF-770

… (ADR-0041 §6)

Adds a read-only bake instrument that counts/logs breach-relevant chains
where a notable exec (interactive shell / package manager) is present on
the entry's runtime but the chain is uncorroborated — exactly the cases
the retiring blanket notable-exec corroboration arm would have flipped to
corroborated. Feeds the Falco-retirement parity matrix (ADR-0041 §6) and
the arm-readiness bake (ADR-0037).

View only, mirroring the cut_divergence comparator's shape: a pure
compute() over the graph + proven chains, an unlabeled OTLP counter
beside the existing corroborations counter, and a structured log line per
match. No path back into the ledger/actuator/arming state, no config
toggle, no wire change.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@thejefflarson
thejefflarson enabled auto-merge (squash) August 7, 2026 02:48
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