AI Attestations and Replay Semantics

Audience: operators, auditors, and integrators who need to verify, replay, or audit AI-generated artifacts produced by Stella Ops Advisory AI.

This guide documents the AI attestation schemas, authority classification, deterministic replay semantics, and the API and CLI surfaces used to generate, verify, and replay AI attestations.

Overview

The attestation and replay designs below describe intended provenance properties. The current API boundary later on this page separates ordinary explanation output from signing-dependent run attestation; it does not guarantee a signature or deterministic replay for every generated artifact. The design aims to:

  1. Capture the exact inputs (prompts, context, model parameters)
  2. Prove the generation chain (model ID, weights digest, configuration)
  3. Enable deterministic replay for compliance verification
  4. Support divergence detection across environments

Attestation Types

AI Artifact Predicate

{
  "_type": "https://stellaops.org/attestation/ai-artifact/v1",
  "artifactId": "ai-artifact-20251226-001",
  "artifactType": "explanation",
  "authority": "ai-generated",
  "generatedAt": "2025-12-26T10:30:00Z",
  "model": {
    "modelId": "llama3-8b-q4km",
    "weightsDigest": "sha256:a1b2c3...",
    "promptTemplateVersion": "v2.1.0"
  },
  "inputs": {
    "systemPromptHash": "sha256:abc123...",
    "userPromptHash": "sha256:def456...",
    "contextHashes": ["sha256:111...", "sha256:222..."]
  },
  "parameters": {
    "temperature": 0.0,
    "seed": 42,
    "maxTokens": 2048,
    "topK": 1
  },
  "output": {
    "contentHash": "sha256:789xyz...",
    "tokenCount": 847
  },
  "replayManifest": {
    "manifestId": "replay-20251226-001",
    "manifestHash": "sha256:manifest..."
  }
}

Artifact Types

TypeDescriptionAuthority
explanationVulnerability explanation for humansai-generated
remediationFix plan with upgrade pathsai-generated
vex_draftDraft VEX statementai-draft-requires-review
policy_draftDraft policy rulesai-draft-requires-review
triage_suggestionTriage action suggestionsai-suggestion

Authority Classification

AI outputs are classified by their authority level:

ai-generated           → Informational only, human review optional
ai-draft-requires-review → Draft requires explicit human approval
ai-suggestion          → Suggestion, user decides action
ai-verified            → AI output verified against ground truth
human-approved         → AI output approved by human reviewer

Replay Manifest

The replay manifest captures everything needed to reproduce an AI generation:

{
  "manifestVersion": "1.0",
  "artifactId": "ai-artifact-20251226-001",
  "artifactType": "explanation",

  "model": {
    "modelId": "llama3-8b-q4km",
    "weightsDigest": "sha256:a1b2c3d4e5f6...",
    "promptTemplateVersion": "v2.1.0"
  },

  "prompts": {
    "systemPrompt": "You are a security analyst...",
    "userPrompt": "Explain CVE-2024-1234 affecting lodash@4.17.20...",
    "systemPromptHash": "sha256:abc123...",
    "userPromptHash": "sha256:def456..."
  },

  "context": {
    "contextPack": [...],
    "contextHashes": ["sha256:111...", "sha256:222..."]
  },

  "parameters": {
    "temperature": 0.0,
    "seed": 42,
    "maxTokens": 2048,
    "topK": 1,
    "topP": 1.0
  },

  "output": {
    "content": "CVE-2024-1234 is a critical vulnerability...",
    "contentHash": "sha256:789xyz...",
    "tokenCount": 847
  },

  "metadata": {
    "generatedAt": "2025-12-26T10:30:00Z",
    "replayable": true,
    "deterministicSettings": true
  }
}

Deterministic Requirements

For an AI artifact to be replayable:

  1. Temperature must be 0: No randomness in token selection
  2. Seed must be fixed: Same seed across replays (default: 42)
  3. Model weights must match: Verified by weights digest
  4. Prompts must match: Verified by prompt hashes
  5. Context must match: All input hashes must verify

Configuration for Determinism

advisoryAi:
  attestations:
    requireDeterminism: true
    defaultSeed: 42

  inference:
    local:
      temperature: 0.0
      seed: 42
      topK: 1
      topP: 1.0

Replay Workflow

Replay Execution

// Load replay manifest
var manifest = await LoadManifestAsync("replay-20251226-001.json");

