Skip to content

refactor: organize shopping extensions into nested subfolder and update redirects - #761

Merged
igrigorik merged 8 commits into
mainfrom
refactor/url-redirects
Aug 25, 2026
Merged

refactor: organize shopping extensions into nested subfolder and update redirects #761
igrigorik merged 8 commits into
mainfrom
refactor/url-redirects

Conversation

@niranjanmanjunath

@niranjanmanjunath niranjanmanjunath commented Aug 21, 2026

Copy link
Copy Markdown
Collaborator

Description

This PR reorganizes the shopping extension specifications (buyer-consent.md, discount.md, fulfillment.md, and loyalty.md) into a dedicated nested directory under docs/specification/shopping/extensions/ to align with the rest of the modular capability structure.
It also adds backward-compatible 301 redirect mappings in mkdocs.yml, updates all internal cross-references, and fixes direct canonical anchors.

Category (Required)

Please select one or more categories that apply to this change.

  • Core Protocol: Changes to the base communication layer, global context, or breaking refactors. (Requires Technical Council approval)
  • Governance/Contributing: Updates to GOVERNANCE.md, CONTRIBUTING.md, or CODEOWNERS. (Requires Governance Council approval)
  • 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: CI/CD, Linters, or build scripts. (Requires DevOps Maintainer approval)
  • Maintenance: Version bumps, lockfile updates, or minor bug fixes. (Requires DevOps Maintainer approval)
  • SDK: Language-specific SDK updates and releases. (Requires DevOps Maintainer approval)
  • Samples / Conformance: Maintaining samples and the conformance suite. (Requires Maintainer approval)
  • UCP Schema: Changes to the ucp-schema tool (resolver, linter, validator). (Requires Maintainer approval)
  • Community Health (.github): Updates to templates, workflows, or org-level configs. (Requires DevOps Maintainer approval)

Related Issues

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.
  • I have added tests that prove my fix is effective or that my feature works.
  • 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.

Screenshots / Logs (if applicable)

image

Comment thread mkdocs.yml Outdated
Model Context Protocol (MCP) transport binding for the Order
Capability, detailing the JSON-RPC tool interface and parameters
for fetching order states.
Extensions:

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

llmstxt Section Hierarchy: Extensions should be nested under Shopping: in llmstxt to maintain 1:1 structural parity with nav rather than defined as a top-level section alongside Shopping and Payment.


