Skip to main content

Extra Object

Objects named extra are the only supported extension points in CTRF. They allow producers to include tool-specific or domain-specific metadata without adding unknown properties to the core format.

Unknown properties outside an extra object are invalid. Consumers must ignore extensions they do not recognize and must not reject a report solely because an extra object contains them.

Where extra Can Appear​

LocationExample use
RootReport-wide pipeline metadata
ResultsRun or shard context
ToolReporter-specific configuration
SummaryCustom aggregate metrics
TestTraceability or test-management data
EnvironmentCustom execution context
AttachmentArtifact metadata
StepStep-specific context
Retry attemptAttempt-specific data
InsightsCustom analysis metrics
BaselineCustom comparison metadata

Extension Keys​

Each property inside extra is a distinct extension. Extension keys should:

  • use a stable, recognizable namespace prefix that identifies the owner
  • include a delimiter such as . or /
  • use the same namespace prefix consistently throughout the document

For example:

{
"extra": {
"myorg.ci": {
"buildId": "build-1234",
"trigger": "pull_request"
}
}
}

The complete key myorg.ci is an opaque identifier. Consumers must not treat the delimiter as a path or infer a hierarchy from it.

Reserved prefixes

The ctrf. and ctrf/ prefixes are reserved for CTRF-defined extensions. Other producers must not use extension keys beginning with either prefix.

Extension Values​

An extension value may be any valid JSON type. Related fields should normally be grouped in an object under one extension key, while an extension containing one value may use a scalar.

The producer defines the structure and meaning of its values. CTRF does not validate their internal shape, and consumers must treat unrecognized extension values as opaque.

Documenting Extensions​

Extension producers should publish enough information for consumers that choose to support their metadata. Useful documentation includes:

  • the extension key and its owner
  • the CTRF object levels where it may appear
  • the structure and meaning of its value
  • any compatibility or versioning policy

A producer may publish a JSON Schema for an extension value when machine validation or generated types would be useful. That schema complements CTRF; it does not add the extension fields to the core CTRF schema.

Consistency Across a Document​

A producer contributing metadata at several levels should use the same namespace prefix at each location. Different producers can then add metadata without colliding:

{
"reportFormat": "CTRF",
"specVersion": "0.1.0",
"extra": {
"myorg.ci": {
"pipelineId": "pipeline-1234"
}
},
"results": {
"tool": {
"name": "example-runner"
},
"summary": {
"tests": 1,
"passed": 1,
"failed": 0,
"skipped": 0,
"pending": 0,
"other": 0,
"start": 1700000000000,
"stop": 1700000005000,
"extra": {
"myorg.ci": {
"retryBudgetUsed": 0
}
}
},
"tests": [
{
"name": "checkout flow completes",
"status": "passed",
"duration": 5000,
"extra": {
"myorg.ci": {
"featureFlag": "new-checkout-ui"
},
"acme.test-management": {
"issueKey": "SHOP-1234",
"testCycle": "Sprint 42"
}
}
}
],
"extra": {
"myorg.ci": {
"environment": "staging"
}
}
}
}

Here, myorg.ci contributes CI metadata at several levels and acme.test-management independently contributes test-management data.

Producer and Consumer Responsibilities​

Producers:

  • must place custom properties inside extra
  • should namespace extension keys to avoid collisions
  • should document the structure and semantics of extensions they publish
  • should use a consistent namespace prefix throughout a document

Consumers:

  • must ignore unrecognized extensions
  • must treat unrecognized extension keys and values as opaque
  • may validate or require an extension only when they explicitly support it
  • must not require custom fields to appear outside extra