The rubric,
as it runs today.
The current public preview methodology — rubric v1.0, the rules the free scan uses right now. Every weight the scan’s scores use is on this page, read from the scoring code itself, including the ones that do not add up to a round number.
Who it is for,
what it measures.
A score is only worth something if a sceptical reader can rebuild it. This is the page they rebuild it from.
- Who it is for
- Shopify merchants deciding what to fix first; agencies and developers who need to reproduce a number; reviewers checking whether a score can be defended.
- What it measures
- Whether a machine can read a Shopify catalogue from its public storefront: product records from
/products.json, product JSON-LD in the raw HTML of up to three product pages, and which named AI crawlersrobots.txtrefuses. The pillar layer addssitemap.xml,llms.txtand the<head>of those same product pages. The full fetch list. - How
- Each check is a deterministic test in code, run on every product read. Results are pass-ratios, not judgements. Catalogues of up to 2,000 products are read in full; larger ones are sampled evenly across the whole catalogue, and the report states the coverage (scanner.ts:52-58).
- What it is not
- A ranking, a traffic figure or a promise. It measures what a machine can read of the catalogue today, not where the store places in anyone’s results.
- Version
- Every scan result is stamped with the rubric version that produced it (v1.0). A score produced under one version is not compared with a score produced under another.
One number,
five steps.
This is score() in src/lib/rubric.ts, step for step. Every number below is imported from that file or produced by running it.
- MOV-01
Catalogue sub-score
For each of the 9 catalogue checks: its weight × the share of products read that pass it. The weights sum to 95, so a catalogue that passes everything scores 95 here, not 100. The sum is published as it is and is not rescaled.
- MOV-02
Schema sub-score
40 for Product JSON-LD node, 20 for Offers, 20 for Availability, 20 for Shipping or return-policy markup. Each element is present or absent across the sampled pages. Maximum 100.
- MOV-03
Blend
80% of the catalogue sub-score plus 20% of the schema sub-score.
- MOV-04
Crawler penalty
6 points for each of the 10 named AI crawlers that
robots.txtdisallows, capped at 30 — the cap is reached at 5 blocked agents. An unreadablerobots.txtcosts nothing. - MOV-05
Round and floor
The blend minus the penalty, rounded to the nearest whole number and never below 1. The highest composite this rubric can produce is 96; the lowest is 1. The report also shows the catalogue sub-score rounded to a whole number.
catalogue = Σ weight × pass-ratio (9 checks, max 95) schema = 40·ld + 20·offers + 20·availability + 20·shipping (max 100) penalty = min(6 × blocked AI crawlers, 30) composite = max(1, round(0.8 × catalogue + 0.2 × schema − penalty)) (max 96)
Source: src/lib/rubric.ts · score() · lines 332-359
9 checks,
95 points, not 100.
Each check runs on every product read. The weight is what a full pass across the catalogue contributes to the catalogue sub-score.
| # | Check | Weight | Passes when | Why it is weighted |
|---|---|---|---|---|
| 01 | Description depth | 16 | The description, with HTML stripped, runs to 180 characters or more. | Under ~180 characters there is nothing for an agent to extract facts from. |
| 02 | Structured attributes | 15 | The description contains a list, a number with a unit (gsm, oz, cm, mm, in, lb, kg, g), or the word dimension, material or composition. | Material, dimensions, composition. The fields agents filter and compare on. |
| 03 | SKU coverage | 12 | The product has at least one variant, and every variant has a non-empty SKU. | Every variant needs a stable identifier or an agent cannot reference what it buys. |
| 04 | Product type set | 12 | Product type is not blank. | Blank type means your product joins no comparison set at all. |
| 05 | Tag richness | 10 | The product carries three or more tags. | Three or more per product. How use-case and occasion queries find you. |
| 06 | Shipping weight | 9 | At least one variant declares a weight above zero grams. | No weight means no delivery estimate - you drop out of speed-filtered results. |
| 07 | Imagery present | 8 | The product has at least one image. | Multimodal agents read images. No image is a hard skip on visual surfaces. |
| 08 | Real variant options | 8 | An option is named something other than “Title” — or the product has exactly one variant. | Default Title tells an agent nothing about size, colour or configuration. |
| 09 | Vendor named | 5 | Vendor is not blank. | Brand attribution. Feeds brand queries and Merchant Center matching. |
| Sum of weights | 95 | Computed from the table above. Not rescaled to 100. | ||
Structured data,
read from raw HTML.
Read from up to three product pages as served, without running JavaScript. The scan stops at the first page carrying product markup, and a store gets credit for an element if any sampled page has it.
| Element | Weight | Passes when |
|---|---|---|
| Product JSON-LD node | 40 | A JSON-LD node typed Product, ProductGroup, ProductModel, IndividualProduct or SomeProducts — including inside @graph. |
| Offers | 20 | That node contains an "offers" property. |
| Availability | 20 | That node contains an "availability" property. |
| Shipping or return-policy markup | 20 | That node contains shippingDetails or hasMerchantReturnPolicy. Either one passes; the key in code is named “shipping”, but the test is broader than the name. |
| Sum of weights | 100 | Worth 20% of the composite after the blend. |
GTIN and MPN are detected on the same pages but carry no weight in this rubric. Markup injected by JavaScript after the page loads is not seen, because agents that do not run JavaScript do not see it either.
10 named crawlers,
one capped penalty.
robots.txt is parsed group by group and checked against each agent by name. A disallowed agent costs 6 points; the total stops at 30.
- GPTBot
- OAI-SearchBot
- ChatGPT-User
- ClaudeBot
- anthropic-ai
- PerplexityBot
- Google-Extended
- Applebot-Extended
- Bytespider
- CCBot
A penalty, not an exclusion. In the world, a compliant crawler that is disallowed does not read the store, so the engine behind it has nothing of the store to draw on. The composite does not model that as a zero: it subtracts a capped penalty. A catalogue that passes every check and blocks all 10 agents still scores 66. That is why the report puts crawler access first — it is the cheapest fix and the one the number understates.
Googlebot and Bingbot (Googlebot, Bingbot) are not in this list. They are read separately and penalise only the SEO pillar (section 07). If the store disallows Rank Sniper’s own crawler, the scan is not run at all — see /bot.
What the number
means.
Agents can read, compare and cite most of the catalogue.
Some products surface; for the rest an agent is guessing.
Agents cannot reliably answer questions about the catalogue.
With a ceiling of 96, the top band runs from 80 to 96. Bands describe legibility, not rank.
Four pillar scores,
29 weighted checks.
The four pillar scores on the report come from a second layer, src/lib/pillars.ts (v1.0), which re-reads the same scan with its own checks and weights. These are the current pillar preview weights, rendered from the function that derives them — not retyped.
How a pillar score is built. The weighted mean of the checks that could be scored, × 100, minus the pillar’s crawler penalty, rounded and held between 0 and 100. A check whose input could not be fetched is left out of the calculation rather than scored zero. Weights are relative within a pillar and do not total 100; the sums below are shown as they are. Pillar scores do not add up to the composite, and the composite is not an average of them.
Most checks are a pass-ratio across products or pages. Three award fixed partial credit (pillars.ts:1031-1033, 1077): titles score half when sampled titles repeat; sitemap.xml scores 0.4 when present but not valid; llms.txt scores 0.5 when present without pointers to the catalogue. Offers and availability score zero when no product markup was found.
Penalties. SEO subtracts 6 per blocked search crawler (Googlebot, Bingbot), capped at 30. GEO subtracts the same penalty as the composite, for the same 10 AI agents. AEO and AIO carry none.
SEO pillar
| Check | Weight | Fix class |
|---|---|---|
| Title length and uniqueness | 14 | Assisted |
| sitemap.xml validity | 14 | Guided |
| Meta description | 12 | Assisted |
| Product type set | 12 | Assisted |
| Canonical tags | 10 | Guided |
| H1 structure | 10 | Guided |
| Tag richness | 10 | Assisted |
| Alt-text coverage | 10 | Assisted |
| URL structure | 8 | Assisted |
| Sum of weights | 100 |
AEO pillar
| Check | Weight | Fix class |
|---|---|---|
| Description depth | 20 | Assisted |
| FAQPage / HowTo schema | 20 | Assisted |
| List and table density | 16 | Assisted |
| Answer-first structure | 16 | Assisted |
| Question-shaped headings | 14 | Assisted |
| Sum of weights | 86 |
GEO pillar
| Check | Weight | Fix class |
|---|---|---|
| llms.txt presence and quality | 20 | Guided |
| Vendor and provenance attribution | 16 | Assisted |
| Quotable claim density | 16 | Assisted |
| Freshness (updated_at) | 16 | Assisted |
| Named entities | 14 | Assisted |
| Sum of weights | 82 |
AIO pillar
| Check | Weight | Fix class |
|---|---|---|
| Structured attributes | 16 | Automatic |
| SKU coverage | 14 | Assisted |
| Variant-level offers | 12 | Automatic |
| Price with priceCurrency | 12 | Automatic |
| Availability in schema | 12 | Automatic |
| Shipping weight | 10 | Assisted |
| Imagery present | 8 | Assisted |
| Real variant options | 8 | Assisted |
| Schema conflict detection | 8 | Guided |
| Entity consistency | 8 | Assisted |
| Sum of weights | 108 |
Transactability sub-score: SKU coverage (14), Variant-level offers (12), Price with priceCurrency (12), Availability in schema (12), Shipping weight (10) — the same checks and weights, scored on their own.
Fix classes
- Automatic
- Published through Rank Sniper’s own metafield namespace, structured data or feed. Designed to need no approval, because it never touches a field you wrote.
- Assisted
- Changes a native Shopify field — a title, description, tag, image or variant field. Drafted and staged; written only when you approve and apply it.
- Guided
- Outside the app’s write scope — a theme template, a file at your domain root. You make the change from exact instructions; the next scan checks it.
A fix class says who would do the work. It describes the design: automatic fixes — app-block structured-data markup Planned, automatic fixes — metadata and restructures Planned, and assisted batch rewrites, applied on merchant approval Planned. Rank Sniper applies none of them to a store today.
Same test,
two weights.
Where a catalogue test feeds both layers, it can carry a different weight in each. That is the code as it stands, published rather than smoothed over. One contract for both is what the canonical Rank Score work is for.
| Rubric test | Composite weight | Pillar check | Pillar weight |
|---|---|---|---|
| Description depth | 16 | AEO · Description depth | 20 |
| Structured attributes | 15 | AEO · List and table density | 16 |
| AIO · Structured attributes | 16 | ||
| SKU coverage | 12 | AIO · SKU coverage | 14 |
| Product type set | 12 | SEO · Product type set | 12 |
| Tag richness | 10 | SEO · Tag richness | 10 |
| Shipping weight | 9 | AIO · Shipping weight | 10 |
| Imagery present | 8 | AIO · Imagery present | 8 |
| Real variant options | 8 | AIO · Real variant options | 8 |
| Vendor named | 5 | GEO · Vendor and provenance attribution | 16 |
58 checks defined,
11 scored.
The check registry (v1.4-draft — a draft, not a stamped release) lists every check the scan is designed to run. A check changes a score only when it is sourced, implemented and weighted.
- Scored · 11
- Description depth, Structured attributes, SKU coverage, Product type set, Tag richness, Shipping weight, Imagery present, Real variant options, Vendor named, Structured data in raw HTML, AI crawler access. These are the composite’s inputs above.
- Experimental · 45
- Defined, and not yet implemented or sourced. They carry no weight and change no score, so they have no row in the weight tables on this page.
- Informational · 2
- Reported where measured, never scored, by rule.
- Not yet in the registry
- The pillar layer’s 29 checks are defined in pillars.ts, not in the registry. Bringing the two lists together is part of the canonical contract work.
What is and is not published here. Every weight used by the scores the public scan returns — composite and pillar — is on this page. The registry’s 47 unscored checks carry no weight, so there is no weight to publish; their definitions are internal for now.
What it does not
measure yet.
On a page whose whole claim is auditability, the limits belong at the same size as the claims.
- Rendered pages. Only the raw HTML is read. Structured data added by JavaScript is not seen; a raw-versus-rendered comparison is defined in the registry and not implemented.
- What agents actually receive.
robots.txtpolicy is read; whether a firewall or CDN blocks an agent thatrobots.txtallows is not tested. Post-fix verification — what agents actually receive: Planned. - Agents not on the list. Only the 10 agents in section 05 are checked. Anthropic’s Claude-SearchBot and Claude-User, for example, are not on it today. Changing the list changes scores, so it moves with a rubric version.
- Traffic, citations and rankings. Nothing here counts agent visits, citations in AI answers or search positions. Those are not measured, so they are not scored.
- Change over time. Each scan is a snapshot. Recurring re-scans, drift detection and alerts: Planned. Score and version history: Planned.
- It is not final. When a check is found to measure something other than what it claims, it is corrected and the version moves, so a score always says which rules produced it.
SEO → AEO → GEO → AIO,
in that order.
Conventional search first, then answer engines, generative engines and the systems that act on a record. The scored registry checks behind the composite, by the pillar each one evidences.
SEO — Search engine optimisation
Whether conventional search engines can crawl, parse, and rank the catalogue.
In the composite: Product type set, Tag richness.
Engage →AEO — Answer engine optimisation
Whether the catalogue can be lifted as a direct answer to a shopper's question.
In the composite: Description depth.
Engage →GEO — Generative engine optimisation
Whether generative engines will cite this store when composing a recommendation.
In the composite: Vendor named, AI crawler access.
Engage →AIO — AI optimisation
Whether an AI system can correctly parse and act on the record without guessing. Includes transactability as a named sub-score.
In the composite: Structured attributes, SKU coverage, Shipping weight, Imagery present, Real variant options, Structured data in raw HTML.
Engage →AIO here means machine readability — whether the record parses and can be acted on. It is not the umbrella definition that treats AIO as all four disciplines at once, and it is not the off-site trust definition.
Score a store
against it.
Run the free scan. Every score in the report traces back to a row on this page.
