# Change-Trace JSON Schema Contract > **Version:** 1.0.0 > **Status:** Draft > **Last Updated:** 2026-01-12 --- ## Overview This document defines the JSON schema for Change-Trace artifacts (`trace.cdxchange.json`). All implementations must conform to this schema for interoperability. --- ## Schema Identifier ``` Schema URI: stella.change-trace/1.0 File Extension: .cdxchange.json MIME Type: application/vnd.stella.change-trace+json ``` --- ## Root Object ```json { "$schema": "https://stella-ops.org/schemas/change-trace/1.0/schema.json", "schema": "stella.change-trace/1.0", "subject": { ... }, "deltas": [ ... ], "summary": { ... }, "analyzedAt": "2026-01-12T14:30:00.000Z", "algorithmVersion": "1.0" } ``` ### Properties | Property | Type | Required | Description | |----------|------|----------|-------------| | `schema` | string | Yes | Schema version identifier. Must be `stella.change-trace/1.0` | | `subject` | object | Yes | Subject of the comparison | | `deltas` | array | Yes | Array of package deltas (may be empty) | | `summary` | object | Yes | Aggregated summary metrics | | `analyzedAt` | string | Yes | ISO 8601 timestamp (UTC) | | `algorithmVersion` | string | No | Algorithm version used (default: "1.0") | --- ## Subject Object ```json { "imageRef": "docker.io/library/nginx:1.25.3", "fromDigest": "sha256:abc123...", "toDigest": "sha256:def456...", "fromScanId": "scan-12345", "toScanId": "scan-67890" } ``` ### Properties | Property | Type | Required | Description | |----------|------|----------|-------------| | `imageRef` | string | Yes | Container image reference | | `fromDigest` | string | Yes | SHA-256 digest of source image | | `toDigest` | string | Yes | SHA-256 digest of target image | | `fromScanId` | string | No | Source scan identifier | | `toScanId` | string | No | Target scan identifier | --- ## PackageDelta Object ```json { "purl": "pkg:deb/debian/libssl3@3.0.9-1", "fromVersion": "3.0.9-1", "toVersion": "3.0.9-1+deb12u3", "changeType": "patched", "symbols": [ ... ], "bytes": [ ... ], "trustDelta": { ... } } ``` ### Properties | Property | Type | Required | Description | |----------|------|----------|-------------| | `purl` | string | Yes | Package URL (RFC 3986 compliant) | | `fromVersion` | string | No | Source version (null if added) | | `toVersion` | string | No | Target version (null if removed) | | `changeType` | enum | Yes | Type of change | | `symbols` | array | No | Symbol-level deltas (if available) | | `bytes` | array | No | Byte-level deltas (if enabled) | | `trustDelta` | object | Yes | Trust impact calculation | ### ChangeType Enum | Value | Description | |-------|-------------| | `unchanged` | No change detected | | `added` | Package added in target | | `removed` | Package removed in target | | `upgraded` | Version increased | | `downgraded` | Version decreased | | `patched` | Security patch applied (same base version) | | `rebuilt` | Same version, different build | --- ## SymbolDelta Object ```json { "symbolName": "ssl3_get_record", "changeType": "patched", "sizeDelta": -24, "cfgBlockDelta": 2, "confidence": 0.97, "matchMethod": "CFGHash+ChunkMatch", "explanation": "Function patched: 2 basic blocks changed" } ``` ### Properties | Property | Type | Required | Description | |----------|------|----------|-------------| | `symbolName` | string | Yes | Symbol/function name | | `changeType` | enum | Yes | Type of symbol change | | `sizeDelta` | integer | No | Size change in bytes | | `cfgBlockDelta` | integer | No | CFG basic block count change | | `confidence` | number | No | Match confidence (0.0-1.0) | | `matchMethod` | string | No | Method used for matching | | `explanation` | string | No | Human-readable explanation | ### SymbolChangeType Enum | Value | Description | |-------|-------------| | `unchanged` | No change detected | | `added` | Symbol added in target | | `removed` | Symbol removed in target | | `modified` | Symbol modified (general) | | `patched` | Security patch detected | --- ## ByteDelta Object ```json { "offset": 4096, "size": 2048, "fromHash": "sha256:abc123...", "toHash": "sha256:def456...", "section": ".text", "context": "Function: ssl3_get_record" } ``` ### Properties | Property | Type | Required | Description | |----------|------|----------|-------------| | `offset` | integer | Yes | Byte offset in binary | | `size` | integer | Yes | Size of changed region | | `fromHash` | string | Yes | SHA-256 hash of source bytes | | `toHash` | string | Yes | SHA-256 hash of target bytes | | `section` | string | No | Binary section name | | `context` | string | No | Context hint (e.g., function name) | **Privacy Note:** Raw byte content is never included; only hashes are stored. --- ## TrustDelta Object ```json { "score": -0.27, "beforeScore": 0.65, "afterScore": 0.92, "reachabilityImpact": "reduced", "exploitabilityImpact": "down", "proofSteps": [ "CVE-2026-12345 affects ssl3_get_record", "Version changed: 3.0.9-1 -> 3.0.9-1+deb12u3", "Patch verified via CFG match: 97% confidence", "Reachable call paths: 3 -> 0 after patch", "DSSE attestation present", "Verdict: risk_down (-0.27)" ] } ``` ### Properties | Property | Type | Required | Description | |----------|------|----------|-------------| | `score` | number | Yes | Trust delta value (-1.0 to +1.0) | | `beforeScore` | number | Yes | Trust score before change | | `afterScore` | number | Yes | Trust score after change | | `reachabilityImpact` | enum | Yes | Impact on code reachability | | `exploitabilityImpact` | enum | Yes | Impact on exploitability | | `proofSteps` | array | Yes | Human-readable proof steps | ### ReachabilityImpact Enum | Value | Description | |-------|-------------| | `unchanged` | No change in reachability | | `introduced` | Path now reachable | | `eliminated` | Path no longer reachable | | `reduced` | Fewer reachable paths | | `increased` | More reachable paths | ### ExploitabilityImpact Enum | Value | Description | |-------|-------------| | `unchanged` | No change in exploitability | | `introduced` | New exploitability concern | | `eliminated` | Exploitability eliminated | | `up` | Increased exploitability | | `down` | Decreased exploitability | --- ## Summary Object ```json { "packagesChanged": 5, "packagesAdded": 1, "packagesRemoved": 0, "symbolsChanged": 23, "bytesChanged": 8192, "trustDelta": -0.15, "overallVerdict": "risk_down" } ``` ### Properties | Property | Type | Required | Description | |----------|------|----------|-------------| | `packagesChanged` | integer | Yes | Total packages with changes | | `packagesAdded` | integer | Yes | Packages added | | `packagesRemoved` | integer | Yes | Packages removed | | `symbolsChanged` | integer | Yes | Total symbols with changes | | `bytesChanged` | integer | Yes | Total bytes changed | | `trustDelta` | number | Yes | Aggregate trust delta | | `overallVerdict` | string | Yes | Overall verdict | ### Verdict Values | Value | Trust Delta Range | Description | |-------|-------------------|-------------| | `risk_down` | < -0.3 | Risk decreased significantly | | `neutral` | -0.3 to +0.3 | No significant risk change | | `risk_up` | > +0.3 | Risk increased significantly | | `inconclusive` | N/A | Unable to determine | --- ## Full Example ```json { "$schema": "https://stella-ops.org/schemas/change-trace/1.0/schema.json", "schema": "stella.change-trace/1.0", "subject": { "imageRef": "docker.io/library/nginx:1.25.3", "fromDigest": "sha256:abc123def456...", "toDigest": "sha256:789ghi012jkl...", "fromScanId": "scan-20260112-001", "toScanId": "scan-20260112-002" }, "deltas": [ { "purl": "pkg:deb/debian/libssl3@3.0.9-1", "fromVersion": "3.0.9-1", "toVersion": "3.0.9-1+deb12u3", "changeType": "patched", "symbols": [ { "symbolName": "ssl3_get_record", "changeType": "patched", "sizeDelta": -24, "cfgBlockDelta": 2, "confidence": 0.97, "matchMethod": "CFGHash+ChunkMatch", "explanation": "Function patched: 2 basic blocks changed" } ], "bytes": [ { "offset": 4096, "size": 2048, "fromHash": "sha256:abc...", "toHash": "sha256:def...", "section": ".text" } ], "trustDelta": { "score": -0.27, "beforeScore": 0.65, "afterScore": 0.92, "reachabilityImpact": "reduced", "exploitabilityImpact": "down", "proofSteps": [ "CVE-2026-12345 affects ssl3_get_record", "Version changed: 3.0.9-1 -> 3.0.9-1+deb12u3", "Patch verified via CFG match: 97% confidence", "Reachable call paths: 3 -> 0 after patch", "DSSE attestation present", "Verdict: risk_down (-0.27)" ] } } ], "summary": { "packagesChanged": 1, "packagesAdded": 0, "packagesRemoved": 0, "symbolsChanged": 1, "bytesChanged": 2048, "trustDelta": -0.27, "overallVerdict": "risk_down" }, "analyzedAt": "2026-01-12T14:30:00.000Z", "algorithmVersion": "1.0" } ``` --- ## Serialization Rules ### Determinism Requirements 1. **Key ordering**: Object keys must be sorted alphabetically 2. **Array ordering**: - `deltas`: Sorted by `purl` (lexicographic) - `symbols`: Sorted by `symbolName` (lexicographic) - `bytes`: Sorted by `offset` (numeric ascending) - `proofSteps`: Preserve generation order 3. **Number formatting**: No trailing zeros, no exponent notation 4. **String escaping**: Minimal escaping per RFC 8785 5. **Timestamps**: ISO 8601 with milliseconds, UTC (`Z` suffix) ### RFC 8785 Compliance All JSON output must conform to [RFC 8785](https://datatracker.ietf.org/doc/html/rfc8785) (JSON Canonicalization Scheme) for digest computation. --- ## Validation ### JSON Schema The formal JSON Schema is available at: ``` https://stella-ops.org/schemas/change-trace/1.0/schema.json ``` ### Validation Command ```bash stella change-trace verify trace.cdxchange.json ``` ### Required Fields The following fields are required for a valid trace: - `schema` - `subject.imageRef` - `subject.fromDigest` - `subject.toDigest` - `deltas` (may be empty array) - `summary.*` (all summary fields) - `analyzedAt` --- ## CycloneDX Integration ### Embedded Mode When embedded in CycloneDX, the change trace is attached as a `component-evidence` extension: ```json { "bomFormat": "CycloneDX", "specVersion": "1.7", "components": [ { "purl": "pkg:deb/debian/libssl3@3.0.9-1+deb12u3", "evidence": { "extensions": [ { "extensionType": "stella-change-trace", "extension": { "schema": "stella.change-trace/1.0", "changeType": "patched", "trustDelta": { ... }, "symbols": [ ... ] } } ] } } ] } ``` ### Standalone Mode Export as separate file: `.cdxchange.json` --- ## Version History | Version | Date | Changes | |---------|------|---------| | 1.0.0 | 2026-01-12 | Initial release | --- ## References - [Architecture Document](../modules/scanner/design/change-trace-architecture.md) - [Trust-Delta Contract](./change-trace-trust-delta.md) - [RFC 8785 - JSON Canonicalization Scheme](https://datatracker.ietf.org/doc/html/rfc8785) - [Package URL Specification](https://github.com/package-url/purl-spec) --- *Document Version: 1.0.0* *Last Updated: 2026-01-12*