Skip to content

fix: clarify version negotiation#200

Open
igrigorik wants to merge 8 commits intomainfrom
fix/version-negotiation
Open

fix: clarify version negotiation#200
igrigorik wants to merge 8 commits intomainfrom
fix/version-negotiation

Conversation

@igrigorik
Copy link
Contributor

Currently, spec requires businesses to process any request from a platform at an older protocol version (via "MUST process if platform ≤ business"). This imposed an unbounded backwards-compatibility obligation — every business must support every historical version indefinitely. Further, the negotiation mechanism is underspecified and missing a primitive for business to advertise which older versions are supported.

Update: businesses can list accepted versions via a supported_versions array in their profile. Platforms can discover the list by fetching the profile from well-known and MUST support the business's declared version to initiate a request -- the request carries a profile link with the version platform wants to use. The business validates the platform's version against its supported_versions list and rejects with 422 if there is no match.

Checklist

  • Bug fix (non-breaking change which fixes an issue)
  • Documentation update
  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation

  Prior spec required businesses to process any request from a platform
  at an older protocol version ("MUST process if platform ≤ business").
  This imposed an unbounded backwards-compatibility obligation — every
  business must support every historical version indefinitely.

  New model: the business's protocol version is canonical. Businesses
  declare accepted versions via a `supported_versions` array in their
  profile (defaults to [version] when omitted). Platforms MUST support
  the business's declared version to initiate a request. The business
  validates the platform's version against its supported_versions list
  and rejects with 422 if there is no match.

  This also reclassifies version_unsupported from a negotiation result
  (HTTP 200 with checkout message schema) to a protocol error (HTTP 422),
  since version mismatch is a pre-negotiation gate check — the buyer
  cannot resolve a protocol incompatibility.
@igrigorik igrigorik added this to the Working Draft milestone Feb 20, 2026
@igrigorik igrigorik added the TC review Ready for TC review label Feb 24, 2026
  The intersection algorithm matched capabilities by name only, without
  specifying how versions are resolved when multiple are present. Add
  explicit step: compute mutual version set, select highest, exclude
  capability if no mutual version exists.
  Protocol and capability versions are independent axes — a flat profile
  cannot express which capabilities are available at which protocol version.
  supported_versions becomes a map from protocol version to profile URI,
  where each URI points to a complete, self-contained profile for that
  version. Platform bootstrap: fetch /.well-known/ucp, match version or
  follow the URI in supported_versions, get an unambiguous capability set.

  Key design choices:
  - uri-reference format allows relative paths (/.well-known/ucp/2026-01-11)
  - Current version served by the root profile; only older versions in map
  - Version-specific profiles are leaf documents (no supported_versions)
  - Both platform and business obligations explicit at version mismatch
  Extension schemas SHOULD declare min_protocol_version to indicate the
  minimum UCP protocol version they require. This makes the protocol
  dependency explicit and verifiable, rather than relying on profile
  publishers to self-attest compatibility.

  The schema author declares the requirement; the profile publisher
  selects and advertises compatible versions. When present, platforms
  and businesses SHOULD verify negotiated version >= min_protocol_version
  during schema resolution. Incompatible extensions are excluded from
  the active capability set with orphan re-pruning.

  Changes:
  - New "Protocol Version Constraint" subsection under Extension Schema
    Pattern with field definition, example, and verification contract
  - Resolution Flow gains step 4 (Protocol Compatibility) between
    Schema Fetch and Compose
@github-actions
Copy link
Contributor

Super-linter summary

Language Validation result
BIOME_LINT Pass ✅
GIT_MERGE_CONFLICT_MARKERS Pass ✅
JSON Pass ✅
MARKDOWN Pass ✅
PRE_COMMIT Pass ✅
TRIVY Pass ✅

All files and directories linted successfully

For more information, see the
GitHub Actions workflow run

Powered by Super-linter

@igrigorik igrigorik marked this pull request as ready for review February 25, 2026 18:28
@igrigorik igrigorik requested review from a team as code owners February 25, 2026 18:28
@igrigorik
Copy link
Contributor Author

@deinck6 @sinhanurag great feedback, ptal at updated draft.

@igrigorik igrigorik requested a review from deinck6 February 25, 2026 18:29
The business's profile at `/.well-known/ucp` describes capabilities for
its current protocol version. Businesses that support older protocol
versions **SHOULD** publish version-specific profiles and advertise them
via the `supported_versions` field — a map from protocol version to
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we'd also need some concept of deprecation cycle baked in. I assume businesses will not want to support every version forever, but need some way to signal to platforms "this will no longer be in supported_versions on this date"

flow between platform and business.
UCP separates protocol version compatibility from capability negotiation.
The business's profile at `/.well-known/ucp` describes capabilities for
its current protocol version. Businesses that support older protocol
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is "current" synonymous with "latest"/ "most recent" here?

advertises compatible versions in their profile.

If `min_protocol_version` is present, platforms and businesses
**SHOULD** verify the negotiated protocol version is >=
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why should, and not must here?

Businesses that support older protocol versions **SHOULD** include a
`supported_versions` object mapping each older version to a
version-specific profile URI. See [Protocol Version](#protocol-version)
for details.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This flow requires an additional HTTP fetch when the platform's version doesn't match version.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

TC review Ready for TC review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants