From ef6ce108aae80d53f72009e1a326642e75d23be1 Mon Sep 17 00:00:00 2001 From: StellaOps Bot Date: Sun, 4 Jan 2026 12:41:14 +0200 Subject: [PATCH] DET-004: Refactor more Policy Gates for determinism - BudgetConstraintEnforcer: inject TimeProvider - EvidenceFreshnessGate: inject TimeProvider Replace DateTimeOffset.UtcNow with _timeProvider.GetUtcNow() Sprint: SPRINT_20260104_001_BE_determinism_timeprovider_injection --- .../StellaOps.Policy/Gates/BudgetConstraintEnforcer.cs | 5 ++++- .../StellaOps.Policy/Gates/EvidenceFreshnessGate.cs | 7 +++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/src/Policy/__Libraries/StellaOps.Policy/Gates/BudgetConstraintEnforcer.cs b/src/Policy/__Libraries/StellaOps.Policy/Gates/BudgetConstraintEnforcer.cs index 85dad239b..350a92726 100644 --- a/src/Policy/__Libraries/StellaOps.Policy/Gates/BudgetConstraintEnforcer.cs +++ b/src/Policy/__Libraries/StellaOps.Policy/Gates/BudgetConstraintEnforcer.cs @@ -11,14 +11,17 @@ public sealed class BudgetConstraintEnforcer : IBudgetConstraintEnforcer private readonly IBudgetLedger _ledger; private readonly IGateSelector _gateSelector; private readonly ILogger _logger; + private readonly TimeProvider _timeProvider; public BudgetConstraintEnforcer( IBudgetLedger ledger, IGateSelector gateSelector, + TimeProvider? timeProvider = null, ILogger? logger = null) { _ledger = ledger ?? throw new ArgumentNullException(nameof(ledger)); _gateSelector = gateSelector ?? throw new ArgumentNullException(nameof(gateSelector)); + _timeProvider = timeProvider ?? TimeProvider.System; _logger = logger ?? NullLogger.Instance; } @@ -134,7 +137,7 @@ public sealed class BudgetConstraintEnforcer : IBudgetConstraintEnforcer TotalRiskPoints = penaltyRiskPoints, Budget = consumeResult.Budget, FollowUpRequired = true, - FollowUpDeadline = DateTimeOffset.UtcNow.AddDays(5) + FollowUpDeadline = _timeProvider.GetUtcNow().AddDays(5) }; } diff --git a/src/Policy/__Libraries/StellaOps.Policy/Gates/EvidenceFreshnessGate.cs b/src/Policy/__Libraries/StellaOps.Policy/Gates/EvidenceFreshnessGate.cs index dbe3db1a7..8d66dceef 100644 --- a/src/Policy/__Libraries/StellaOps.Policy/Gates/EvidenceFreshnessGate.cs +++ b/src/Policy/__Libraries/StellaOps.Policy/Gates/EvidenceFreshnessGate.cs @@ -13,13 +13,16 @@ public sealed class EvidenceFreshnessGate : IPolicyGate { private readonly IEvidenceTtlEnforcer _ttlEnforcer; private readonly ILogger _logger; + private readonly TimeProvider _timeProvider; public EvidenceFreshnessGate( IEvidenceTtlEnforcer ttlEnforcer, - ILogger logger) + ILogger logger, + TimeProvider? timeProvider = null) { _ttlEnforcer = ttlEnforcer; _logger = logger; + _timeProvider = timeProvider ?? TimeProvider.System; } public Task EvaluateAsync( @@ -30,7 +33,7 @@ public sealed class EvidenceFreshnessGate : IPolicyGate // Build evidence bundle from context var evidenceBundle = BuildEvidenceBundleFromContext(context); - var freshnessResult = _ttlEnforcer.CheckFreshness(evidenceBundle, DateTimeOffset.UtcNow); + var freshnessResult = _ttlEnforcer.CheckFreshness(evidenceBundle, _timeProvider.GetUtcNow()); var details = ImmutableDictionary.CreateBuilder(); details.Add("overall_status", freshnessResult.OverallStatus.ToString());