Change-Trace JSON Schema Contract

Version: 1.0.0 Status: Implemented Last Updated: 2026-05-30


Overview

This document defines the JSON schema for StellaOps Change-Trace artifacts (.cdxchange.json) — the deterministic record of what changed between two scans or two binaries, and how that change moves trust. All implementations must conform to this schema for interoperability.

Audience: Scanner engineers producing Change-Trace artifacts, CLI/UI consumers reading them, and integrators embedding them into CycloneDX BOMs. For the scoring math behind the trustDelta/summary fields, see the Change-Trace Trust-Delta Contract.

The canonical implementation lives in StellaOps.Scanner.ChangeTrace:

Naming/casing note (grounded in ChangeTraceSerializer): the canonical serializer applies JsonNamingPolicy.CamelCase to both property names and JsonStringEnumConverter. Therefore enum values are emitted in camelCase on the wire (e.g. upgraded, riskDown, vendorBackport, reduced, down). The C# enum members are PascalCase (e.g. Upgraded, RiskDown); the deserializer is case-insensitive, so hand-authored fixtures using PascalCase values are accepted on read but are not what the serializer produces.


Schema Identifier

Schema identifier: stella.change-trace/1.0   (root "schema" field; const ChangeTrace.SchemaVersion)
File Extension:    .cdxchange.json           (default JSON export extension; ChangeTraceCommandGroup)

The MIME type application/vnd.stella.change-trace+json and the $schema/https://stella-ops.org/schemas/... JSON-Schema URL referenced in earlier drafts are not present in the implementation. The root model (ChangeTrace.cs) has no $schema property and no published JSON Schema document; the only authoritative identifier is the schema string field.


Root Object

Grounded in Models/ChangeTrace.cs (ChangeTrace record).

{
  "schema": "stella.change-trace/1.0",
  "subject": { ... },
  "basis": { ... },
  "deltas": [ ... ],
  "summary": { ... },
  "commitment": { ... },
  "attestation": { ... }
}

Properties

PropertyTypeRequiredDescription
schemastringYesSchema version identifier. Defaults to stella.change-trace/1.0 (ChangeTrace.SchemaVersion).
subjectobjectYesSubject artifact being compared.
basisobjectYesAnalysis basis and configuration (scan IDs, policies, diff methods, engine version, analyzedAt).
deltasarrayYes (may be empty)Array of package deltas. Sorted by purl (ordinal) on serialization.
summaryobjectYesAggregated summary metrics.
commitmentobjectNoRFC 8785 + SHA-256 commitment hash. Omitted when null.
attestationobjectNoReference to a DSSE attestation. Omitted when null.

Note: there is no top-level analyzedAt or algorithmVersion field. The analysis timestamp lives at basis.analyzedAt; the engine version lives at basis.engineVersion.

Commitment Object

Grounded in ChangeTraceCommitment (Models/ChangeTrace.cs) and ChangeTraceSerializer.ComputeCommitmentHash.

PropertyTypeRequiredDescription
sha256stringYesSHA-256 hash of the canonical JSON, computed with the commitment and attestation fields removed.
algorithmstringNoDefaults to RFC8785+SHA256.

Attestation Object

Grounded in ChangeTraceAttestationRef (Models/ChangeTrace.cs).

PropertyTypeRequiredDescription
predicateTypestringYesPredicate type of the DSSE attestation.
envelopeDigeststringNoDigest of the DSSE envelope.

Subject Object

Grounded in ChangeTraceSubject (Models/ChangeTrace.cs).

{
  "type": "oci.image",
  "digest": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
  "purl": "pkg:oci/debian/bookworm@sha256:e3b0c442...",
  "name": "debian:bookworm"
}

Properties

PropertyTypeRequiredDescription
typestringYesArtifact type: oci.image, binary, or package.
digeststringYesDigest of the artifact (e.g., sha256:...).
purlstringNoPackage URL, if applicable.
namestringNoHuman-readable artifact name.

The imageRef, fromDigest, and toDigest fields from earlier drafts do not exist. The single subject digest identifies the artifact; the “before”/“after” linkage is expressed via basis.fromScanId / basis.toScanId below.


Basis Object

Grounded in ChangeTraceBasis (Models/ChangeTrace.cs). Carries the analysis configuration and the before/after linkage.

