Exploit evidence in consumer decisions
Verified on 2026-09-10 against backend source f0e29caa15 and Console source a91225af2b, using the source checks below and live Findings/Policy/browser readback. EXP-3 acceptance is complete.
Stella Ops keeps exploitation, exploit availability, and probability separate.
| Signal | Meaning | Curated exploitation gate |
|---|---|---|
exploited_in_wild | A source declares observed exploitation; CISA KEV supplies this class | Can block when the vulnerability becomes reachable |
exploit_available | Exploit code or tooling is available | Does not set the curated exploitation flag |
| EPSS | Estimated exploitation probability | Uses its separate probability threshold |
The Findings vulnerability-detail response exposes exploitEvidence records with kind, source, addedAt, dueDate, and references. corpusDigest and evidenceKey identify the actual local projection entries used for the response; neither is presented as an upstream raw-document digest. Metadata, evidence and tenant-scoped affected findings are read from one pinned active-generation snapshot. exploitedInWild is true only for the curated evidence kind.
The Console labels the evidence kind and source and links the recorded references. EPSS remains labeled as probability. A boolean without source evidence is shown as unavailable provenance rather than attributed to CISA. Findings’ aggregate risk score continues to use severity and reachability; this change adds no KEV weight.
Policy imports the owner corpus in the background and evaluates against its own completed mirror. A failed sync commits neither partial rows nor a new sync marker. Before any completed sync, the exploitation measurement is unknown. After sync, an unlisted vulnerability is a measured absence, and availability alone remains separate from exploitation.
Gate responses identify the decision’s delta through evidence.deltaId. GET /api/policy/deltas/{deltaId} exposes each driver’s nullable isKnownExploited measurement and typed exploitEvidence records. Gate evaluation does not call the vulnerability hub. An unavailable hub therefore does not replace the already completed local measurement with an invented empty result.
Upgrade and verification
Policy migration 008_exploit_evidence_provenance.sql adds reference storage and a provenance-format marker. Existing rows receive an empty reference list; no references are manufactured. The next normal background sync refreshes a marker from an older format even if its timestamp is recent. Existing gate measurements remain usable while that refresh completes. No Findings schema change is required.
The retained acceptance tests use private PostgreSQL instances and real Kestrel HTTP endpoints. They cover curated, availability-only and absent controls, active generation selection, source-reference retention, and Policy decisions after the hub transport becomes unavailable:
pwsh tools/scripts/test-targeted-xunit.ps1 -Project src/Findings/__Tests/StellaOps.Findings.Security.Tests/StellaOps.Findings.Security.Tests.csproj -Class '*ExploitEvidenceConsumerEndpointTests' -BuildProjectReferences
pwsh tools/scripts/test-targeted-xunit.ps1 -Project src/Policy/__Tests/StellaOps.Policy.Engine.Tests/StellaOps.Policy.Engine.Tests.csproj -Class '*ExploitEvidenceGateConsumerTests' -BuildProjectReferences
pwsh tools/scripts/test-targeted-xunit.ps1 -Project src/Policy/__Tests/StellaOps.Policy.Persistence.Tests/StellaOps.Policy.Persistence.Tests.csproj -Class '*ExploitEvidenceProjectionTests' -BuildProjectReferences
The approved 2026-09-10 rollout applied Policy migrations 008/009 and refreshed its mirror to provenance format 1. Actual controlled gate queries produced KEV Block with typed source evidence, and KEV Pass for a newly affected non-KEV control while preserving its independent warning. The decisions reported unattested when their Attestor connection was unavailable. These queries do not establish image membership: the current materializer selects the tenant’s latest export.
The fixed-CVE browser proof verifies the visible curated kind/source/dates/reference on CVE-2021-44228 and an empty exploitation state for CVE-1999-0001, including the date/reference separator. Its sibling browser observations and screenshots retain the actual responses; the earlier run-001 consumer API receipts retain the Policy controls. Broader four-persona Console acceptance remains a separate gate.
To repeat the fixed-CVE browser check, prepare ordinary operator auth state/report with the existing live-frontdoor-auth.mjs helper under the checkout’s private .local-secrets/ directory. Set STELLAOPS_AUTH_STATE_PATH, STELLAOPS_AUTH_REPORT_PATH and a fresh STELLA_EVIDENCE_ROOT, then run npx playwright test operator-trust/exp-003-exploit-evidence-detail.spec.mjs --workers=1 --retries=0 from src/__Tests/playwright/. Remove private auth state after the run; the retained test disables credential-bearing traces and writes only explicit browser observations and screenshots.
