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

187 lines
7.2 KiB
Markdown

# 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
```csharp
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
```csharp
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
```csharp
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
```bash
# 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
```csharp
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
## Related Sprints
- 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)