{
  "scanId": "scan-20260112-backport-libssl",
  "fromScanId": "scan-20260111-libssl-3.0.9-1+deb12u2",
  "toScanId": "scan-20260112-libssl-3.0.9-1+deb12u3",
  "policies": ["lattice:default@v3"],
  "diffMethod": ["pkg", "symbol"],
  "engineVersion": "1.0.0",
  "engineDigest": "sha256:...",
  "analyzedAt": "2026-01-12T10:00:00+00:00"
}

Properties

PropertyTypeRequiredDescription
scanIdstringYesPrimary scan identifier for this comparison.
fromScanIdstringNoScan ID of the “before” state.
toScanIdstringNoScan ID of the “after” state.
policiesarray<string>NoLattice policies applied during analysis.
diffMethodarray<string>NoDiff methods used: pkg, symbol, byte.
engineVersionstringYesVersion of the engine that produced this trace.
engineDigeststringNoDigest of the engine binary/source for reproducibility.
analyzedAtstringYesISO 8601 timestamp when analysis was performed.

PackageDelta Object

Grounded in PackageDelta (Models/PackageDelta.cs).

{
  "scope": "pkg",
  "purl": "pkg:deb/debian/libssl3@3.0.9-1+deb12u3?distro=debian-12",
  "name": "libssl3",
  "fromVersion": "3.0.9-1+deb12u2",
  "toVersion": "3.0.9-1+deb12u3",
  "changeType": "upgraded",
  "explain": "vendorBackport",
  "evidence": { ... },
  "trustDelta": { ... },
  "symbolDeltas": [ ... ],
  "byteDeltas": [ ... ]
}

Properties

PropertyTypeRequiredDescription
scopestringYesAlways pkg for package deltas.
purlstringYesPackage URL identifying the package.
namestringYesHuman-readable package name.
fromVersionstringYesVersion before the change.
toVersionstringYesVersion after the change.
changeTypeenumYesType of change (see ChangeType Enum).
explainenumYesExplanation category (see Explanation Enum).
evidenceobjectYesEvidence supporting the change classification.
trustDeltaobjectNoTrust impact calculation (null when not computed).
symbolDeltasarrayNoSymbol-level deltas (sorted by name on serialization).
byteDeltasarrayNoByte-level deltas (sorted by offset on serialization).

Field names corrected from earlier drafts: the nested arrays are symbolDeltas / byteDeltas (not symbols / bytes), name and explain and evidence are required, fromVersion / toVersion are required (not nullable), and trustDelta is optional (not required).

ChangeType Enum

Grounded in PackageChangeType (Models/PackageDelta.cs). Serialized camelCase.

Value (wire)C# memberDescription
addedAddedPackage added in target.
removedRemovedPackage removed in target.
modifiedModifiedPackage modified (general change).
upgradedUpgradedVersion upgraded.
downgradedDowngradedVersion downgraded.
rebuiltRebuiltRebuilt without version change.

There is no unchanged or patched member in PackageChangeType (those existed only in earlier drafts). A general change is modified; security-patch intent is conveyed by explain: securityPatch and by the symbol-level patched change type, not by the package changeType.

Explanation Enum

Grounded in PackageChangeExplanation (Models/PackageDelta.cs). Carried in the explain field. Serialized camelCase.

Value (wire)C# memberDescription
vendorBackportVendorBackportVendor backport of upstream fixes.
upstreamUpgradeUpstreamUpgradeStandard upstream version upgrade.
securityPatchSecurityPatchSecurity patch applied.
rebuildRebuildRebuilt without source changes.
flagChangeFlagChangeCompilation flags / build options changed.
newDependencyNewDependencyNew dependency added.
removedDependencyRemovedDependencyDependency removed.
unknownUnknownChange reason could not be determined.

PackageDeltaEvidence Object

Grounded in PackageDeltaEvidence (Models/PackageDelta.cs). Required on every package delta.

{
  "patchIds": ["DSA-5678-1"],
  "cveIds": ["CVE-2026-12345"],
  "symbolsChanged": 1,
  "bytesChanged": 512,
  "functions": ["ssl3_get_record"],
  "verificationMethod": "CFGHash",
  "confidence": 0.98
}
PropertyTypeRequiredDescription
patchIdsarray<string>NoPatch identifiers associated with the change.
cveIdsarray<string>NoCVE identifiers addressed by the change.
symbolsChangedintegerNoNumber of symbols changed in this package.
bytesChangedinteger (int64)NoTotal bytes changed in this package.
functionsarray<string>NoFunction names affected.
verificationMethodstringNoMethod used to verify the change.
confidencenumberNoConfidence for the classification (0.0–1.0).

