{
 "tool": "geotoolbox",
 "raw_files": [
  "raw/geotoolbox_scanner_lab2.txt",
  "raw/geotoolbox_llms_lab2.txt",
  "raw/geotoolbox_scanner_lab2-clean.txt",
  "raw/geotoolbox_llms_lab2-clean.txt"
 ],
 "reach": {
  "fetched_paths": [
   "/",
   "/robots.txt",
   "/llms.txt",
   "/llms-full.txt (404)",
   "/sitemap_index.xml (404)",
   "/sitemap.xml",
   "/sitemap-pages.xml",
   "/unavailable (after ClaudeBot 302)",
   "/services",
   "/contact",
   "/warranty (404)",
   "/financing (404)",
   "/.well-known/http-message-signatures-directory (404)",
   "/sg-w1-notfound-* (404 probe)",
   "/assets/site.css",
   "/assets/site.js",
   "/img/*.svg",
   "/favicon.ico"
  ],
  "agents": [
   "Chrome 124 desktop (robots, homepage, llms checker)",
   "OAI-SearchBot/1.0 (200, stripped page)",
   "PerplexityBot/1.0 (403)",
   "Googlebot/2.1 desktop (200, cloaked block served)",
   "GPTBot/1.2 (429)",
   "ClaudeBot/1.0 (302 -> /unavailable)",
   "CCBot/2.0",
   "ChatGPT-User/1.0",
   "Perplexity-User/1.0",
   "Googlebot/2.1 (sitemaps)",
   "Chrome 138 headless render",
   "AI-Readiness-Probe/2.0-2.1"
  ],
  "reach_classes": "home: D1 I5 J2 L1 P5 S1 S2 S3 S4 S5 S6 T1 T4; files fetched: robots, llms, sitemap; sub faults reached: D2 D3"
 },
 "faults": {
  "R1": {
   "v": "caught",
   "quote": "ClaudeBot · Anthropic · Model training · Disallow: / (line 11)",
   "where": "scanner, CRAWLER ACCESS. Line 11 is the line Google's reference parser applies (GRADING.md correction); the grader note in the raw file calling it another group's line is superseded."
  },
  "R2": {
   "v": "missed"
  },
  "R3": {
   "v": "missed"
  },
  "R4": {
   "v": "missed"
  },
  "R5": {
   "v": "missed"
  },
  "R6": {
   "v": "missed"
  },
  "R7": {
   "v": "missed"
  },
  "S1": {
   "v": "caught",
   "quote": "PerplexityBot (HTTP 403 — robots does not disallow it (possible UA filtering))",
   "where": "scanner, AI crawler reachability (live probe); log: PerplexityBot GET / -> 403"
  },
  "S2": {
   "v": "missed"
  },
  "S3": {
   "v": "missed"
  },
  "S4": {
   "v": "partial",
   "quote": "ClaudeBot (200 but only 4 words)",
   "where": "scanner live probe; log: ClaudeBot GET / -> 302, then /unavailable -> 200. Symptom visible (no content), but the 302 to /unavailable is reported as a 200 and not located."
  },
  "S5": {
   "v": "caught",
   "quote": "GPTBot (HTTP 429 — robots does not disallow it (possible UA filtering))",
   "where": "scanner live probe; log: GPTBot GET / -> 429"
  },
  "S6": {
   "v": "missed"
  },
  "S7": {
   "v": "unreached"
  },
  "I1": {
   "v": "unreached"
  },
  "I2": {
   "v": "unreached"
  },
  "I3": {
   "v": "unreached"
  },
  "I4": {
   "v": "unreached"
  },
  "I5": {
   "v": "caught",
   "quote": "FIX Indexable (no noindex/nosnippet) 4 pts — Page sends nosnippet (meta robots).",
   "where": "scanner, FIX THESE FIRST (homepage)"
  },
  "I6": {
   "v": "unreached"
  },
  "I7": {
   "v": "unreached"
  },
  "J1": {
   "v": "unreached"
  },
  "J2": {
   "v": "missed"
  },
  "J3": {
   "v": "unreached"
  },
  "J4": {
   "v": "unreached"
  },
  "J5": {
   "v": "unreached"
  },
  "J6": {
   "v": "unreached"
  },
  "D1": {
   "v": "partial",
   "quote": "FIX Schema.org structured data 8 pts — No JSON-LD schema.org markup found.",
   "where": "scanner. The block exists and fails to parse; reported as absent (GRADING.md's own partial example). Counted here only, not also as a false claim."
  },
  "D2": {
   "v": "missed"
  },
  "D3": {
   "v": "missed"
  },
  "D4": {
   "v": "unreached"
  },
  "D5": {
   "v": "unreached"
  },
  "D6": {
   "v": "unreached"
  },
  "D7": {
   "v": "unreached"
  },
  "M1": {
   "v": "caught",
   "quote": "ERROR Missing H1 title (line 1) — The spec requires exactly one H1 (the site/project name)",
   "where": "llms.txt checker"
  },
  "M2": {
   "v": "caught",
   "quote": "BROKEN 2 dead links — Linked page(s) returned 404/410, e.g. <url>",
   "where": "llms.txt checker; log: /warranty and /financing -> 404"
  },
  "M3": {
   "v": "unreached"
  },
  "M4": {
   "v": "unreached"
  },
  "M5": {
   "v": "unreached"
  },
  "X1": {
   "v": "missed"
  },
  "X2": {
   "v": "missed"
  },
  "X3": {
   "v": "missed"
  },
  "X4": {
   "v": "missed"
  },
  "X5": {
   "v": "missed"
  },
  "X6": {
   "v": "missed"
  },
  "L1": {
   "v": "missed"
  },
  "L2": {
   "v": "unreached"
  },
  "L3": {
   "v": "unreached"
  },
  "L4": {
   "v": "unreached"
  },
  "L5": {
   "v": "unreached"
  },
  "L6": {
   "v": "unreached"
  },
  "L7": {
   "v": "unreached"
  },
  "P1": {
   "v": "unreached"
  },
  "P2": {
   "v": "unreached"
  },
  "P3": {
   "v": "unreached"
  },
  "P4": {
   "v": "unreached"
  },
  "P5": {
   "v": "missed"
  },
  "P6": {
   "v": "unreached"
  },
  "P7": {
   "v": "unreached"
  },
  "T1": {
   "v": "missed"
  },
  "T2": {
   "v": "unreached"
  },
  "T3": {
   "v": "unreached"
  },
  "T4": {
   "v": "missed"
  }
 },
 "score": {
  "caught": 6,
  "partial": 2,
  "points": 7.0,
  "wrong": 0,
  "reached": 30,
  "points_of_reached": 0.233,
  "pct_of_63": 11.1
 },
 "clean": {
  "false_alarms": [],
  "advisories": [
   {
    "claim": "No Last-Modified on llms.txt",
    "quote": "ADVISORY No Last-Modified date",
    "why": "true (worker sends no Last-Modified); optional"
   },
   {
    "claim": "llms.txt links to HTML not .md",
    "quote": "ADVISORY Links point to HTML, not .md",
    "why": "true; optional"
   },
   {
    "claim": "no llms-full.txt",
    "quote": "ADVISORY No /llms-full.txt",
    "why": "true (404); optional"
   },
   {
    "claim": "few answer-friendly structures",
    "quote": "WARN Answers likely questions 4 pts — Few answer-friendly structures on this page (no FAQ, question headings, tables or rich lists).",
    "why": "homepage has no FAQ/tables; content-style advice, optional"
   },
   {
    "claim": "missing OpeningHoursSpecification",
    "quote": "Missing expected type(s): OpeningHoursSpecification.",
    "why": "true, optional property"
   },
   {
    "claim": "no BLUF value statement",
    "quote": "WARN Clear value up top (BLUF) 4 pts — Has an H1 but no clear value statement up top.",
    "why": "subjective copy advice; first paragraph arguably is a value statement, but not a factual error"
   },
   {
    "claim": "Level 4 needs MCP/API",
    "quote": "Level 4 (Agent-Operable) requires live capability surfaces (MCP/API)",
    "why": "emerging, optional"
   }
  ]
 },
 "other_false_claims_lab2": [],
 "evidence_quality": {
  "score": 3,
  "why": "Cites robots line numbers (line 11, llms line 1), observed status codes per bot UA (429, 403) and word counts from live probes it actually made under each UA, and counts resolving llms.txt links (2/4, 11/11, both correct per the log)."
 },
 "strengths_not_scored": [
  "Separates robots permission from server behaviour: \"robots does not disallow it (possible UA filtering)\" — the right diagnosis for UA-based blocking.",
  "Link-checks every llms.txt link: \"2/4 links resolve, 2 dead\" on lab2 and \"11/11 links resolve\" on clean, both exact per the log.",
  "Accurately labels optional items as optional: \"WARNING No summary blockquote — Optional per spec.\" (true on lab2, not a key fault).",
  "Probes a random 404 URL and the Web Bot Auth directory; lists agent surfaces as \"DETECTED, NOT SCORED\" rather than penalising them.",
  "Zero false alarms on the clean twin; the clean score (83 vs 64; llms 95 vs 40) moves in the right direction."
 ],
 "notes": "Two free tools graded as one. Probed homepage as OAI-SearchBot (got the S3 stripped page), Googlebot (got the S6 hidden keyword block) and CCBot, yet counted all as \"real content\", so S3/S6 are missed (not wrong: they did return content). Never sent Applebot (S2) or Bingbot (S7). Fetched sitemap.xml and sitemap-pages.xml as Googlebot but reported nothing about them; on lab2 it tried /sitemap_index.xml (404) before /sitemap.xml, while on clean it went straight to /sitemap.xml, which suggests it fell back to guessing because the relative Sitemap line (R6) was not used — but the output never says so (Discovery 14/15 vs 15/15 is an unlocated 1-point difference that cannot be tied to R6), so R6 is missed. /contact (D2, D3) was fetched only as an llms.txt link check. Score labels such as \"Dominant in AI answers\" (clean) and \"Inconsistent\" (lab2) are grade-band names, not measurements, and are not counted as claims. Never fetched security.txt (M3-M5 unreached)."
}