You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Goal: Improve UCP repo structure & developer tooling to facilitate new vertical support. Status: Proposal (Inviting feedback from Community & Tech Council discussion) Related:#499, #484
Summary
This proposal outlines the restructuring of the Universal Commerce Protocol (UCP) repositories and schemas to support multiple verticals (such as Food) alongside the existing Shopping specification. It details the phases required to transition from a retail-centric codebase to a modular, vertical-agnostic architecture, enabling UCP to scale as a multi-vertical standard.
Motivation
UCP was started with "Shopping" as the first domain. However, as UCP expands to verticals like Food (menu exploration, cart building, checkout fulfillment), the current repository structure is inefficient.
Currently, retail-specific schemas and documentation are treated as the default "core" of UCP (e.g., checkout and cart specs living at the root of docs/specification/). Furthermore, foundational schemas like signals.json live under shopping specific paths (e.g., source/schemas/shopping/types), and shared transactional concepts like payment instruments are not consolidated as a horizontal layer.
To support multiple verticals without duplication and allow them to evolve independently, we must:
Delineate core/common types from vertical-specific types
Restructure the directory layout of the main ucp repo (specs and schemas)
Align developer tooling (samples, conformance) and SDKs to support vertical-scoped constructs
[Not in scope for this RFC] Design a standard process to deal with PR triage and review
This refactor will ensure that UCP remains robust, easy to navigate for readers, and simple to maintain for implementers.
Problem 1 (File Structure): The docs/specification/ directory contains retail-specific files at the root (e.g., checkout.md, cart.md).
Problem 2 (Rendering Logic): The documentation rendering script (main.py) is tightly coupled to the Shopping vertical layout and assumes a single-vertical structure when it comes to macro definitions. We also need to make reference.md and site navigation bar clearly categorize capabilities under vertical headers (Shopping, Common).
What lands
Move existing retail-specific specifications from the root of docs/specification/ to docs/specification/shopping/ (e.g., checkout.md, cart.md, order.md and their -mcp.md/-rest.md bindings).
Update main.py to be vertical-agnostic, dynamically generating the documentation site navigation by scanning the vertical subdirectories.
Update the UCP website navigation sidebar to group specifications under vertical headers:
Problem 1 (Common Types): Foundational types like totals.json, signals.json, and context.json are treated as Shopping-specific types (living specifically under source/schemas/shopping/types/).
Problem 2 (Payment Modelling): Payments (instrument modelling) are critical regardless of the vertical, but currently these schemas live under a Shopping specific path instead of being defined as a common horizontal construct.
Refactor payment instrument schemas under source/schemas/common/ (or common/types/).
Update all references ($ref) in existing schemas to point to the new centralized common schema locations and also fix any references in specification documentation.
The samples/ and conformance/ repositories are monolithic and assume a retail-only environment. Conformance tests are coupled to shopping mock stores, making it impossible to run conformance tests for other verticals independently.
As we add more verticals, maintaining duplicate test runners and boilerplate code across multiple repositories will lead to high maintenance overhead.
What lands
Restructure the conformance/ repository into a core test runner and vertical-specific test plugins:
Update the conformance orchestrator to dynamically load and execute the appropriate vertical plugins based on the capabilities declared in the business's /.well-known/ucp profile (supporting mixed-vertical profiles) or what files have been modified in the draft PR.
SDK code generators output models into a single flat namespace, leading to naming collisions for capabilities that share names across verticals (e.g., Cart in Shopping vs Cart in another vertical).
Cross-Namespace Referencing: During generation, vertical-specific models must reference common models (e.g., shopping/checkout.py needs common/totals.py). The generator must resolve these dependencies into correct local imports without creating circular dependencies.
What lands (Assuming Alt A is selected from Open Questions 1)
To align with the recommended Alternative A packaging strategy, we will restructure both SDK repos to support multiple verticals inside a single package release:
Directory & Namespace Restructure
We will transition the source code structure to segregate models by vertical namespace:
Python (python-sdk):
Restructure src/ucp_sdk/ to introduce namespace submodules:
Restructure src/ to support subpath exports within the single @ucp-js/sdk package:
src/
├── common/ # exported as @ucp-js/sdk/common
└── shopping/ # exported as @ucp-js/sdk/shopping
We will configure the exports field in package.json to enable clean subpath imports for modern JS bundlers without requiring multiple package publishes:
Multi-target Generation: Update generate_models.sh in both repositories to invoke the code generator independently for each vertical subdirectory, pointing to the restructured schema paths (e.g. schemas/common/, schemas/shopping/).
Reference Resolution: Configure preprocessor scripts (e.g. preprocess_schemas.py for Python SDK) to resolve relative JSON Schema $ref paths (e.g., ../common/types/totals.json) into correct package-relative imports (e.g., from ucp.sdk.common.types import Totals) instead of copying the referenced schema inline or failing.
Implementation Sequence and Suggested PR Titles
Phase
Repo
Suggested PR title
1
ucp
refactor: Restructure docs/specification into vertical subdirectories
1
ucp
chore: Make docs rendering logic in main.py vertical-agnostic
2
ucp
refactor: Move common schemas to common/types
2
ucp
refactor: Move payment schemas to common horizontal constructs
3
samples
refactor: Restructure samples repo to support vertical subdirectories
3
conformance
refactor: Restructure conformance repo and implement plugin-based architecture for multi-vertical testing
4
python-sdk
refactor: Update python-sdk generator to support vertical-scoped packages
4
js-sdk
refactor: Update js-sdk generator to support vertical-scoped packages
Developer contribution process: This RFC does not look at process enhancements for PR reviews or escalation channels for DTC.
Defining vertical business logic: We are strictly restructuring the repository and schemas for readiness; defining the actual schemas for new verticals is out of scope.
Open questions
1. SDK Package Structure & Distribution
How should the generated SDKs be packaged and distributed to developers? We propose 3 approaches based on well-known industry patterns:
[Recommended] Alternative A: Monolithic Package with Vertical Namespaces
All verticals and common models are shipped in a single package (e.g., pip install ucp-sdk or npm install @ucp-js/sdk), segregated by namespaces.
Industry Reference: Stripe SDKs (all services in one package)
Pros:
Simplicity: Developers only manage a single dependency.
Unified Versioning: SDK version maps directly to UCP release version.
Frictionless Cross-Vertical Use: Easy to use multiple verticals (e.g., Shopping and a related vertical like Food) in the same application.
Cons:
Package Size: Developers inherit models for verticals they do not use (primarily a concern in frontend JS environments, though mitigable via tree-shaking).
Alternative B: Modular Packages (Multi-Package Monorepo)
Each vertical and the common core are published as separate packages (e.g., @ucp-js/sdk-common, @ucp-js/sdk-shopping, @ucp-js/sdk-food).
Industry Reference: Google Cloud Client Libraries
Pros:
Minimal Footprint: Developers only install what they need, minimizing dependency bloat.
Independent Updates: A bug fix in one vertical's SDK does not require releasing a new version of all other vertical SDKs.
Cons:
Dependency Management: Higher cognitive load for developers using multiple verticals.
Publishing Overhead: Requires complex monorepo tooling (e.g., npm workspaces) and CI/CD pipelines to manage inter-package dependencies and publish N packages.
Alternative C: Core Package + Dynamic Schema Resolution (No Generated Models)
Ship a lightweight "Core" SDK that contains no hardcoded vertical models. Instead, the SDK dynamically downloads or bundles UCP JSON schemas and performs runtime validation/serialization using a generic processor.
Industry Reference: AWS Boto3/Botocore (loads service definitions from JSON at runtime)
Pros:
Zero Code Generation: No need to run generators for different languages; SDK remains thin.
Instant Support: Immediately supports new capability versions or verticals just by updating the JSON schema files.
Cons:
No Compile-time Safety: Developers lose IDE autocomplete and compile-time type checking for vertical entities (e.g., no typed Checkout or Cart classes in IDE).
Runtime Performance: Parsing schemas and dynamic validation adds runtime overhead.
2. Extension Rendering & Navigation
How should extensions that are used across capabilities or even verticals (in the case of common extensions like Loyalty) be rendered in the documentation site navigation?
[Recommended] Alternative A: Contextual Nesting (Current State)
Extensions are documented under the capability that leverages them (e.g., Shopping Discounts extension nested under Shopping Checkout capability). If another capability needs it, it is referenced again in the nav.
Pros:
Contextual: the reader sees the extension in the flow of the capability.
Explicit: in the case that there are vertical specific extensions with the same name (e.g., Shopping Fulfillment vs. Food Fulfillment), it's very clear to the user which one is currently being referenced by the capability.
Cons:
Duplicate entries in the sidebar if multiple capabilities or verticals use the same extension (bloated nav bar).
Alternative B: Centralized "Extensions" Directory
Move all extension documentation to a top-level specification/extensions directory, grouping them by vertical or as common. Individual capability’s md files will have a table listing out all the supported extensions.
Pros: Eliminates sidebar duplication; highlights extensions as reusable components.
Cons: Disconnects the extension from the core capability documentation, forcing readers to jump between sections to understand the full flow.
Summary
This proposal outlines the restructuring of the Universal Commerce Protocol (UCP) repositories and schemas to support multiple verticals (such as Food) alongside the existing Shopping specification. It details the phases required to transition from a retail-centric codebase to a modular, vertical-agnostic architecture, enabling UCP to scale as a multi-vertical standard.
Motivation
UCP was started with "Shopping" as the first domain. However, as UCP expands to verticals like Food (menu exploration, cart building, checkout fulfillment), the current repository structure is inefficient.
Currently, retail-specific schemas and documentation are treated as the default "core" of UCP (e.g., checkout and cart specs living at the root of
docs/specification/). Furthermore, foundational schemas likesignals.jsonlive under shopping specific paths (e.g.,source/schemas/shopping/types), and shared transactional concepts like payment instruments are not consolidated as a horizontal layer.To support multiple verticals without duplication and allow them to evolve independently, we must:
ucprepo (specs and schemas)samples,conformance) and SDKs to support vertical-scoped constructsThis refactor will ensure that UCP remains robust, easy to navigate for readers, and simple to maintain for implementers.
Proposed phases
Phase 1: Restructure specification documentation
Target:
ucpProblem statements
docs/specification/directory contains retail-specific files at the root (e.g.,checkout.md,cart.md).main.py) is tightly coupled to the Shopping vertical layout and assumes a single-vertical structure when it comes to macro definitions. We also need to makereference.mdand site navigation bar clearly categorize capabilities under vertical headers (Shopping, Common).What lands
docs/specification/todocs/specification/shopping/(e.g.,checkout.md,cart.md,order.mdand their-mcp.md/-rest.mdbindings).main.pyto be vertical-agnostic, dynamically generating the documentation site navigation by scanning the vertical subdirectories.Phase 2: Refactor additional common schemas
Target:
ucpProblem statements
totals.json,signals.json, andcontext.jsonare treated as Shopping-specific types (living specifically undersource/schemas/shopping/types/).What lands
source/schemas/shopping/types/tosource/schemas/common/types/. This will include files like:totals.json(pricing breakdowns)signals.json(system-derived data)context.json(provisional buyer context)source/schemas/common/(orcommon/types/).$ref) in existing schemas to point to the new centralizedcommonschema locations and also fix any references in specification documentation.Phase 3: Restructure developer tooling repos
Target:
samples,conformanceProblem statements:
samples/andconformance/repositories are monolithic and assume a retail-only environment. Conformance tests are coupled to shopping mock stores, making it impossible to run conformance tests for other verticals independently.What lands
conformance/repository into a core test runner and vertical-specific test plugins:conformance/core/: Handles profile discovery (/.well-known/ucp) & negotiation, and error schema assertions.conformance/shopping/,conformance/<vertical>/: Vertical-specific plugins containing semantic test assertions (e.g., validating cart totals calculations or fulfillment logic)./.well-known/ucpprofile (supporting mixed-vertical profiles) or what files have been modified in the draft PR.Phase 4proposal in [RFC] Proposal: UCP Open Source Unified Toolchain and SDK Generation #484.Phase 4: Restructure SDK setup
Target:
python-sdk,js-sdk(and other languages in the future)Problem statements
Cartin Shopping vsCartin another vertical).shopping/checkout.pyneedscommon/totals.py). The generator must resolve these dependencies into correct local imports without creating circular dependencies.What lands (Assuming Alt A is selected from Open Questions 1)
To align with the recommended Alternative A packaging strategy, we will restructure both SDK repos to support multiple verticals inside a single package release:
Directory & Namespace Restructure
We will transition the source code structure to segregate models by vertical namespace:
python-sdk):src/ucp_sdk/to introduce namespace submodules:js-sdk):src/to support subpath exports within the single@ucp-js/sdkpackage:exportsfield inpackage.jsonto enable clean subpath imports for modern JS bundlers without requiring multiple package publishes:Generator Toolchain Adaptation
generate_models.shin both repositories to invoke the code generator independently for each vertical subdirectory, pointing to the restructured schema paths (e.g.schemas/common/,schemas/shopping/).preprocess_schemas.pyfor Python SDK) to resolve relative JSON Schema$refpaths (e.g.,../common/types/totals.json) into correct package-relative imports (e.g., fromucp.sdk.common.types import Totals) instead of copying the referenced schema inline or failing.Implementation Sequence and Suggested PR Titles
ucprefactor: Restructure docs/specification into vertical subdirectoriesucpchore: Make docs rendering logic in main.py vertical-agnosticucprefactor: Move common schemas to common/typesucprefactor: Move payment schemas to common horizontal constructssamplesrefactor: Restructure samples repo to support vertical subdirectoriesconformancerefactor: Restructure conformance repo and implement plugin-based architecture for multi-vertical testingpython-sdkrefactor: Update python-sdk generator to support vertical-scoped packagesjs-sdkrefactor: Update js-sdk generator to support vertical-scoped packagesNon-goals
Open questions
1. SDK Package Structure & Distribution
How should the generated SDKs be packaged and distributed to developers? We propose 3 approaches based on well-known industry patterns:
[Recommended] Alternative A: Monolithic Package with Vertical Namespaces
All verticals and common models are shipped in a single package (e.g.,
pip install ucp-sdkornpm install @ucp-js/sdk), segregated by namespaces.Alternative B: Modular Packages (Multi-Package Monorepo)
Each vertical and the common core are published as separate packages (e.g.,
@ucp-js/sdk-common,@ucp-js/sdk-shopping,@ucp-js/sdk-food).Alternative C: Core Package + Dynamic Schema Resolution (No Generated Models)
Ship a lightweight "Core" SDK that contains no hardcoded vertical models. Instead, the SDK dynamically downloads or bundles UCP JSON schemas and performs runtime validation/serialization using a generic processor.
CheckoutorCartclasses in IDE).2. Extension Rendering & Navigation
How should extensions that are used across capabilities or even verticals (in the case of common extensions like
Loyalty) be rendered in the documentation site navigation?[Recommended] Alternative A: Contextual Nesting (Current State)
Extensions are documented under the capability that leverages them (e.g., Shopping
Discountsextension nested under ShoppingCheckoutcapability). If another capability needs it, it is referenced again in the nav.Alternative B: Centralized "Extensions" Directory
Move all extension documentation to a top-level
specification/extensionsdirectory, grouping them by vertical or as common. Individual capability’s md files will have a table listing out all the supported extensions.