// Create replayer with same model
var replayer = replayerFactory.Create(manifest.Model.ModelId);

// Execute replay
var result = await replayer.ReplayAsync(manifest, cancellationToken);

// Check if output is identical
if (result.Identical)
{
    Console.WriteLine("Replay successful: output matches original");
}
else
{
    Console.WriteLine($"Divergence detected: similarity = {result.SimilarityScore:P2}");
}

Divergence Detection

When replay produces different output:

{
  "diverged": true,
  "similarityScore": 0.97,
  "originalHash": "sha256:789xyz...",
  "replayedHash": "sha256:different...",
  "details": [
    {
      "type": "content_divergence",
      "description": "Content differs at position",
      "position": 1842,
      "originalSnippet": "...vulnerability allows...",
      "replayedSnippet": "...vulnerability permits..."
    }
  ]
}

Common Divergence Causes

CauseDetectionResolution
Different model weightsWeights digest mismatchUse exact model version
Non-zero temperatureParameter checkSet temperature to 0
Different seedParameter checkUse same seed
Prompt template changeTemplate version mismatchPin template version
Context orderingContext hash mismatchSort context deterministically

Attestation Signing

DSSE Envelope Format

AI attestations use DSSE (Dead Simple Signing Envelope):

{
  "payloadType": "application/vnd.stellaops.ai-attestation+json",
  "payload": "<base64-encoded-attestation>",
  "signatures": [
    {
      "keyId": "stellaops-ai-signer-2025",
      "sig": "<base64-signature>"
    }
  ]
}

Signing Configuration

advisoryAi:
  attestations:
    sign: true
    keyId: "stellaops-ai-signer-2025"
    cryptoScheme: ed25519  # ed25519 | ecdsa-p256 | gost3410 | sm2

Current API boundary

PCD-456 source review at ad9edbcef5 (2026-10-08) separates explanation output, run attestation and replay. The composed host uses /api/advisoryai/v1/advisory-ai; retained operations preserve their actual bodies and policy metadata.

Explanation generation

POST /api/advisoryai/v1/advisory-ai/explain uses ExplainRequest, including required finding/artifact/scope/scopeId/vulnerability fields. Its response is ExplainResponse, with content, citations and provenance metadata. The former generateAttestation/signAttestation options and signed-attestation response are not this contract. Operate/admin and the explain-scope check apply.

Verify a recorded AI run attestation

POST /api/advisoryai/v1/advisory-ai/attestations/verify takes a body with runId. It requires operate/admin and a claim tenant matching the stored record. It returns AttestationVerificationResponse: isValid, run/digest/key/error/time and digest/signature validity fields; invalid/missing/foreign records return 400 with invalid result rather than a successful verification. Missing tenant returns 401. It does not accept the former arbitrary attestation/options payload.

Completion and signing remain separate: the run’s /complete operation does not create a signature; /attest requires configured signing custody and fails closed when signing is unavailable. No key, provider or live validity is established here.

Replay boundaries

Explanation replay is GET /api/advisoryai/v1/advisory-ai/explain/{explanationId}/replay and returns a regenerated ExplainResponse, not a manifest comparison. The former POST replay-by-manifest example has no composed owner operation and is unavailable. The schema/CLI replay sketches elsewhere on this page are design material, not proof that those workflow requests are published or bit-for-bit reproducible.

Reverify Program.cs, explanation request/response contracts, RunEndpoints.cs, AttestationEndpoints.cs and the explanation generator under src/AdvisoryAI/. This is source publication; it is not an executed signing/replay/deployment receipt.

CLI Commands

# Generate explanation with attestation
stella advisory explain finding-123 --attest --sign

# Verify attestation
stella attest verify ai-artifact-20251226-001.dsse.json

# Replay from manifest
stella advisory replay --manifest replay-20251226-001.json

# Check divergence
stella advisory replay --manifest replay-20251226-001.json --detect-divergence

Storage and Retrieval

Attestation Storage

Attestations are stored in the Evidence Locker:

/evidence/ai-attestations/
  ├── 2025/12/26/
  │   ├── ai-artifact-20251226-001.json
  │   ├── ai-artifact-20251226-001.dsse.json
  │   └── replay-20251226-001.json

Retrieval

GET /api/v1/attestation/ai-artifact-20251226-001

# Returns attestation + replay manifest

