167 lines
6.8 KiB
C#
167 lines
6.8 KiB
C#
// -----------------------------------------------------------------------------
|
|
// 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;
|
|
|
|
/// <summary>
|
|
/// Extension methods for integrating AI Code Guard evidence with PolicyDsl SignalContext.
|
|
/// </summary>
|
|
public static class AiCodeGuardSignalContextExtensions
|
|
{
|
|
/// <summary>
|
|
/// Adds AI Code Guard evidence signals to the signal context.
|
|
/// </summary>
|
|
/// <param name="context">The signal context.</param>
|
|
/// <param name="evidenceContext">The AI Code Guard evidence context.</param>
|
|
/// <returns>The signal context for chaining.</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds AI Code Guard evidence signals to the signal context builder.
|
|
/// </summary>
|
|
/// <param name="builder">The signal context builder.</param>
|
|
/// <param name="evidenceContext">The AI Code Guard evidence context.</param>
|
|
/// <returns>The builder for chaining.</returns>
|
|
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;
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds AI Code Guard evidence signals from a provider.
|
|
/// </summary>
|
|
/// <param name="builder">The signal context builder.</param>
|
|
/// <param name="provider">The AI Code Guard evidence provider.</param>
|
|
/// <returns>The builder for chaining.</returns>
|
|
public static SignalContextBuilder WithAiCodeGuardEvidence(
|
|
this SignalContextBuilder builder,
|
|
IAiCodeGuardEvidenceProvider provider)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(builder);
|
|
ArgumentNullException.ThrowIfNull(provider);
|
|
|
|
var context = new AiCodeGuardEvidenceContext(provider);
|
|
return builder.WithAiCodeGuardEvidence(context);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a signal context builder with AI Code Guard evidence.
|
|
/// </summary>
|
|
/// <param name="evidenceContext">The AI Code Guard evidence context.</param>
|
|
/// <returns>A new builder with guard signals.</returns>
|
|
public static SignalContextBuilder CreateBuilderWithGuardEvidence(AiCodeGuardEvidenceContext evidenceContext)
|
|
{
|
|
return SignalContext.Builder().WithAiCodeGuardEvidence(evidenceContext);
|
|
}
|
|
|
|
/// <summary>
|
|
/// Creates a signal context with AI Code Guard evidence.
|
|
/// </summary>
|
|
/// <param name="evidenceContext">The AI Code Guard evidence context.</param>
|
|
/// <returns>A new signal context with guard signals.</returns>
|
|
public static SignalContext CreateContextWithGuardEvidence(AiCodeGuardEvidenceContext evidenceContext)
|
|
{
|
|
return CreateBuilderWithGuardEvidence(evidenceContext).Build();
|
|
}
|
|
|
|
/// <summary>
|
|
/// Adds simplified AI Code Guard result signals for quick checks.
|
|
/// This is useful when you have analysis results but not a full evidence provider.
|
|
/// </summary>
|
|
/// <param name="builder">The signal context builder.</param>
|
|
/// <param name="status">The verdict status.</param>
|
|
/// <param name="totalFindings">Total finding count.</param>
|
|
/// <param name="criticalCount">Critical severity count.</param>
|
|
/// <param name="highCount">High severity count.</param>
|
|
/// <param name="mediumCount">Medium severity count.</param>
|
|
/// <param name="aiPercentage">Optional AI-generated percentage.</param>
|
|
/// <returns>The builder for chaining.</returns>
|
|
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;
|
|
}
|
|
}
|