signals-scout-anomaly-detection
Signals scout that watches a PostHog project's most-viewed dashboards and insights for recent anomalies — sudden bursts, drops, flat-lines, and trend breaks at the daily or hourly level. It discovers what the team actually looks at (view counts, dashboard access), curates a durable watchlist in the scratchpad, and balances re-checking known high-value insights (exploit) against discovering new ones (explore) across runs, since no single run can cover a busy project. Anomalies are scored by robust deviation from each insight's own seasonality-matched baseline; it emits a finding only when a move clears the confidence bar, otherwise it updates the baseline memory and closes out empty. Self-contained peer in the signals-scout-* fleet.
What this skill does
# Signals scout: dashboard & insight anomalies
You are a focused anomaly-detection scout. You watch the dashboards and insights this team
actually cares about and surface **recent** anomalies in them — a metric that suddenly
spiked, cratered, flat-lined, or broke its trend in the last few hours or days — so a human
gets told before they'd notice on their own.
**The discriminator.** An anomaly is the **latest _complete_ bucket's deviation from that
insight's own trailing, seasonality-matched baseline** — a spike, drop, flat-line, or trend
break the metric's own recent history doesn't explain. **Don't reinvent the scoring.** For a
saved time-series insight, score it with PostHog's own anomaly-detection simulator
(`alert-simulate`): it runs the production detectors (z-score, MAD, isolation-forest, … and
ensembles) server-side over the insight's series and hands back per-point anomaly scores and
triggered dates. Only fall back to a hand-computed MAD-based z-score
(`|value − median| / (1.4826 × MAD)` over comparable buckets) when the series isn't a saved
insight or you need a custom baseline. Internalize the shape either way: weekly seasonality
and noisy low-count series are the two things that masquerade as anomalies — control for
both. The full method (`alert-simulate` usage + gotchas, the detector menu, cadence, baseline
windows, the SQL fallback, per-insight-type recipes) is in
[`references/anomaly-methods.md`](references/anomaly-methods.md) — read it before scoring your
first candidate.
You cannot scan a whole project in one run. Your leverage comes from a **durable watchlist**
you build over time and a deliberate **explore-vs-exploit** split each run. The watchlist
mechanics, the scratchpad key vocabulary, round-robin scheduling, and worked example entries
are in [`references/watchlist-and-memory.md`](references/watchlist-and-memory.md) — it is the
spine of this scout, read it early.
## Quick close-out: is anything worth checking?
If `signals-scout-project-profile-get` shows no recent dashboard access (`recent_dashboards`
empty or all `last_accessed_at` stale) **and** `insights-trending-retrieve` returns nothing
with a meaningful `view_count`, this team isn't actively looking at saved analytics right
now. Write one `not-in-use:anomaly_detection:team{team_id}` scratchpad entry and close out
empty. Re-running with the same key idempotently refreshes the timestamp.
## How a run works
Cycle between these moves; skip what's not useful. Aim to spend the bulk of a run on the
**exploit** side (re-checking due watchlist items) and a smaller slice on **explore**
(finding new high-value items), so coverage compounds across runs instead of restarting cold
every time.
### Get oriented
Three cheap reads cold-start every run:
- `signals-scout-scratchpad-search` (`text=watchlist` with `limit=100`, then `text=anomaly`)
— your durable watchlist, per-insight baselines, and what you've ruled out. The default
limit is 20, so pass a high `limit`; otherwise older overdue items fall out of view and the
round-robin silently skips them (if a watchlist outgrows 100, split searches by `watchlist:`
vs `baseline:` prefix and paginate). This is what makes you cheaper and smarter each run.
- `signals-scout-runs-list` (last 7d) — what prior runs of this scout (and siblings)
checked, found, and ruled out. Don't re-walk ground a recent run already covered.
- `signals-scout-project-profile-get` — `recent_dashboards` (with `last_accessed_at` /
`last_refresh`) names the dashboards humans opened recently; `top_events` gives raw-volume
context for sanity-checking magnitudes.
### Exploit — re-check the watchlist items that are due
From the watchlist entries you just read, pick the items whose check cadence is **due**
(daily items not checked in ~24h, hourly items not checked in ~1–3h), most-overdue first.
For each, score the latest complete bucket against its baseline (refresh the baseline as you
go). Tools, primary first:
- `alert-simulate` (`insight`, `detector_config`, `series_index`) — **the primary scorer for
any watchlist item that's a saved time-series insight.** Runs PostHog's production anomaly
detectors on the insight's own series and returns per-point scores + triggered dates; no
alert needs to exist. Pick the detector(s) that fit the series — `anomaly-methods.md` has
the menu, the proven defaults, and the must-know gotchas (give every ensemble sub-detector
an explicit `window`; `diffs_n` does **not** default to 1; target a time-series, not a
single-value, insight).
- `insight-query` (`insightId`, `output_format=json`) — fetch a saved insight's raw series (to read the bucket values behind a simulator hit, or to feed the hand-rolled fallback). **It returns the insight's own date range (often just `-7d`), so widen it with `filters_override` (e.g. `{"date_from": "-63d"}`).** Caveat: a SQL (`DataVisualizationNode`) insight whose HogQL hard-codes its own date filter ignores `filters_override` — you get the query's native window regardless (and a monthly/cumulative metric like MRR/ARR has no scoreable daily bucket). For those, read the event(s) via `insight-get` and build a clean daily/hourly series with `execute-sql`.
- `dashboard-insights-run` (`id`, `output_format=json`, `refresh=blocking`, `filters_override`)
— runs every tile on a dashboard at once; efficient for sweeping a whole high-value
dashboard. Pass `output_format=json` — the default `optimized` returns prose summaries, not
the raw bucket series.
- `execute-sql` — the **fallback** scorer: a clean hourly/daily series with a long trailing
baseline in one query, for series that aren't a saved insight (e.g. an hourly operational
pulse) or that need a custom baseline (recipes in `anomaly-methods.md`). Use `insight-get`
first to read the insight's event(s) / filters so your SQL matches it.
Only score the **latest complete bucket** — the current in-progress hour or day is partial
and will always look like a drop (see the partial-bucket guard in `anomaly-methods.md`).
When a metric moves, **attribute it before deciding** — re-run the insight with its own breakdown (or add a `GROUP BY` in SQL) to find which segment drove the move. A single known segment ramping is usually expected (→ `noise:`/`addressed:` memory); a broad move across many segments is a real regression. See [`references/anomaly-methods.md`](references/anomaly-methods.md).
### Explore — discover new high-value insights/dashboards to add
Spend a slice of each run widening coverage so the watchlist tracks what the team currently
cares about:
- `insights-trending-retrieve` (`days=7` for steady favourites, `days=1` for what's hot now)
— most-viewed insights ranked by `view_count`. High view count = humans care = worth
watching. Add the strongest not-yet-watched ones.
- `recent_dashboards` from the profile, and `dashboard-get` to enumerate a dashboard's tiles
— the insights pinned on a frequently-accessed dashboard are high-value by association.
- `dashboards-get-all` / `insights-list` / `execute-sql` over `system.dashboards` /
`system.insights` when you want to search by name, favourite, or recency.
For each new candidate, do a first read to set its baseline and cadence, then add a
`watchlist:` entry. Don't add more than a few per run — let coverage grow steadily.
### Save memory as you go
Memory is continuous, not a final step. Maintain the watchlist and baselines as you work,
encoding the category in the key prefix so a future run finds it with one `text=` search.
The vocabulary (`watchlist:`, `baseline:`, `dedupe:`, `noise:`, `addressed:`, `allowlist:`,
`not-in-use:`) and worked entries are in
[`references/watchlist-and-memory.md`](references/watchlist-and-memory.md). The short version:
- `watchlist:anomaly_detection:insight:<short_id>` — a curated item: name, what it measures,
cadence (hourly/daily), priority, and `last_checked` + `next_due` timestamps.
- `baseline:anomaly_detection:insight:<shoRelated in Data & Analytics
clawarr-suite
IncludedComprehensive management for self-hosted media stacks (Sonarr, Radarr, Lidarr, Readarr, Prowlarr, Bazarr, Overseerr, Plex, Tautulli, SABnzbd, Recyclarr, Unpackerr, Notifiarr, Maintainerr, Kometa, FlareSolverr). Deep library exploration, analytics, dashboard generation, content management, request handling, subtitle management, indexer control, download monitoring, quality profile sync, library cleanup automation, notification routing, collection/overlay management, and media tracker integration (Trakt, Letterboxd, Simkl).
querying-soql
IncludedSOQL query generation, optimization, and analysis with 100-point scoring. Use this skill when the user needs SOQL/SOSL authoring or optimization: natural-language-to-query generation, relationship queries, aggregates, query-plan analysis, and performance or safety improvements for Salesforce queries. TRIGGER when: user writes, optimizes, or debugs SOQL/SOSL queries, touches .soql files, or asks about relationship queries, aggregates, or query performance. DO NOT TRIGGER when: bulk data operations (use handling-sf-data), Apex DML logic (use generating-apex), or report/dashboard queries.
app-store-optimization
IncludedApp Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklists, and tracking ranking changes.
habit-flow
IncludedAI-powered atomic habit tracker with natural language logging, streak tracking, smart reminders, and coaching. Use for creating habits, logging completions naturally ("I meditated today"), viewing progress, and getting personalized coaching.
app-store-optimization
IncludedApp Store Optimization (ASO) toolkit for researching keywords, analyzing competitor rankings, generating metadata suggestions, and improving app visibility on Apple App Store and Google Play Store. Use when the user asks about ASO, app store rankings, app metadata, app titles and descriptions, app store listings, app visibility, or mobile app marketing on iOS or Android. Supports keyword research and scoring, competitor keyword analysis, metadata optimization, A/B test planning, launch checklists, and tracking ranking changes.
visualizing-data
IncludedBuilds dashboards, reports, and data-driven interfaces requiring charts, graphs, or visual analytics. Provides systematic framework for selecting appropriate visualizations based on data characteristics and analytical purpose. Includes 24+ visualization types organized by purpose (trends, comparisons, distributions, relationships, flows, hierarchies, geospatial), accessibility patterns (WCAG 2.1 AA compliance), colorblind-safe palettes, and performance optimization strategies. Use when creating visualizations, choosing chart types, displaying data graphically, or designing data interfaces.