{
 "tool": "writesonic",
 "raw_files": [
  "raw/ws_lab2.json",
  "raw/ws_lab2-clean.json",
  "raw/ws_post_lab2.json",
  "raw/ws_post_lab2-clean.json"
 ],
 "reach": {
  "fetched_paths": [
   "/",
   "/robots.txt",
   "/sitemap.xml",
   "/llms.txt",
   "/services",
   "/areas",
   "/reviews",
   "/blog",
   "/pricing"
  ],
  "agents": [
   "WritesonicBot/1.0",
   "Chrome 131 macOS (one homepage fetch, the \"browser\" side of its cloaking check)"
  ],
  "not_fetched": "No AI crawler, Googlebot, Bingbot or Applebot user agent; sitemap children, security.txt and most sub-pages not fetched."
 },
 "faults": {
  "R1": {
   "v": "missed",
   "quote": "",
   "where": "",
   "note": "bots[3] ClaudeBot \"robots\": \"allow\" (the widely-used-parser reading; not wrong per GRADING.md).",
   "loc": "robots"
  },
  "R2": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "robots"
  },
  "R3": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "robots"
  },
  "R4": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "robots"
  },
  "R5": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "robots"
  },
  "R6": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "robots"
  },
  "R7": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "robots"
  },
  "S1": {
   "v": "wrong",
   "quote": "\"name\": \"PerplexityBot\", ... \"robots\": \"allow\", \"canRead\": \"yes\"",
   "where": "ws_lab2.json report.bots[6]",
   "note": "PerplexityBot gets 403. Never fetched as PerplexityBot; the verdict is inferred. Also signals[7] \"No WAF / network block\": \"passed\".",
   "loc": "home:PerplexityBot"
  },
  "S2": {
   "v": "wrong",
   "quote": "\"name\": \"Applebot\", ... \"robots\": \"allow\", \"canRead\": \"yes\"",
   "where": "ws_lab2.json report.bots[15]",
   "note": "Applebot gets a 200 challenge page. Not fetched as Applebot.",
   "loc": "home:Applebot"
  },
  "S3": {
   "v": "missed",
   "quote": "",
   "where": "",
   "note": "Set by the independent verification pass (grades/_verification.json).",
   "loc": "home:OAI-SearchBot"
  },
  "S4": {
   "v": "wrong",
   "quote": "\"name\": \"ClaudeBot\", ... \"robots\": \"allow\", \"canRead\": \"yes\"",
   "where": "ws_lab2.json report.bots[3]",
   "note": "ClaudeBot is 302-redirected to /unavailable on every page. Not fetched as ClaudeBot.",
   "loc": "home:ClaudeBot"
  },
  "S5": {
   "v": "wrong",
   "quote": "\"name\": \"GPTBot\", ... \"robots\": \"allow\", \"canRead\": \"yes\"",
   "where": "ws_lab2.json report.bots[0]",
   "note": "GPTBot gets 429 on every request. Not fetched as GPTBot.",
   "loc": "home:GPTBot"
  },
  "S6": {
   "v": "wrong",
   "quote": "\"dynamic\": {\"checked\": true, \"cloaking\": false, \"botWords\": 169, \"browserWords\": 169}",
   "where": "ws_lab2.json report.dynamic",
   "note": "Googlebot UAs get a hidden keyword block. The check compared WritesonicBot with a browser, so it could not see Googlebot cloaking, yet it states \"cloaking\": false.",
   "loc": "home:Googlebot"
  },
  "S7": {
   "v": "missed",
   "quote": "",
   "where": "",
   "note": "Set by the independent verification pass (grades/_verification.json).",
   "loc": "sub:/pricing:Bingbot"
  },
  "I1": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/services/gutter-guards"
  },
  "I2": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "sub:/pricing"
  },
  "I3": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/areas/riverbend"
  },
  "I4": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/services/downspout-repair"
  },
  "I5": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "home"
  },
  "I6": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/faq"
  },
  "I7": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/about"
  },
  "J1": {
   "v": "wrong",
   "quote": "\"url\": \"https://lab2.crawlcheck.io/pricing\", \"verdict\": \"readable\", ... \"mode\": \"Server-rendered\"",
   "where": "ws_lab2.json report.pages[3]",
   "note": "The prices are only in a script (\"Loading prices…\" in the HTML); the tool says the page is server-rendered.",
   "loc": "sub:/pricing"
  },
  "J2": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "home"
  },
  "J3": {
   "v": "wrong",
   "quote": "\"url\": \"https://lab2.crawlcheck.io/reviews\", \"verdict\": \"readable\", \"words\": 39, ... \"mode\": \"Server-rendered\"",
   "where": "ws_lab2.json report.pages[4]",
   "note": "/reviews body is an empty div filled by script; the 39 words are nav, H1 and footer (clean twin: 75 words).",
   "loc": "sub:/reviews"
  },
  "J4": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/faq"
  },
  "J5": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/gallery"
  },
  "J6": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/careers"
  },
  "D1": {
   "v": "partial",
   "quote": "\"label\": \"Structured data (JSON-LD)\", \"value\": \"none\", \"status\": \"fail\"",
   "where": "ws_lab2.json report.signals[3]",
   "note": "The JSON-LD exists but does not parse; reported as absent (clean twin reports \"LocalBusiness\").",
   "loc": "home"
  },
  "D2": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/contact"
  },
  "D3": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/contact"
  },
  "D4": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "sub:/reviews"
  },
  "D5": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/about"
  },
  "D6": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/about"
  },
  "D7": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/blog/*"
  },
  "M1": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "llms"
  },
  "M2": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "llms"
  },
  "M3": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "security"
  },
  "M4": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "security"
  },
  "M5": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "security"
  },
  "X1": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "smidx"
  },
  "X2": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "smpages"
  },
  "X3": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "smpages"
  },
  "X4": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "smpages"
  },
  "X5": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "smpages"
  },
  "X6": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "smpages"
  },
  "L1": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "home"
  },
  "L2": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/old-gutter-page"
  },
  "L3": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/blog/do-gutter-guards-work,/promo-a"
  },
  "L4": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/specials"
  },
  "L5": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "smpages"
  },
  "L6": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/faq/"
  },
  "L7": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/about"
  },
  "P1": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/careers"
  },
  "P2": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/areas/millbrook,/areas/cedar-park"
  },
  "P3": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/services/fascia-repair"
  },
  "P4": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/services/ice-dam-prevention"
  },
  "P5": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "home"
  },
  "P6": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/privacy"
  },
  "P7": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/terms"
  },
  "T1": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "home"
  },
  "T2": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/about"
  },
  "T3": {
   "v": "unreached",
   "quote": "",
   "where": "",
   "loc": "sub:/blog/do-gutter-guards-work"
  },
  "T4": {
   "v": "missed",
   "quote": "",
   "where": "",
   "loc": "home"
  }
 },
 "score": {
  "caught": 0,
  "partial": 1,
  "points": 0.5,
  "wrong": 7,
  "reached": 28,
  "points_of_reached": 0.018,
  "pct_of_63": 0.8
 },
 "clean": {
  "false_alarms": [],
  "advisories": [
   {
    "claim": "thin homepage",
    "quote": "AI can read this page, but there is very little on it",
    "where": "ws_lab2-clean.json report.actionables[0].title"
   },
   {
    "claim": "schema rated warn with no reason given",
    "quote": "\"label\": \"Structured data (JSON-LD)\", \"value\": \"LocalBusiness\", \"status\": \"warn\"",
    "where": "ws_lab2-clean.json report.signals[3]",
    "note": "No untrue statement; the warn is unexplained."
   },
   {
    "claim": "short page word count",
    "quote": "\"label\": \"Visible body words in raw HTML\", \"value\": \"167 words\", \"status\": \"warn\"",
    "where": "ws_lab2-clean.json report.signals[0]"
   }
  ]
 },
 "other_false_claims_lab2": [
  {
   "claim": "sitemap page count",
   "quote": "\"sitemapPages\": 2",
   "where": "ws_lab2.json report.preview.sitemapPages",
   "why_false": "/sitemap.xml is an index of 2 child sitemaps; sitemap-pages.xml alone lists 38 URLs. 2 is the number of child sitemaps, not pages. Minor."
  },
  {
   "claim": "no WAF or network block",
   "quote": "\"label\": \"No WAF / network block\", \"value\": \"passed\", \"status\": \"pass\"",
   "where": "ws_lab2.json report.signals[7]",
   "why_false": "True only for WritesonicBot; the site refuses GPTBot (429) and PerplexityBot (403). Overlaps S1/S5."
  }
 ],
 "evidence_quality": {
  "score": 1,
  "why": "Gives labels and counts (words, links, \"canRead\") with no status codes, agents actually used or rules; the per-bot verdicts are not backed by any fetch as those bots."
 },
 "strengths_not_scored": [
  "Crawls 6 pages (homepage plus 5 linked pages) and reports words/links/render mode per page.",
  "Raw-HTML vs rendered word comparison and a bot-vs-browser cloaking check (against its own UA).",
  "Detects llms.txt and robots.txt presence.",
  "Clean twin: zero false alarms."
 ],
 "notes": "The most damaging pattern in the set: a 16-bot table that says \"canRead: yes\" for every bot, including GPTBot (429), PerplexityBot (403), ClaudeBot (302) and Applebot (challenge), none of which it fetched as. Its JS check, the tool's headline feature, called /pricing and /reviews \"Server-rendered\" though their main content is script-injected. Wrong verdicts are counted in \"reached\" because the tool chose to state them. ws_lab2-clean.json came from a re-poll after the batch ended with report:null (runs.jsonl); the lab2-clean request window is unaffected."
}