up
Some checks failed
Concelier Attestation Tests / attestation-tests (push) Has been cancelled
Policy Simulation / policy-simulate (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Signals CI & Image / signals-ci (push) Has been cancelled
Signals Reachability Scoring & Events / reachability-smoke (push) Has been cancelled
Signals Reachability Scoring & Events / sign-and-upload (push) Has been cancelled
Docs CI / lint-and-preview (push) Has been cancelled
Policy Lint & Smoke / policy-lint (push) Has been cancelled
Scanner Analyzers / Discover Analyzers (push) Has been cancelled
Scanner Analyzers / Build Analyzers (push) Has been cancelled
Scanner Analyzers / Test Language Analyzers (push) Has been cancelled
Scanner Analyzers / Validate Test Fixtures (push) Has been cancelled
Scanner Analyzers / Verify Deterministic Output (push) Has been cancelled

This commit is contained in:
StellaOps Bot
2025-12-13 09:37:15 +02:00
parent e00f6365da
commit 6e45066e37
349 changed files with 17160 additions and 1867 deletions

View File

@@ -0,0 +1,311 @@
# Replay Manifest v2 Acceptance Contract
_Last updated: 2025-12-13. Owner: BE-Base Platform Guild._
This document defines the acceptance criteria and test vectors for replay manifest v2, enabling Task 19 (GAP-REP-004) to proceed with implementation.
---
## 1. Overview
Replay manifest v2 introduces:
- **BLAKE3 graph hashes:** Primary hash algorithm for reachability graphs
- **Sorted CAS entries:** Deterministic ordering of all CAS references
- **hashAlg fields:** Explicit algorithm declarations for forward compatibility
- **code_id coverage:** Coverage metrics for stripped binary handling
---
## 2. Schema Changes (v1 → v2)
### 2.1 Version Field
```json
{
"schemaVersion": "2.0",
...
}
```
### 2.2 Hash Algorithm Declaration
All hash fields now include explicit algorithm:
```json
{
"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:
| Array | Sort 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:
```json
{
"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 Type | CAS Path Pattern | Required |
|---------------|------------------|----------|
| Graph body | `cas://reachability/graphs/{hash}` | Yes |
| Graph DSSE | `cas://reachability/graphs/{hash}.dsse` | Yes |
| Runtime trace | `cas://reachability/runtime/{hash}` | Conditional |
| Edge bundle | `cas://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
```csharp
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
```json
{
"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
```json
{
"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):
```json
{
"reachability": {
"graphs": [
{"casUri": "cas://reachability/graphs/blake3:zzzz...", "kind": "framework"},
{"casUri": "cas://reachability/graphs/blake3:aaaa...", "kind": "static"}
]
}
}
```
Expected output (sorted):
```json
{
"reachability": {
"graphs": [
{"casUri": "cas://reachability/graphs/blake3:aaaa...", "kind": "static"},
{"casUri": "cas://reachability/graphs/blake3:zzzz...", "kind": "framework"}
]
}
}
```
### 4.4 Invalid Manifest Vectors
| Test Case | Input | Expected 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 graphs | See 4.3 input | `REPLAY_MANIFEST_UNSORTED_ENTRIES` |
| Missing CAS reference | `{"casUri": "cas://missing/..."}` | `REPLAY_MANIFEST_CAS_NOT_FOUND` |
| Hash mismatch | CAS content differs | `REPLAY_MANIFEST_HASH_MISMATCH` |
---
## 5. Migration Path
### 5.1 v1 → v2 Upgrade
```csharp
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
- v2 readers MUST accept v1 manifests with warning
- v2 writers MUST always emit v2 format
- v1 writers deprecated after 2026-03-01
---
## 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
- [ ] Update `ReplayManifest` record with v2 fields
- [ ] Add `hashAlg` to all hash-bearing types
- [ ] Implement sorting in `ReachabilityReplayWriter`
- [ ] Add CAS registration validation
- [ ] Create test fixtures
- [ ] Update `DETERMINISTIC_REPLAY.md` section 3
- [ ] Wire into RecordModeService
---
_Last updated: 2025-12-13. See Sprint 0401 GAP-REP-004 for implementation._