5.3 KiB
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
{
"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
public sealed record UncertaintyEvidence(string Type, string SourceId, string Detail);
public sealed record UncertaintyState(
string Code,
string Name,
double Entropy,
IReadOnlyList<UncertaintyEvidence> 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)
kdefaults to0.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
U1with entropy ≥ 0.70 until symbols or runtime probes are provided. - Warn when only
U3exists – allow deployment but require corroboration (OSV/GHSA, CSAF). - Auto-create tasks for
U2to fix SBOM/purl data quality.
Recommended policy predicates:
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:
{
"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. |
8. Unknowns registry tie-in
Unresolved identities and missing edges should be recorded as Unknowns (see docs/signals/unknowns-registry.md). Signals scoring may add an unknowns_pressure term when density of unresolved items is high near entrypoints; Policy and UI should surface these records so operators can close the gaps rather than hiding the uncertainty.
Keep this file updated as new states (U4+) or tooling hooks land. Link additional guides (symbol upload, purl overrides) once available.