Replay Manifest v2 Acceptance Contract

Last updated: 2025-12-13. Owner: BE-Base Platform Guild.

Audience: Stella Ops developers implementing replay manifest v2. Scope: The acceptance criteria, schema changes, and frozen test vectors that define what a conformant v2 manifest must satisfy. For the baseline v1 schema and CLI, see the Deterministic Replay Specification; for the export/verify workflow, see the Replay Manifest Guide.


1. Overview

Replay manifest v2 introduces:


2. Schema Changes (v1 → v2)

2.1 Version Field

{
  "schemaVersion": "2.0",
  ...
}

2.2 Hash Algorithm Declaration

All hash fields now include explicit algorithm:

{
  "reachability": {
    "graphs": [
      {
        "hash": "blake3:a1b2c3d4e5f6...",
        "hashAlg": "blake3-256",
        "casUri": "cas://reachability/graphs/blake3:a1b2c3d4..."
      }
    ],
    "runtimeTraces": [
      {
        "hash": "sha256:feedface...",
        "hashAlg": "sha256",
        "casUri": "cas://reachability/runtime/sha256:feedface..."
      }
    ]
  }
}

2.3 Sorted CAS Entries

All arrays must be sorted by deterministic key:

ArraySort Key
reachability.graphs[]casUri (lexicographic)
reachability.runtimeTraces[]casUri (lexicographic)
inputs.feeds[]name (lexicographic)
inputs.tools[]name (lexicographic)

2.4 Code ID Coverage

New field for stripped binary support:

{
  "reachability": {
    "code_id_coverage": {
      "total_nodes": 1247,
      "nodes_with_symbol_id": 1189,
      "nodes_with_code_id": 58,
      "coverage_percent": 100.0
    }
  }
}

3. CAS Registration Gates

3.1 Required Registration

All referenced artifacts must be registered in CAS before manifest finalization:

Artifact TypeCAS Path PatternRequired
Graph bodycas://reachability/graphs/{hash}Yes
Graph DSSEcas://reachability/graphs/{hash}.dsseYes
Runtime tracecas://reachability/runtime/{hash}Conditional
Edge bundlecas://reachability/edges/{graph_hash}/{bundle_id}Conditional

3.2 Registration Validation

Before signing a replay manifest:

  1. Verify all casUri references resolve to existing CAS objects
  2. Verify hash matches CAS content
  3. Verify DSSE envelope exists for all graph references
  4. Fail manifest creation if any reference is missing

3.3 Validation API

public interface ICasValidator
{
    Task<CasValidationResult> ValidateAsync(string casUri, string expectedHash);
    Task<CasValidationResult> ValidateBatchAsync(IEnumerable<CasReference> refs);
}

public record CasValidationResult(
    bool IsValid,
    string? ActualHash,
    string? Error
);

4. Acceptance Test Vectors

4.1 Minimal Valid Manifest v2

{
  "schemaVersion": "2.0",
  "scan": {
    "id": "scan-test-001",
    "time": "2025-12-13T10:00:00Z",
    "mode": "record",
    "scannerVersion": "10.2.0"
  },
  "subject": {
    "ociDigest": "sha256:abc123..."
  },
  "inputs": {
    "feeds": [],
    "tools": []
  },
  "reachability": {
    "graphs": [
      {
        "kind": "static",
        "analyzer": "scanner.java@10.2.0",
        "hash": "blake3:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2",
        "hashAlg": "blake3-256",
        "casUri": "cas://reachability/graphs/blake3:a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6e7f8a9b0c1d2e3f4a5b6c7d8e9f0a1b2"
      }
    ],
    "runtimeTraces": [],
    "code_id_coverage": {
      "total_nodes": 100,
      "nodes_with_symbol_id": 100,
      "nodes_with_code_id": 0,
      "coverage_percent": 100.0
    }
  },
  "outputs": {},
  "provenance": {}
}

Expected canonical hash: sha256:e7f8a9b0... (computed from canonical JSON)

4.2 Manifest with Runtime Traces

{
  "schemaVersion": "2.0",
  "scan": {
    "id": "scan-test-002",
    "time": "2025-12-13T11:00:00Z",
    "mode": "record",
    "scannerVersion": "10.2.0"
  },
  "reachability": {
    "graphs": [
      {
        "kind": "static",
        "analyzer": "scanner.java@10.2.0",
        "hash": "blake3:1111111111111111111111111111111111111111111111111111111111111111",
        "hashAlg": "blake3-256",
        "casUri": "cas://reachability/graphs/blake3:1111111111111111111111111111111111111111111111111111111111111111"
      }
    ],
    "runtimeTraces": [
      {
        "source": "eventpipe",
        "hash": "sha256:2222222222222222222222222222222222222222222222222222222222222222",
        "hashAlg": "sha256",
        "casUri": "cas://reachability/runtime/sha256:2222222222222222222222222222222222222222222222222222222222222222",
        "recordedAt": "2025-12-13T10:30:00Z"
      }
    ]
  }
}

4.3 Sorting Validation Vector

Input (unsorted):

{
  "reachability": {
    "graphs": [
      {"casUri": "cas://reachability/graphs/blake3:zzzz...", "kind": "framework"},
      {"casUri": "cas://reachability/graphs/blake3:aaaa...", "kind": "static"}
    ]
  }
}

Expected output (sorted):

{
  "reachability": {
    "graphs": [
      {"casUri": "cas://reachability/graphs/blake3:aaaa...", "kind": "static"},
      {"casUri": "cas://reachability/graphs/blake3:zzzz...", "kind": "framework"}
    ]
  }
}

4.4 Invalid Manifest Vectors

Test CaseInputExpected Error
Missing schemaVersion{}REPLAY_MANIFEST_MISSING_VERSION
Invalid version{"schemaVersion": "1.0"}REPLAY_MANIFEST_VERSION_MISMATCH (when v2 required)
Missing hashAlg{"hash": "blake3:..."}REPLAY_MANIFEST_MISSING_HASH_ALG
Unsorted graphsSee 4.3 inputREPLAY_MANIFEST_UNSORTED_ENTRIES
Missing CAS reference{"casUri": "cas://missing/..."}REPLAY_MANIFEST_CAS_NOT_FOUND
Hash mismatchCAS content differsREPLAY_MANIFEST_HASH_MISMATCH

5. Migration Path

5.1 v1 → v2 Upgrade

public static ReplayManifest UpgradeToV2(ReplayManifest v1)
{
    return v1 with
    {
        SchemaVersion = "2.0",
        Reachability = v1.Reachability with
        {
            Graphs = v1.Reachability.Graphs
                .Select(g => g with { HashAlg = InferHashAlg(g.Hash) })
                .OrderBy(g => g.CasUri)
                .ToList(),
            RuntimeTraces = v1.Reachability.RuntimeTraces
                .Select(t => t with { HashAlg = InferHashAlg(t.Hash) })
                .OrderBy(t => t.CasUri)
                .ToList()
        }
    };
}

5.2 Backward Compatibility


6. Test Fixture Locations

tests/Replay/
  fixtures/
    manifest-v2-minimal.json
    manifest-v2-with-runtime.json
    manifest-v2-sorted.json
    manifest-v2-code-id-coverage.json
  invalid/
    manifest-missing-version.json
    manifest-unsorted.json
    manifest-missing-hashalg.json
  golden/
    manifest-v2-canonical.golden.json
    manifest-v2-hash.golden.txt

7. Implementation Checklist


See Sprint 0401 / GAP-REP-004 for implementation tracking.