The crawl job's context ends on a cancel or at the job timeout. Storing
the pages, links and issues now runs on a context detached from it with
its own 10-minute bound, a timeout ends the crawl failed with a
time-limit error, a LoadLimits failure falls back to the defaults, and a
fetch cut short by the cancellation is recorded as canceled.
- github.com/chromedp/chromedp v0.21.0 (decision note
2026-10-28-chromedp-rendered-crawl.md): with golem15.seo.crawl_chrome_path
the crawl renders up to golem15.seo.crawl_render_max pages (200) and
compares them with the raw HTML; without a path it records skipped
- guard: site host and www twin resolved and checked with
fetchguard.IsPrivateAddr, pinned through --host-resolver-rules with a
final MAP * ~NOTFOUND; Fetch-domain interception fails every request
outside the site (third-party scripts never load); fresh temporary
profile removed on Close; downloads denied; one tab, 20 s, 5 MiB DOM
- a relative or non-executable path, a private address or a Chrome that
does not start records render_status failed; the crawl still finishes
- config keys documented; README Rendered comparison section
- TestChromeRenderer (runs with a local Chromium) and TestRendererGuards
- golem15_seo_crawls, crawl pages, links, issues and ignores (P33-37)
- classes/crawl: fetchguard client on the site host and its www twin,
sitemap index and robots.txt seeds, two workers with a delay, limits
- h1_missing and h1_multiple with the P33-38 fix route
- POST /_seo/api/v1/crawls queues the golem15.seo.crawl job; GET /issues
answers the stored issues with id, severity, source, fix, found_at,
ignored and crawl_id