PR #226 (Ryan C, 2026-03-10) introduced the convention that reference.md is the canonical render destination for all types/ schemas. The fix:
- Added a link checker to CI
- Expanded
reference.md to render shared types (Pagination, Error Code, etc.) natively
- Added a redirect rule in
main.py:311-313 so any cross-reference to a types/ schema resolves its anchor to reference.md, regardless of which capability page is rendering it
Before #226, capability pages each rendered their own types/ schemas inline, with intra-page anchors. Cross-references between types could break because not every page had every anchor. #226's fixes this.
Gap
#226 made the cross-references resolve to reference.md, but did not remove the inline schemas from capability pages. So today:
reference.md is the canonical destination for all types/ cross-references — anchors and links go there
cart.md, checkout.md, catalog/index.md still render the same types/ tables inline (Buyer, Context, Signals, Attribution, Total, Line Item, Message, Link, etc), but they're not used in internal refs, everything gets routed to reference.md.
- The same tables get rendered three times: once in each capability page, once in
reference.md
- The macro's second
spec_file_name argument is dead weight for types/..., can/should be removed.
Desired end state
- Capability pages stop rendering
types/... tables inline. Each entity section keeps its heading and brief prose context (the "what is this and why is it here" paragraph), but links to reference.md#<anchor> instead of duplicating the table render.
reference.md is the single source of truth for shared-type field tables. It already is functionally — this just makes it consistent.
schema_fields macro signature simplifies. The second arg either:
- Gets removed entirely (and the redirect logic becomes the default), or
- Gets enforced (callers passing
'cart' or 'checkout' for a types/... schema fail loudly), making misuse visible.
Tradeoff to acknowledge
Cross-linking out to reference.md from capability pages breaks the flow of reading a single page end-to-end. A reader on cart.md who wants to understand what fields signals carries has to navigate to reference.md, find the section, and navigate back. Self-contained capability pages are nicer to read.
The counter-argument — and the reason #226 went this way in the first place — is that UCP has many shared types, and replicating all of them across every capability page is tedious to maintain and creates anchor-resolution problems. Centralizing into reference.md was the pragmatic call; we just didn't finish the cleanup.
PR #226 (Ryan C, 2026-03-10) introduced the convention that
reference.mdis the canonical render destination for alltypes/schemas. The fix:reference.mdto render shared types (Pagination, Error Code, etc.) nativelymain.py:311-313so any cross-reference to atypes/schema resolves its anchor toreference.md, regardless of which capability page is rendering itBefore #226, capability pages each rendered their own
types/schemas inline, with intra-page anchors. Cross-references between types could break because not every page had every anchor. #226's fixes this.Gap
#226 made the cross-references resolve to
reference.md, but did not remove the inline schemas from capability pages. So today:reference.mdis the canonical destination for alltypes/cross-references — anchors and links go therecart.md,checkout.md,catalog/index.mdstill render the sametypes/tables inline (Buyer, Context, Signals, Attribution, Total, Line Item, Message, Link, etc), but they're not used in internal refs, everything gets routed toreference.md.reference.mdspec_file_nameargument is dead weight fortypes/..., can/should be removed.Desired end state
types/...tables inline. Each entity section keeps its heading and brief prose context (the "what is this and why is it here" paragraph), but links toreference.md#<anchor>instead of duplicating the table render.reference.mdis the single source of truth for shared-type field tables. It already is functionally — this just makes it consistent.schema_fieldsmacro signature simplifies. The second arg either:'cart'or'checkout'for atypes/...schema fail loudly), making misuse visible.Tradeoff to acknowledge
Cross-linking out to
reference.mdfrom capability pages breaks the flow of reading a single page end-to-end. A reader oncart.mdwho wants to understand what fieldssignalscarries has to navigate toreference.md, find the section, and navigate back. Self-contained capability pages are nicer to read.The counter-argument — and the reason #226 went this way in the first place — is that UCP has many shared types, and replicating all of them across every capability page is tedious to maintain and creates anchor-resolution problems. Centralizing into
reference.mdwas the pragmatic call; we just didn't finish the cleanup.