v1.1   Status: Released  ·  2026-05-12  ·  Apache 2.0

ChangeSpec 1.1 Specification

A standard event format for communicating software changes from producers to consumers.

Abstract #

ChangeSpec defines a standard event format for communicating software changes from producers (vendors, library maintainers, service operators) to consumers (developers, agents, compliance teams). A ChangeSpec event is a self-describing JSON object with a fixed set of required fields and a rich set of optional fields covering severity, affected version ranges, migration guidance, and source attribution.

This document specifies:

  1. The core event structure and field semantics
  2. The category taxonomy
  3. The severity taxonomy
  4. Vendor identifier format
  5. Source attribution model
  6. Signing and verification for publisher-verified events
  7. Envelope format and CloudEvents compatibility
  8. Transport bindings: HTTPS webhook, MCP, RSS/Atom, polling API
  9. Extension field convention
  10. Backward compatibility rules

Conformance #

The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

A conforming event is a JSON object that validates against the ChangeSpec JSON Schema (schema.json) included in this repository.

A conforming producer generates events that are conforming events.

A conforming consumer accepts conforming events and ignores unknown fields (including extension fields) without error.


1. Core Event Structure #

A ChangeSpec event is a JSON object. All field names are lowercase with underscores.

1.1 Required Fields #

Field Type Description
specversion string Must be "1.1". ("1.0" is accepted by conforming consumers for backward compatibility.)
id string Globally unique event identifier. Producers SHOULD use the format cs_ followed by a ULID or UUIDv4. Must be stable - the same logical event must always have the same id.
vendor_id string Identifies the vendor or package. See Section 3.
category string Change category. One of the values defined in Section 4.
severity string Change severity. One of the values defined in Section 5.
title string Short, human-readable change title. Maximum 200 characters. Plain text; no markdown.
summary string 1-5 sentence plain-English description of what changed and what the impact is. No markdown. Maximum 2000 characters.
published_at string RFC 3339 timestamp when this event was published. Example: "2026-04-10T14:00:00Z".
source_type string Indicates how this event was produced. One of: publisher_verified, crawled, community. See Section 6.

1.2 Optional Fields #

Field Type Description
effective_date string RFC 3339 full-date when the change takes effect.
source_url string URL of the primary source document for this event.
affected_versions string Semver range string (npm semver syntax) describing which versions are affected.
fixed_in_version string Exact semver version where this issue is resolved.
migration_hint string One or two sentences describing the immediate action a consumer should take. Maximum 500 characters.
migration_url string URL of a migration guide or detailed remediation instructions.
confidence_score number Float in [0.0, 1.0]. Producer confidence in the classification. 1.0 for publisher-verified events.
sunset_date string RFC 3339 full-date. For deprecations: when the deprecated feature is removed.
cve_id string CVE identifier in format CVE-YYYY-NNNNN. For security events only.
cvss_score number CVSS base score (0.0-10.0). For security events only.
cvss_vector string CVSS vector string.
affected_systems array of string Named systems or products within the vendor that are affected.
affected_sections array of string Document section headers affected (relevant for TOS/DPA changes).
action_required boolean Whether consumers must take action. true for breaking changes and critical security events.
recommended_reviewers array of string Suggested reviewer roles: engineering, security, legal, compliance, procurement.
tags array of string Freeform tags for filtering. Maximum 20 tags, each maximum 50 characters.
do_not_install boolean When true, tooling MUST NOT install the affected versions. Only valid when category is retraction. Added in v1.1.
provenance_invalidated boolean When true, signals that build attestations (SLSA, Sigstore) for the affected versions are valid but from a compromised pipeline and MUST NOT be trusted. Added in v1.1.
last_known_good_version string Exact semver version of the last version the vendor considers safe to install. Provided by the vendor in retraction events. Added in v1.1.
retraction_reason string Machine-readable reason code for a retraction. One of: supply_chain_compromise, critical_defect, accidental_publish, security_vulnerability. Added in v1.1.
signature object Ed25519 signature block. Present only on publisher_verified events. See Section 7.
ext:* any Extension fields. See Section 10.