Base [Context](shopping/catalog/index.md#context) defines an optional `location`: a
stable, opaque [Location](glossary.md#commerce) identifier in the Business's
Base [Context](../catalog/index.md#context) defines an optional `location`: a

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Update Discovery Profile spec URLs: Discovery profile examples in this file (lines 712, 735, 761) and across other docs (discount.md:51, buyer-consent.md:70, loyalty.md:147, overview/index.md:980, playground.md:508, core-concepts.md:170) still advertise the old root spec URLs:

"spec": "https://ucp.dev/{{ ucp_version }}/specification/fulfillment"

These should be updated across all examples to:

"spec": "https://ucp.dev/{{ ucp_version }}/specification/shopping/extensions/fulfillment"

#### Loyalty

{{ extension_schema_fields('loyalty.json#/$defs/loyalty', 'loyalty') }}
{{ extension_schema_fields('loyalty.json#/$defs/loyalty', 'shopping/extensions/loyalty') }}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

source/schemas/common/loyalty.json is namespaced as dev.ucp.common.loyalty (a common extension across verticals, like Identity Linking), but its documentation is now located at specification/shopping/extensions/loyalty.md under Shopping -> Extensions.

We should either move its documentation to specification/common/loyalty.md (matching Identity Linking) or track updating the schema namespace to dev.ucp.shopping.loyalty.


* **MUST** implement the `get_order` tool per the
[OpenRPC schema](<https://ucp.dev/{{ ucp_version }}/services/shopping/mcp.openrpc.json>)
[OpenRPC schema](site:services/shopping/mcp.openrpc.json)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Good fix converting this to canonical site:services/shopping/mcp.openrpc.json.

We should also convert the root-relative links in payment/guide.md:763 and overview/index.md:1518 (which currently link to /documentation/schema-authoring/...) to canonical site:documentation/schema-authoring/#... so they work across subpath deployments.

@gsmith85 gsmith85 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

LGTM! Documentation restructuring, redirects, llmstxt, and discovery profile examples all look clean and consistent.

Comment thread scripts/check_links.py Outdated
@damaz91 damaz91 added the status:needs-triage Signal that the PR is ready for human triage label Aug 24, 2026
@igrigorik

Copy link
Copy Markdown
Contributor

Asked my agent friend to review/building this branch and main side by side (DOCS_MODE=spec) and diff rendered hrefs against live ucp.dev. A few flags and recommendations it flagged...

1. Blocking — the new documentation/ stubs drop URL fragments

overview/index.md:1518 and payment/guide.md:763 now use site:documentation/schema-authoring/#anchor. Under mike that resolves version-scoped to /draft/documentation/schema-authoring/#…, which is served by the hooks.py stub — and the stub has no anchor preservation, so the fragment is lost.

Live today: /draft/specification/overview/ renders /documentation/schema-authoring/#the-reserved-ucp-member — one hop, anchor intact. With this PR the reader lands at the top of a long page instead.

mkdocs-redirects already solves this; the hook should do the same:

f.write(
  "<!doctype html>"
  f'<link rel="canonical" href="{target}">'
  '<script>var a=location.hash.substr(1);'
  f'location.href="{target}"+(a?"#"+a:"")</script>'
  f'<meta http-equiv="refresh" content="0; url={target}">'
)

Related: #759 ("fix: preserve fragments in root spec links") landed five commits ago and is the source of this PR's merge conflict — same two files. Worth rebasing onto it first.

2. scripts/check_links.py — land it working or drop it

The redirect-following block is currently a no-op: I built this branch's site, swapped in main's unmodified check_links.py, and it still passes. @gsmith85's diagnosis is right — the outer loop's file_cache[file_path] = parser.ids primes the cache with the stub's empty set(), so get_file_ids() short-circuits and never reaches the new code.

Two options, both fine:

  • Fix it here (get_file_ids(file_path) at the outer loop) and add a fixture that fails without it. Also worth a visiting set — the current target != path guard doesn't stop a 2-cycle.
  • Drop the file from this PR and land it separately.

Merging it as-is means shipping untested code that changes no outcome.

3. Finish the migration, or write the rule down

Three dev.ucp.shopping.* extensions are still flat at specification/ root and still in nav under Checkout Capability:

  • ap2-mandates.md (dev.ucp.shopping.ap2_mandate)
  • payment-terms.md (dev.ucp.shopping.payment_terms)
  • permalink.md (dev.ucp.shopping.permalink)

Seems like ap2 and payment term should also move? Permalink I'm not sure about.

4. Hierarchy (@gsmith85's open comment)

Shopping Extensions: is a top-level section alongside Shopping:/Payment:. Nest it under Shopping: for 1:1 parity with nav. Same fix as #3 will also empty ap2-mandates/payment-terms out of Checkout Capability:.

5. Drop the never-published redirect entry

specification/shopping/extensions/loyalty.md:
  specification/common/extensions/loyalty.md

That source path was never published (https://ucp.dev/draft/specification/shopping/extensions/loyalty/ → 404); it only existed mid-review on this branch. The redirect map should record real historical URLs, not review history.

6. Revert the Python reindent

shopping/checkout/index.md:1297-1310 reindents the illustrative Python from 4-space to 2-space (landed in 9c285614). PEP 8 is 4, it's the only Python fence in the spec docs, and no pre-commit hook (ruff/markdownlint/prettier) touches Python inside markdown fences. Unrelated to the reorg.

7. Two fixes to the PR description

  • Loyalty moved to common/extensions/, not shopping/extensions/.
  • "301 redirect mappings" → mkdocs-redirects emits HTTP 200 + client-side meta-refresh/JS, verified live. This matters because spec is a wire field in /.well-known/ucp that this PR rewrites: a non-browser client dereferencing the old URL gets an HTML shim with no 3xx to follow.

…URLs

- Move loyalty specification to docs/specification/common/extensions/loyalty.md

- Update navigation, redirects, and llmstxt sections in mkdocs.yml

- Update discovery profile spec URLs across overview, checkout, extensions, and guides

- Convert schema authoring links to canonical site: URLs

- Update hooks.py and check_links.py to support directory-based documentation redirects

@igrigorik igrigorik left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍

@igrigorik
igrigorik merged commit 7c0e4c4 into main Aug 25, 2026
20 checks passed
@igrigorik
igrigorik deleted the refactor/url-redirects branch August 25, 2026 00:32
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

status:needs-triage Signal that the PR is ready for human triage

Projects

None yet

Development

Successfully merging this pull request may close these issues.

5 participants