{
 "tool": "crawlcheck",
 "raw_files": [
  "raw/cc_r_wyka6piddc.json",
  "raw/cc_r_wyka6piddc.html",
  "raw/cc_r_kcys45p8jf.json",
  "raw/cc_r_kcys45p8jf.html",
  "raw/cc_depth_i61juq337r.json",
  "raw/cc_depth_i61juq337r.html",
  "raw/cc_depth_6vgln95jk3.json",
  "raw/cc_depth_6vgln95jk3.html",
  "log/lab2-log.json"
 ],
 "reach": {
  "classes": [
   "home",
   "file",
   "sub"
  ],
  "summary": "Homepage scan 05:13:20Z plus 41-URL crawl ~05:14Z. Log (CrawlCheck UA): every declared page, /specials, /quote, /promo-a+b, /old-gutter-page, /gutters, /services/roof-repair, robots, llms.txt, security.txt (200), sitemap.xml, sitemap-pages.xml, sitemap-blog.xml (404 x5). Named-crawler UAs only on /. Never requested: /services/, /faq/, /api/faq.json, /embed/careers, /warranty, /financing, /profiles/facebook. Every fault lives on a page or file it fetched, so all 63 count as reached. S7 page was reached but never as Bingbot.",
  "unreached": []
 },
 "faults": {
  "R1": {
   "v": "caught",
   "quote": "ClaudeBot | BLOCKED at / · Anthropic training · named rule",
   "where": "cc_r_wyka6piddc.html 'AI and search agents' table; also 'What each crawler was served': 'ClaudeBot | disallowed'. No line number or ambiguity explained.",
   "visible_in_html": true
  },
  "R2": {
   "v": "caught",
   "quote": "2 render resources referenced by the homepage are disallowed to every crawler by this site's own robots.txt: /assets/site.css (/assets/), /assets/site.js",
   "where": "cc_r_wyka6piddc.html top finding (free, full); json findings[0].detail",
   "visible_in_html": true
  },
  "R3": {
   "v": "caught",
   "quote": "Googlebot-Image | BLOCKED at / · Google image crawler · named rule",
   "where": "cc_r_wyka6piddc.html 'AI and search agents' table; also locked finding title json findings[1].title 'robots.txt keeps Google's image crawler off the site's images'",
   "visible_in_html": true
  },
  "R4": {
   "v": "caught",
   "quote": "Storebot-Google | BLOCKED at / · Google Shopping · named rule",
   "where": "cc_r_wyka6piddc.html 'AI and search agents' table; 'Disallowed in robots.txt | Google image crawler · Google Shopping'",
   "visible_in_html": true
  },
  "R5": {
   "v": "missed",
   "quote": "PerplexityBot | allowed · Perplexity index · wildcard rule",
   "where": "cc_r_wyka6piddc.html 'AI and search agents' table. True verdict, but the mis-spelt 'Perplexity-Bot' group is never mentioned.",
   "visible_in_html": true
  },
  "R6": {
   "v": "partial",
   "quote": "robots.txt names a sitemap | 1 Sitemap: line(s) | at least one | ✓ Passed",
   "where": "cc_r_wyka6piddc.html 'Machine-file trust chain'. Relative path not flagged; 'Sitemap coverage' contradicts it with 'Sitemaps named in robots.txt resolve: none named'.",
   "visible_in_html": true,
   "note": "Set by the independent verification pass (grades/_verification.json)."
  },
  "R7": {
   "v": "missed",
   "quote": "(no mention of the Noindex: line)",
   "where": "cc_r_wyka6piddc.html robots sections; no output mentions it",
   "visible_in_html": true
  },
  "S1": {
   "v": "caught",
   "quote": "PerplexityBot | allowed | 403 | 1 | — | blocked by the server",
   "where": "cc_r_wyka6piddc.html 'What each crawler was served'; json agentview[5] status 403",
   "visible_in_html": true
  },
  "S2": {
   "v": "caught",
   "quote": "Applebot | allowed | 200 · an interstitial challenge | 19 | 0% | blocked by the server",
   "where": "cc_r_wyka6piddc.html 'What each crawler was served'; json agentview[10]",
   "visible_in_html": true
  },
  "S3": {
   "v": "partial",
   "quote": "OAI-SearchBot | different | words (198 → 164) | a template or a cache variant, not a different page",
   "where": "cc_r_wyka6piddc.html 'Which document each identity received'. Right crawler, less text, but explained away; first table calls it 'same page'; removed sections not named.",
   "visible_in_html": true
  },
  "S4": {
   "v": "caught",
   "quote": "ClaudeBot | 200 | 5 | 0 | sent to /unavailable",
   "where": "cc_r_wyka6piddc.html 'What each agent receives' table. Same section contradicts it: 'No identity is sent to a different URL | none | ✓ Passed'; the 302 status is not shown.",
   "visible_in_html": true
  },
  "S5": {
   "v": "caught",
   "quote": "GPTBot | 429 | 3 | — | rate-limited (HTTP 429) — throttled, not blocked",
   "where": "cc_r_wyka6piddc.html 'What each agent receives'; json agentview[1] status 429",
   "visible_in_html": true
  },
  "S6": {
   "v": "partial",
   "quote": "Googlebot | 200 | 220 | 0.91 | different body text",
   "where": "cc_r_wyka6piddc.html 'What each agent receives'. Hidden keyword block not identified. Same report says 'Content served only to crawlers | none ... ✓ Passed' and counts Googlebot among identities handed 'the same document'.",
   "visible_in_html": true
  },
  "S7": {
   "v": "missed",
   "quote": "Bingbot | allowed | 200 | 207 | 100% | same page",
   "where": "cc_r_wyka6piddc.html — Bingbot probed on / only; /pricing was crawled with CrawlCheck's own UA, never as Bingbot (log). Page reached, fault not tested.",
   "visible_in_html": true
  },
  "I1": {
   "v": "caught",
   "quote": "/services/gutter-guards noindex · listed in the sitemap",
   "where": "cc_depth_i61juq337r.html 'Crawl budget' list; 'Every page' row shows '200 noindex'",
   "visible_in_html": true
  },
  "I2": {
   "v": "caught",
   "quote": "1 set by X-Robots-Tag",
   "where": "cc_depth_i61juq337r.html 'Page directives'; 'Every page' row '/pricing ... | noindex'",
   "visible_in_html": true
  },
  "I3": {
   "v": "partial",
   "quote": "/areas/riverbend canonical elsewhere · listed in the sitemap",
   "where": "cc_depth_i61juq337r.html 'Crawl budget'. Located, but never says the canonical target returns 404.",
   "visible_in_html": true
  },
  "I4": {
   "v": "caught",
   "quote": "/services/downspout-repair canonical elsewhere · listed in the sitemap",
   "where": "cc_depth_i61juq337r.html 'Crawl budget' list and 'Every page' Canonical column 'elsewhere'",
   "visible_in_html": true
  },
  "I5": {
   "v": "caught",
   "quote": "/ nosnippet",
   "where": "cc_depth_i61juq337r.html 'Page directives' (indexable pages with their snippet or preview cut). Homepage report itself does not mention it.",
   "visible_in_html": true
  },
  "I6": {
   "v": "partial",
   "quote": "Gutter FAQ | Northfield Gutter Co. | 200 | 1 | 65 | ... | self | noindex",
   "where": "cc_depth_i61juq337r.html 'Every page' row /faq. Effective noindex shown; the two conflicting robots tags are not.",
   "visible_in_html": true
  },
  "I7": {
   "v": "wrong",
   "quote": "About Northfield Gutter Co. | 200 | 1 | 171 | 36.3% | 2 | none | 1 | self",
   "where": "cc_depth_i61juq337r.html 'Every page' row /about, Canonical column 'self'. The canonical is http://lab2.crawlcheck.io/about (json render_parity holds that value but it is not shown in the HTML).",
   "visible_in_html": true
  },
  "J1": {
   "v": "partial",
   "quote": "/pricing | 106 → 132 | 20% | 14 → 14 | 0 → 0 | —",
   "where": "cc_depth_i61juq337r.html 'Raw vs rendered'. JS-only share shown but not flagged; prices not named.",
   "visible_in_html": true
  },
  "J2": {
   "v": "partial",
   "quote": "7 elements with onclick and no tabindex or role (span.lnk, span.lnk, span.lnk)",
   "where": "cc_r_wyka6piddc.html 'Accessibility structure' row 2.1.1, framed as keyboard access; never says the area links are not crawlable. Depth: '0 add links only after JavaScript'.",
   "visible_in_html": true
  },
  "J3": {
   "v": "caught",
   "quote": "/reviews | 46 → 95 | 52% | 14 → 14 | 1 → 1 | —",
   "where": "cc_depth_i61juq337r.html 'Raw vs rendered', with '1 have most of their text only after JavaScript'",
   "visible_in_html": true
  },
  "J4": {
   "v": "partial",
   "quote": "/faq | 65 → 94 | 31% | 14 → 14 | 0 → 0 | —",
   "where": "cc_depth_i61juq337r.html 'Raw vs rendered'. Not flagged; /api/faq.json not mentioned.",
   "visible_in_html": true
  },
  "J5": {
   "v": "missed",
   "quote": "(nothing about /gallery images)",
   "where": "cc_depth_i61juq337r.html /gallery appears only as a short, 77%-template page",
   "visible_in_html": true
  },
  "J6": {
   "v": "missed",
   "quote": "/careers | 41 | 77%",
   "where": "cc_depth_i61juq337r.html 'template share' table; the iframe is never mentioned",
   "visible_in_html": true
  },
  "D1": {
   "v": "caught",
   "quote": "JSON-LD blocks that parse | ... | 0 of 1 | every block | ✗ Failed",
   "where": "cc_r_wyka6piddc.html 'RDF and linked-data surface'; 'Files fetched... Derived: JSON-LD unreadable'; json fact_lineage.read.jsonld_nodes 0",
   "visible_in_html": true
  },
  "D2": {
   "v": "missed",
   "quote": "(no output about /contact schema)",
   "where": "cc_r_wyka6piddc.html/cc_depth_i61juq337r.html — /contact crawled (log), not assessed",
   "visible_in_html": true
  },
  "D3": {
   "v": "missed",
   "quote": "(no output about /contact telephone)",
   "where": "cc_r_wyka6piddc.html/cc_depth_i61juq337r.html",
   "visible_in_html": true
  },
  "D4": {
   "v": "missed",
   "quote": "(no output about AggregateRating on /reviews)",
   "where": "cc_depth_i61juq337r.html",
   "visible_in_html": true
  },
  "D5": {
   "v": "missed",
   "quote": "(no output about /about Organization nodes; only 'JSON-LD 2')",
   "where": "cc_depth_i61juq337r.html 'Every page' row /about",
   "visible_in_html": true
  },
  "D6": {
   "v": "missed",
   "quote": "(no output; /profiles/facebook never requested per log)",
   "where": "cc_depth_i61juq337r.html",
   "visible_in_html": true
  },
  "D7": {
   "v": "missed",
   "quote": "(no output about Article markup on blog posts)",
   "where": "cc_depth_i61juq337r.html",
   "visible_in_html": true
  },
  "M1": {
   "v": "caught",
   "quote": "malformed: no H1 title on the first line",
   "where": "cc_r_wyka6piddc.html 'Machine layer' row 'llms.txt format'",
   "visible_in_html": true
  },
  "M2": {
   "v": "missed",
   "quote": "llms.txt links stay on this host | 4 links · 0 off-host | ✓ Passed",
   "where": "cc_r_wyka6piddc.html 'Machine-file trust chain'; /warranty and /financing never requested (log)",
   "visible_in_html": true
  },
  "M3": {
   "v": "missed",
   "quote": "security.txt | ... | absent (200) | a Contact and a future Expires (RFC 9116)",
   "where": "cc_r_wyka6piddc.html 'Machine layer'. File was fetched (log: 200) but called absent; expiry not reported.",
   "visible_in_html": true
  },
  "M4": {
   "v": "missed",
   "quote": "security.txt | ... | absent (200)",
   "where": "cc_r_wyka6piddc.html 'Machine layer'",
   "visible_in_html": true
  },
  "M5": {
   "v": "partial",
   "quote": "security.txt | ... | absent (200)",
   "where": "cc_r_wyka6piddc.html 'Machine layer'. A 200 rejected as absent is the symptom of the wrong type, but text/html is never named and the file is said not to exist.",
   "visible_in_html": true
  },
  "X1": {
   "v": "missed",
   "quote": "Every sitemap read lists at least one URL | every file read lists URLs | 0 empty | ✓ Passed",
   "where": "cc_r_wyka6piddc.html 'Sitemap coverage'. /sitemap-blog.xml fetched 5 times (404, log) and never reported.",
   "visible_in_html": true
  },
  "X2": {
   "v": "caught",
   "quote": "/services/gutter-guards noindex · listed in the sitemap",
   "where": "cc_depth_i61juq337r.html 'Crawl budget'; '1 noindex pages in the sitemap'",
   "visible_in_html": true
  },
  "X3": {
   "v": "caught",
   "quote": "/old-gutter-page status 301 · listed in the sitemap",
   "where": "cc_depth_i61juq337r.html 'Crawl budget'",
   "visible_in_html": true
  },
  "X4": {
   "v": "caught",
   "quote": "/services/roof-repair status 404 · listed in the sitemap",
   "where": "cc_depth_i61juq337r.html 'Crawl budget'",
   "visible_in_html": true
  },
  "X5": {
   "v": "partial",
   "quote": "Sitemap URLs with a change date | ... | 36 of 38",
   "where": "cc_r_wyka6piddc.html 'Freshness' section. Two entries counted as undated; invalid values and their URLs not named.",
   "visible_in_html": true
  },
  "X6": {
   "v": "partial",
   "quote": "/services status 530 · listed in the sitemap",
   "where": "cc_depth_i61juq337r.html 'Crawl budget' and 'Every page'. Link target is the other host, but the displayed label is '/services', reading as a lab2 page.",
   "visible_in_html": true
  },
  "L1": {
   "v": "partial",
   "quote": "/services/roof-repair Not found | 404 | 1 | 4 | ... | 1 | 0",
   "where": "cc_depth_i61juq337r.html 'Every page' (1 click, 1 inbound). Linking page never named; homepage report scores 'Internal links 100' ('targets resolve').",
   "visible_in_html": true
  },
  "L2": {
   "v": "partial",
   "quote": "/old-gutter-page 2 hops: 301 permanent → 301 permanent → https://lab2.crawlcheck.io/services/ (200)",
   "where": "cc_depth_i61juq337r.html 'Redirects'. Chain flagged, but it is 3 hops; /services/ answers 301 and was never requested (log).",
   "visible_in_html": true
  },
  "L3": {
   "v": "caught",
   "quote": "/promo-a 2 hops: 302 temporary → 302 temporary → loop",
   "where": "cc_depth_i61juq337r.html 'Redirects'; 'Linked but not declared: /promo-a 1 inbound'",
   "visible_in_html": true
  },
  "L4": {
   "v": "partial",
   "quote": "/specials Page not found | 200 | 1 link-found | 13",
   "where": "cc_depth_i61juq337r.html 'Every page'. 'Page not found' title at 200 is visible but never called a soft 404; homepage report lists it only as 'Linked but missing from the sitemap'.",
   "visible_in_html": true
  },
  "L5": {
   "v": "caught",
   "quote": "Orphans — declared in the sitemap, linked from no crawled page ... https://lab2.crawlcheck.io/areas/lakeside",
   "where": "cc_depth_i61juq337r.html 'Orphans'",
   "visible_in_html": true
  },
  "L6": {
   "v": "missed",
   "quote": "(no output; /faq/ never requested per log)",
   "where": "cc_depth_i61juq337r.html",
   "visible_in_html": true
  },
  "L7": {
   "v": "missed",
   "quote": "(no output about the http:// link on /about)",
   "where": "cc_depth_i61juq337r.html",
   "visible_in_html": true
  },
  "P1": {
   "v": "caught",
   "quote": "/careers | | no title",
   "where": "cc_depth_i61juq337r.html 'Titles across the site'",
   "visible_in_html": true
  },
  "P2": {
   "v": "caught",
   "quote": "Gutters in Millbrook | Northfield Gutter Co. on 2 pages",
   "where": "cc_depth_i61juq337r.html 'Duplicate titles'",
   "visible_in_html": true
  },
  "P3": {
   "v": "missed",
   "quote": "(not in HTML; json meta_descriptions.missing 2 without URLs)",
   "where": "cc_depth_i61juq337r.html json meta_descriptions only",
   "visible_in_html": false
  },
  "P4": {
   "v": "caught",
   "quote": "more than one h1 on 1",
   "where": "cc_depth_i61juq337r.html status line; 'Every page' row /services/ice-dam-prevention h1 column '2'",
   "visible_in_html": true
  },
  "P5": {
   "v": "caught",
   "quote": "Missing alt text | ... | 3 missing, 0 empty (100% missing)",
   "where": "cc_r_wyka6piddc.html 'Image signals'; also 'Images carry an alt attribute 0 of 3 ✗ Failed'",
   "visible_in_html": true
  },
  "P6": {
   "v": "missed",
   "quote": "(no output about /privacy lang)",
   "where": "cc_depth_i61juq337r.html",
   "visible_in_html": true
  },
  "P7": {
   "v": "missed",
   "quote": "(no output about /terms viewport)",
   "where": "cc_depth_i61juq337r.html",
   "visible_in_html": true
  },
  "T1": {
   "v": "caught",
   "quote": "HSTS (HTTPS on every return visit) | ... | not sent | max-age of at least one year | ✗ Failed",
   "where": "cc_r_wyka6piddc.html 'Site safety'; also locked title 'HTTPS is served without a Strict-Transport-Security header'",
   "visible_in_html": true
  },
  "T2": {
   "v": "missed",
   "quote": "(no output; homepage-only check: 'Insecure resources on the HTTPS page | 0')",
   "where": "cc_r_wyka6piddc.html 'Site safety'",
   "visible_in_html": true
  },
  "T3": {
   "v": "missed",
   "quote": "(no output about staging.lab2.crawlcheck.io)",
   "where": "cc_depth_i61juq337r.html",
   "visible_in_html": true
  },
  "T4": {
   "v": "caught",
   "quote": "Cookies without the Secure flag | ... | 1 of 1: sid (homepage) | 0 | ✗ Failed",
   "where": "cc_r_wyka6piddc.html 'Site safety'; also 'Session cookies readable by page scripts (no HttpOnly) | sid (homepage) | ✗ Failed'",
   "visible_in_html": true
  }
 },
 "score": {
  "caught": 26,
  "partial": 14,
  "points": 33.0,
  "wrong": 1,
  "reached": 63,
  "points_of_reached": 0.524,
  "pct_of_63": 52.4
 },
 "clean": {
  "false_alarms": [
   {
    "claim": "Business phone on the page: none found (one defect, three statements: \"none found ✗ Failed\", \"structured data only, not shown to readers\", \"Phone numbers written on the page | 0\")",
    "quote": "Business phone on the page | ... | none found | ... | ✗ Failed",
    "why_false": "The number is printed in the page body and footer. Cause: the page-side phone check read only tel: links. Fixed after grading (2026-11-04); the first run is what is graded."
   },
   {
    "claim": "The sitemap lists URLs but carries no lastmod dates / Add <lastmod> dates",
    "quote": "The sitemap lists URLs but carries no lastmod dates",
    "why_false": "Every entry has a lastmod. The detail line is true (all 35 share one build-stamp date) but the explanation and fix shown were the no-lastmod text. Fixed after grading (2026-11-04)."
   }
  ],
  "unverifiable": [
   {
    "claim": "This domain is on the browser HSTS preload list but the header no longer qualifies (locked title)",
    "note": "Only evidence shown is 'hstspreload.org: preloaded' in the Server and hosting row. Same claim on both hosts. Not counted as false"
   }
  ],
  "advisories": [
   "The sitemap does not say when anything changed (all 35 lastmod = 2026-11-02; a single-date stamp)",
   "A business record gives an address but no coordinates (locked title; true)",
   "entitymap.json absent (404) ✗",
   "Vary not set ✗",
   "No CSP / X-Frame-Options / nosniff ✗, Permissions-Policy Warning",
   "HTTP to HTTPS redirect: 'stays on HTTP: http://lab2-clean.crawlcheck.io (200)' (true: log shows its http request answered 200)",
   "No GBP link, geo, opening hours ✗",
   "llms.txt not named in robots.txt; llms.txt names neither sitemap nor entity graph ✗",
   "No Person node, no founder/employee, no foundingDate ✗",
   "Fewer than 3 entity nodes; fewer than 2 sameAs ✗",
   "Domain age 83 days ✗",
   "No og:image or entity image ✗",
   "No prices on homepage ✗",
   "404 page has no way back ✗",
   "Lead paragraph lacks defining verb; 40% first-person paragraphs ✗",
   "Agent surfaces absent (agents.md, SKILL.md, markdown negotiation, MCP card, ARD...) reported, not scored",
   "Star rating / review count on homepage suggested from its own model tests",
   {
    "claim": "This domain is on the browser HSTS preload list but the header no longer qualifies",
    "why_advisory": "True: hstspreload.org reports lab2-clean.crawlcheck.io preloaded through the parent crawlcheck.io entry (bulk, includeSubDomains); the clean twin's header lacks the preload directive. Optional for a subdomain covered by its parent."
   }
  ]
 },
 "other_false_claims_lab2": [
  {
   "claim": "Business phone on the page | none found; no local business is declared, so none is expected",
   "where": "cc_r_wyka6piddc.html 'Trust and reputation'",
   "truth": "phone printed on the homepage, which the same report quotes: 'Call (555) 014-2290'"
  },
  {
   "claim": "/old-gutter-page 2 hops: ... → https://lab2.crawlcheck.io/services/ (200)",
   "where": "cc_depth_i61juq337r.html 'Redirects'",
   "truth": "/services/ answers 301 → /services/seamless-gutters; CrawlCheck never requested /services/ (log). The 200 belongs to /services. Tied to L2"
  },
  {
   "claim": "No identity is sent to a different URL | none | ✓ Passed",
   "where": "cc_r_wyka6piddc.html 'What each agent receives'",
   "truth": "ClaudeBot gets 302 → /unavailable; the same table says 'sent to /unavailable'. Tied to S4"
  },
  {
   "claim": "Content served only to crawlers | none ... ✓ Passed",
   "where": "cc_r_wyka6piddc.html 'Site safety'",
   "truth": "Googlebot gets an extra hidden keyword block. The row is scoped to scripts, links and redirects. Tied to S6"
  },
  {
   "claim": "Internal linking 100 — 'Anchors carry words, targets resolve'",
   "where": "cc_r_wyka6piddc.html section card",
   "truth": "homepage links to /services/roof-repair (404). Tied to L1"
  },
  {
   "claim": "security.txt | absent (200)",
   "where": "cc_r_wyka6piddc.html 'Machine layer'",
   "truth": "file is served (200, text/html) with an Expires line. Tied to M3-M5"
  },
  {
   "claim": "Entity nodes 0 — 'with no schema the site has no declared identity at all'; 'this site declares no local business'",
   "where": "cc_r_wyka6piddc.html 'Schema and entity graph', 'What AI looks for'",
   "truth": "a LocalBusiness block exists but fails to parse. The RDF section states that correctly. Consequence of D1"
  },
  {
   "claim": "Sitemaps named in robots.txt resolve | none named",
   "where": "cc_r_wyka6piddc.html 'Sitemap coverage'",
   "truth": "robots.txt has 'Sitemap: /sitemap.xml' (relative). The trust-chain section of the same report counts '1 Sitemap: line(s)'. Tied to R6"
  }
 ],
 "locked_for_free_user": [
  "Detail, fix and evidence for 4 of 5 findings on lab2 (titles only): 'robots.txt keeps Google's image crawler off the site's images'; 'This domain is on the browser HSTS preload list but the header no longer qualifies'; 'An answer engine's crawler was refused while a browser was served (unconfirmed from this vantage)'; 'HTTPS is served without a Strict-Transport-Security header'",
  "Clean twin: 2 of 3 findings locked (HSTS preload; address without coordinates)",
  "35 headroom rows on lab2 (26 on clean): points per fix; json score_ledger.rows_withheld 35",
  "11 locked sections: The record, Change receipts, Which pages (names the pages behind the whole-site counts), The 300-page walk, Citation watch, Arrivals and leads, Search Console series, Business Profile series, Directories and who links, YouTube, Identity Guard",
  "Homepage report withholds 'Which declared pages nothing links to', yet the free depth crawl names the orphan (/areas/lakeside)",
  "'1 more finding has a second-network reading; a licence for this domain shows which.'",
  "No verdict here depended on locked content: R3 and T1 are also caught from free rows. The 'answer engine refused' title repeats the free S1/S2 rows"
 ],
 "evidence_quality": {
  "score": 2,
  "why": "Free output names agents, URLs and observed values: per-identity status, words, bytes and sha256; machine-file transcript with status, content-type and bytes; redirect hops; JS raw-vs-rendered counts; top finding with rule link and fetch manifest. Not 3: most finding evidence is locked, robots verdicts carry no line numbers, and several rows contradict the report's own tables (ClaudeBot redirect, Googlebot split, internal links resolve, sitemap named). One redirect status (/services/ 200) was never observed."
 },
 "notes": "Strict grading with no benefit of the doubt. Depth crawl (a separate free page) supplies most indexing, sitemap and link catches. The homepage report alone would catch about 15. Unsure verdicts: I7 wrong vs missed; S6 partial vs wrong; S3, I6, M5, L1, X6, J1, J4 and L2 are partial and could each be argued a level up or down. Times: scans 2026-11-02 ~10:13-10:14 PM MST (05:13-05:14Z Nov 3). HSTS preload finding checked 2026-11-04 on hstspreload.org: lab2.crawlcheck.io is preloaded via the crawlcheck.io entry, so the lab2 finding is true (no HSTS header) and the clean-twin one is an advisory."
}