Verify JEF-284 pivot-quarantine gates on evidence, not mere reachability+CVE (JEF-322)#276
Conversation
…ne (JEF-284)
Verifies whether quarantine_targets_on_path's RemotelyExploitable trigger
requires on-pod exploitation evidence or fires on mere reachability + CVE
presence. Finding: it fires on presence alone — compromisable() is the
static CVE/KEV predicate, not actively_exploited()'s live-signal one — and
Mitigation::is_live_corroborated treats every QuarantineWorkload mitigation
as unconditionally auto-actionable, bypassing the corroborated/promoted/
adjudicated gate ADR-0013 requires for the entry-foothold lane ("CVE
presence no longer auto-cuts").
This is a verified, deliberate asymmetry, not a bug fix: adds a
characterizing regression suite (pivot_quarantine_tests.rs) that pins the
CURRENT behavior on both the proof-layer target-selection side and the
actuator's auto-action gate, plus a contrast test showing a live signal on
the pivot upgrades it to ActivelyExploited. Comments at both trigger sites
cite the finding for future readers. No production behavior changed —
whether to close the tension (model-gate the pivot) or accept it as
intended is flagged as DECISION NEEDED for the architect.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VtjoJttCvBY4dzCoE4f9vP
…uarantine-gates-on-evidence-not-mere
|
Architect note (INTEGRATE) — merging the verification/tests as-is; recording the open decision. The characterizing suite + doc comments are merged on green: they lock current behavior in place without endorsing it, and touch no quarantine/actuation/corroboration logic (non-test files are comment-only; the unconditional Open decision recorded for a
No code changed to resolve this; filing the decision as an ADR + ticket is the main loop's follow-up. Minor non-blocking nit for that follow-up: the new |
Summary
This is a verification + regression-test ticket (JEF-322), not a feature. It answers: does
quarantine_targets_on_path'sRemotelyExploitablepivot-quarantine trigger (engine/src/engine/reason/proof/chain.rs) require on-pod exploitation evidence, per the JEF-284 design intent ("never a merely-reached pod") and the product thesis (presence ≠ exploitability, ADR-0011/0013/0016) — or does it fire on mere reachability + CVE presence?Finding: it fires on reachability + CVE presence alone
RemotelyExploitable's condition isnode != entry && net_reachable(node) && compromisable(node).compromisableis the static CVE/KEV predicate — the same one used for the compromise-gate walk — notactively_exploited's live-signal one (alert / notable exec / alarming write). No runtime evidence, corroboration, or model verdict is required.This is sharper than it first looks, because of the actuator side too:
Mitigation::is_live_corroboratedspecial-cases everyQuarantineWorkloadmitigation — including aRemotelyExploitableone — as unconditionally auto-actionable, bypassing thecorroborated || promoted+adjudicated+breach_relevantgate that ADR-0013 requires for the entry-foothold lane. ADR-0013 exists specifically to reverse "CVE presence alone auto-cuts" for the entry ("the engine never cuts on mere CVE presence... with no model a foothold is propose-only"). The pivot-quarantine path does exactly what ADR-0013 forbids for the entry, with no model involved at all.This confirms the tension the ticket describes on a live cluster: the e2e's pivot pod
storegets deterministically quarantined (RemotelyExploitable, no model, no alert) purely because it's reachable from the exposedwebentry and carries a critical CVE.What I did
chain.rsand the actuator'sis_live_corroboratedgate inrespond/mod.rs, confirmed empirically with tests.engine/src/engine/reason/proof/pivot_quarantine_tests.rs— a characterizing regression suite (documents, doesn't endorse) that locks the current behavior in place so it can't silently drift further:pivot_reachable_plus_cve_alone_currently_promotes_to_remotely_exploitable— a pivot pod reachable from an exposed entry with a critical CVE and zero runtime evidence still getsRemotelyExploitableat target selection, andMitigation::is_live_corroborated()returnstruefor it.entry_foothold_alone_does_not_meet_the_stricter_action_bar— contrast: the SAME chain's entry-sidemeets_action_bar()stays closed with no corroboration/promotion (ADR-0013's stricter bar), highlighting the asymmetry.pivot_with_live_signal_is_actively_exploited_not_remotely_exploitable— a live signal on the pivot correctly upgrades it toActivelyExploited(the one shape that DOES carry genuine evidence).chain.rs,respond/mod.rs) citing the JEF-322 finding for future readers.DECISION NEEDED
Per the ticket: since the code fires on mere reachability+CVE (not evidence), this needs an explicit call from the architect between:
RemotelyExploitablepromotes to a quarantine target/auto-action, mirroring ADR-0013's entry-foothold bar. Closes the asymmetry but narrows JEF-284's original "always contain a remotely-exploitable pivot" guarantee and adds a model dependency to a currently-deterministic, always-available lane.decide()still apply before anything actually applies live. Close JEF-322 with no code change beyond this verification's regression tests.I did not pick between these — it changes quarantine's live-actuation surface, which is exactly the kind of call the ticket asks the architect to make explicitly rather than have an agent decide silently.
Test plan
cargo fmt— cleancargo clippy --all-targets -- -D warnings— cleancargo test— 926 passed (923 prior + 3 new), 0 failed, 2 ignored/soundcheck:pr-review— comments-only diff + new test file, no Critical/High findings/simplify— deduplicated repeated graph-fixture code across two new tests into one parameterized helperCloses JEF-322
Co-Authored-By: Claude Opus 4.8 noreply@anthropic.com
Claude-Session: https://claude.ai/code/session_01VtjoJttCvBY4dzCoE4f9vP