sprints completion. new product advisories prepared

This commit is contained in:
master
2026-01-16 16:30:03 +02:00
parent a927d924e3
commit 4ca3ce8fb4
255 changed files with 42434 additions and 1020 deletions

View File

@@ -0,0 +1,137 @@
// -----------------------------------------------------------------------------
// AiCodeGuardOptions.cs
// Sprint: SPRINT_20260112_010_SCANNER_ai_code_guard_core
// Task: SCANNER-AIGUARD-001
// Description: AI Code Guard options with deterministic defaults.
// -----------------------------------------------------------------------------
using System.Collections.Immutable;
namespace StellaOps.Scanner.AiCodeGuard;
/// <summary>
/// Configuration options for AI Code Guard analysis.
/// </summary>
public sealed class AiCodeGuardOptions
{
/// <summary>
/// Configuration section name.
/// </summary>
public const string SectionName = "AiCodeGuard";
/// <summary>
/// Whether AI Code Guard is enabled.
/// </summary>
public bool Enabled { get; set; } = true;
/// <summary>
/// Detection confidence threshold (0.0-1.0).
/// Findings below this threshold are excluded.
/// </summary>
public double ConfidenceThreshold { get; set; } = 0.7;
/// <summary>
/// Enabled detection categories.
/// </summary>
public IReadOnlyList<string> EnabledCategories { get; set; } = new[]
{
"AiGenerated",
"InsecurePattern",
"Hallucination",
"LicenseRisk",
"UntrustedDependency",
"QualityIssue"
};
/// <summary>
/// Severity threshold for blocking (findings at or above this level block).
/// </summary>
public string BlockingSeverity { get; set; } = "High";
/// <summary>
/// Maximum number of hunks to analyze per file.
/// </summary>
public int MaxHunksPerFile { get; set; } = 100;
/// <summary>
/// Maximum total lines to analyze per scan.
/// </summary>
public int MaxTotalLines { get; set; } = 50000;
/// <summary>
/// Path to allowlist corpus for similarity checking.
/// </summary>
public string? AllowlistCorpusPath { get; set; }
/// <summary>
/// Path to denylist corpus for similarity checking.
/// </summary>
public string? DenylistCorpusPath { get; set; }
/// <summary>
/// Similarity threshold for snippet matching (0.0-1.0).
/// </summary>
public double SimilarityThreshold { get; set; } = 0.85;
/// <summary>
/// License hygiene configuration.
/// </summary>
public LicenseHygieneOptions LicenseHygiene { get; set; } = new();
/// <summary>
/// Rule sets to apply (null = all default rules).
/// </summary>
public IReadOnlyList<string>? RuleSets { get; set; }
/// <summary>
/// Scanner version identifier for reproducibility.
/// </summary>
public string ScannerVersion { get; set; } = "1.0.0";
/// <summary>
/// Model version identifier for reproducibility.
/// </summary>
public string ModelVersion { get; set; } = "1.0.0";
}
/// <summary>
/// License hygiene check options.
/// </summary>
public sealed class LicenseHygieneOptions
{
/// <summary>
/// Whether license hygiene checks are enabled.
/// </summary>
public bool Enabled { get; set; } = true;
/// <summary>
/// Allowed license SPDX identifiers.
/// </summary>
public IReadOnlyList<string> AllowedLicenses { get; set; } = new[]
{
"MIT",
"Apache-2.0",
"BSD-2-Clause",
"BSD-3-Clause",
"ISC",
"CC0-1.0",
"Unlicense"
};
/// <summary>
/// Denied license SPDX identifiers (block if detected).
/// </summary>
public IReadOnlyList<string> DeniedLicenses { get; set; } = new[]
{
"GPL-2.0-only",
"GPL-3.0-only",
"AGPL-3.0-only",
"LGPL-2.1-only",
"LGPL-3.0-only"
};
/// <summary>
/// Action when unknown license is detected.
/// </summary>
public string UnknownLicenseAction { get; set; } = "RequireReview";
}

View File

