This document is the human-readable specification of how NorthCinder orders offers. The ranking is deterministic and auditable (never "provably neutral"): the ordering itself is a check your own machine runs, not a promise you take on faith — with an honest scope, spelled out in What verification proves — and what it doesn't:
- The implementation is open:
packages/protocol/src/ranking/rank.ts, shipped in@northcinder/protocol. The aggregation service implementation in this source tree uses this open ranker when run locally. - Every
/v1/searchresponse returns all the ranking inputs — the offers and thetrustSignalsthe ranking consumed — so the open client re-runsrankOfferslocally and diffs the service's order (verifySearchRanking). A boosted re-order is flaggedrankingVerified: falsewith the exact divergence, in both the tool output and your local audit log. - The section between the markers below is generated from the code by
corepack pnpm --filter @northcinder/protocol gen:ranking-doc. The protocol drift test (packages/protocol/test/ranking-doc.test.ts) compares the committed generated section with the exact renderer output and fails when they differ. - A deterministic, on-demand probe battery is recorded in NEUTRALITY-AUDIT.md for the measured choice profile (position-shuffle, sponsored-injection, and attribute-weight probe batteries).
Client-side verification proves that the ordering, scores, and reasons are
exactly what the open rankOffers produces GIVEN the inputs the service
disclosed. Within that scope it is airtight: the service cannot boost, bury,
or re-score any offer relative to the data it showed you without being flagged.
It does not prove the disclosed inputs are themselves honest. A dishonest
service could fabricate trust levels, strip an offer's sponsored flag, or
curate the offer set (drop or invent offers) — and then rank honestly over
those doctored inputs, passing with rankingVerified: true. The trust levels,
sponsored flags, and offer-set completeness are the service's claims, and
today they are only partially cross-checkable: you can independently re-query
any merchant's trust level via /v1/trust, and the evidence strings inside
each result's reasons expose what the ranking believed about each merchant.
Offer-set and flag honesty ultimately rest on the service and its adapters
being truthful about their sources — which is why the client's audit log keeps
a summary of every ranked response (per-offer id, store, price, sponsored flag,
score, reasons, and the verification outcome), so after-the-fact comparison
against the stores themselves stays possible.
Only the buyer's criteria, exactly as sent in the search query: price, budget,
must-have attributes, delivery deadline, availability, merchant trust, and
ethics preferences. Every ranked result carries machine-readable reasons
naming the criteria that produced its position.
Exact product identity, complete known landed-cost components, return-policy facts, warranty facts, and sourced research claims feed explicit decision readiness and provenance. Missing or incomplete evidence keeps a decision provisional. Sourced claims do not change rank, score, or tie-breaking; ranking remains the deterministic policy below.
The canonical product subject must contain every declared variant, model,
generation, and identifier value. Evidence is bound to a unique canonical JSON
[sourceStore, offerId] tuple and merges incrementally by logical claim;
omitted facts and unresolved claims do not disappear. Readiness displays at
most 16 conflict and unknown summaries per offer while reporting exact totals
and whether either list was truncated.
Buyer context (subject, intended use, occasion, location, and owned-item compatibility) belongs to the current search session. It is echoed for that search so the buyer can correct it, but is not written into the local audit.
| Weight | Points | Applies when |
|---|---|---|
priceBest |
+40 | linear within a currency group: cheapest offer earns the full points, priciest earns 0 |
overBudgetPenalty |
−25 | the offer price exceeds the buyer's maxPrice budget (same currency) |
specMatchFull |
+30 | scaled by the fraction of mustHaveAttributes the offer matches |
specMissPenaltyEach |
−10 | per required attribute the offer is missing |
deliveryMeets |
+10 | the promised delivery date meets the buyer's deliveryBy |
deliveryMissesPenalty |
−15 | the promised delivery date misses the buyer's deliveryBy |
inStock |
+5 | availability is in_stock |
preorderPenalty |
−5 | availability is preorder |
outOfStockPenalty |
−20 | availability is out_of_stock |
trustTrusted |
+10 | the merchant's trust signal is trusted |
trustKnown |
+5 | the merchant's trust signal is known |
flaggedPenalty |
−40 | the merchant's trust signal is flagged |
ethicsMatchFull |
+8 | scaled by the fraction of the buyer's ethicsFlags the offer matches |
requiredcriteria do not change scores. A failed requirement places the offer in the eliminated tier and adds the criterion id, importance, and one of these stable codes:required_attribute_missing,required_price_exceeded,required_delivery_missed,required_delivery_unknown,required_ethics_missing, orrequired_availability_mismatch.preferredcriteria use fixed code-owned points. Callers cannot provide weights, component scores, or final scores.
| Preferred kind | Fixed points |
|---|---|
attribute |
+12 on match; 0 on miss |
max_price |
+10 on match; 0 on miss |
delivery_by |
+8 on match; 0 on miss |
ethics |
+6 on match; 0 on miss |
availability |
+4 on match; 0 on miss |
tie_breakercriteria add zero points. They compare typed facts only when main scores are equal: lower price, earlier known delivery, an attribute or ethics match, then equality with the requested availability value.
- Sponsored placement is NOT a score input.
sponsored: truecontributes zero points in either direction. Instead, every sponsored offer is placed in a strictly lower tier than every non-sponsored offer, is always labeled, and always carries the reason:sponsored listing: labeled and ranked below all non-sponsored offers. Tested property: settingsponsored: trueon any offer can never raise its rank. - There is no input a seller can pay to influence. Scores derive only from the buyer's criteria: price, spec match, delivery, availability, merchant trust, ethics.
Tiers, in order: non-sponsored before sponsored (primary — the brand promise),
then candidates meeting all named requirements before eliminated candidates, then
buyable before out-of-stock (a buyer cannot buy what isn't there; tested property:
setting out_of_stock can never raise a rank). Main score follows. When scores are
equal, named tie breakers run in query order, then price (asc), then the canonical
JSON [sourceStore, offerId] tuple (asc) provides a collision-free total,
input-order-independent order. The ranking is pure and
deterministic: no clock, no randomness, no I/O; same inputs → byte-identical output.
Without named tie breakers, the legacy fallback remains score (desc), then price (asc), then the canonical store-scoped offer tuple (asc).
Within one source store, that reduces to score (desc), then price (asc), then offer id (asc).
- Search via the open client (
@northcinder/client): everysearch_productsresult includesrankingVerified, computed on YOUR machine by re-running the openrankOffersover the offers + trust signals the service returned. - Or do it by hand: take any
/v1/searchresponse, feedresults[].offerandtrustSignalstorankOffers(offers, query, { trust })from@northcinder/protocol, and compare orders, scores, and reasons.
Both checks verify the ordering over the inputs the service disclosed —
see What verification proves — and what it doesn't
for exactly what that does and does not cover. To probe input honesty, spot-check
merchants independently via /v1/trust and compare the evidence strings in
reasons against what you know about the merchant.