Skip to content

RFC 0001: Declared Discovery, Structured Identifiers, and Reference Price for SKU.md

Specification notes

A draft proposal to let hosted stores declare a catalog outside /sku.md, give GTIN, MPN, brand, and SKU a parseable form, and add a dated reference price that is never an offer.

SKU.md 1.0.0-beta is deliberately small. A root catalog at /sku.md, optional product knowledge documents, and a Source link on every fact. That size makes it easy to validate. It also leaves three gaps that matter for independent stores in AI shopping conversations, and RFC 0001 is a draft proposal to close them.

The RFC is not part of the active specification. No validator, generator, CLI, MCP tool, or Agent Skill implements it yet, and every 1.0.0-beta document would stay valid if it were accepted. The full text is in RFC 0001.

Three proposed changes branch from the current SKU.md format: declared discovery, structured identifiers, and a dated reference price
The three proposals are additive. The current catalog and product documents remain valid under each one.

Gap one: hosted stores cannot serve the root path

The specification requires the catalog path to be exactly /sku.md. The project’s own Shopify guide records that the platform manages the store root and limits App Proxy prefixes. File-library hosting on other platforms usually relies on a redirect that changes the final path. Those merchants can often serve the same Markdown from another same-origin path, but today that does not conform.

The RFC keeps /sku.md as the first place a reader looks. When it is missing, a store may declare another same-origin catalog URL through one of five hints, checked in a fixed order:

  1. A reserved /.well-known/sku.md path, which would need registration with IANA first.
  2. An HTTP Link header on the home page with rel="alternate", type="text/markdown", and title="SKU.md".
  3. The same relation as an HTML link element on the home page.
  4. A link labeled SKU.md catalog in a Product knowledge section of llms.txt.
  5. A line starting with SKU.md catalog: in agents.md.

The last two are the same pointers that the discovery-links guide recommends today, so a store that adds them now would already have the declaration in place.

Every hint must stay on the same origin, and the declared file is validated exactly like a root catalog. Two hints that disagree are reported as a conflict. The RFC also asks consumers to prefer hints that require control of the home page over hints in files a platform may regenerate, because a looser path rule raises the risk of declaring content the merchant does not control.

Gap two: identifiers are free text

GTIN, MPN, brand, and merchant SKU are how shopping systems decide that two mentions describe one product. Under 1.0.0-beta they can appear in an Identifiers section, but only as free text. The RFC adds a structured form that a parser can read without guessing:

## Identifiers
- GTIN: 00012345678905 [Source](https://www.example-outdoor.com/products/tent)
- MPN: UL2P-24 [Source](https://www.example-outdoor.com/products/tent)
- Brand: Example Outdoor Gear [Source](https://www.example-outdoor.com/pages/about)
- SKU: TENT-UL2P-GRN [Source](https://www.example-outdoor.com/products/tent)

The labels GTIN, MPN, Brand, SKU, and ISBN are reserved. A GTIN must pass its GS1 check digit, and an item that starts with a reserved label but fails its rule is invalid rather than quietly treated as prose. Identifiers that differ by variant can add for and the variant name. When a structured GTIN conflicts with Product JSON-LD or a feed, a consumer should report the conflict and send the shopper to the live page instead of choosing one value.

Gap three: price has no place at all

Price is often the first filter in a shopping conversation. 1.0.0-beta keeps live price out of static files, and the RFC keeps that rule. What it adds is an optional Reference price section with a date and a source:

## Reference price
- USD 349.00 as of 2026-08-11 [Source](https://www.example-outdoor.com/products/tent)
- USD 299.00 to 349.00 as of 2026-08-11 for all variants [Source](https://www.example-outdoor.com/products/tent)

The currency is an ISO 4217 code, the amount uses a dot and no thousands separator, and the as of date cannot be later than the document’s Updated date. The section cannot carry sale prices, coupons, member prices, shipping, tax, or stock. A consumer that uses the value must present it as a dated reference, must not use it for a cart or checkout, and should treat a date older than 90 days as stale.

This is the most debatable part of the draft. The reasoning is that an assistant filtering by budget will skip a product with no price context at all, while a clearly dated and sourced reference sends the shopper to the live page to confirm.

What the RFC leaves out

Several ideas from the same review are deferred to later proposals: a root Markets section for regions, languages, and currencies; optional Brand and Categories sections in the root catalog; separating the 31-document graph bound from the specification; a lenient parsing profile for consumers; and guidance on sitemaps and canonical pages for Markdown resources. The RFC lists them so that comments on this draft stay focused.

Open questions and how to comment

The draft asks four questions directly. Should the project request the well-known registration now or wait for a second implementation? Should the llms.txt and agents.md hints stay, given that platforms may overwrite those files? Is 90 days the right staleness threshold for fast-moving categories? Should Brand also be allowed in the root catalog?

Comments are open on the project repository. The rollout plan asks for a preview flag in the validator, conformance fixtures for each new issue code, at least one hosted-platform merchant publishing through a declared URL, and one independent consumer reading it before any release adopts the proposal. Until then, the current specification is the one to implement.