Audit Trail

AI operations are logged for compliance:

{
  "timestamp": "2025-12-26T10:30:00Z",
  "operation": "ai_generation",
  "artifactId": "ai-artifact-20251226-001",
  "artifactType": "explanation",
  "modelId": "llama3-8b-q4km",
  "authority": "ai-generated",
  "user": "system",
  "inputHashes": ["sha256:..."],
  "outputHash": "sha256:...",
  "signed": true,
  "replayable": true
}

Integration with VEX

AI-drafted VEX statements require human approval:

graph LR
    A[AI generates VEX draft] --> B[Authority: ai-draft-requires-review]
    B --> C[Human reviews draft]
    C --> D{Approve?}
    D -->|Yes| E[Authority: human-approved]
    D -->|No| F[Draft rejected]
    E --> G[Publish VEX]

Run Attestation API Reference

The endpoints below operate on run attestations — the per-run record of model, prompt template, turns, and token usage that backs an AI conversation. All requests require a bearer token and the tenant header shown.

Get Run Attestation

GET /v1/advisory-ai/runs/{runId}/attestation
Authorization: Bearer <token>
X-StellaOps-TenantId: <tenant-id>

Response (200 OK):

{
  "runId": "run-abc123",
  "attestation": {
    "runId": "run-abc123",
    "tenantId": "tenant-xyz",
    "userId": "user@example.com",
    "modelInfo": {
      "modelId": "llama3-8b-q4km",
      "modelVersion": "v2.1.0",
      "provider": "inhouse-ternary"
    },
    "promptTemplate": {
      "templateId": "security-explain",
      "version": "1.2.0"
    },
    "turnSummaries": [...],
    "totalTokens": 2140,
    "startTime": "2026-01-10T14:29:55Z",
    "endTime": "2026-01-10T14:30:05Z"
  },
  "envelope": { ... },
  "links": {
    "claims": "/v1/advisory-ai/runs/run-abc123/claims",
    "verify": "/v1/advisory-ai/attestations/verify"
  }
}

List Run Claims

GET /v1/advisory-ai/runs/{runId}/claims
Authorization: Bearer <token>
X-StellaOps-TenantId: <tenant-id>

Response (200 OK):

{
  "runId": "run-abc123",
  "count": 3,
  "claims": [
    {
      "claimId": "claim-789",
      "runId": "run-abc123",
      "turnId": "turn-001",
      "claimType": "vulnerability_assessment",
      "claimText": "CVE-2024-1234 is reachable through /api/users",
      "confidence": 0.85,
      "evidence": [...],
      "timestamp": "2026-01-10T14:30:02Z"
    }
  ]
}

List Recent Attestations

GET /v1/advisory-ai/attestations/recent?limit=20
Authorization: Bearer <token>
X-StellaOps-TenantId: <tenant-id>

Verify Attestation

POST /v1/advisory-ai/attestations/verify
Authorization: Bearer <token>
X-StellaOps-TenantId: <tenant-id>
Content-Type: application/json

{
  "runId": "run-abc123"
}

Response (200 OK):

{
  "isValid": true,
  "runId": "run-abc123",
  "contentDigest": "sha256:abc...",
  "verifiedAt": "2026-01-10T15:00:00Z",
  "signingKeyId": "key-xyz",
  "digestValid": true,
  "signatureValid": true
}

Claim Types

TypeDescription
vulnerability_assessmentAI assessment of vulnerability severity or exploitability
reachability_analysisAI analysis of code reachability
remediation_recommendationAI-suggested fix or mitigation
policy_interpretationAI interpretation of security policy
risk_explanationAI explanation of security risk
prioritizationAI-based vulnerability prioritization

Integration Example

// Inject the attestation service
public class MyService(IAiAttestationService attestationService)
{
    public async Task AttestRunAsync(AiRunAttestation attestation)
    {
        var result = await attestationService.CreateRunAttestationAsync(
            attestation, sign: true);
        
        if (result.Success)
        {
            Console.WriteLine($"Attestation created: {result.ContentDigest}");
        }
    }
    
    public async Task VerifyAsync(string runId)
    {
        var verification = await attestationService.VerifyRunAttestationAsync(runId);
        if (!verification.Valid)
        {
            Console.WriteLine($"Verification failed: {verification.FailureReason}");
        }
    }
}

Last updated: 2026-01-10 (UTC).