SymbolDelta Object

Grounded in SymbolDelta (Models/SymbolDelta.cs).

{
  "scope": "symbol",
  "name": "ssl3_get_record",
  "changeType": "patched",
  "fromHash": "sha256:abc123",
  "toHash": "sha256:def456",
  "sizeDelta": 64,
  "cfgBlockDelta": 2,
  "similarity": 0.98,
  "confidence": 0.95,
  "matchMethod": "CFGHash",
  "explanation": "Security patch for buffer overflow",
  "matchedChunks": [0, 1, 2, 5, 6]
}

Properties

PropertyTypeRequiredDescription
scopestringYesAlways symbol for symbol deltas.
namestringYesSymbol/function name.
changeTypeenumYesType of symbol change.
fromHashstringNoHash of the symbol in the “before” state.
toHashstringNoHash of the symbol in the “after” state.
sizeDeltaintegerNoSize change in bytes.
cfgBlockDeltaintegerNoCFG basic-block count change (nullable).
similaritynumberNoSimilarity score between before/after (0.0–1.0).
confidencenumberNoMatch confidence (0.0–1.0).
matchMethodstringNoMatch method, e.g. CFGHash, InstructionHash, SemanticHash.
explanationstringNoHuman-readable explanation.
matchedChunksarray<integer>NoIndices of matched instruction chunks.

Field name corrected: the symbol name field is name (not symbolName). The model also adds scope, fromHash, toHash, similarity, and matchedChunks, which earlier drafts omitted.

SymbolChangeType Enum

Grounded in SymbolChangeType (Models/SymbolDelta.cs). Serialized camelCase.

Value (wire)C# memberDescription
unchangedUnchangedNo change detected.
addedAddedSymbol added in target.
removedRemovedSymbol removed in target.
modifiedModifiedSymbol modified (general).
patchedPatchedSecurity/bug-fix patch detected.

ByteDelta Object

Grounded in ByteDelta (Models/ByteDelta.cs).

{
  "scope": "byte",
  "offset": 4096,
  "size": 2048,
  "fromHash": "sha256:abc123...",
  "toHash": "sha256:def456...",
  "section": ".text",
  "context": "Function: ssl3_get_record"
}

Properties

PropertyTypeRequiredDescription
scopestringYesAlways byte for byte deltas.
offsetinteger (int64)YesByte offset where the change begins.
sizeintegerYesSize of the changed region in bytes.
fromHashstringYesRolling hash of the “before” bytes.
toHashstringYesRolling hash of the “after” bytes.
sectionstringNoBinary section name (e.g., .text, .data).
contextstringNoOptional context description.

Privacy Note: Raw byte content is never included; only hashes are stored.


TrustDelta Object

Grounded in TrustDelta (Models/TrustDelta.cs) and Scoring/TrustDeltaCalculator.cs.

{
  "reachabilityImpact": "reduced",
  "exploitabilityImpact": "down",
  "score": -0.27,
  "beforeScore": 0.85,
  "afterScore": 0.62,
  "proofSteps": [
    "CVE-2026-12345 affects ssl3_get_record",
    "Function patched in 3.0.9-1+deb12u3",
    "CFG match: 0.98 similarity",
    "Reachable call paths: 3 -> 0 after patch"
  ]
}

Properties

PropertyTypeRequiredDescription
reachabilityImpactenumYesImpact on code reachability.
exploitabilityImpactenumYesImpact on exploitability.
scorenumberYesTrust delta value (-1.0 to +1.0). Negative = risk reduction, positive = risk increase. Rounded to 2 decimals by the calculator.
beforeScorenumberNoTrust score before the change (nullable).
afterScorenumberNoTrust score after the change (nullable).
proofStepsarray<string>NoHuman-readable proof steps; generation order is preserved.

Corrected from earlier drafts: beforeScore, afterScore, and proofSteps are optional (nullable / default-empty), not required. Score sign semantics per TrustDeltaCalculator: delta = (beforeTrust - afterTrust) / max(beforeTrust, minDenom), so a negative score means risk went down.

ReachabilityImpact Enum

Grounded in ReachabilityImpact (Models/TrustDelta.cs). Serialized camelCase.

Value (wire)C# memberDescription
unchangedUnchangedNo change in reachability.
reducedReducedFewer reachable paths.
increasedIncreasedMore reachable paths.
eliminatedEliminatedAll vulnerable paths eliminated.
introducedIntroducedNew reachable paths introduced.

