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


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:

SymbolChangeTracer

Location: src/BinaryIndex/__Libraries/StellaOps.BinaryIndex.DeltaSig/

Performs binary-level comparison:

TrustDeltaCalculator

Location: src/Scanner/__Libraries/StellaOps.Scanner.ChangeTrace/Scoring/

Computes risk impact:

ByteLevelDiffer

Location: src/Scanner/__Libraries/StellaOps.Scanner.ChangeTrace/ByteDiff/

Performs byte-level analysis:


Key Models

ChangeTrace (Root)

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

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

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:

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 RangeVerdict
< -0.3risk_down
-0.3 to +0.3neutral
> +0.3risk_up

Integration Points

VexLens Integration

ReachGraph Integration

BinaryIndex Integration

Attestor Integration


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

# 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

MetricTarget
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

Integrity

Access Control


Future Enhancements

Phase 2

Phase 3


References

Implementation Status Note (2026-03-05)

The previously documented advisory-translation gaps are closed:

Closure sprints:


Document Version: 1.0.0 Last Updated: 2026-03-05