feat(audit): Apply TreatWarningsAsErrors=true to 160+ production csproj files

Sprint: SPRINT_20251229_049_BE_csproj_audit_maint_tests
Tasks: AUDIT-0001 through AUDIT-0147 APPLY tasks (approved decisions 1-9)

Changes:
- Set TreatWarningsAsErrors=true for all production .NET projects
- Fixed nullable warnings in Scanner.EntryTrace, Scanner.Evidence,
  Scheduler.Worker, Concelier connectors, and other modules
- Injected TimeProvider/IGuidProvider for deterministic time/ID generation
- Added path traversal validation in AirGap.Bundle
- Fixed NULL handling in various cursor classes
- Third-party GostCryptography retains TreatWarningsAsErrors=false (preserves original)
- Test projects excluded per user decision (rejected decision 10)

Note: All 17 ACSC connector tests pass after snapshot fixture sync
This commit is contained in:
StellaOps Bot
2026-01-04 11:21:16 +02:00
parent bc4dd4f377
commit e411fde1a9
438 changed files with 2648 additions and 668 deletions

View File

@@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Collections.Immutable;
using System.Diagnostics.Metrics;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.Extensions.Logging;
@@ -246,7 +248,7 @@ public sealed class AdvisoryMergeService
foreach (var advisory in inputs)
{
var statementId = Guid.NewGuid();
var statementId = ComputeDeterministicStatementId(vulnerabilityKey, advisory);
statementIds[advisory] = statementId;
var (provenance, trust) = ResolveDsseMetadata(advisory);
statements.Add(new AdvisoryStatementInput(
@@ -260,7 +262,7 @@ public sealed class AdvisoryMergeService
Trust: trust));
}
var canonicalStatementId = Guid.NewGuid();
var canonicalStatementId = ComputeDeterministicStatementId(vulnerabilityKey, merged);
statementIds[merged] = canonicalStatementId;
var (canonicalProvenance, canonicalTrust) = ResolveDsseMetadata(merged);
statements.Add(new AdvisoryStatementInput(
@@ -352,9 +354,9 @@ public sealed class AdvisoryMergeService
var canonicalJson = explainer.ToCanonicalJson();
var document = JsonDocument.Parse(canonicalJson);
var asOf = (detail.Primary.Modified ?? detail.Suppressed.Modified ?? recordedAt).ToUniversalTime();
var conflictId = Guid.NewGuid();
var statementIdArray = ImmutableArray.CreateRange(related);
var conflictHash = explainer.ComputeHashHex(canonicalJson);
var conflictId = ComputeDeterministicConflictId(vulnerabilityKey, conflictHash);
var statementIdArray = ImmutableArray.CreateRange(related);
inputs.Add(new AdvisoryConflictInput(
vulnerabilityKey,
@@ -572,6 +574,21 @@ public sealed class AdvisoryMergeService
return component.SeedAdvisoryKey;
}
private static Guid ComputeDeterministicStatementId(string vulnerabilityKey, Advisory advisory)
{
var canonicalJson = CanonicalJsonSerializer.Serialize(advisory);
var input = $"statement:{vulnerabilityKey}:{advisory.AdvisoryKey}:{canonicalJson}";
var hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(input));
return new Guid(hashBytes[..16]);
}
private static Guid ComputeDeterministicConflictId(string vulnerabilityKey, string conflictHash)
{
var input = $"conflict:{vulnerabilityKey}:{conflictHash}";
var hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(input));
return new Guid(hashBytes[..16]);
}
}
public sealed record AdvisoryMergeResult(

View File

@@ -2,6 +2,7 @@ namespace StellaOps.Concelier.Merge.Services;
using System.Security.Cryptography;
using System.Linq;
using System.Text;
using Microsoft.Extensions.Logging;
using StellaOps.Concelier.Merge.Backport;
using StellaOps.Concelier.Models;
@@ -69,9 +70,10 @@ public sealed class MergeEventWriter
// Convert backport evidence to audit decisions
var evidenceDecisions = ConvertToAuditDecisions(backportEvidence);
var eventId = ComputeDeterministicEventId(advisoryKey, afterHash, timestamp);
var record = new MergeEventRecord(
Guid.NewGuid(),
eventId,
advisoryKey,
beforeHash,
afterHash,
@@ -123,4 +125,11 @@ public sealed class MergeEventWriter
e.ProofId,
e.EvidenceDate)).ToArray();
}
private static Guid ComputeDeterministicEventId(string advisoryKey, byte[] afterHash, DateTimeOffset timestamp)
{
var input = $"merge-event:{advisoryKey}:{Convert.ToHexString(afterHash)}:{timestamp:O}";
var hashBytes = SHA256.HashData(Encoding.UTF8.GetBytes(input));
return new Guid(hashBytes[..16]);
}
}