ExploitabilityImpact Enum

Grounded in ExploitabilityImpact (Models/TrustDelta.cs). Serialized camelCase.

Value (wire)C# memberDescription
unchangedUnchangedNo change in exploitability.
downDownExploitability decreased.
upUpExploitability increased.
eliminatedEliminatedVulnerability eliminated.
introducedIntroducedNew vulnerability introduced.

Summary Object

Grounded in ChangeTraceSummary (Models/ChangeTraceSummary.cs).

{
  "changedPackages": 1,
  "changedSymbols": 1,
  "changedBytes": 512,
  "riskDelta": -0.27,
  "verdict": "riskDown",
  "beforeRiskScore": 0.85,
  "afterRiskScore": 0.62
}

Properties

PropertyTypeRequiredDescription
changedPackagesintegerYesTotal packages with changes.
changedSymbolsintegerYesTotal symbols with changes.
changedBytesinteger (int64)YesTotal bytes changed across all packages.
riskDeltanumberYesAggregated risk delta score.
verdictenumYesOverall verdict (see Verdict Values).
beforeRiskScorenumberNoRisk score before changes (nullable).
afterRiskScorenumberNoRisk score after changes (nullable).

Field names corrected from earlier drafts: counts are changedPackages / changedSymbols / changedBytes (not packagesChanged etc.); the aggregate score field is riskDelta (not trustDelta); the verdict field is verdict (not overallVerdict). There are no packagesAdded / packagesRemoved fields in the summary.

Verdict Values

Grounded in ChangeTraceVerdict (Models/ChangeTraceSummary.cs) and ChangeTraceBuilder.ComputeVerdict(riskDelta). Serialized camelCase.

Value (wire)C# memberRisk Delta RangeDescription
riskDownRiskDown< -0.3Risk decreased significantly.
neutralNeutral-0.3 ≤ delta ≤ 0.3No significant risk change.
riskUpRiskUp> 0.3Risk increased significantly.
inconclusiveInconclusiveN/AUnable to determine (enum value exists; not produced by ComputeVerdict, which returns only the three threshold-based verdicts).

Full Example

Based on the golden fixture src/Scanner/__Tests/StellaOps.Scanner.ChangeTrace.Tests/Golden/backport_libssl.json. Enum values shown in the camelCase form produced by the canonical serializer (the fixture itself stores PascalCase, which the case-insensitive deserializer also accepts).

{
  "schema": "stella.change-trace/1.0",
  "subject": {
    "type": "oci.image",
    "digest": "sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "purl": "pkg:oci/debian/bookworm@sha256:e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    "name": "debian:bookworm"
  },
  "basis": {
    "scanId": "scan-20260112-backport-libssl",
    "fromScanId": "scan-20260111-libssl-3.0.9-1+deb12u2",
    "toScanId": "scan-20260112-libssl-3.0.9-1+deb12u3",
    "policies": ["lattice:default@v3"],
    "diffMethod": ["pkg", "symbol"],
    "engineVersion": "1.0.0",
    "analyzedAt": "2026-01-12T10:00:00+00:00"
  },
  "deltas": [
    {
      "scope": "pkg",
      "purl": "pkg:deb/debian/libssl3@3.0.9-1+deb12u3?distro=debian-12",
      "name": "libssl3",
      "fromVersion": "3.0.9-1+deb12u2",
      "toVersion": "3.0.9-1+deb12u3",
      "changeType": "upgraded",
      "explain": "vendorBackport",
      "evidence": {
        "patchIds": ["DSA-5678-1"],
        "cveIds": ["CVE-2026-12345"],
        "symbolsChanged": 1,
        "bytesChanged": 512,
        "functions": ["ssl3_get_record"],
        "verificationMethod": "CFGHash",
        "confidence": 0.98
      },
      "trustDelta": {
        "reachabilityImpact": "reduced",
        "exploitabilityImpact": "down",
        "score": -0.27,
        "beforeScore": 0.85,
        "afterScore": 0.62,
        "proofSteps": [
          "CVE-2026-12345 affects ssl3_get_record",
          "Function patched in 3.0.9-1+deb12u3",
          "CFG match: 0.98 similarity",
          "Reachable call paths: 3 -> 0 after patch"
        ]
      },
      "symbolDeltas": [
        {
          "scope": "symbol",
          "name": "ssl3_get_record",
          "changeType": "patched",
          "fromHash": "sha256:abc123",
          "toHash": "sha256:def456",
          "sizeDelta": 64,
          "cfgBlockDelta": 2,
          "similarity": 0.98,
          "confidence": 0.95,
          "matchMethod": "CFGHash",
          "explanation": "Security patch for buffer overflow",
          "matchedChunks": [0, 1, 2, 5, 6]
        }
      ],
      "byteDeltas": []
    }
  ],
  "summary": {
    "changedPackages": 1,
    "changedSymbols": 1,
    "changedBytes": 512,
    "riskDelta": -0.27,
    "verdict": "riskDown",
    "beforeRiskScore": 0.85,
    "afterRiskScore": 0.62
  },
  "commitment": {
    "sha256": "<computed RFC8785+SHA256 hash>",
    "algorithm": "RFC8785+SHA256"
  }
}

