release orchestrator v1 draft and build fixes
This commit is contained in:
361
docs/modules/scanner/design/change-trace-architecture.md
Normal file
361
docs/modules/scanner/design/change-trace-architecture.md
Normal file
@@ -0,0 +1,361 @@
|
||||
# Change-Trace Architecture
|
||||
|
||||
> **Module:** Scanner / ChangeTrace
|
||||
> **Version:** 1.0.0
|
||||
> **Status:** Draft
|
||||
> **Last Updated:** 2026-01-12
|
||||
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The Change-Trace feature provides deterministic comparison of binary artifacts across versions, producing a "trust-delta" view that explains what changed, why (backport, rebuild, upgrade), and what it means for security risk.
|
||||
|
||||
### Strategic Value
|
||||
|
||||
- **Differentiating capability**: Explains backports and security patches that competitors flag as "version mismatch"
|
||||
- **Audit trail**: Produces verifiable evidence for every version change decision
|
||||
- **Reduced review time**: Pre-computed deltas with proof steps eliminate manual investigation
|
||||
- **Compliance support**: Generates attestations suitable for regulatory frameworks
|
||||
|
||||
---
|
||||
|
||||
## Architecture Diagram
|
||||
|
||||
```
|
||||
+------------------+
|
||||
| CLI / API |
|
||||
| (entry points) |
|
||||
+--------+---------+
|
||||
|
|
||||
+-------------+v+-------------+
|
||||
| ChangeTraceBuilder |
|
||||
| (orchestrates comparison) |
|
||||
+---+-----+-----+-----+------+
|
||||
| | | |
|
||||
+------------+ | | +------------+
|
||||
| | | |
|
||||
v v v v
|
||||
+-------+------+ +------+-----+------+ +-------+------+
|
||||
| ScanResult | | BinaryIndex | | VexLens |
|
||||
| Loader | | DeltaSigMatcher | | Consensus |
|
||||
+--------------+ +-------------------+ +--------------+
|
||||
| | |
|
||||
v v v
|
||||
+-------+------+ +------+-----+------+ +------+-------+
|
||||
| PackageDelta | | SymbolDelta | | TrustDelta |
|
||||
| Generator | | + ByteDelta | | Calculator |
|
||||
+--------------+ +-------------------+ +--------------+
|
||||
| | |
|
||||
+------------------+----------------------+
|
||||
|
|
||||
+---------v----------+
|
||||
| ChangeTrace |
|
||||
| (output model) |
|
||||
+--------------------+
|
||||
|
|
||||
+------------------+------------------+
|
||||
| | |
|
||||
v v v
|
||||
+-------+------+ +------+-----+------+ +--+-------------+
|
||||
| JSON Export | | DSSE Attestation | | CycloneDX |
|
||||
| (standalone) | | (signing) | | (embedded) |
|
||||
+--------------+ +-------------------+ +----------------+
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Data Flow
|
||||
|
||||
### 1. Input Stage
|
||||
|
||||
```
|
||||
Scan1 (from) Scan2 (to)
|
||||
| |
|
||||
v v
|
||||
+----+----+ +----+----+
|
||||
| SBOM | | SBOM |
|
||||
| Findings| | Findings|
|
||||
| Binary | | Binary |
|
||||
| Sigs | | Sigs |
|
||||
+---------+ +---------+
|
||||
```
|
||||
|
||||
### 2. Comparison Stage
|
||||
|
||||
```
|
||||
Package Comparison:
|
||||
- Match by PURL
|
||||
- Detect: Added, Removed, Upgraded, Downgraded, Patched, Rebuilt
|
||||
|
||||
Symbol Comparison (via BinaryIndex):
|
||||
- CFG hash matching
|
||||
- Instruction hash matching
|
||||
- Semantic hash matching
|
||||
- Chunk-level similarity
|
||||
|
||||
Byte Comparison (optional):
|
||||
- Rolling hash windows (2KB)
|
||||
- Per-section analysis
|
||||
- Delta identification
|
||||
```
|
||||
|
||||
### 3. Trust Scoring Stage
|
||||
|
||||
```
|
||||
For each PackageDelta:
|
||||
1. Get VEX consensus (from, to)
|
||||
2. Query reachability (from, to)
|
||||
3. Apply patch verification bonus
|
||||
4. Compute trust delta
|
||||
|
||||
Formula:
|
||||
TrustDelta = (AfterTrust - BeforeTrust) / max(BeforeTrust, 0.01)
|
||||
```
|
||||
|
||||
### 4. Output Stage
|
||||
|
||||
```
|
||||
ChangeTrace JSON
|
||||
-> Standalone export (.cdxchange.json)
|
||||
-> DSSE attestation (stella.ops/changetrace@v1)
|
||||
-> CycloneDX embedded (component-evidence extension)
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Component Responsibilities
|
||||
|
||||
### ChangeTraceBuilder
|
||||
|
||||
**Location:** `src/Scanner/__Libraries/StellaOps.Scanner.ChangeTrace/`
|
||||
|
||||
Orchestrates the comparison workflow:
|
||||
- Loads scan results
|
||||
- Coordinates package, symbol, and byte comparisons
|
||||
- Aggregates results into `ChangeTrace` model
|
||||
- Ensures deterministic output (stable ordering, UTC timestamps)
|
||||
|
||||
### SymbolChangeTracer
|
||||
|
||||
**Location:** `src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.DeltaSig/`
|
||||
|
||||
Performs binary-level comparison:
|
||||
- Compares `SymbolSignature` objects
|
||||
- Identifies change type (Added, Removed, Modified, Patched)
|
||||
- Computes similarity metrics
|
||||
- Generates human-readable explanations
|
||||
|
||||
### TrustDeltaCalculator
|
||||
|
||||
**Location:** `src/Scanner/__Libraries/StellaOps.Scanner.ChangeTrace/Scoring/`
|
||||
|
||||
Computes risk impact:
|
||||
- Integrates with VexLens for consensus scores
|
||||
- Integrates with ReachGraph for reachability data
|
||||
- Applies patch verification bonus
|
||||
- Generates proof steps
|
||||
|
||||
### ByteLevelDiffer
|
||||
|
||||
**Location:** `src/Scanner/__Libraries/StellaOps.Scanner.ChangeTrace/ByteDiff/`
|
||||
|
||||
Performs byte-level analysis:
|
||||
- Rolling hash window comparison
|
||||
- Section-aware diffing (ELF/PE/Mach-O)
|
||||
- Privacy-preserving output (hashes only)
|
||||
|
||||
---
|
||||
|
||||
## Key Models
|
||||
|
||||
### ChangeTrace (Root)
|
||||
|
||||
```csharp
|
||||
public sealed record ChangeTrace
|
||||
{
|
||||
public const string SchemaVersion = "stella.change-trace/1.0";
|
||||
public string Schema { get; init; } = SchemaVersion;
|
||||
public required ChangeTraceSubject Subject { get; init; }
|
||||
public ImmutableArray<PackageDelta> Deltas { get; init; } = [];
|
||||
public required ChangeTraceSummary Summary { get; init; }
|
||||
public required DateTimeOffset AnalyzedAt { get; init; }
|
||||
public string AlgorithmVersion { get; init; } = "1.0";
|
||||
}
|
||||
```
|
||||
|
||||
### PackageDelta
|
||||
|
||||
```csharp
|
||||
public sealed record PackageDelta
|
||||
{
|
||||
public required string Purl { get; init; }
|
||||
public string? FromVersion { get; init; }
|
||||
public string? ToVersion { get; init; }
|
||||
public required ChangeType ChangeType { get; init; }
|
||||
public ImmutableArray<SymbolDelta> Symbols { get; init; } = [];
|
||||
public ImmutableArray<ByteDelta> Bytes { get; init; } = [];
|
||||
public required TrustDelta TrustDelta { get; init; }
|
||||
}
|
||||
```
|
||||
|
||||
### TrustDelta
|
||||
|
||||
```csharp
|
||||
public sealed record TrustDelta
|
||||
{
|
||||
public double Score { get; init; } // [-1, +1]
|
||||
public double BeforeScore { get; init; }
|
||||
public double AfterScore { get; init; }
|
||||
public ReachabilityImpact ReachabilityImpact { get; init; }
|
||||
public ExploitabilityImpact ExploitabilityImpact { get; init; }
|
||||
public ImmutableArray<string> ProofSteps { get; init; } = [];
|
||||
}
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Trust-Delta Formula
|
||||
|
||||
### Core Formula
|
||||
|
||||
```
|
||||
TrustDelta = (AfterTrust - BeforeTrust) / max(BeforeTrust, 0.01)
|
||||
```
|
||||
|
||||
Where:
|
||||
- `BeforeTrust = VexConsensus(from) * ReachabilityFactor(from)`
|
||||
- `AfterTrust = VexConsensus(to) * ReachabilityFactor(to) + PatchBonus`
|
||||
|
||||
### Reachability Factor
|
||||
|
||||
```
|
||||
ReachabilityFactor(callPaths) =
|
||||
- 1.0 if callPaths > 0 (reachable)
|
||||
- 0.7 if callPaths == 0 (unreachable, 30% reduction)
|
||||
- 1.0 if callPaths is null (unknown)
|
||||
```
|
||||
|
||||
### Patch Verification Bonus
|
||||
|
||||
```
|
||||
PatchBonus =
|
||||
+ (FunctionMatchWeight * PatchConfidence) // 0.25 weight
|
||||
+ (SectionMatchWeight * SymbolSimilarity) // 0.15 weight
|
||||
+ (AttestationWeight * IssuerAuthority) // 0.10 weight (if DSSE present)
|
||||
```
|
||||
|
||||
### Verdict Mapping
|
||||
|
||||
| Delta Range | Verdict |
|
||||
|-------------|---------|
|
||||
| < -0.3 | risk_down |
|
||||
| -0.3 to +0.3 | neutral |
|
||||
| > +0.3 | risk_up |
|
||||
|
||||
---
|
||||
|
||||
## Integration Points
|
||||
|
||||
### VexLens Integration
|
||||
|
||||
- `IVexLensClient.GetConsensusAsync(purl, version)`: Get trust score
|
||||
- `IVexLensClient.GetAdvisoryAsync(cveId)`: Get CVE details for proof steps
|
||||
|
||||
### ReachGraph Integration
|
||||
|
||||
- `IReachGraphClient.GetReachabilityAsync(purl, version)`: Get call path count
|
||||
- Used for reachability impact calculation
|
||||
|
||||
### BinaryIndex Integration
|
||||
|
||||
- `IDeltaSignatureMatcher.CompareSignaturesAsync(from, to)`: Symbol comparison
|
||||
- `ISymbolChangeTracer.CompareSymbols(fromSymbol, toSymbol)`: Detailed symbol diff
|
||||
|
||||
### Attestor Integration
|
||||
|
||||
- `IAttestationService.CreateChangeTraceAttestationAsync(trace)`: DSSE envelope
|
||||
- Predicate type: `stella.ops/changetrace@v1`
|
||||
|
||||
---
|
||||
|
||||
## Determinism Requirements
|
||||
|
||||
All outputs must be reproducible:
|
||||
|
||||
1. **Stable ordering**: Sort deltas by PURL, symbols by name, bytes by offset
|
||||
2. **UTC timestamps**: Use `TimeProvider` for all timestamps
|
||||
3. **Canonical JSON**: RFC 8785 compliant serialization
|
||||
4. **No randomness**: Deterministic ID generation from content hashes
|
||||
|
||||
### Verification
|
||||
|
||||
```bash
|
||||
# Two runs should produce identical output
|
||||
stella change-trace build --from scan1 --to scan2 > trace1.json
|
||||
stella change-trace build --from scan1 --to scan2 > trace2.json
|
||||
diff trace1.json trace2.json # Should be empty
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Performance Targets
|
||||
|
||||
| Metric | Target |
|
||||
|--------|--------|
|
||||
| Package comparison | < 100ms |
|
||||
| Symbol comparison | < 100ms per binary |
|
||||
| Byte-level diffing | < 500ms for binaries < 5MB |
|
||||
| Full trace build | < 5s for typical container |
|
||||
| Memory usage | < 500MB peak |
|
||||
|
||||
---
|
||||
|
||||
## Security Considerations
|
||||
|
||||
### Privacy
|
||||
|
||||
- Byte content is never included in output
|
||||
- Only hashes, offsets, and sizes are exported
|
||||
- Symbol names may be sensitive (review before external export)
|
||||
|
||||
### Integrity
|
||||
|
||||
- DSSE attestations provide tamper-evidence
|
||||
- Signature verification available via `stella change-trace verify`
|
||||
|
||||
### Access Control
|
||||
|
||||
- API endpoints require authentication
|
||||
- Traces inherit visibility from source scans
|
||||
|
||||
---
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
### Phase 2
|
||||
|
||||
- Function-level heatmap visualization
|
||||
- Side-by-side disassembly view
|
||||
- AI-assisted change explanation
|
||||
|
||||
### Phase 3
|
||||
|
||||
- Historical trend analysis
|
||||
- Anomaly detection for unexpected changes
|
||||
- Integration with SLSA provenance
|
||||
|
||||
---
|
||||
|
||||
## References
|
||||
|
||||
- [Sprint INDEX](../../implplan/SPRINT_20260112_200_000_INDEX_change_trace.md)
|
||||
- [JSON Schema Contract](../../contracts/change-trace-schema.md)
|
||||
- [Trust-Delta Contract](../../contracts/change-trace-trust-delta.md)
|
||||
- [BinaryIndex Architecture](../../modules/binary-index/architecture.md)
|
||||
- [VexLens Architecture](../../modules/vexlens/architecture.md)
|
||||
|
||||
---
|
||||
|
||||
*Document Version: 1.0.0*
|
||||
*Last Updated: 2026-01-12*
|
||||
Reference in New Issue
Block a user