SIGN IN SIGN UP

perf(dashboard): serve conversation metrics from an hourly presence rollup (#1616)

The dashboard overview's conversation aggregates (bucket trend + activity
distinct/request counts) and the unfiltered reports summary/daily
conversation counts were the last rollup-uncovered reads on the 30s poll
path, scanning the full raw request_logs window per poll (7-13s observed in
production). Reverse the documented "distinct conversation counts stay
raw-bound" non-goal with a conversation presence satellite:

- New request_conversation_hourly_rollups keyed by (bucket_epoch,
  normalized conversation_id, account_id, is_deleted) with an additive
  request_count. is_deleted is a dimension because the dashboard readers
  exclude soft-deleted rows while the reports readers include them;
  account_id is carried only so the shared lifecycle mirror registry keeps
  soft delete, hard history delete, and duplicate consolidation exact.
- Dedicated conversation_folded_through watermark (same state row and
  FOR UPDATE lock) with run_conversation_fold_pass as a third scheduler
  leg, reusing the DELETE-then-INSERT slice contract and paced backfill.
- Reads merge the folded presence with its exact raw complement in ONE
  statement (the watermark joined into both UNION branches), so
  COUNT(DISTINCT) dedups conversations straddling the fold boundary and
  epoch/missing watermarks degrade to the exact legacy raw queries.
  Filtered reports reads and non-hour-multiple display buckets keep the
  legacy raw path.
- Retention prune gate now takes the min over all three fold watermarks,
  so conversation statistics survive request-log pruning (retention parity
  expectations reversed accordingly).

openspec: add-conversation-presence-rollup

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
S
Soju06 committed
80df35adebc07bd7e299cca73d64f44125329aa7
Parent: 54881d2
Committed by GitHub <noreply@github.com> on 8/6/2026, 6:42:13 AM