Serialization Rules

Grounded in ChangeTraceSerializer (which delegates canonicalization to StellaOps.Canonical.Json.CanonJson) and ChangeTraceSerializer.SortTrace / SortPackageDelta.

  1. Key ordering: Object member keys are emitted in ordinal (UTF-16 code-unit) order by CanonJson.WriteElementSorted after NFC normalization — not the host language’s locale-aware “alphabetical” order. This is the RFC 8785 member-ordering rule.
  2. Array ordering (applied by ChangeTraceSerializer.SortTrace):
    • deltas: Sorted by purl using StringComparer.Ordinal.
    • symbolDeltas: Sorted by name using StringComparer.Ordinal.
    • byteDeltas: Sorted by offset (numeric ascending).
    • proofSteps: Generation order preserved (not sorted).
  3. Number formatting: Per CanonJson number normalization (e.g. -0 is written as 0).
  4. String escaping: UnsafeRelaxedJsonEscaping on the System.Text.Json options; final canonical bytes follow RFC 8785 via CanonJson.Canonicalize.
  5. Null handling: DefaultIgnoreCondition = WhenWritingNull — null-valued optional properties (commitment, attestation, purl, etc.) are omitted entirely.
  6. Timestamps: DateTimeOffset serialized by System.Text.Json (round-trip “O” form). The golden fixtures use offset form (2026-01-12T10:00:00+00:00).

RFC 8785 Compliance

All JSON output must conform to RFC 8785 (JSON Canonicalization Scheme) for digest computation.


Validation

JSON Schema

No published JSON Schema document exists. The https://stella-ops.org/schemas/change-trace/1.0/schema.json URL referenced in earlier drafts is not implemented — there is no $schema property on the model and no schema file is served. Validation is performed programmatically by ChangeTraceValidator (below); the only authoritative identifier is the schema string field (stella.change-trace/1.0).

Validation Command

stella change-trace verify <file>

Grounded in ChangeTraceCommandGroup.BuildVerifyCommand. Takes a positional file argument (any path; .cdxchange.json by convention) and an optional --strict flag (fail when any warnings are present). Exit codes follow ChangeTraceExitCodes (see CLI section).

Required Fields (validator errors)

Grounded in ChangeTraceValidator. A missing/empty value for any of the following produces an error (invalidates the trace):

An empty deltas array is valid (means “no changes”).

The following produce warnings only (do not invalidate): non-standard schema prefix, subject.digest without an algorithm prefix, missing basis.engineVersion, missing basis.analyzedAt, missing basis.diffMethod, out-of-range riskDelta / delta confidence / trustDelta.score, a delta with neither fromVersion nor toVersion, and a missing commitment.algorithm.

The subject.imageRef, subject.fromDigest, subject.toDigest, and top-level analyzedAt fields listed in earlier drafts as required do not exist in the model or the validator.


CLI

Grounded in src/Cli/StellaOps.Cli/Commands/ChangeTraceCommandGroup.cs. The change-trace command group exposes three subcommands:

stella change-trace build

Builds a change trace comparing two scans or two binary files.

OptionAliasRequiredDescription
--fromYesSource scan ID or binary file path.
--toYesTarget scan ID or binary file path.
--include-byte-diffNoInclude byte-level diffing (slower).
--output-oNoOutput file path (default: stdout).
--format-fNojson (default), table, or summary.

If both --from and --to resolve to existing files, a binary comparison is performed; otherwise they are treated as scan IDs. The exit code reflects the verdict: RiskDown/Neutral -> Success (0), RiskUp -> RiskUp (2), anything else -> Inconclusive (3).

