Skip to content

Introduce deprecated annotations#6

Open
raginpirate wants to merge 1 commit intoUniversal-Commerce-Protocol:mainfrom
raginpirate:raginpirate/introduce-deprecation-annotations
Open

Introduce deprecated annotations#6
raginpirate wants to merge 1 commit intoUniversal-Commerce-Protocol:mainfrom
raginpirate:raginpirate/introduce-deprecation-annotations

Conversation

@raginpirate
Copy link

@raginpirate raginpirate commented Feb 6, 2026

Description

Adds first-class support for field deprecation with explicit transition semantics. This enables schema authors to signal upcoming breaking changes while preserving backwards compatibility during the transition period.

Motivation

When evolving APIs, transitions like required → optional or required → omit are breaking changes that affect different parties:

  • Loosening (required → optional): Receivers must update to handle absence
  • Tightening (optional → required): Senders must update to always include the field
  • Removal: Both parties need to adapt

Previously, there was no way to express "this field is currently required but will be removed" in a machine-readable way.

Changes

Introduces four new visibility values that encode both current runtime behaviour AND the target state:

Annotation Runtime Transition Burden on
deprecated_required_to_optional optional Loosening Receivers
deprecated_required_to_omit optional Removal Receivers
deprecated_optional_to_omit optional Removal Senders
deprecated_optional_to_required optional Tightening Senders

Why do we need 4 states instead of 1 or 2?

Theres two limitations at play that lead to this outcome:

  • No versioning of all commits to UCP, so one does not have a reference to "what existing clients have implemented for this field" potentially.
  • UCP annotations are symmetrical by default between the sender and receiver; we are introducing integration burdens on just one party for a given request/response (i.e. sender of request, please start ALWAYS sending it as its becoming required, or receiver of this response, stop expecting it even though it was required).

The naming convention deprecated_{current}_to_{target} makes the transition explicit and self-documenting.

@raginpirate raginpirate force-pushed the raginpirate/introduce-deprecation-annotations branch from 26a3294 to f846aa8 Compare February 6, 2026 14:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant