{
  "name": "AIqSight scoring rubric",
  "description": "Every check, category weight, severity and limit behind the two AIqSight scores, Search SEO and AI Visibility.",
  "url": "https://aiqsight.com/rubric.json",
  "documentation": "https://aiqsight.com/rubric/",
  "publisher": {
    "name": "QuikForge Limited",
    "url": "https://quikforge.com/"
  },
  "license": "© QuikForge Limited. You may quote and cite it with attribution to AIqSight (aiqsight.com).",
  "version": {
    "rubric": "0.3.0",
    "check_map": "0.2.0"
  },
  "dateModified": "2026-10-05",
  "never_blend": true,
  "formula": "score = sum(category_value * weight) / sum(active weight)",
  "category_formula": "category_value = 100 * sum(status_factor * severity) / sum(severity), over scored findings only",
  "status_factors": {
    "pass": 1,
    "warn": 0.5,
    "fail": 0
  },
  "excluded_statuses": {
    "needs_api": "an API we did not connect — never counts as a pass and never penalises; report the count",
    "not_applicable": "the check does not apply to this site"
  },
  "coverage_floor_pct": 70,
  "severity_gate": {
    "severity": 5,
    "status": "fail",
    "caps_score_at": 40,
    "band": "F"
  },
  "bands": [
    {
      "letter": "A",
      "min": 90
    },
    {
      "letter": "B",
      "min": 80
    },
    {
      "letter": "C",
      "min": 70
    },
    {
      "letter": "D",
      "min": 60
    },
    {
      "letter": "F",
      "min": 0
    }
  ],
  "severity_scale": {
    "1": "Minor. Reported for completeness; a site can be excellent without it.",
    "2": "Hygiene. Worth fixing, cheap to fix, rarely decisive on its own.",
    "3": "A real defect with measurable impact, but the page still works without it.",
    "4": "A primary signal is broken or absent. Directly costs indexing, ranking or citability.",
    "5": "The site cannot be indexed or reached at all. Nothing else on the report matters while it holds, and it caps the axis at 40."
  },
  "axes": {
    "search_seo": {
      "label": "Search SEO",
      "description": "How well the page is set up to rank in classic search engines.",
      "categories": [
        {
          "name": "Indexability & Crawl",
          "weight": 22,
          "modules": [
            "M1",
            "M2",
            "M3"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Core Web Vitals / Performance",
          "weight": 16,
          "modules": [
            "M15"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "On-Page & Meta",
          "weight": 12,
          "modules": [
            "M7"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Structured Data",
          "weight": 12,
          "modules": [
            "M5"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Rendering",
          "weight": 8,
          "modules": [
            "M4"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Internal Linking & Semantics",
          "weight": 8,
          "modules": [
            "M10"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "E-E-A-T",
          "weight": 7,
          "modules": [
            "M16"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Images / Media",
          "weight": 5,
          "modules": [
            "M9"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Sitemaps & Discovery",
          "weight": 5,
          "modules": [
            "M17"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Freshness",
          "weight": 3,
          "modules": [
            "M13"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Social Cards",
          "weight": 2,
          "modules": [
            "M8"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "E-commerce",
          "weight": 15,
          "modules": [
            "M18"
          ],
          "conditional": true,
          "scored": true
        },
        {
          "name": "Local",
          "weight": 10,
          "modules": [
            "M19"
          ],
          "conditional": true,
          "scored": true
        },
        {
          "name": "International",
          "weight": 8,
          "modules": [
            "M20"
          ],
          "conditional": true,
          "scored": true
        }
      ]
    },
    "ai_visibility": {
      "label": "AI Visibility",
      "description": "How extractable and citable the page is for AI answer engines (GEO/AEO).",
      "categories": [
        {
          "name": "Answer Extractability",
          "weight": 20,
          "modules": [
            "M11"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Structured Data",
          "weight": 16,
          "modules": [
            "M5"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Fact Density / Original Data",
          "weight": 14,
          "modules": [
            "M12"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "AI Crawler Access",
          "weight": 12,
          "modules": [
            "M14"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Rendering (non-JS)",
          "weight": 10,
          "modules": [
            "M4"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Entity / Knowledge-Graph",
          "weight": 10,
          "modules": [
            "M6"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "E-E-A-T / Authority",
          "weight": 9,
          "modules": [
            "M16"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Freshness",
          "weight": 6,
          "modules": [
            "M13"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "Images / Multimodal",
          "weight": 3,
          "modules": [
            "M9"
          ],
          "conditional": false,
          "scored": true
        },
        {
          "name": "llms.txt",
          "weight": 0,
          "modules": [
            "M21"
          ],
          "conditional": false,
          "scored": false
        }
      ]
    }
  },
  "counts": {
    "checks": 104,
    "modules": 21,
    "unscored": 21
  },
  "modules": [
    {
      "id": "M1",
      "name": "Crawlability",
      "axes": [
        "search"
      ],
      "depth": "full",
      "conditional": false
    },
    {
      "id": "M2",
      "name": "Indexability",
      "axes": [
        "search"
      ],
      "depth": "full",
      "conditional": false
    },
    {
      "id": "M3",
      "name": "Site health",
      "axes": [
        "search"
      ],
      "depth": "full",
      "conditional": false
    },
    {
      "id": "M4",
      "name": "Rendering / JS dependency",
      "axes": [
        "search",
        "ai"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "Raw HTML only. We see what a non-JS crawler receives, which is the question that matters for AI citability, but with no rendered-DOM diff we cannot separate 'missing for everyone' from 'missing only for AI', nor classify SSR/SSG/ISR."
    },
    {
      "id": "M5",
      "name": "Structured data",
      "axes": [
        "search",
        "ai"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "Type presence, markup/body parity (S6, 2026-09-13) and, on the offer page, Offer presence and Offer parity (OF2, OF3, 2026-10-02). No validation of the required properties per schema.org type, so an Organization block with no name still passes."
    },
    {
      "id": "M6",
      "name": "Entity / knowledge graph",
      "axes": [
        "ai"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "The site's own declaration only: whether a primary entity exists, what identity links it publishes, and whether it names itself consistently. Nothing is reconciled against Wikidata or a company register, so we can see that a site claims an identity, never that the claim resolves to the right one. No NAP consistency across third-party directories."
    },
    {
      "id": "M7",
      "name": "On-page & meta",
      "axes": [
        "search"
      ],
      "depth": "full",
      "conditional": false
    },
    {
      "id": "M8",
      "name": "Social cards",
      "axes": [
        "search"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "Open Graph only. No twitter:card family."
    },
    {
      "id": "M9",
      "name": "Images / media",
      "axes": [
        "search",
        "ai"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "Alt coverage only. No alt quality, no modern-format check, no VideoObject."
    },
    {
      "id": "M10",
      "name": "Internal linking & semantics",
      "axes": [
        "search"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "Orphan detection only. No anchor-text grading, pillar/cluster mapping or click depth."
    },
    {
      "id": "M11",
      "name": "Answer extractability",
      "axes": [
        "ai"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "Structure only: question headings and the length of what answers them, extractable blocks, segmentation, and whether a section opens on an unresolved reference. Whether an answer is correct, complete or better than a competitor's is not judged, and self-containment is tested on the opening sentence rather than the whole passage. Since 2026-10-02 (OF1) the offer page is read for where its prices sit; whether the offer itself is clear is not judged."
    },
    {
      "id": "M12",
      "name": "Fact density / original data",
      "axes": [
        "ai"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "Counts figures, outbound sources and promotional claims. It cannot tell original data from restated data — a proprietary survey and a quoted industry statistic look identical to a counter — so the original-data half of this category is named, not measured. The claim list is English-only, which under-reads a Chinese-language page. PP7 (thin content) is reported under this heading as context but is not scored: word count is not fact density."
    },
    {
      "id": "M13",
      "name": "Freshness",
      "axes": [
        "search",
        "ai"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "Presence of a visible timestamp, sitemap lastmod, and a claimed freshness date judged against the crawl date (O10, 2026-09-13). No staleness judgement against topic volatility: a rates page a year old is stale, a evergreen guide a year old is not, and telling them apart needs a per-vertical model we do not yet have. A visible updated date is compared with dateModified (O11, 2026-10-02, reported, not scored); whether a date is older than the content's last change is not observable from outside and is not claimed."
    },
    {
      "id": "M14",
      "name": "AI crawler access",
      "axes": [
        "ai"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "robots.txt policy only — what the site declares, not what its edge actually serves. A WAF or bot-management rule can refuse a crawler that robots.txt admits, and that is invisible from a crawl; confirming it needs a request sent under each crawler's user-agent, or Bing Webmaster's AI performance report. The user-agent lists are verified first-party in docs/ai-visibility-research-2026-09-09.md."
    },
    {
      "id": "M15",
      "name": "Core Web Vitals / performance",
      "axes": [
        "search"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "Crawl-only runs measure proxies: TTFB, compression, caching, image weight, script loading. Real field data needs --pagespeed, which raises this module to full (PS1-PS5)."
    },
    {
      "id": "M16",
      "name": "E-E-A-T / authority",
      "axes": [
        "search",
        "ai"
      ],
      "depth": "partial",
      "conditional": false,
      "gap": "Presence of the trust signals only: a byline or author node on content pages, an about and a contact page, a published privacy policy, a contact route in the markup. We can see that a page names an author; we cannot see that the author is qualified, and no credential, affiliation or citation of one is verified."
    },
    {
      "id": "M17",
      "name": "Sitemaps & discovery",
      "axes": [
        "search"
      ],
      "depth": "full",
      "conditional": false
    },
    {
      "id": "M18",
      "name": "E-commerce",
      "axes": [
        "search"
      ],
      "depth": "none",
      "conditional": true,
      "gap": "No Product/Offer checks. The category stays inactive and re-normalises out, which is correct for every seed site and for most HK/SG SME prospects."
    },
    {
      "id": "M19",
      "name": "Local",
      "axes": [
        "search"
      ],
      "depth": "none",
      "conditional": true,
      "gap": "No LocalBusiness, NAP or opening-hours check. This one matters commercially — most HK/SG SME prospects are local businesses — and it re-normalises out today rather than scoring them on it."
    },
    {
      "id": "M20",
      "name": "International / hreflang",
      "axes": [
        "search"
      ],
      "depth": "full",
      "conditional": true
    },
    {
      "id": "M21",
      "name": "llms.txt",
      "axes": [
        "ai"
      ],
      "depth": "full",
      "conditional": false
    }
  ],
  "checks": [
    {
      "id": "T1",
      "name": "HTTPS redirect",
      "module": "M3",
      "axis": "search",
      "severity": 4
    },
    {
      "id": "T2",
      "name": "non-canonical host folds to canonical",
      "module": "M2",
      "axis": "search",
      "severity": 4
    },
    {
      "id": "T3",
      "name": "alt host redirects, not merely canonical",
      "module": "M2",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "T4",
      "name": "/index.html redirects to /",
      "module": "M2",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "T5",
      "name": "sitemap.xml reachable",
      "module": "M17",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "T6",
      "name": "sitemap URL count",
      "module": "M17",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "T7",
      "name": "sitemap lastmod",
      "module": "M17",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "T8",
      "name": "robots.txt present and references a sitemap",
      "module": "M1",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "T10",
      "name": "custom 404",
      "module": "M3",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "T11",
      "name": "homepage canonical",
      "module": "M2",
      "axis": "search",
      "severity": 4
    },
    {
      "id": "T12",
      "name": "meta viewport",
      "module": "M7",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "T13",
      "name": "robots.txt crawl access",
      "module": "M1",
      "axis": "search",
      "severity": 5
    },
    {
      "id": "C1",
      "name": "homepage canonical exact",
      "module": "M2",
      "axis": "search",
      "severity": 4
    },
    {
      "id": "C2",
      "name": "/index.html 301s",
      "module": "M2",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "C3",
      "name": "alt-host canonical when it serves 200",
      "module": "M2",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "C4",
      "name": "no internal index.html links",
      "module": "M2",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "C5",
      "name": "no links to the non-canonical host",
      "module": "M2",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "S1",
      "name": "JSON-LD on homepage",
      "module": "M5",
      "axis": "both",
      "severity": 4
    },
    {
      "id": "S2",
      "name": "homepage schema types",
      "module": "M5",
      "axis": "both",
      "severity": 3
    },
    {
      "id": "S3",
      "name": "JSON-LD on article",
      "module": "M5",
      "axis": "both",
      "severity": 3
    },
    {
      "id": "S4",
      "name": "article schema type",
      "module": "M5",
      "axis": "both",
      "severity": 2
    },
    {
      "id": "S5",
      "name": "no page is noindex",
      "module": "M2",
      "axis": "search",
      "severity": 5
    },
    {
      "id": "S6",
      "name": "markup/body parity",
      "module": "M5",
      "axis": "both",
      "severity": 4
    },
    {
      "id": "O1",
      "name": "title tag",
      "module": "M7",
      "axis": "search",
      "severity": 4
    },
    {
      "id": "O2",
      "name": "meta description",
      "module": "M7",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "O3",
      "name": "single H1",
      "module": "M7",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "O4",
      "name": "html lang",
      "module": "M7",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "O5",
      "name": "Open Graph tags",
      "module": "M8",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "O6",
      "name": "OG image reachable",
      "module": "M8",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "O7",
      "name": "visible timestamp",
      "module": "M13",
      "axis": "both",
      "severity": 2
    },
    {
      "id": "O8",
      "name": "article title lengths",
      "module": "M7",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "O9",
      "name": "image alt coverage",
      "module": "M9",
      "axis": "both",
      "severity": 3
    },
    {
      "id": "O10",
      "name": "visible freshness",
      "module": "M13",
      "axis": "both",
      "severity": 3
    },
    {
      "id": "P2",
      "name": "LCP fetchpriority",
      "module": "M15",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "P3",
      "name": "LCP preload",
      "module": "M15",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "P4",
      "name": "image dimensions (CLS)",
      "module": "M15",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "P5",
      "name": "script defer/async",
      "module": "M15",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "P6",
      "name": "large images",
      "module": "M15",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "I1",
      "name": "sitemap URL list",
      "module": "M17",
      "axis": "search",
      "severity": 1
    },
    {
      "id": "I2",
      "name": "sitemap URLs return 200",
      "module": "M3",
      "axis": "search",
      "severity": 4
    },
    {
      "id": "I3",
      "name": "orphan detection",
      "module": "M10",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "X1",
      "name": "duplicate titles",
      "module": "M7",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "X2",
      "name": "duplicate meta descriptions",
      "module": "M7",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "X3",
      "name": "self-referential canonical",
      "module": "M2",
      "axis": "search",
      "severity": 4
    },
    {
      "id": "X4",
      "name": "mixed content",
      "module": "M3",
      "axis": "search",
      "severity": 4
    },
    {
      "id": "HD1",
      "name": "HSTS header",
      "module": "M3",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "HD2",
      "name": "X-Content-Type-Options",
      "module": "M3",
      "axis": "search",
      "severity": 1
    },
    {
      "id": "HD3",
      "name": "frame protection",
      "module": "M3",
      "axis": "search",
      "severity": 1
    },
    {
      "id": "HD4",
      "name": "Referrer-Policy",
      "module": "M3",
      "axis": "search",
      "severity": 1
    },
    {
      "id": "HD5",
      "name": "compression",
      "module": "M15",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "HD6",
      "name": "Cache-Control",
      "module": "M15",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "HD7",
      "name": "TTFB",
      "module": "M15",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "HD8",
      "name": "redirect chain",
      "module": "M3",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "HL1",
      "name": "hreflang tags",
      "module": "M20",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "HL2",
      "name": "hreflang values valid",
      "module": "M20",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "HL3",
      "name": "self-referencing hreflang",
      "module": "M20",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "HL4",
      "name": "hreflang x-default",
      "module": "M20",
      "axis": "search",
      "severity": 2
    },
    {
      "id": "HL5",
      "name": "hreflang reciprocity",
      "module": "M20",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "HL6",
      "name": "hreflang targets 200",
      "module": "M20",
      "axis": "search",
      "severity": 3
    },
    {
      "id": "L1",
      "name": "llms.txt present",
      "module": "M21",
      "axis": "ai",
      "severity": 2
    },
    {
      "id": "L2",
      "name": "llms.txt starts with H1",
      "module": "M21",
      "axis": "ai",
      "severity": 1
    },
    {
      "id": "L3",
      "name": "llms.txt links resolve",
      "module": "M21",
      "axis": "ai",
      "severity": 2
    },
    {
      "id": "L4",
      "name": "llms.txt declared in head",
      "module": "M21",
      "axis": "ai",
      "severity": 1
    },
    {
      "id": "R1",
      "name": "content without JS",
      "module": "M4",
      "axis": "both",
      "severity": 4
    },
    {
      "id": "R2",
      "name": "headings without JS",
      "module": "M4",
      "axis": "both",
      "severity": 3
    },
    {
      "id": "R3",
      "name": "links without JS",
      "module": "M4",
      "axis": "both",
      "severity": 4
    },
    {
      "id": "R4",
      "name": "client-side app shell",
      "module": "M4",
      "axis": "both",
      "severity": 4
    },
    {
      "id": "PS1",
      "name": "mobile performance",
      "module": "M15",
      "axis": "search",
      "severity": 4,
      "needs": "pagespeed"
    },
    {
      "id": "PS2",
      "name": "LCP (mobile)",
      "module": "M15",
      "axis": "search",
      "severity": 4,
      "needs": "pagespeed"
    },
    {
      "id": "PS3",
      "name": "CLS (mobile)",
      "module": "M15",
      "axis": "search",
      "severity": 3,
      "needs": "pagespeed"
    },
    {
      "id": "PS4",
      "name": "TBT (mobile)",
      "module": "M15",
      "axis": "search",
      "severity": 3,
      "needs": "pagespeed"
    },
    {
      "id": "PS5",
      "name": "desktop performance",
      "module": "M15",
      "axis": "search",
      "severity": 2,
      "needs": "pagespeed"
    },
    {
      "id": "G4",
      "name": "homepage indexed",
      "module": "M2",
      "axis": "search",
      "severity": 5,
      "needs": "gsc"
    },
    {
      "id": "B2",
      "name": "Bing page alerts",
      "module": "M3",
      "axis": "search",
      "severity": 3,
      "needs": "bing"
    },
    {
      "id": "B3",
      "name": "Bing crawl stats",
      "module": "M3",
      "axis": "search",
      "severity": 2,
      "needs": "bing"
    },
    {
      "id": "AI1",
      "name": "AI answer engines can reach the site",
      "module": "M14",
      "axis": "ai",
      "severity": 5
    },
    {
      "id": "AI2",
      "name": "citation crawlers individually allowed",
      "module": "M14",
      "axis": "ai",
      "severity": 4
    },
    {
      "id": "AI3",
      "name": "user-triggered fetchers allowed",
      "module": "M14",
      "axis": "ai",
      "severity": 3
    },
    {
      "id": "AB1",
      "name": "question headings answered directly",
      "module": "M11",
      "axis": "ai",
      "severity": 4
    },
    {
      "id": "AB2",
      "name": "extractable structures present",
      "module": "M11",
      "axis": "ai",
      "severity": 3
    },
    {
      "id": "AB3",
      "name": "content is segmented into passages",
      "module": "M11",
      "axis": "ai",
      "severity": 3
    },
    {
      "id": "AB4",
      "name": "sections open self-contained",
      "module": "M11",
      "axis": "ai",
      "severity": 2
    },
    {
      "id": "FD1",
      "name": "statistic density",
      "module": "M12",
      "axis": "ai",
      "severity": 4
    },
    {
      "id": "FD2",
      "name": "outbound citations to third-party sources",
      "module": "M12",
      "axis": "ai",
      "severity": 3
    },
    {
      "id": "FD3",
      "name": "claims supported by figures",
      "module": "M12",
      "axis": "ai",
      "severity": 2
    },
    {
      "id": "EN1",
      "name": "primary entity declared",
      "module": "M6",
      "axis": "ai",
      "severity": 4
    },
    {
      "id": "EN2",
      "name": "identity links (sameAs)",
      "module": "M6",
      "axis": "ai",
      "severity": 4
    },
    {
      "id": "EN3",
      "name": "the entity is named consistently",
      "module": "M6",
      "axis": "ai",
      "severity": 2
    },
    {
      "id": "EE1",
      "name": "content carries an author",
      "module": "M16",
      "axis": "both",
      "severity": 3
    },
    {
      "id": "EE2",
      "name": "the business is identifiable",
      "module": "M16",
      "axis": "both",
      "severity": 3
    },
    {
      "id": "EE3",
      "name": "published policies",
      "module": "M16",
      "axis": "both",
      "severity": 2
    },
    {
      "id": "EE4",
      "name": "a real contact route",
      "module": "M16",
      "axis": "both",
      "severity": 3
    },
    {
      "id": "PP1",
      "name": "inner-page H1",
      "module": "M7",
      "axis": "search",
      "severity": 3,
      "needs": "full"
    },
    {
      "id": "PP2",
      "name": "inner-page titles",
      "module": "M7",
      "axis": "search",
      "severity": 3,
      "needs": "full"
    },
    {
      "id": "PP3",
      "name": "inner-page meta",
      "module": "M7",
      "axis": "search",
      "severity": 2,
      "needs": "full"
    },
    {
      "id": "PP4",
      "name": "inner-page canonical",
      "module": "M2",
      "axis": "search",
      "severity": 4,
      "needs": "full"
    },
    {
      "id": "PP5",
      "name": "inner-page schema",
      "module": "M5",
      "axis": "both",
      "severity": 3,
      "needs": "full"
    },
    {
      "id": "PP6",
      "name": "inner-page image alt",
      "module": "M9",
      "axis": "both",
      "severity": 3,
      "needs": "full"
    },
    {
      "id": "PP8",
      "name": "noindex pages",
      "module": "M2",
      "axis": "search",
      "severity": 4,
      "needs": "full"
    },
    {
      "id": "PP9",
      "name": "duplicate content",
      "module": "M2",
      "axis": "search",
      "severity": 3,
      "needs": "full"
    },
    {
      "id": "OF1",
      "name": "prices in an extractable structure",
      "module": "M11",
      "axis": "ai",
      "severity": 3
    },
    {
      "id": "OF2",
      "name": "offer markup present",
      "module": "M5",
      "axis": "ai",
      "severity": 3
    },
    {
      "id": "OF3",
      "name": "offer markup matches the page",
      "module": "M5",
      "axis": "ai",
      "severity": 3
    },
    {
      "id": "L5",
      "name": "llms.txt agrees with the pages",
      "module": "M21",
      "axis": "ai",
      "severity": 2
    }
  ],
  "unscored": [
    {
      "id": "T9",
      "reason": "ads.txt — only meaningful if the site sells ad inventory. Absence is not a defect."
    },
    {
      "id": "P1",
      "reason": "GA4 tag — analytics choice, not an SEO property. Plenty of good sites use something else or nothing."
    },
    {
      "id": "A1",
      "reason": "AdSense snippet — monetisation, not visibility."
    },
    {
      "id": "A2",
      "reason": "AdSense pub-ID match — monetisation, not visibility."
    },
    {
      "id": "I4",
      "reason": "cross-site partner links — our own inter-property linking convention, driven by partnerDomains config. Meaningless for a client."
    },
    {
      "id": "IN1",
      "reason": "IndexNow key file — our deployment practice, and only observable when we hold the filesystem."
    },
    {
      "id": "H1",
      "reason": ".htaccess present — needs filesystem access we do not have on a prospect, and duplicates the redirect and security-header tests, which we can see from outside."
    },
    {
      "id": "H2",
      "reason": ".htaccess HTTPS rule — same; the outcome is already measured by the HTTPS-redirect test."
    },
    {
      "id": "H3",
      "reason": ".htaccess www rule — same; the outcome is already measured by the www-redirect test."
    },
    {
      "id": "H4",
      "reason": ".htaccess index.html rule — same; the outcome is already measured by the index.html redirect test."
    },
    {
      "id": "H5",
      "reason": ".htaccess security headers — same; the outcome is already measured by the HSTS-header test."
    },
    {
      "id": "G1",
      "reason": "GSC property access — a diagnostic of our own connection, not of the site."
    },
    {
      "id": "G2",
      "reason": "GSC search performance — data for the narrative, not a verdict."
    },
    {
      "id": "G3",
      "reason": "GSC top queries — data for the narrative, not a verdict."
    },
    {
      "id": "B1",
      "reason": "Bing access — a diagnostic of our own connection."
    },
    {
      "id": "B4",
      "reason": "Bing performance — data, not a verdict."
    },
    {
      "id": "B5",
      "reason": "Bing top queries — data, not a verdict."
    },
    {
      "id": "B6",
      "reason": "Bing top pages — data, not a verdict."
    },
    {
      "id": "AI4",
      "reason": "training-crawler policy — which model-training crawlers robots.txt refuses. Refusing them is a legitimate business choice that costs no citations, per docs/ai-visibility-research-2026-09-09.md, so this returns data for the report to state rather than a verdict to score."
    },
    {
      "id": "PP7",
      "reason": "thin content — reported under M12 as context. Word count is not fact density; scoring it there would overstate what we measure."
    },
    {
      "id": "O11",
      "reason": "Visible updated date against dateModified. Reported, not scored, for its first cycle, and not for either reason above: the check is new and scores once a month of client data shows how often a correct site trips it."
    }
  ]
}
