Repository navigation
feat(skills): add vector-ranking skill - #3
Merged
Merged
Conversation
Discovery vector ranking spans two APIs — vocabularies and item taste are authored on Core, ranking happens on Discovery — so it gets its own skill rather than being split across query and mutation. New skill `vector-ranking` with three references: - vocabulary-authoring: vocabulary design, positional weights, upsertVocabulary, setItemTaste, key validation, publish, ignite, verify - ranking-signals: the five rankBy signals, the per-tenant field enums, normalization defaults, multi-value collapse, rankScore/rankExplain, rerank window - personalization: context.userTaste, magnitude, sourcing the shopper vector, blending with rankBy, nearestTo Verified against the live Core API and a ranking-enabled Discovery tenant by introspection rather than from the docs alone. That surfaced several things the docs omit or state loosely: - RankExplainEntry carries `index`, needed to tell two fieldBoost terms apart - fieldBoost.field is the TenantRankByField enum (NUMBER/DATE filterable attributes, facet fields excluded), not any numeric field - igniteDiscoApi takes `stacks`; vectors are only built with `stacks: opensearch`, and omitting it fails silently - IgnitionBulkTaskResult and SetItemTasteResult both include ExperimentalFeaturesNotAvailableError - under rerank, cursor pagination falls back to offset and skip past the window returns nothing The skill leads with capability detection: rankBy, context and nearestTo are absent from a tenant's schema until ranking is enabled, so referencing them is a validation error rather than an unranked result. Also refreshes query/references/discovery-api.md, which had drifted from the served schema — adds autocomplete, options.fuzzy, sorting, filter operators, profiling, pathResolutionMethod, priceRange, and a note that the schema is generated per tenant. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
…ples Review feedback on #3: Core Next error members all implement the BasicError interface, so one fragment covers every failure and errorName identifies which one — spelling out each error type is noise. This was already the convention elsewhere in mutation/references/core-api.md; the vector ranking examples simply did not follow it. setItemTaste and igniteDiscoApi now select `... on BasicError { errorName message }`. The schema listings still name the individual union members, since that is reference material rather than a query to copy. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This was referenced Sep 22, 2026
vydimitrov
added a commit
that referenced
this pull request
Sep 28, 2026
* feat(skills): add bookable-resources skill
Bookable resources — products held for a window of time instead of counted
in stock — had no coverage in any skill. Two storefront builds (Tools
Universe rentals, and the rental work in Car Parts Universe) had to
discover the whole surface from the schema, and three of its failure modes
are silent.
New skill `bookable-resources`, with references for the Core setup, the
Shop API flow and modelling.
Verified on 2026-09-24 against the live Core API and Shop API on the
tools-universe tenant, including two test reservations taken and released.
Confirmed directly:
- Policy durations are seconds. `heavy-equipment` reads back as
advanceWindow 10368000 = 120 days, cancellationWindow 172800 = 2 days,
pendingHoldDuration 900 = 15 minutes. `humanized` gives the same
values as { value, unit }, which is how you catch a wrong unit.
- `bookingPolicies` is a connection, and `stats.referencingProductCount`
is what blocks a delete.
- A pool is units or capacity, never both; unit `meta` carries depot,
serial and service data, and Discovery serves it back on the item.
- `checkBooking` requires `language` and returns { ok, reason }, not a
union. `bookSkuItem` returns Cart | ReservationConflict | NotBookable |
InvalidRange | InvalidUnitId — refusals are results, not errors.
- The reservation id is on the cart LINE's meta (`reservationIds`),
alongside a `booking.window` the API writes itself. The line's unitId
is not returned, so the caller has to store it.
- `cancelReservation(cartId, reservationId)` applies the cancellation
window to a hold that was never bought: a booking for tomorrow under a
two-day window answers CancellationWindowClosed, so a shopper cannot
empty their own basket. Re-hydrating without the line releases it, and
the reservation then reads null.
- `confirmCartBooking` answers Cart | NotPlaced | NothingToConfirm |
ReservationNoLongerHeld.
The one thing a storefront cannot get right by reading the schema is the
double confirmation: `confirmCartBooking` writes `orderId` onto the
reservations only if the cart already has one, and the cart is linked in
the background a few hundred ms after `createFromCart` returns. A single
confirm leaves { state: CONFIRMED, orderId: null } and the admin shows
"No order — not checked out" for a booking that was paid for. The skill
documents polling the cart and confirming again, as Tools Universe does.
Version to 3.7.0 in the three manifests. mcp-servers/crystallize was left
on 3.5.0 by #3 and is brought back into lockstep.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
* fix(skills): align bookable-resources with the backend
- No feature flag gates bookings; RBAC does. Replace the
ExperimentalFeaturesNotAvailableError probe with the FORBIDDEN case.
- setBookable, reapplyBookablePolicy and clearBookable write the draft;
each needs a publish before the Shop sees it.
- BookablePoolKindChangeError only fires capacity -> units while a
capacity pool is published; document clear, publish, drain, set.
- bookableProducts lists published configurations only; the pool is
shared by every language of the product.
- The first confirmCartBooking commits the slot (CONFIRMED never
expires); mark it optional, place payment in the sequence, and show
the /booking/admin cancel for a failed payment.
- Expired holds become EXPIRED and are re-taken on hydrate; placed
carts refuse hydrate, cancel and rebook.
- Add the hydrate shape for a booking line (lineId, window, unit), the
exact cancellation rule, why orderId must be polled, and that
bookSkuItem ignores group and type.
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-authored-by: Vasil Dimitrov <v.y.dimitrov@gmail.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds a
vector-rankingskill covering Discovery vector ranking, and refreshes the Discovery query reference, which had drifted from the served schema.Why its own skill
Vector ranking spans two APIs — vocabularies and item taste are authored on Core, ranking happens on Discovery — so splitting it across
queryandmutationwould have left the flow without a single narrative. It also has a modelling dimension (designing a vocabulary) closer totaxonomythan to either, and its trigger vocabulary ("personalization", "more like this", "boost by margin", "recommendations") would never have matchedquery.What's in it
SKILL.mdreferences/vocabulary-authoring.mdupsertVocabulary,setItemTaste, key validation, publish, ignite, verificationreferences/ranking-signals.mdrankBysignals, per-tenant field enums, normalization, multi-value collapse,rankScore/rankExplain, rerank windowreferences/personalization.mdcontext.userTaste, magnitude, sourcing the shopper vector, blending,nearestToqueryandmutationget## Related skillspointers, andmutation/references/core-api.mdgains a Vector Ranking Mutations section so the Core calls are findable from where they live.Verified against the API, not just the docs
Everything was checked by introspecting the live Core API and a ranking-enabled Discovery tenant. That surfaced several things the documentation omits or states loosely:
RankExplainEntrycarriesindex— without it you cannot tell twofieldBoostterms apart.fieldBoost.fieldis theTenantRankByFieldenum (NUMBER/DATE filterable attributes, facet fields excluded), not "any numeric field". Guessing a field name fails validation.igniteDiscoApitakesstacks, and vectors are only built withstacks: opensearch. Omitting it rebuilds the index without vectors and raises no error, so it is documented as a required step and as its own row in the failure-mode table.IgnitionBulkTaskResultandSetItemTasteResultboth includeExperimentalFeaturesNotAvailableError, which appears in neither doc version.skippast the rerank window returns nothing.The skill leads with capability detection:
rankBy,contextandnearestToare absent from a tenant's Discovery schema until ranking is enabled, so referencing them is a GraphQL validation error rather than an unranked result. That is the failure an agent is most likely to hit, so it is the first section rather than a footnote.Where the two public doc pages contradict each other on how
sortingcomposes with ranking, the skill says so and declines to assert either reading.Discovery reference refresh
query/references/discovery-api.mdwas missingautocomplete,options.fuzzy,sorting, filter operators,profiling,pathResolutionMethodandpriceRange, and did not mention that the schema is generated per tenant. All added.Notes for the reviewer
virtual:skills) and the docs site discover skills from the filesystem. Plugin version bumped 3.5.0 → 3.6.0 and the README list updated.query/andmutation/are back to formatted-clean as they were onmain.make codeclean's type-check/lint andmake testswere not run locally —bunwas unavailable in the authoring environment. No TypeScript is touched, so CI should be green, but that is unverified from my side.mass-operations/*andpermissions/SKILL.mdare not oxfmt-clean onmain, and three relative links are broken (js-api-client×2,query/references/core-api.md×1). Happy to fix either in a separate PR.🤖 Generated with Claude Code