Rebuild weekly search report on the durable analytics API (fail-loud)#120
Merged
Conversation
Add getToolBreakdown reader (full tool_name, mirrors getToolCounts) + GET /api/analytics/tool-breakdown route, and unique_ip_count_window / unique_session_count_window to the analytics summary. Query_log-backed, additive. Includes reader + HTTP route tests.
Deterministic (no-LLM) report that reads the durable analytics API and publishes to Notion. Fails loud (non-zero exit + Slack, never a degraded page) on missing token / fetch failure / malformed payload. Renders native Notion tables, derives window/title labels from the actual queried window, and sanitizes all cell/observation text.
Sunday cron GHA workflow reusing PATHFINDER_ANALYTICS_TOKEN / NOTION_TOKEN / SLACK_WEBHOOK_OSS_ALERTS. Extend tsconfig.scripts.json + static-quality prettier glob to typecheck/format-check scripts/weekly-search-report.
3 tasks
jpr5
added a commit
that referenced
this pull request
Jun 22, 2026
## Summary Follow-up to #120. The weekly search report previously only emitted to Slack on **failure** (`#oss-alerts`). A *successful* report is valuable signal, so on a successful Notion publish it now posts a digest to **#engr**: `📊 Pathfinder weekly search report — 2551 tool calls · 198 unique IPs · top: Agents/CoAgents/AG-UI · 3.3% empty · [report]` (where **[report]** is a Slack mrkdwn link to the Notion page). - New `SLACK_ENGR_WEBHOOK` env (workflow secret `SLACK_WEBHOOK_ENGR`, a B0T `#engr` incoming webhook — same convention as `SLACK_WEBHOOK_OSS_ALERTS`/`SLACK_WEBHOOK_TEAM_SHOWCASE`). - **Failures unchanged** — still fail-loud to `#oss-alerts` via `SLACK_WEBHOOK`. - Best-effort success ping: **no-ops when the webhook is unset** (so this is safe to merge before the secret exists) and never affects the run's exit code. ## Test plan - [x] Red-green: success run posts the digest (incl. `<url|report>`) to the success poster and NOT the failure poster; fetch/token failure posts to the failure poster and NOT the success poster; unset success webhook no-ops. (52 report tests; full suite 6522 green) - [x] `tsc` (root + scripts), `npm run build`, `prettier --check`, `actionlint` clean - [ ] After merge: create the B0T `#engr` incoming webhook → set org secret `SLACK_WEBHOOK_ENGR`; next Sunday run (or a `workflow_dispatch`) posts to `#engr` 7-agent CR converged on round 1 (zero in-subject findings); pre-existing report-rendering follow-ups (table backslash-escape, categorization `useCoAgent` keyword, parseReportDays cap, etc.) tracked from #120, not in scope here. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Rebuilds the weekly "Pathfinder Search Query Report" — which failed on 2026-06-21 because the claude.ai routine running it assumed a
RAILWAY_API_TOKENthat claude.ai routine runtimes never receive, scraped ephemeral Railway stdout logs, and silently posted a Notion "error page" when its token was missing.scripts/weekly-search-report/) that reads the query_log-backed analytics JSON API (the same source asmonthly-gap-analysis) instead of ephemeral Railway stdout. New analytics surface:GET /api/analytics/tool-breakdown(fulltool_name, mirrorsgetToolCounts) +unique_ip_count_window/unique_session_count_windowsummary fields — all additive.[weekly-report] FAILED, post a Slack alert, and exit non-zero — and never publish a degraded/partial page (multi-batch publish archives a partial page on append failure).weekly-search-report.ymlGHA workflow (Sunday cron) reusingPATHFINDER_ANALYTICS_TOKEN/NOTION_TOKEN/SLACK_WEBHOOK_OSS_ALERTS— already repo secrets inmonthly-gap-analysis.yml. The new script dir is gated undertsconfig.scripts.jsontypecheck + the static-quality prettier check.Report renders native Notion tables (per-day, tool breakdown, keyword-categorized top queries, top-20, empty-result queries, explore/bash breakdown), and derives the window banner + page title from the actual queried window so labels never contradict the data.
Design spec: https://app.notion.com/p/3873aa38185281f883bef4dda4d51002
Test plan
tsc --noEmit(root +tsconfig.scripts.json),npm run build,prettier --check,actionlintall cleanworkflow_dispatchthe new workflow and verify a correct Notion page, then disable the claude.ai routinetrig_01AGpAF4r3z6Utn4hSyBoPhLFollow-ups (out of scope, logged from CR)
prettieras a devDependency (pre-existing unpinnednpx prettierCI pattern)getBlockedQueries/getAtlasRetrievalMetricscoercion + window alignment + request-source)/mcpdon't refreshsessionLastActivity)parseReportDaysupper clamp🤖 Generated with Claude Code