1.3 Field Constraints #

  • All string fields containing URLs MUST be valid absolute URIs (RFC 3986).
  • published_at MUST be a valid RFC 3339 datetime string.
  • effective_date and sunset_date, when present, MUST be valid RFC 3339 full-date strings (YYYY-MM-DD).
  • id MUST be unique across all events from a given producer.
  • title MUST NOT contain newlines.
  • summary MUST be plain text. Producers MUST NOT include markdown syntax, HTML, or other markup.

2. Minimal Conforming Event #

The smallest valid ChangeSpec event:

{
  "specversion": "1.1",
  "id": "cs_01HXYZ1234ABCD",
  "vendor_id": "acme",
  "category": "informational",
  "severity": "informational",
  "title": "Documentation typo fix in authentication section",
  "summary": "Corrected a typo in the authentication section of the developer documentation. No behavior change.",
  "published_at": "2026-04-10T14:00:00Z",
  "source_type": "crawled"
}

3. Vendor Identifier Format #

The vendor_id field identifies the vendor or package. It uses a namespaced format to avoid collisions between ecosystems.

3.1 Format Rules

A vendor_id MUST match the pattern:

vendor_id = [namespace ":"] slug
namespace = 1*( ALPHA / DIGIT )
slug      = 1*( ALPHA / DIGIT / "-" / "_" )

3.2 Namespace Conventions

NamespaceMeaningExample
(none)Named company or service, globally uniquestripe, anthropic, github
npmnpm registry packagenpm:lodash
pypiPython Package Indexpypi:requests
cargoRust crates.iocargo:serde
gemRubyGemsgem:rails
mavenMaven Centralmaven:org.springframework:spring-core
goGo modulego:golang.org/x/net
dockerDocker Hub imagedocker:nginx
ghGitHub repositorygh:facebook/react

3.3 Registry

Vendor IDs without a namespace represent named services and companies. The ChangeSpec registry (maintained by Roboticforce Inc.) is the canonical source for no-namespace vendor IDs. Registry submissions are open.


4. Category Taxonomy #

The category field classifies what kind of change this event represents. Categories drive routing and filtering in consuming systems.

ValueDescription
api_breakingA change to a public API, SDK, or service interface that is not backward compatible. Callers that do not update their code will break.
api_deprecationA feature, endpoint, parameter, or behavior is deprecated and will be removed in a future version. Not immediately breaking. Carries a sunset date.
securityA security vulnerability, patch, or advisory. Use for CVEs, credential exposure risks, and authentication changes that affect security posture.
data_handlingA change to how user or customer data is stored, processed, shared, or retained. Covers DPA changes, subprocessor additions or removals, data residency changes, and retention policy updates.
liabilityA change to terms of service, SLA, indemnification clauses, limitation of liability, or warranty terms.
pricingA change to pricing, billing, plan limits, free tier entitlements, or trial terms.
tosA change to terms of service, acceptable use policy, or community guidelines not covered by liability.
retractionA signed vendor declaration that one or more versions should not be installed or used. Indicates a supply-chain compromise, critical defect, or other condition making the package unsafe. Carries do_not_install, last_known_good_version, and optionally provenance_invalidated. Added in v1.1.
cosmeticA change to documentation, UI text, marketing copy, or visual design. No functional impact.
informationalA change that does not fit other categories and requires no action.

4.1 Category Selection Guidance

Categories are mutually exclusive. A single event has one category. When a change fits multiple categories, use the most specific or highest-impact category:

  • A DPA update that also constitutes a TOS change: use data_handling
  • A security patch that also breaks an API: use security
  • A pricing change that is also a TOS update: use pricing
  • A new subprocessor announced in a blog post: use data_handling

5. Severity Taxonomy #

The severity field communicates urgency and potential impact.

ValueDescription
criticalImmediate action required. Examples: actively exploited vulnerability (CVSS >= 9.0), breaking change already in production with no migration path, data breach notification.
highAction required within a short timeframe (days to weeks). Examples: breaking API change with migration path, CVSS 7.0-8.9 vulnerability, major pricing increase with short notice.
mediumAction required before a future deadline. Examples: deprecation with a 6-month sunset, CVSS 4.0-6.9 vulnerability, subprocessor change requiring DPA review.
lowAdvisory. No immediate action required. Examples: long-horizon deprecations, minor pricing restructuring with no net increase, informational TOS clarification.
informationalNo action required. Purely informational. Examples: documentation improvements, minor wording changes, cosmetic updates.

