# Uncertainty States & Entropy Scoring > **Status:** Draft – aligns with the November 2025 advisory on explicit uncertainty tracking. > **Owners:** Signals Guild · Concelier Guild · UI Guild. Stella Ops treats missing data and untrusted evidence as **first-class uncertainty states**, not silent false negatives. Each finding stores a list of `UncertaintyState` entries plus supporting evidence; the risk scorer uses their entropy to adjust final risk. Policy and UI surfaces reveal uncertainty to operators rather than hiding it. --- ## 1. Core states (extensible) | Code | Name | Meaning | |------|------------------------|---------------------------------------------------------------------------| | `U1` | MissingSymbolResolution| Vulnerability → function mapping unresolved (no PDB/IL map, missing dSYMs). | | `U2` | MissingPurl | Package identity/version ambiguous (lockfile absent, heuristics only). | | `U3` | UntrustedAdvisory | Advisory source lacks DSSE/Sigstore provenance or corroboration. | | `U4+`| (future) | e.g. partial SBOM coverage, missing container layers, unresolved transitives. | Each state records `entropy` (0–1) and an evidence list pointing to analyzers, heuristics, or advisory sources that asserted the uncertainty. --- ## 2. Schema ```jsonc { "uncertainty": { "states": [ { "code": "U1", "name": "MissingSymbolResolution", "entropy": 0.72, "evidence": [ { "type": "AnalyzerProbe", "sourceId": "dotnet.symbolizer", "detail": "No PDB/IL map for Foo.Bar::DoWork" } ], "timestamp": "2025-11-12T14:12:00Z" }, { "code": "U2", "name": "MissingPurl", "entropy": 0.55, "evidence": [ { "type": "PackageHeuristic", "sourceId": "jar.manifest", "detail": "Guessed groupId=com.example, version ~= 1.9.x" } ] } ] } } ``` ### C# models ```csharp public sealed record UncertaintyEvidence(string Type, string SourceId, string Detail); public sealed record UncertaintyState( string Code, string Name, double Entropy, IReadOnlyList Evidence); ``` Store them alongside `FindingDocument` in Signals and expose via APIs/CLI/GraphQL so downstream services can display them or enforce policies. --- ## 3. Risk score math ``` riskScore = baseScore × reachabilityFactor (0..1) × trustFactor (0..1) × (1 + entropyBoost) entropyBoost = clamp(avg(uncertainty[i].entropy) × k, 0 .. 0.5) ``` * `k` defaults to `0.5`. With mean entropy = 0.8, boost = 0.4 → risk increases 40% to highlight unknowns. * If no uncertainty states exist, entropy boost = 0 and the previous scoring remains. Persist both `uncertainty.states` and `riskScore` so policies, dashboards, and APIs stay deterministic. --- ## 4. Policy + actions Use uncertainty in Concelier/Excitors policies: * **Block release** if critical CVE has `U1` with entropy ≥ 0.70 until symbols or runtime probes are provided. * **Warn** when only `U3` exists – allow deployment but require corroboration (OSV/GHSA, CSAF). * **Auto-create tasks** for `U2` to fix SBOM/purl data quality. Recommended policy predicates: ```yaml when: all: - uncertaintyCodesAny: ["U1"] - maxEntropyGte: 0.7 ``` Excitors can suggest remediation actions (upload PDBs, add lockfiles, fetch signed CSAF) based on state codes. --- ## 5. UI guidelines * Display chips `U1`, `U2`, … on each finding. Tooltip: entropy level + evidence bullets (“AnalyzerProbe/dotnet.symbolizer: …”). * Provide “How to reduce entropy” hints: symbol uploads, EventPipe probes, purl overrides, advisory verification. * Show entropy in filters (e.g., “entropy ≥ 0.5”) so teams can prioritise closing uncertainty gaps. See `components/UncertaintyChipStack` (planned) for a reference implementation. --- ## 6. Event sourcing / audit Emit `FindingUncertaintyUpdated` events whenever the set changes: ```json { "type": "FindingUncertaintyUpdated", "findingId": "finding:service:prod:CVE-2023-12345", "updatedAt": "2025-11-12T14:21:33Z", "uncertainty": [ ...states... ] } ``` Projections recompute `riskScore` deterministically, and the event log provides an audit trail showing when/why entropy changed. --- ## 7. Action hints (per state) | Code | Suggested remediation | |------|-----------------------| | `U1` | Upload PDBs/dSYM files, enable symbolizer connectors, attach runtime probes (EventPipe/JFR). | | `U2` | Provide package overrides, ingest lockfiles, fix SBOM generator metadata. | | `U3` | Obtain signed CSAF/OSV evidence, verify via Excitors connectors, or mark trust overrides in policy. | Keep this file updated as new states (U4+) or tooling hooks land. Link additional guides (symbol upload, purl overrides) once available.