Skip to content

fix(skills): correct five places where the skills contradict the API - #8

Merged
Plopix merged 1 commit into
mainfrom
fix/skills-contradictions
Sep 22, 2026
Merged

Plopix merged 1 commit into
mainfrom
fix/skills-contradictions

Conversation

@papelipe

Copy link
Copy Markdown
Member
Q A
Branch? main
Bug fix? yes
New feature? no
BC breaks? no
Fixed tickets #...

Two storefront builds on Crystallize (Food Universe, B2B with three languages, and Photo Store, B2C/B2B on Discovery vectors) turned up places where following a skill produces a call the API rejects, or a step the API doesn't need. This PR fixes the five places where a skill contradicts the API. Gaps, where a skill just doesn't mention something, come in later PRs.

Every change was checked against the live API before the text was written.

What changes

# Skill said API does Checked by
1 Price list: priceVariants: ["retail"], selectedProductVariants: { type: ALL }, targetAudience without type priceVariants: [{ identifier, modifier }], type: ALL_SKUS | SOME_SKUS with per-SKU variants, and targetAudience.type (EVERYONE | SOME) is required Introspection of Core and the legacy PIM API (both take the same shape)
2 Checkout: createFromCart, then fulfill createFromCart already moves the cart to ordered and sets orderId; the order id is the cart id All 8 food-universe orders, created with createFromCart by a storefront that never calls fulfill: every cart is ordered with orderId = its own id, updated 150–550 ms after the order was created. The Shop API schema describes fulfill as "change its state and assign the orderId", which is exactly what createFromCart already did
3 Vector pipeline: publishItems, then index publishItems returns a PublishItemsRequest, and both projects found it returns before the items are published. publishItem answers per item Schema, and both projects' seed scripts (see below)
4 decimalPlaces range 0–64 Mass-operation validation rejects 0: Too small: expected number to be >0 build-mass-operation
5 Vocabulary is an enum value after indexing True, but before any vocabulary is indexed the argument is a String, and a query fails with Vocabulary taste not found Introspection of NearestToInput / UserTasteInput on food-universe (enum) and furniture (String), plus the error on furniture

Files

  • pricing/references/price-lists-and-markets.md: Core createPriceList example, a table of the input shapes, a SOME_SKUS example, and a note on the PIM API and the mass-operation intent
  • mutation/references/shop-api-mutations.md: cart state table, the Fulfill section and the checkout flow
  • mutation/references/shop-api-order-mutations.md: a note after the createFromCart example
  • mutation/references/core-api.md, vector-ranking/SKILL.md, vector-ranking/references/vocabulary-authoring.md: publishItem per item and language; both forms of the vocabulary argument
  • mass-operations/references/limits.md, content-model/references/create-shape-api.md: decimalPlaces 1–64

Deliberately cautious

Two claims are worded no stronger than what was verified:

  • fulfill after createFromCart. The skill now says the step isn't needed. It doesn't say that fulfill fails afterwards, which is what the Food Universe finding reports, because that call wasn't run in this verification. Photo Store calls it and swallows the error with .catch(() => undefined), which points the same way.
  • publishItems asynchronous. The skill says its return "is not proof that the items are published yet", not that it is always asynchronous.

Merge note

No plugin version bump. Several skill PRs follow from the same findings, so one bump on whichever merges last avoids conflicts. mcp-servers/crystallize/package.json is still on 3.5.0 while the plugin manifests are on 3.6.0 (#3 missed it); that bump should fix it too.

make codeclean leaves the skills unchanged (oxfmt --check use-crystallize/skills passes).

🤖 Generated with Claude Code

Building the Food Universe and Photo Store storefronts turned up places
where following a skill produces a wrong call. Each one below was checked
against the live API before changing the text.

Price lists (pricing/references/price-lists-and-markets.md)
  The example sent `priceVariants: ["retail"]`, `selectedProductVariants:
  { type: ALL }` and a `targetAudience` without `type`. Every one of those
  is rejected. Introspection of both Core and the legacy PIM API shows
  `priceVariants: [{ identifier, modifier }]`, `type: ALL_SKUS | SOME_SKUS`
  with per-SKU `variants`, and a required `targetAudience.type` of
  `EVERYONE | SOME`. The example now uses Core `createPriceList`, with a
  table of the input shapes and a SOME_SKUS example.

Checkout (mutation/references/shop-api-mutations.md, shop-api-order-mutations.md)
  The flow listed `fulfill` as a step after `createFromCart`. The Shop API
  schema describes `fulfill` as "change its state and assign the orderId".
  `createFromCart` already does both: all 8 food-universe orders, created by
  a storefront that never calls `fulfill`, have carts that are `ordered`
  with `orderId` equal to the cart's own id, updated within about half a
  second of the order.
  The step is gone. `fulfill` is described as linking a cart to an order
  created some other way.

Publishing for vector ranking (vector-ranking, mutation/references/core-api.md)
  The pipeline recommended `publishItems` right before indexing.
  `publishItems` returns a `PublishItemsRequest`, and both storefront
  projects found that it can return before the items are published. The
  pipeline now uses `publishItem` per item and language, which returns the
  published version or an error for that item.

Numeric decimalPlaces (mass-operations/references/limits.md, create-shape-api.md)
  limits.md gave the range as 0-64. Mass-operation validation rejects 0
  ("Too small: expected number to be >0"). The range is now 1-64, with
  the advice to leave the key out for integers.

Vocabulary argument type (vector-ranking)
  The skill only described the enum. On a tenant with no indexed
  vocabulary (checked on `furniture`), `nearestTo.vocabulary` and
  `userTaste.vocabulary` are typed String and a query fails with
  "Vocabulary taste not found". On `food-universe`, after indexing, they
  are the enum. Both forms are now documented, with a failure-mode row
  for the String case.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@Plopix
Plopix merged commit a455df6 into main Sep 22, 2026
1 check passed
@Plopix
Plopix deleted the fix/skills-contradictions branch September 22, 2026 18:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants