DET-001/002/003: Add IGuidProvider abstraction and refactor Policy.Unknowns for determinism

- Created IGuidProvider interface and SystemGuidProvider in StellaOps.Determinism.Abstractions
- Added SequentialGuidProvider for testing deterministic GUID generation
- Added DeterminismServiceCollectionExtensions with AddDeterminismDefaults()
- Refactored Policy.Unknowns:
  - UnknownsRepository now uses TimeProvider and IGuidProvider
  - BudgetExceededEventFactory accepts optional TimeProvider parameter
  - ServiceCollectionExtensions calls AddDeterminismDefaults()
- Fixed Policy.Exceptions csproj (added ImplicitUsings, Nullable, PackageReferences)

Sprint: SPRINT_20260104_001_BE_determinism_timeprovider_injection
Tasks: DET-001 (audit), DET-002 (IGuidProvider), DET-003 (registration pattern), DET-004 (partial - Policy.Unknowns)
This commit is contained in:
StellaOps Bot
2026-01-04 12:37:12 +02:00
parent 3130cdb702
commit cb898a4ac8
9 changed files with 151 additions and 14 deletions

View File

@@ -29,9 +29,15 @@ public static class BudgetExceededEventFactory
/// <summary>
/// Creates a budget exceeded notification event payload.
/// </summary>
/// <param name="environment">The environment name.</param>
/// <param name="result">The budget check result.</param>
/// <param name="timeProvider">Time provider for timestamp. Uses system time if null.</param>
/// <param name="imageDigest">Optional image digest.</param>
/// <param name="policyRevisionId">Optional policy revision ID.</param>
public static BudgetEventPayload CreatePayload(
string environment,
BudgetCheckResult result,
TimeProvider? timeProvider = null,
string? imageDigest = null,
string? policyRevisionId = null)
{
@@ -57,7 +63,7 @@ public static class BudgetExceededEventFactory
Message = result.Message,
ImageDigest = imageDigest,
PolicyRevisionId = policyRevisionId,
Timestamp = DateTimeOffset.UtcNow
Timestamp = (timeProvider ?? TimeProvider.System).GetUtcNow()
};
}
@@ -198,7 +204,7 @@ public sealed record BudgetEventPayload
/// <summary>
/// Event timestamp.
/// </summary>
public DateTimeOffset Timestamp { get; init; } = DateTimeOffset.UtcNow;
public DateTimeOffset Timestamp { get; init; }
}
/// <summary>