Skip to content

feat(permalink): add ucp/version protocol version parameter - #793

Open
gil-- wants to merge 1 commit into
Universal-Commerce-Protocol:mainfrom
gil--:gil/permalink-ucp-version
Open

feat(permalink): add ucp/version protocol version parameter#793
gil-- wants to merge 1 commit into
Universal-Commerce-Protocol:mainfrom
gil--:gil/permalink-ucp-version

Conversation

@gil--

@gil-- gil-- commented Sep 1, 2026

Copy link
Copy Markdown

Description

A shopping permalink is a browser GET with no version negotiation, and links outlive their authoring (emails, QR codes, social posts). Today nothing in the URL says which UCP release the field paths and compact item tokens were written against, so a Business cannot interpret an older link deterministically once its schemas move.

This adds ucp/version as a protocol parameter in the reserved ucp root of the permalink query string. It carries the same value as ucp.version in a profile (YYYY-MM-DD), so a permalink is pinned to one release.

https://merchant.example/buy/sku_123:1?ucp/version=2026-08-25&context/postal_code=94105&continue_to=/

Platform requirements

  • Include exactly one ucp/version in every generated permalink, set to the ucp.version of the profile the endpoint was discovered from (a supported_versions leaf may carry its own endpoint at its own version).
  • Never a pre-release identifier.

Business requirements

  • Select the release from ucp/version before resolving any field-path parameter or compact item token.
  • Accept the current release and every supported_versions release; SHOULD keep resolving retired releases (resolution-only compatibility).
  • Absent → resolve under a documented default release (SHOULD be the oldest supported); MUST NOT reject solely for absence.
  • Unknown but well-formed → fall forward to the oldest later supported release (else newest); treat inputs that no longer apply as handled shopping errors. Never answer a browser navigation with a UCP JSON version_unsupported error.
  • Malformed / duplicate values → existing malformed-permalink handling.
  • Consumed on resolution; SHOULD NOT appear on the redirect URL. All other ucp/* pointers are consumed and never applied as shopping state.

Changes

  • docs/specification/permalink.md: new Protocol Version (ucp/version) section; discovery, URL shape, query processing (release selection precedes classification), redirect resolution, error handling, and all examples updated.
  • source/services/shopping/permalink.openapi.json: shared ucp_version query parameter on both routes; x-ucp-query-semantics.control_parameters now ["ucp/version", "continue_to"].
  • source/schemas/shopping/permalink.json: description notes field paths are interpreted under the pinned release.

Opened as a draft for early feedback on the semantics (in particular default-when-absent = oldest supported, and fall-forward for unknown versions), before any Enhancement Proposal if maintainers consider this a significant change.

Category (Required)

  • Core Protocol
  • Governance/Contributing
  • Capability: New schemas (Discovery, Cart, etc.) or extensions. (Requires Maintainer approval)
  • Documentation: Updates to README, or documentations regarding schema or capabilities. (Requires Maintainer approval)
  • Infrastructure
  • Maintenance
  • SDK
  • Samples / Conformance
  • UCP Schema
  • Community Health (.github)

Related Issues

Follow-up to #523 (permalink capability).

Checklist

  • I have followed the Contributing Guide (including Conventional Commits title requirements and ! for breaking changes).
  • I have updated the documentation (if applicable).
  • My changes pass all local linting and formatting checks (ucp-schema lint source/, scripts/validate_examples.py, cspell, markdownlint).
  • I have added tests that prove my fix is effective or that my feature works. (No conformance tests cover permalinks yet.)
  • New and existing unit tests pass locally with my changes.
  • (For Core/Capability) I have included/updated the relevant JSON schemas.
  • I have regenerated Python Pydantic models by running generate_models.sh under python_sdk. (No generated model changes — only a schema description changed.)

Screenshots / Logs (if applicable)

Not a breaking change: ucp/version is optional for Businesses to receive, and existing permalinks without it resolve under the Business's default release.

@google-cla

google-cla Bot commented Sep 1, 2026

Copy link
Copy Markdown

Thanks for your pull request! It looks like this may be your first contribution to a Google open source project. Before we can look at your pull request, you'll need to sign a Contributor License Agreement (CLA).

View this failed invocation of the CLA check for more information.

For the most up to date status, view the checks section at the bottom of the pull request.

@gil--
gil-- force-pushed the gil/permalink-ucp-version branch from 9782fea to 20b280f Compare September 1, 2026 20:59
A permalink is a browser GET with no version negotiation, and links outlive
their authoring, so the URL must carry the release it was generated against.
Add `ucp/version` as a control parameter in the reserved `ucp` root:

- Platforms MUST include exactly one `ucp/version`, set to the `ucp.version`
  of the profile the endpoint was discovered from (dated release only).
- Businesses select the release before resolving any field path or compact
  item token; MUST accept current and `supported_versions` releases and
  SHOULD keep resolving retired ones; absent -> documented default (SHOULD be
  oldest supported); unknown well-formed -> fall forward to the oldest later
  release; never answer with a UCP JSON `version_unsupported` error.
- `ucp/version` is consumed on resolution and SHOULD NOT appear on the
  redirect URL; other `ucp/*` pointers are consumed and never applied.

Updates the OpenAPI binding (shared `ucp_version` parameter, control
parameter list) and the capability schema description accordingly.
@gil--
gil-- force-pushed the gil/permalink-ucp-version branch from 20b280f to 3c51764 Compare September 1, 2026 20:59
@gil--
gil-- marked this pull request as ready for review September 3, 2026 13:27
@damaz91 damaz91 added the status:needs-triage Signal that the PR is ready for human triage label Sep 3, 2026
@carolinerg1 carolinerg1 added status:under-review gov:needs-gc-review and removed status:needs-triage Signal that the PR is ready for human triage labels Sep 3, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants