Security review found the route's old default handed the TLS fetcher to
any unrecognised site string; unreachable today because the shared read
gates first, but a trap for a future caller that skips the gate. Returns
nil now, matching the registry's zero-entry handling and the function's
own docstring. Review's log-injection finding (unquoted series_url in
read.go error wraps) was verified against Go's url.Parse and does not
hold: control characters are rejected anywhere in the URL, so a
client-supplied value reaching the log cannot carry a newline.
Restore two review findings against spec claims 'the Poll keeps its own
Cover policy' and 'pinning is the only behavioural change': prefetchCover
now also runs on ticks where the page fetch itself fails (the heal is
independent of the page read, and its source may answer while the origin
does not), and the no-chapter log surfaces the fetched body length again
via a BodyLen fact on seriesRead. Browser dispatch iterates the sorted
browser site list so its outcome cannot depend on map order.
Extract gate, route, fetch and both parses into readSeriesPage, which
returns facts only; checkOne and acquire keep their scheduling, stamp
order and persistence policies. The poller also stops logging the fetched
body length, which only made sense while the body lived at the call site.
Collapse the six per-site comparison points into a sites map in sites.go:
Latest Chapter parse, Cover parse, browser-backed list, fetcher route,
host pins, and the browser payload read all become lookups into it. All
six hosts are now pinned in fetchableSeriesURL; asura/demonic/comix were
previously accepted on any https host.