5.1 Severity and Category Relationship

Recommended pairings (producers MAY deviate when warranted):

CategoryTypical Severity Range
retractioncritical
api_breakinghigh to critical
api_deprecationlow to medium
securitymedium to critical
data_handlingmedium to high
liabilitymedium to high
pricinglow to high
toslow to medium
cosmeticinformational
informationalinformational to low

6. Source Attribution #

The source_type field communicates how this event was produced and how much trust a consumer should place in the classification.

ValueDescription
publisher_verifiedThe vendor that owns the vendor_id pushed this event directly through a publisher API. Eligible for signing (see Section 7).
crawledThe event was generated by an automated system that detected a change. Classification was performed by AI or automated rules. confidence_score SHOULD be set.
communityThe event was submitted by a community member who is not the vendor. Subject to moderation. confidence_score SHOULD be set lower than for crawled unless independently verified.

6.1 Confidence Score

The confidence_score field is a float in [0.0, 1.0]:

  • publisher_verified events: SHOULD be 1.0
  • crawled events: SHOULD reflect AI model confidence. Values below 0.7 indicate uncertain classification and SHOULD trigger human review.
  • community events: producers SHOULD default to 0.6 unless verification has been performed.

7. Signing and Verification #

Publisher-verified events MAY be signed using Ed25519 to allow consumers to verify authenticity.

7.1 Why Ed25519

Ed25519 provides compact signatures (64 bytes), fast verification, and is not vulnerable to weak random number generation attacks that affect ECDSA. It is implemented in the Go standard library (crypto/ed25519), Node.js (crypto), and Python (cryptography package).

7.2 Signature Object

{
  "signature": {
    "alg": "ed25519",
    "key_id": "stripe-2026-01",
    "value": "<base64url-encoded 64-byte signature>",
    "signed_fields": ["id", "vendor_id", "category", "severity", "title", "summary", "published_at"]
  }
}

7.3 Signature Input Construction

The signature is computed over a canonical byte string:

  1. For each field name in signed_fields, in the order listed:
    1. Append the field name as UTF-8 bytes
    2. Append a newline character (\n)
    3. Append the field value serialized as its JSON value
    4. Append a newline character (\n)
  2. Sign the resulting byte string with Ed25519.

7.4 Key Distribution

Vendors publish their Ed25519 public keys at a well-known URL:

https://{vendor-domain}/.well-known/changespec-keys.json
{
  "keys": [
    {
      "key_id": "stripe-2026-01",
      "alg": "ed25519",
      "public_key": "<base64url-encoded 32-byte public key>",
      "valid_from": "2026-01-01",
      "valid_until": "2027-01-01"
    }
  ]
}

7.5 Verification Steps

A conforming consumer verifying a signed event MUST:

  1. Check that source_type is publisher_verified.
  2. Retrieve the public key identified by signature.key_id.
  3. Check that the current time is within the key's valid_from/valid_until window.
  4. Reconstruct the signature input from signed_fields and their values.
  5. Verify the Ed25519 signature.
  6. Reject the event if verification fails.

7.6 Key Separation from CI (v1.1) #

Signing keys used for publisher_verified events, and especially for retraction events, MUST be stored and accessed outside the CI/CD pipeline that builds and publishes the package. The signing step MUST be performed in a context where CI credentials do not have access to the private key material.

This requirement exists because build provenance (SLSA, Sigstore) attests that a package was built in a specific CI environment - it does not attest vendor intent. If signing keys are accessible from within the same CI context, a compromised pipeline can produce both valid attestations and valid ChangeSpec signatures. Keys held separately are the orthogonal signal that provenance alone cannot provide.

Acceptable key storage patterns include: hardware security modules (HSM), secrets managers with CI access blocked by policy, or manual out-of-band signing workflows for retraction events.


8. Envelope Format #

8.1 Standalone Format

The default transport format is a standalone JSON object. The event fields defined in this spec are the top-level keys.

8.2 CloudEvents Envelope

ChangeSpec events MAY be transported inside a CloudEvents 1.0 envelope.

