Files
git.stella-ops.org/src/__Libraries/StellaOps.Verdict/AGENTS.md

7.2 KiB

AGENTS.md -- StellaOps.Verdict Module

Overview

The StellaOps.Verdict module provides a unified StellaVerdict artifact that consolidates vulnerability disposition decisions into a single, signed, portable proof. It combines PolicyVerdict, ProofBundle, and KnowledgeSnapshot into a content-addressable artifact with JSON-LD support.

Module Structure

src/__Libraries/StellaOps.Verdict/
+-- Schema/
|   +-- StellaVerdict.cs          # Core verdict schema and supporting types
+-- Contexts/
|   +-- verdict-1.0.jsonld        # JSON-LD context for standards interop
+-- Services/
|   +-- VerdictAssemblyService.cs # Assembles verdicts from components
|   +-- VerdictSigningService.cs  # DSSE signing integration
|   +-- IVerdictAssemblyService.cs
+-- Persistence/
|   +-- PostgresVerdictStore.cs   # PostgreSQL (EF Core) storage implementation
|   +-- IVerdictStore.cs          # Storage interface
|   +-- VerdictRow.cs             # EF Core entity (Fluent API mappings)
|   +-- EfCore/
|   |   +-- Context/
|   |   |   +-- VerdictDbContext.cs                   # Partial DbContext with Fluent API
|   |   |   +-- VerdictDesignTimeDbContextFactory.cs  # For dotnet ef CLI
|   |   +-- CompiledModels/
|   |       +-- VerdictDbContextModel.cs              # Compiled model singleton
|   |       +-- VerdictDbContextModelBuilder.cs       # Compiled model builder
|   |       +-- VerdictDbContextAssemblyAttributes.cs # Excluded from compilation
|   +-- Postgres/
|   |   +-- VerdictDataSource.cs       # DataSourceBase derivation, connection pool
|   |   +-- VerdictDbContextFactory.cs # Runtime factory with compiled model hookup
|   +-- Migrations/
|       +-- 001_create_verdicts.sql
+-- Api/
|   +-- VerdictEndpoints.cs       # REST API endpoints
|   +-- VerdictContracts.cs       # Request/response DTOs
|   +-- VerdictPolicies.cs        # Authorization policies
+-- Oci/
|   +-- OciAttestationPublisher.cs # OCI registry attestation
+-- Export/
|   +-- VerdictBundleExporter.cs  # Replay bundle export
+-- StellaOps.Verdict.csproj

DAL Architecture (EF Core v10)

The Verdict persistence layer follows the EF Core v10 standards documented in docs/db/EF_CORE_MODEL_GENERATION_STANDARDS.md:

  • DbContext: VerdictDbContext (partial class, schema-injectable, Fluent API mappings)
  • Schema: stellaops (shared platform schema)
  • Design-time factory: VerdictDesignTimeDbContextFactory (for dotnet ef CLI)
  • Runtime factory: VerdictDbContextFactory (compiled model for default schema, reflection for non-default)
  • DataSource: VerdictDataSource extends DataSourceBase for connection pooling and tenant context
  • Compiled model: Stub in EfCore/CompiledModels/; assembly attributes excluded from compilation
  • Migration registry: Registered as VerdictMigrationModulePlugin in Platform.Database

Connection Pattern

await using var connection = await _dataSource.OpenConnectionAsync(tenantId.ToString(), "reader", ct);
await using var context = VerdictDbContextFactory.Create(connection, CommandTimeoutSeconds, GetSchemaName());
// Use context.Verdicts with AsNoTracking() for reads...

Schema Governance

  • SQL migrations in Persistence/Migrations/ are the authoritative schema definition
  • EF Core models are derived from schema, not the reverse
  • No EF Core auto-migrations at runtime
  • Schema changes require new SQL migration files

Key Concepts

StellaVerdict Schema

