save progress
This commit is contained in:
@@ -0,0 +1,171 @@
|
||||
# StellaOps.Policy.Determinization - Agent Guide
|
||||
|
||||
## Module Overview
|
||||
|
||||
The **Determinization** library handles CVEs that arrive without complete evidence (EPSS, VEX, reachability). It treats unknown observations as probabilistic with entropy-weighted trust that matures as evidence arrives.
|
||||
|
||||
**Key Concepts:**
|
||||
- `ObservationState`: Lifecycle state for CVE observations (PendingDeterminization, Determined, Disputed, etc.)
|
||||
- `SignalState<T>`: Null-aware wrapper distinguishing "not queried" from "queried but absent"
|
||||
- `UncertaintyScore`: Knowledge completeness measurement (high entropy = missing signals)
|
||||
- `ObservationDecay`: Time-based confidence decay with configurable half-life
|
||||
- `GuardRails`: Monitoring requirements when allowing uncertain observations
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```
|
||||
src/Policy/__Libraries/StellaOps.Policy.Determinization/
|
||||
├── Models/ # Core data models
|
||||
│ ├── ObservationState.cs
|
||||
│ ├── SignalState.cs
|
||||
│ ├── SignalSnapshot.cs
|
||||
│ ├── UncertaintyScore.cs
|
||||
│ ├── ObservationDecay.cs
|
||||
│ ├── GuardRails.cs
|
||||
│ └── DeterminizationContext.cs
|
||||
├── Evidence/ # Signal evidence types
|
||||
│ ├── EpssEvidence.cs
|
||||
│ ├── VexClaimSummary.cs
|
||||
│ ├── ReachabilityEvidence.cs
|
||||
│ └── ...
|
||||
├── Scoring/ # Calculation services
|
||||
│ ├── UncertaintyScoreCalculator.cs
|
||||
│ ├── DecayedConfidenceCalculator.cs
|
||||
│ ├── TrustScoreAggregator.cs
|
||||
│ └── SignalWeights.cs
|
||||
├── Policies/ # Policy rules (in Policy.Engine)
|
||||
└── DeterminizationOptions.cs
|
||||
```
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### 1. SignalState<T> Usage
|
||||
|
||||
Always use `SignalState<T>` to wrap signal values:
|
||||
|
||||
```csharp
|
||||
// Good - explicit status
|
||||
var epss = SignalState<EpssEvidence>.WithValue(evidence, queriedAt, "first.org");
|
||||
var vex = SignalState<VexClaimSummary>.Absent(queriedAt, "vendor");
|
||||
var reach = SignalState<ReachabilityEvidence>.NotQueried();
|
||||
var failed = SignalState<CvssEvidence>.Failed("Timeout");
|
||||
|
||||
// Bad - nullable without status
|
||||
EpssEvidence? epss = null; // Can't tell if not queried or absent
|
||||
```
|
||||
|
||||
### 2. Uncertainty Calculation
|
||||
|
||||
Entropy = 1 - (weighted present signals / max weight):
|
||||
|
||||
```csharp
|
||||
// All signals present = 0.0 entropy (fully certain)
|
||||
// No signals present = 1.0 entropy (fully uncertain)
|
||||
// Formula uses configurable weights per signal type
|
||||
```
|
||||
|
||||
### 3. Decay Calculation
|
||||
|
||||
Exponential decay with floor:
|
||||
|
||||
```csharp
|
||||
decayed = max(floor, exp(-ln(2) * age_days / half_life_days))
|
||||
|
||||
// Default: 14-day half-life, 0.35 floor
|
||||
// After 14 days: ~50% confidence
|
||||
// After 28 days: ~35% confidence (floor)
|
||||
```
|
||||
|
||||
### 4. Policy Rules
|
||||
|
||||
Rules evaluate in priority order (lower = first):
|
||||
|
||||
| Priority | Rule | Outcome |
|
||||
|----------|------|---------|
|
||||
| 10 | Runtime shows loaded | Escalated |
|
||||
| 20 | EPSS >= threshold | Blocked |
|
||||
| 25 | Proven reachable | Blocked |
|
||||
| 30 | High entropy in prod | Blocked |
|
||||
| 40 | Evidence stale | Deferred |
|
||||
| 50 | Uncertain + non-prod | GuardedPass |
|
||||
| 60 | Unreachable + confident | Pass |
|
||||
| 70 | Sufficient evidence | Pass |
|
||||
| 100 | Default | Deferred |
|
||||
|
||||
## Testing Guidelines
|
||||
|
||||
### Unit Tests Required
|
||||
|
||||
1. `SignalState<T>` factory methods
|
||||
2. `UncertaintyScoreCalculator` entropy bounds [0.0, 1.0]
|
||||
3. `DecayedConfidenceCalculator` half-life formula
|
||||
4. Policy rule priority ordering
|
||||
5. State transition logic
|
||||
|
||||
### Property Tests
|
||||
|
||||
- Entropy always in [0.0, 1.0]
|
||||
- Decay monotonically decreasing with age
|
||||
- Same snapshot produces same uncertainty
|
||||
|
||||
### Integration Tests
|
||||
|
||||
- DI registration with configuration
|
||||
- Signal snapshot building
|
||||
- Policy gate evaluation
|
||||
|
||||
## Configuration
|
||||
|
||||
```yaml
|
||||
Determinization:
|
||||
EpssQuarantineThreshold: 0.4
|
||||
GuardedAllowScoreThreshold: 0.5
|
||||
GuardedAllowEntropyThreshold: 0.4
|
||||
ProductionBlockEntropyThreshold: 0.3
|
||||
DecayHalfLifeDays: 14
|
||||
DecayFloor: 0.35
|
||||
GuardedReviewIntervalDays: 7
|
||||
MaxGuardedDurationDays: 30
|
||||
SignalWeights:
|
||||
Vex: 0.25
|
||||
Epss: 0.15
|
||||
Reachability: 0.25
|
||||
Runtime: 0.15
|
||||
Backport: 0.10
|
||||
SbomLineage: 0.10
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
1. **Don't confuse EntropySignal with UncertaintyScore**: `EntropySignal` measures code complexity; `UncertaintyScore` measures knowledge completeness.
|
||||
|
||||
2. **Always inject TimeProvider**: Never use `DateTime.UtcNow` directly for decay calculations.
|
||||
|
||||
3. **Normalize weights before calculation**: Call `SignalWeights.Normalize()` to ensure weights sum to 1.0.
|
||||
|
||||
4. **Check signal status before accessing value**: `signal.HasValue` must be true before using `signal.Value!`.
|
||||
|
||||
5. **Handle all ObservationStates**: Switch expressions must be exhaustive.
|
||||
|
||||
## Dependencies
|
||||
|
||||
- `StellaOps.Policy` (PolicyVerdictStatus, existing confidence models)
|
||||
- `System.Collections.Immutable` (ImmutableArray for collections)
|
||||
- `Microsoft.Extensions.Options` (configuration)
|
||||
- `Microsoft.Extensions.Logging` (logging)
|
||||
|
||||
## Related Modules
|
||||
|
||||
- **Policy.Engine**: DeterminizationGate integrates with policy pipeline
|
||||
- **Feedser**: Signal attachers emit SignalState<T>
|
||||
- **VexLens**: VEX updates emit SignalUpdatedEvent
|
||||
- **Graph**: CVE nodes carry ObservationState and UncertaintyScore
|
||||
- **Findings**: Observation persistence and audit trail
|
||||
|
||||
## Sprint References
|
||||
|
||||
- SPRINT_20260106_001_001_LB: Core models
|
||||
- SPRINT_20260106_001_002_LB: Scoring services
|
||||
- SPRINT_20260106_001_003_POLICY: Policy integration
|
||||
- SPRINT_20260106_001_004_BE: Backend integration
|
||||
- SPRINT_20260106_001_005_FE: Frontend UI
|
||||
Reference in New Issue
Block a user