Skip to content

Versioning and Backwards Compatibility

DCP versions itself using Semantic Versioning at the protocol level. The dcp_version field in every envelope carries major.minor, and schemas are namespaced by major version in their $id (…/v1/…). Within a major version, only additive, optional changes are permitted, so an older validator keeps accepting newer-but-compatible messages.

By InterIP Networks · Last updated 2026-07-01.

dcp_version is a required string on every envelope, matching the pattern ^1\.[0-9]{1,4}$. Consumers MUST parse it as two separate integers — major and minor — never as a float. Treating it as a float breaks ordering: 1.10 would sort below 1.9 as a number, even though minor version 10 is newer than minor version 9.

Schemas mirror this: every schema file lives under schemas/v1/ on disk and declares an $id under https://schemas.devcopro.org/v1/…. The major-version segment in the path is the compatibility boundary, not a cosmetic detail.

Inside v1, DCP permits only additive, optional changes:

  • New optional fields on the envelope, an Event, or an entity.
  • New values in open controlled-vocabulary fields: status, verb, priority, severity, impact_level, dependency_type, review_type.
  • New worked examples, conformance cases, and documentation.

These fields are open tokens with a controlled vocabulary, not closed enums — adding a new value to any of them is not a breaking change. A consumer built against v1.0 MUST tolerate and pass through both unknown verbs and unknown enumerated values it does not recognize, rather than rejecting the message. This is the same forward-compatibility posture DCP takes toward extensions: unrecognized data is ignored, not treated as an error. It’s also why status is described as a vocabulary rather than a fixed state machine — the set of valid values is expected to grow.

What is closed, and why that’s different

Section titled “What is closed, and why that’s different”

Two structures are deliberately closed rather than open, because they act as single-responsibility guards on the protocol’s shape rather than descriptive labels:

  • entity_type — the eight canonical nouns (Project, Task, Dependency, ArchitectureImpact, Decision, ReviewRequest, Finding, Milestone).
  • The rel vocabulary — the eight relationship types usable in refs (relates_to, part_of, references, caused_by, derived_from, supersedes, concerns, blocks).

Adding a ninth entity type, or a new rel value, changes what DCP messages can structurally assert — that’s a major-version concern, not a minor one. This mirrors why entity_type and rel stay closed while verbs stay open: closed sets protect the boundaries of what DCP is allowed to mean; open sets let the vocabulary of how things change keep growing without breaking anyone.

Breaking changes go to a new major version

Section titled “Breaking changes go to a new major version”

Removing or renaming a field, changing a field’s type, making an optional field required, tightening a constraint so previously-valid messages become invalid, or changing either closed set — all of these require a new major version. Breaking changes ship under a new namespace, schemas/v2/…, with $id values under https://schemas.devcopro.org/v2/…. Critically, v1 remains valid and supported alongside v2 — adopting v2 is never forced, and existing v1 producers and consumers keep working.

Per SPEC §10.1, https://schemas.devcopro.org/v1/… is the canonical, permanent namespace for v1 schemas. It is stable and will not be rebased within the v1 major version — a future v2 would use its own …/v2/… namespace rather than reusing or renumbering this one. Because every $ref inside a v1 schema resolves as an absolute URL against this host, keeping it resolvable is part of DCP’s operational contract. That said, consumers SHOULD prefer bundled or cached copies of the schemas over live fetches at validation time — a network dependency in the validation hot path is an availability risk DCP doesn’t need you to take.

A validator written against v1.0 should still work correctly against a v1.4 message it has never seen, as long as the new fields and vocabulary values it doesn’t recognize are additive. That’s the whole compatibility promise: don’t reject what you don’t understand, as long as it arrived in the same major-version namespace. As of 2026-07-01, DCP v1 ships 14 JSON Schemas (2020-12) implementing this contract — the same schemas referenced from the event reference and exercised by the protocol’s conformance suite.

This additive-only discipline is also what distinguishes protocol versioning from transport concerns: DCP’s version number describes the shape of the message body, never how it was delivered, retried, or acknowledged — see the comparison with CloudEvents for how another spec’s specversion field plays a similar, narrowly-scoped role.