Files
git.stella-ops.org/docs/implplan/archived/VERDICT-8200-001_DeltaVerdict_Audit.md
StellaOps Bot 2a06f780cf sprints work
2025-12-25 12:19:12 +02:00

5.5 KiB

VERDICT-8200-001: DeltaVerdict Instantiation Audit

Date: 2025-01-12
Auditor: Implementer Agent
Status: Complete

Summary

This audit documents all locations in the codebase where DeltaVerdict records are instantiated, identifying which use random GUIDs and require migration to content-addressed IDs.


Key Findings

Two Distinct DeltaVerdict Models Exist

Model Namespace Purpose Has GUID Issue
DeltaVerdict StellaOps.Policy.Deltas Policy gate verdict (pass/fail/warn) YES - Line 211
DeltaVerdict StellaOps.DeltaVerdict.Models Diff computation result NO - Uses content-addressed DeltaId

Impact Assessment

  1. StellaOps.Policy.Deltas.DeltaVerdict - Uses Guid.NewGuid() in builder (CRITICAL)
  2. StellaOps.DeltaVerdict.Models.DeltaVerdict - Already uses content-addressed DeltaId (OK)

Detailed Audit

1. StellaOps.Policy.Deltas.DeltaVerdict (NEEDS FIX)

File: src/Policy/__Libraries/StellaOps.Policy/Deltas/DeltaVerdict.cs

// Line 211 in DeltaVerdictBuilder.Build()
return new DeltaVerdict
{
    VerdictId = $"dv:{Guid.NewGuid():N}",  // ❌ PROBLEM: Non-deterministic
    DeltaId = deltaId,
    EvaluatedAt = DateTimeOffset.UtcNow,
    // ...
};

Required Fix: Replace with:

VerdictId = VerdictIdGenerator.ComputeVerdictId(
    deltaId,
    _blockingDrivers,
    _warningDrivers,
    _exceptions,
    _gate);

2. StellaOps.DeltaVerdict.Models.DeltaVerdict (OK)

File: src/__Libraries/StellaOps.DeltaVerdict/Engine/DeltaComputationEngine.cs

// Line 60 - Uses content-addressed DeltaId
return new DeltaVerdict.Models.DeltaVerdict
{
    DeltaId = ComputeDeltaId(baseVerdict, headVerdict),  // ✅ Already content-addressed
    // ...
};

Assessment: This model computes a deterministic DeltaId from base/head verdicts. No change needed.


Test Files Using DeltaVerdict

These files create test instances and may need updates to match new VerdictId format:

File Line(s) Instance Type Notes
StellaOps.DeltaVerdict.Tests/DeltaVerdictTests.cs 58, 91 Models.DeltaVerdict OK - Uses DeltaId
StellaOps.Scanner.SmartDiff.Tests/DeltaVerdictBuilderTests.cs 49-61 Test fixtures Uses DeltaVerdictBuilder
StellaOps.Scanner.SmartDiff.Tests/Integration/DeltaVerdictAttestationTests.cs Multiple Test fixtures Uses DeltaVerdictBuilder
StellaOps.Scanner.SmartDiff.Tests/Snapshots/DeltaVerdictSnapshotTests.cs 50, 66 Snapshot tests May need baseline updates
StellaOps.Policy.Engine.Tests/Attestation/VerdictAttestationIntegrationTests.cs 54 Test setup Uses Guid.NewGuid() for test ID
StellaOps.Integration.Determinism/VerdictArtifactDeterminismTests.cs 143-425 Determinism tests Uses fixed GUIDs for reproducibility

Files Requiring Modification

Primary (Production Code)

  1. src/Policy/__Libraries/StellaOps.Policy/Deltas/DeltaVerdict.cs

    • Remove Guid.NewGuid() from DeltaVerdictBuilder.Build()
    • Accept computed VerdictId as parameter or compute internally
  2. NEW: src/Policy/__Libraries/StellaOps.Policy/Deltas/VerdictIdGenerator.cs

    • Create new helper class for content-addressed VerdictId computation

Secondary (Tests - may need updates)

  1. tests/integration/StellaOps.Integration.Determinism/VerdictArtifactDeterminismTests.cs

    • Verify determinism tests pass with new VerdictId format
    • Fixed GUIDs currently used may need to become fixed content-addressed IDs
  2. src/Policy/__Tests/StellaOps.Policy.Engine.Tests/Attestation/VerdictAttestationIntegrationTests.cs

    • Update test verdictId generation

VerdictId Computation Formula

Based on ContentAddressedIdGenerator pattern and sprint specification:

VerdictId = "verdict:" + SHA256(CanonicalJson(
    DeltaId,
    Sort(BlockingDrivers by FindingKey),
    Sort(WarningDrivers by FindingKey),
    Sort(AppliedExceptions),
    GateLevel
))

Prefix: verdict: (not dv:) Hash: SHA-256, lowercase hex Canonicalization: JCS (RFC 8785) with stella:canon:v1 version marker


Existing Content-Addressed ID Patterns

The codebase already has established patterns in ContentAddressedIdGenerator:

Method Input Output Prefix
ComputeEvidenceId EvidencePredicate evidence:sha256:
ComputeReasoningId ReasoningPredicate reasoning:sha256:
ComputeVexVerdictId VexPredicate vex:sha256:
ComputeProofBundleId Merkle tree of IDs proof:sha256:
ComputeGraphRevisionId Nodes + edges + digests graph:sha256:

Recommended: Follow same pattern with verdict:sha256:<hex>


Recommendations

  1. Create VerdictIdGenerator in StellaOps.Policy.Deltas namespace
  2. Keep logic local to Policy module (no cross-module dependency needed)
  3. Use existing canonicalizer via DI for consistency
  4. Add ComputeVerdictId to IContentAddressedIdGenerator interface for discoverability (optional)
  5. Prefix with verdict:sha256: to match established patterns

Next Tasks

  • VERDICT-8200-001: Audit complete (this document)
  • VERDICT-8200-002: Review ContentAddressedIdGenerator API
  • VERDICT-8200-003: Implement VerdictIdGenerator
  • VERDICT-8200-004: Update DeltaVerdict record
  • VERDICT-8200-005-006: Update all verdict creation sites
  • VERDICT-8200-007-010: Add tests
  • VERDICT-8200-011-012: Update documentation