stella change-trace export

Exports an existing change-trace JSON file in another format.

OptionAliasRequiredDescription
--input-iYesInput change-trace JSON file.
--format-fNojson (default), cyclonedx, bundle.
--output-oNoOutput file path.
--cdx-embeddedNoEmbed in a CycloneDX BOM as a change-trace extension.
--cdx-bomNoExisting CycloneDX BOM to embed the trace into.

Default output filename when --output is omitted: trace-export.cdxchange.json for plain JSON export, and trace-export.cdx.json for CycloneDX export.

stella change-trace verify

Validates a change-trace file (see Validation Command above).

Exit Codes

Grounded in ChangeTraceExitCodes:

CodeNameMeaning
0SuccessSuccess, or RiskDown/Neutral verdict.
1ErrorGeneral error.
2RiskUpRiskUp verdict (trust delta indicates increased risk).
3InconclusiveUnable to determine verdict.
4FileNotFoundInput file not found.
5ValidationFailedValidation failed / invalid JSON.
6ServiceUnavailableService not available.

CycloneDX Integration

Grounded in CycloneDx/ChangeTraceEvidenceExtension.cs and ChangeTraceEvidenceOptions. Options: IncludeProofSteps (default true), IncludeSymbolDeltas (default true), IncludeByteDeltas (default false), MaxDeltas (default 100), SpecVersion (default "1.7").

Corrected from earlier drafts. The extension is not attached to a per-component evidence.extensions array, the extensionType is stella.change-trace (a dot, not a hyphen), and the payload lives under a changeTrace object (not extension). The embedded changeTrace object mirrors the trace structure (schema/subject/basis/summary/commitment/deltas) with a reduced per-delta projection — there is no top-level changeType/symbols shape.

Embedded Mode (EmbedInCycloneDx)

The extension object is appended to the BOM root extensions array (the array is created if absent):

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.7",
  "extensions": [
    {
      "extensionType": "stella.change-trace",
      "changeTrace": {
        "schema": "stella.change-trace/1.0",
        "subject": { "type": "oci.image", "digest": "sha256:...", "purl": "...", "name": "..." },
        "basis": { "scanId": "...", "engineVersion": "1.0.0", "analyzedAt": "...", "fromScanId": "...", "toScanId": "...", "policies": [ ... ], "diffMethod": [ ... ] },
        "summary": { "changedPackages": 1, "changedSymbols": 1, "changedBytes": 512, "riskDelta": -0.27, "verdict": "riskdown" },
        "commitment": { "sha256": "...", "algorithm": "RFC8785+SHA256" },
        "deltas": [
          {
            "purl": "pkg:deb/debian/libssl3@3.0.9-1+deb12u3",
            "name": "libssl3",
            "fromVersion": "3.0.9-1+deb12u2",
            "toVersion": "3.0.9-1+deb12u3",
            "changeType": "upgraded",
            "explain": "vendorbackport",
            "evidence": { "symbolsChanged": 1, "bytesChanged": 512, "confidence": 0.98 },
            "trustDelta": { "score": -0.27, "reachabilityImpact": "reduced", "exploitabilityImpact": "down", "proofSteps": [ ... ] },
            "symbolDeltas": [ { "name": "ssl3_get_record", "changeType": "patched" } ]
          }
        ]
      }
    }
  ]
}

Notes grounded in BuildExtensionObject / BuildDeltaNode:

Standalone Mode (ExportAsStandalone)

Produces a minimal CycloneDX document wrapping the same changeTrace extension:

{
  "bomFormat": "CycloneDX",
  "specVersion": "1.7",
  "serialNumber": "urn:uuid:<random>",
  "version": 1,
  "metadata": {
    "timestamp": "<basis.analyzedAt 'O'>",
    "tools": [ { "vendor": "StellaOps", "name": "ChangeTrace", "version": "<basis.engineVersion>" } ]
  },
  "extensions": [ { "extensionType": "stella.change-trace", "changeTrace": { ... } } ],
  "components": [
    { "type": "container", "bom-ref": "change-trace-subject", "purl": "<subject.purl>", "hashes": [ { "alg": "SHA-256", "content": "<digest sans algo prefix>" } ] }
  ]
}

The components entry is emitted only when subject.purl is set. The serialNumber is a random urn:uuid (non-deterministic, observability only).

File Extensions


Version History

VersionDateChanges
1.0.02026-01-12Initial release

References