CloudEvents FieldValue
specversion"1.0" (CloudEvents version)
idThe ChangeSpec event id
source"https://changespec.com/vendors/{vendor_id}"
type"com.changespec.change.v1"
datacontenttype"application/json"
timeThe ChangeSpec published_at value
dataThe complete ChangeSpec event object

9. Transport Bindings #

ChangeSpec defines four transport bindings. Platforms are free to implement any or all of them.

9.1 HTTPS POST Webhook #

The event is delivered as an HTTP POST request with:

  • Content-Type: application/json
  • Body: standalone ChangeSpec event JSON

Webhook security follows the Standard Webhooks specification (standardwebhooks.com).

9.2 MCP (Model Context Protocol) #

ChangeSpec events are returned by MCP tool calls as JSON objects. Conforming MCP implementations MUST return the standalone ChangeSpec event format in tool responses. Events returned by MCP tools MAY be truncated when context length is a concern; truncation MUST be indicated by setting _truncated: true in the returned object.

9.3 RSS/Atom Feed #

RSS 2.0 field mapping:

RSS FieldChangeSpec Source
<title>title
<description>summary
<link>source_url
<pubDate>published_at (RFC 822 format)
<guid>id
<category>category

The full ChangeSpec event object SHOULD be embedded as a <changespec:event> extension element with namespace xmlns:changespec="https://changespec.com/ns/1.0".

9.4 Polling API #

Platforms providing a polling API MUST return events in the following envelope:

{
  "events": [
    { ... ChangeSpec event ... }
  ],
  "next_cursor": "opaque-pagination-token",
  "has_more": true
}

10. Extension Fields #

Producers MAY add extension fields using the ext: prefix:

{
  "ext:compliance.osfi_b10": true,
  "ext:compliance.dora_article": "32",
  "ext:internal.ticket_id": "ENG-4521",
  "ext:risk.vendor_tier": 1
}

Extension field namespaces SHOULD be registered to avoid conflicts. A public namespace registry is planned at changespec.com/extensions. Conforming consumers MUST ignore unknown extension fields without error.


11. Backward Compatibility Rules #

11.1 Producer Rules

  • Producers MUST set specversion to the version of this spec they conform to.
  • Producers MUST NOT remove required fields.
  • Producers MAY add extension fields at any time.

11.2 Consumer Rules

  • Consumers MUST ignore fields they do not recognize, including extension fields.
  • Consumers MUST NOT reject events solely because they contain unknown fields.

11.3 Spec Evolution Rules

  • Patch releases (1.0.1): Clarifications only. No field additions, removals, or semantic changes.
  • Minor releases (1.1, 1.2): May add optional fields. May extend enum values in category and severity. Existing values MUST NOT be removed or redefined.
  • Major releases (2.0): May change required fields. Require a formal deprecation period of at least 12 months.

12. Security Considerations #

12.1 Input Validation

Consumers MUST validate all incoming events against the JSON Schema before processing. Malformed events MUST be rejected before any field values are processed.

12.2 URL Fields

All URL fields (source_url, migration_url) are untrusted input. Consumers that fetch content from these URLs MUST use a safelist of permitted URL schemes, implement timeouts and size limits, and not render fetched content without sanitization.

12.3 Signature Verification

Consumers that accept publisher_verified events from untrusted transport layers SHOULD verify signatures. Consumers receiving events from a trusted platform that has already performed verification MAY omit re-verification.

12.4 Replay Attacks

The id field is a stable identifier. Consumers SHOULD implement idempotency using id to prevent processing duplicate deliveries.


Appendix A: Field Quick Reference #

Required fields: specversion, id, vendor_id, category, severity, title, summary, published_at, source_type

Security fields: cve_id, cvss_score, cvss_vector, fixed_in_version

Version fields: affected_versions, fixed_in_version

Temporal fields: published_at, effective_date, sunset_date

Guidance fields: migration_hint, migration_url, action_required, recommended_reviewers

Attribution fields: source_url, source_type, confidence_score

Signing fields: signature


Appendix B: MIME Type #

The MIME type for a ChangeSpec event document is:

application/vnd.changespec+json

When serving events over HTTP, producers SHOULD set Content-Type: application/vnd.changespec+json.


Appendix C: Normative References #