// ----------------------------------------------------------------------------- // AiCodeGuardSignalContextExtensions.cs // Sprint: SPRINT_20260112_010_POLICY_ai_code_guard_policy // Task: POLICY-AIGUARD-001/005 - AI Code Guard signal context integration // ----------------------------------------------------------------------------- using StellaOps.Policy.AiCodeGuard; namespace StellaOps.PolicyDsl; /// /// Extension methods for integrating AI Code Guard evidence with PolicyDsl SignalContext. /// public static class AiCodeGuardSignalContextExtensions { /// /// Adds AI Code Guard evidence signals to the signal context. /// /// The signal context. /// The AI Code Guard evidence context. /// The signal context for chaining. public static SignalContext WithAiCodeGuardEvidence( this SignalContext context, AiCodeGuardEvidenceContext evidenceContext) { ArgumentNullException.ThrowIfNull(context); ArgumentNullException.ThrowIfNull(evidenceContext); // Add flat signals var signals = AiCodeGuardSignalBinder.BindToSignals(evidenceContext); foreach (var (name, value) in signals) { context.SetSignal(name, value); } // Add nested object for member access (guard.severity.high, etc.) var nested = AiCodeGuardSignalBinder.BindToNestedObject(evidenceContext); context.SetSignal("guard", nested); // Add policy recommendation context.SetSignal("guard.recommendation", AiCodeGuardSignalBinder.GetRecommendation(evidenceContext)); // Add explain trace for deterministic auditing context.SetSignal("guard.explain_trace", AiCodeGuardSignalBinder.CreateExplainTrace(evidenceContext)); return context; } /// /// Adds AI Code Guard evidence signals to the signal context builder. /// /// The signal context builder. /// The AI Code Guard evidence context. /// The builder for chaining. public static SignalContextBuilder WithAiCodeGuardEvidence( this SignalContextBuilder builder, AiCodeGuardEvidenceContext evidenceContext) { ArgumentNullException.ThrowIfNull(builder); ArgumentNullException.ThrowIfNull(evidenceContext); // Add flat signals var signals = AiCodeGuardSignalBinder.BindToSignals(evidenceContext); foreach (var (name, value) in signals) { builder.WithSignal(name, value); } // Add nested object for member access var nested = AiCodeGuardSignalBinder.BindToNestedObject(evidenceContext); builder.WithSignal("guard", nested); // Add policy recommendation builder.WithSignal("guard.recommendation", AiCodeGuardSignalBinder.GetRecommendation(evidenceContext)); // Add explain trace builder.WithSignal("guard.explain_trace", AiCodeGuardSignalBinder.CreateExplainTrace(evidenceContext)); return builder; } /// /// Adds AI Code Guard evidence signals from a provider. /// /// The signal context builder. /// The AI Code Guard evidence provider. /// The builder for chaining. public static SignalContextBuilder WithAiCodeGuardEvidence( this SignalContextBuilder builder, IAiCodeGuardEvidenceProvider provider) { ArgumentNullException.ThrowIfNull(builder); ArgumentNullException.ThrowIfNull(provider); var context = new AiCodeGuardEvidenceContext(provider); return builder.WithAiCodeGuardEvidence(context); } /// /// Creates a signal context builder with AI Code Guard evidence. /// /// The AI Code Guard evidence context. /// A new builder with guard signals. public static SignalContextBuilder CreateBuilderWithGuardEvidence(AiCodeGuardEvidenceContext evidenceContext) { return SignalContext.Builder().WithAiCodeGuardEvidence(evidenceContext); } /// /// Creates a signal context with AI Code Guard evidence. /// /// The AI Code Guard evidence context. /// A new signal context with guard signals. public static SignalContext CreateContextWithGuardEvidence(AiCodeGuardEvidenceContext evidenceContext) { return CreateBuilderWithGuardEvidence(evidenceContext).Build(); } /// /// Adds simplified AI Code Guard result signals for quick checks. /// This is useful when you have analysis results but not a full evidence provider. /// /// The signal context builder. /// The verdict status. /// Total finding count. /// Critical severity count. /// High severity count. /// Medium severity count. /// Optional AI-generated percentage. /// The builder for chaining. public static SignalContextBuilder WithAiCodeGuardResult( this SignalContextBuilder builder, string status, int totalFindings, int criticalCount = 0, int highCount = 0, int mediumCount = 0, double? aiPercentage = null) { ArgumentNullException.ThrowIfNull(builder); builder.WithSignal("guard.verdict", status.ToLowerInvariant()); builder.WithSignal("guard.count", totalFindings); builder.WithSignal("guard.has_finding", totalFindings > 0); builder.WithSignal("guard.severity.critical", criticalCount > 0); builder.WithSignal("guard.severity.critical_count", criticalCount); builder.WithSignal("guard.severity.high", highCount > 0); builder.WithSignal("guard.severity.high_count", highCount); builder.WithSignal("guard.severity.medium", mediumCount > 0); builder.WithSignal("guard.severity.medium_count", mediumCount); builder.WithSignal("guard.ai_percentage", aiPercentage); // Derive recommendation var recommendation = status.ToLowerInvariant() switch { "pass" => "allow", "passwithwarnings" or "pass_with_warnings" => "review", "fail" => "block", "error" => "block", _ => "review" }; builder.WithSignal("guard.recommendation", recommendation); return builder; } }