@@ -0,0 +1,214 @@
// -----------------------------------------------------------------------------
// IAiCodeGuardService.cs
// Sprint: SPRINT_20260112_010_SCANNER_ai_code_guard_core
// Task: SCANNER-AIGUARD-002/006
// Description: AI Code Guard service interface for Scanner.
// -----------------------------------------------------------------------------
using System.Collections.Immutable;
namespace StellaOps.Scanner.AiCodeGuard;
/// <summary>
/// Service for AI Code Guard analysis.
/// </summary>
public interface IAiCodeGuardService
{
/// <summary>
/// Analyzes changed hunks for AI-generated code issues.
/// </summary>
/// <param name="request">Analysis request with hunks and options.</param>
/// <param name="cancellationToken">Cancellation token.</param>
/// <returns>Analysis result with findings and verdict.</returns>
Task<AiCodeGuardAnalysisResult> AnalyzeAsync(
AiCodeGuardAnalysisRequest request,
CancellationToken cancellationToken = default);
}
/// <summary>
/// Analysis request for AI Code Guard.
/// </summary>
public sealed record AiCodeGuardAnalysisRequest
{
/// <summary>
/// Repository URI.
/// </summary>
public required string RepositoryUri { get; init; }
/// <summary>
/// Commit SHA being analyzed.
/// </summary>
public required string CommitSha { get; init; }
/// <summary>
/// Branch name (optional).
/// </summary>
public string? Branch { get; init; }
/// <summary>
/// Base commit for diff comparison (optional, for PR analysis).
/// </summary>
public string? BaseCommitSha { get; init; }
/// <summary>
/// Changed hunks to analyze.
/// </summary>
public required IReadOnlyList<CodeHunk> Hunks { get; init; }
/// <summary>
/// Analysis timestamp (input, not wall-clock for determinism).
/// </summary>
public required DateTimeOffset AnalysisTimestamp { get; init; }
/// <summary>
/// Optional options override (uses defaults if null).
/// </summary>
public AiCodeGuardOptions? Options { get; init; }
}
/// <summary>
/// A code hunk to analyze.
/// </summary>
public sealed record CodeHunk
{
/// <summary>
/// File path relative to repository root.
/// </summary>
public required string FilePath { get; init; }
/// <summary>
/// Programming language (detected or specified).
/// </summary>
public required string Language { get; init; }
/// <summary>
/// Start line in the file (1-based).
/// </summary>
public required int StartLine { get; init; }
/// <summary>
/// End line in the file (1-based).
/// </summary>
public required int EndLine { get; init; }
/// <summary>
/// Hunk content (source code).
/// </summary>
public required string Content { get; init; }
/// <summary>
/// Whether this is new code (added) vs existing.
/// </summary>
public required bool IsNew { get; init; }
/// <summary>
/// SHA-256 hash of normalized content for deterministic hunk ID.
/// </summary>
public string? ContentHash { get; init; }
}
/// <summary>
/// AI Code Guard analysis result.
/// </summary>
public sealed record AiCodeGuardAnalysisResult
{
/// <summary>
/// Whether analysis completed successfully.
/// </summary>
public required bool Success { get; init; }
/// <summary>
/// Scanner configuration used.
/// </summary>
public required AiCodeGuardScannerConfigResult ScannerConfig { get; init; }
/// <summary>
/// Files analyzed.
/// </summary>
public required ImmutableList<AiCodeGuardFileResult> Files { get; init; }
/// <summary>
/// Detected findings.
/// </summary>
public required ImmutableList<AiCodeGuardFindingResult> Findings { get; init; }
/// <summary>
/// Overall verdict.
/// </summary>
public required AiCodeGuardVerdictResult Verdict { get; init; }
/// <summary>
/// Total lines analyzed.
/// </summary>
public required long TotalLinesAnalyzed { get; init; }
/// <summary>
/// Error message if Success is false.
/// </summary>
public string? Error { get; init; }
/// <summary>
/// Content digest for the analysis result (SHA-256).
/// </summary>
public string? ContentDigest { get; init; }
}
/// <summary>
/// Scanner configuration in result.
/// </summary>
public sealed record AiCodeGuardScannerConfigResult
{
public required string ScannerVersion { get; init; }
public required string ModelVersion { get; init; }
public required double ConfidenceThreshold { get; init; }
public required ImmutableList<string> EnabledCategories { get; init; }
public ImmutableList<string>? RuleSets { get; init; }
}
/// <summary>
/// File analyzed in result.
/// </summary>
public sealed record AiCodeGuardFileResult
{
public required string Path { get; init; }
public required string Digest { get; init; }
public required int LineCount { get; init; }
public string? Language { get; init; }
}
/// <summary>
/// Finding in result.
/// </summary>
public sealed record AiCodeGuardFindingResult
{
public required string Id { get; init; }
public required string Category { get; init; }
public required string Severity { get; init; }
public required double Confidence { get; init; }
public required string FilePath { get; init; }
public required int StartLine { get; init; }
public required int EndLine { get; init; }
public int? StartColumn { get; init; }
public int? EndColumn { get; init; }
public string? Snippet { get; init; }
public required string Description { get; init; }
public required string RuleId { get; init; }
public string? DetectionMethod { get; init; }
public ImmutableList<string>? Indicators { get; init; }
public double? PerplexityScore { get; init; }
public ImmutableList<string>? PatternMatches { get; init; }
public string? Remediation { get; init; }
}
/// <summary>
/// Verdict in result.
/// </summary>
public sealed record AiCodeGuardVerdictResult
{
public required string Status { get; init; }
public required int TotalFindings { get; init; }
public required ImmutableDictionary<string, int> FindingsBySeverity { get; init; }
public double? AiGeneratedPercentage { get; init; }
public required string Message { get; init; }
public string? Recommendation { get; init; }
}