The core StellaVerdict record contains:

  • VerdictId: Content-addressable ID (urn:stella:verdict:sha256:...)
  • Subject: Vulnerability ID + Component PURL
  • Claim: Status, confidence, reason
  • Inputs: Advisory sources, VEX, CVSS, EPSS, KEV, reachability
  • EvidenceGraph: Proof nodes and edges from ProofBundle
  • PolicyPath: Rule evaluation trace
  • Result: Disposition, score, expiration
  • Provenance: Generator, run ID, timestamp
  • Signatures: DSSE signatures

Verdict Status Values

  • Pass: Component passed all policy checks
  • Blocked: Component blocked by policy
  • Ignored: Finding ignored per policy
  • Warned: Warning issued but not blocking
  • Deferred: Decision deferred for manual review
  • Escalated: Escalated for security team
  • RequiresVex: Needs VEX statement to resolve

Usage Patterns

Assembling a Verdict

var context = new VerdictAssemblyContext
{
    VulnerabilityId = "CVE-2024-1234",
    Purl = "pkg:npm/lodash@4.17.15",
    PolicyVerdict = policyResult,
    Knowledge = knowledgeInputs,
    Generator = "StellaOps Scanner",
    RunId = scanId
};

var verdict = assemblyService.AssembleVerdict(context);

Storing and Querying

await store.StoreAsync(verdict, tenantId, cancellationToken);

var query = new VerdictQuery { Purl = "pkg:npm/lodash@*", Status = VerdictStatus.Blocked };
var results = await store.QueryAsync(query, cancellationToken);

CLI Verification

# Verify by ID (fetches from API)
stella verify verdict --verdict urn:stella:verdict:sha256:abc123

# Verify from file with replay bundle
stella verify verdict --verdict ./verdict.json --replay ./bundle/

# Show full policy trace
stella verify verdict --verdict ./verdict.json --show-trace

OCI Attestation

var result = await publisher.PublishAsync(verdict, "registry.io/app:latest@sha256:...");

API Endpoints

Endpoint Method Description
/v1/verdicts POST Create and store verdict
/v1/verdicts/{id} GET Get verdict by ID
/v1/verdicts GET Query verdicts (purl, cve, status)
/v1/verdicts/{id}/verify POST Verify signature and content ID
/v1/verdicts/{id}/download GET Download as JSON-LD
/v1/verdicts/latest GET Get latest for purl+cve
/v1/verdicts/expired DELETE Clean up expired verdicts

Dependencies

  • StellaOps.Policy: PolicyVerdict, PolicyExplanation
  • StellaOps.Attestor.Envelope: DSSE signing
  • StellaOps.Cryptography: BLAKE3/SHA256 hashing
  • StellaOps.Replay.Core: Bundle structures
  • StellaOps.Infrastructure.Postgres: DataSourceBase, PostgresOptions, connection pooling

Testing

Unit tests should cover:

  • Schema serialization determinism (sorted keys)
  • Content-addressable ID computation
  • Assembly from various input combinations
  • Signature verification
  • Query filtering and pagination

Integration tests should cover:

  • Full assembly -> sign -> store -> query -> verify flow
  • OCI publish/fetch cycle
  • Replay bundle export and verification

Coding Guidelines

  1. Determinism: All JSON output must be deterministic (sorted keys, stable ordering)
  2. Content Addressing: VerdictId must match ComputeVerdictId() output
  3. Immutability: Use records with init properties
  4. Tenant Isolation: All store operations must include tenantId; RLS enforced at DB level
  5. Offline Support: OCI publisher and CLI must handle offline mode
  6. EF Core Standards: Follow docs/db/EF_CORE_MODEL_GENERATION_STANDARDS.md
  7. AsNoTracking: Always use for read-only queries
  8. DbContext per operation: Create via VerdictDbContextFactory, not cached
  • SPRINT_1227_0014_0001: StellaVerdict Unified Artifact Consolidation
  • SPRINT_1227_0014_0002: Verdict UI Components (pending)
  • SPRINT_20260222_080: Verdict Persistence DAL to EF Core (queue order 16)