# Exception Recheck Policy System ## Module Policy ## Status IMPLEMENTED ## Description Auto-invalidation policies for exceptions with 9 condition types (EPSS threshold, CVSS threshold, reachability graph change, unknowns budget, new CVE in package, KEV flagging, expiry proximity, VEX status change, package version change). Actions: Warn, RequireReapproval, Revoke, Block. Environment-scoped conditions with per-condition action overrides. ## Implementation Details - **RecheckPolicy**: `src/Policy/__Libraries/StellaOps.Policy.Exceptions/Models/RecheckPolicy.cs` (sealed record) - PolicyId, Name, Conditions (`ImmutableArray`), DefaultAction, IsActive, CreatedAt - **RecheckCondition**: same file (sealed record) - Type (`RecheckConditionType`), Threshold (decimal?), EnvironmentScope (`ImmutableArray`), Action (per-condition override, nullable), Description - **RecheckConditionType enum** (9 types): - `ReachGraphChange` -- reachability graph changes (new paths discovered) - `EPSSAbove` -- EPSS score exceeds threshold - `CVSSAbove` -- CVSS score exceeds threshold - `UnknownsAbove` -- unknown budget exceeds threshold - `NewCVEInPackage` -- new CVE added to same package - `KEVFlagged` -- KEV flag set - `ExpiryWithin` -- exception nearing expiry (days before) - `VEXStatusChange` -- VEX status changes - `PackageVersionChange` -- package version changes - **RecheckAction enum**: Warn (priority 1), RequireReapproval (priority 2), Revoke (priority 3), Block (priority 4) - **RecheckEvaluationService**: `src/Policy/__Libraries/StellaOps.Policy.Exceptions/Services/RecheckEvaluationService.cs` (sealed class implements `IRecheckEvaluationService`) - `EvaluateAsync(exception, context)` iterates conditions, checks environment scope, evaluates each condition type - Returns `RecheckEvaluationResult` with IsTriggered, TriggeredConditions, RecommendedAction (highest priority among triggered) - Environment scoping: condition applies only if EnvironmentScope is empty or contains the evaluation environment - Per-condition action override: uses condition.Action if set, otherwise falls back to policy DefaultAction - Action priority ordering: Block (4) > Revoke (3) > RequireReapproval (2) > Warn (1) - **RecheckEvaluationResult**: sealed record with IsTriggered, TriggeredConditions (`ImmutableArray`), RecommendedAction, EvaluatedAt, Summary - **TriggeredCondition**: record with Type, Description, CurrentValue, ThresholdValue, Action - **ExceptionObject integration**: `src/Policy/__Libraries/StellaOps.Policy.Exceptions/Models/ExceptionObject.cs` - `RecheckPolicy?` property on ExceptionObject - `LastRecheckResult?` and `LastRecheckAt?` for tracking last evaluation - `IsBlockedByRecheck` computed property (triggered + Block action) - `RequiresReapproval` computed property (triggered + RequireReapproval action) ## E2E Test Plan - [ ] Configure RecheckPolicy with EPSSAbove=0.80 (Block); provide context with EpssScore=0.85; verify IsTriggered=true, RecommendedAction=Block, TriggeredConditions contains EPSSAbove with CurrentValue=0.85 and ThresholdValue=0.80 - [ ] Configure RecheckPolicy with CVSSAbove=9.0 (Warn); provide context with CvssScore=8.5; verify IsTriggered=false - [ ] Configure RecheckPolicy with KEVFlagged (Revoke); provide context with KevFlagged=true; verify IsTriggered=true, RecommendedAction=Revoke - [ ] Configure RecheckPolicy with ExpiryWithin=7 days (Warn); exception expires in 5 days; verify triggered with CurrentValue~5 and ThresholdValue=7 - [ ] Configure RecheckPolicy with 2 conditions: EPSSAbove=0.50 (Warn) and KEVFlagged (Block); trigger both; verify RecommendedAction=Block (highest priority) - [ ] Configure condition with EnvironmentScope=["prod"]; evaluate in "staging"; verify condition is NOT triggered - [ ] Configure condition with EnvironmentScope=["prod"]; evaluate in "prod"; verify condition IS triggered - [ ] Configure condition with per-condition Action=RequireReapproval overriding policy DefaultAction=Warn; verify triggered condition uses RequireReapproval - [ ] Configure RecheckPolicy with ReachGraphChange condition; provide context with ReachGraphChanged=true; verify triggered - [ ] Configure all 9 condition types; trigger each one individually; verify each produces correct TriggeredCondition type