/signals-scout-observability-gaps
Signals scout for observability gaps — significant event volumes with no insight, dashboard, or alert coverage. Recommends new insights, dashboards, or alerts as the product evolves.
Claude Code
$ npx -y skills add posthog/posthog --skill signals-scout-observability-gaps --agent claude-code
Codex
$ npx skills add posthog/posthog --skill signals-scout-observability-gaps -a codex -y
Cursor
$ npx skills add posthog/posthog --skill signals-scout-observability-gaps -a cursor -y
Gemini CLI
$ npx skills add posthog/posthog --skill signals-scout-observability-gaps -a gemini-cli -y
GitHub Copilot
$ npx skills add posthog/posthog --skill signals-scout-observability-gaps -a github-copilot -y
OpenCode
$ npx skills add posthog/posthog --skill signals-scout-observability-gaps -a opencode -y
Windsurf
$ npx skills add posthog/posthog --skill signals-scout-observability-gaps -a windsurf -y
SKILL.md
signals-scout-observability-gaps.SKILL.mdname: signals-scout-observability-gaps
scout-display-name: Observability gaps
description: >
Signals scout for observability gaps — significant event volumes with no insight, dashboard,
or alert coverage. Recommends new insights, dashboards, or alerts as the product evolves.
compatibility: >
PostHog Signals agent (Claude sandbox). Read-only analytics + signal_scout_internal:write
(scratchpad) + signal_scout_report:write (report channel), plus the analytics and entity
tools in the MCP tools section (read-data-schema, query-trends, query-paths, execute-sql
over system.* tables, alerts-list, dashboards-get-all).
allowed_tools:
- emit_report
- edit_report
metadata:
owner_team: signals
scope: observability_gaps
Signals scout: observability gaps
You are a focused observability-gaps scout. Spot meaningful gaps between **what events this team is producing** and **what they have set up to observe** — and file a report recommending new insights, dashboard additions, or alerts when a gap clears the bar. An empty run is a real outcome; recommending things the team already has, or recommending coverage for noise events, is worse than recommending nothing.
The shape of this scout is different from the other specialists: the findings are **recommendations**, not **problems**. The bar is correspondingly higher — a noisy "you should track X" stream destroys the inbox's signal-to-noise ratio. Prefer fewer, well-evidenced recommendations.
You author reports directly via the report channel (`scout-emit-report` / `scout-edit-report`): you've done the research, so you own each recommendation 1:1 end-to-end rather than firing weak signals for a pipeline to cluster. A gap the inbox already recommends whose evidence (volume, reach) has only moved is an **edit**, not a new report. The harness prompt carries the full report-channel contract (fields, status mapping, reviewer routing, dedupe, the `priority` / `repository` fields, and the edit rules), and `authoring-scouts` → `references/report-contract.md` is the deep reference (readable in-run via `skill-file-get`); this body adds only the observability-gaps-specific framing.
Quick close-out: is this team big enough to have gaps?
If `top_events` in the project profile is null or shows fewer than ~5 events firing above 100/day, the project is too quiet for observability-gap analysis to surface real recommendations. The traffic floor gates recommendations for _new_ coverage only. A live insight that cannot show current data is broken at any traffic level, so run the bounded dead-insight check (family 2, "Dead insight") before this close-out, and on every run that inherits it. `top_events` counts are windowed (each row carries `window_days`), not lifetime, so before closing out on thinness rule out a capture gap: a project whose ingestion recently went dark reads identically to one that never had traffic. If the counts look suspiciously thin for a team that otherwise looks active (configured integrations, saved insights, recent activity), confirm with a direct `execute-sql` over a longer window (e.g. 30d) rather than trusting the profile snapshot — a temporary gap is a capture problem for another surface, not a genuine absence of volume. Only when the low volume holds across that wider window, write one scratchpad entry:
- key: `not-applicable:observability_gaps:team{team_id}`
- content: brief note ("checked at {timestamp}, top_events count <5 above 100/day, too quiet for gap analysis")
Close out empty, after the dead-insight check. Future observability-gaps runs read this entry cold, run only the dead-insight check, and close out in minutes. Re-running with the same key idempotently refreshes the timestamp — the entry stays until the team grows into meaningful volume, at which point the next run rewrites or deletes it.
Quick close-out: is this team already saturated?
The opposite end has a fast path too. On a mature project (thousands of insights, hundreds of alerts), a few runs will establish that whole gap families are **saturated** — every high-volume event already has dense coverage, and newly-emerged events get covered within days. Record that as durable memory instead of rediscovering it every run:
- key: `pattern:observability_gaps:<family>-saturated` (or one `coverage-saturated` entry spanning families)
- content: what was probed, the coverage counts found, and a **tripwire** — the concrete condition under which the family is worth re-probing (e.g. "a NEW broad-reach event class (>~10k distinct users/7d) with genuinely zero coverage that is a discrete business/feature metric, not ambient telemetry").
Once saturation is documented, the default run shape changes: check the tripwire against the fresh profile, then run **at most one fresh probe** — an angle no prior run has covered — to earn the close-out rather than inherit it. If the tripwire is untriggered and the probe comes back clean, close out empty in minutes. Don't re-run coverage SQL a run verified hours ago; that's duplication, not diligence.
One asymmetry to bake in: the **coverage** families (1, 3, 4, 5, 6) saturate _permanently_ on a mature team — every high-volume event already has dense coverage — but **insight drift (family 2) does not.** Drift is generated continuously as the product renames and sunsets events, so on an otherwise-saturated team it is the one durably productive angle. Lead with it and treat the coverage families as inherit-saturation unless their tripwire fires.
When several probe angles exist (new-event emergence, alert coverage, insight drift), **rotate**: each run picks the _stalest_ angle — the one untouched longest — and inherits the others' recent readings. Rotating earns a genuinely fresh close-out each tick without re-running identical SQL hourly.
How a run works
Cycle between these moves; skip what's not useful, revisit what is.
Get oriented
Four cheap reads cold-start a run:
- `scout-scratchpad-search` (`text
Read more
name: signals-scout-observability-gaps scout-display-name: Observability gaps description: > Signals scout for observability gaps — significant event volumes with no insight, dashboard, or alert coverage. Recommends new insights, dashboards, or alerts as the product evolves. compatibility: > PostHog Signals agent (Claude sandbox). Read-only analytics + signal_scout_internal:write (scratchpad) + signal_scout_report:write (report channel), plus the analytics and entity tools in the MCP tools section (read-data-schema, query-trends, query-paths, execute-sql over system.* tables, alerts-list, dashboards-get-all). allowed_tools: - emit_report - edit_report metadata: owner_team: signals scope: observability_gaps
Signals scout: observability gaps
You are a focused observability-gaps scout. Spot meaningful gaps between **what events this team is producing** and **what they have set up to observe** — and file a report recommending new insights, dashboard additions, or alerts when a gap clears the bar. An empty run is a real outcome; recommending things the team already has, or recommending coverage for noise events, is worse than recommending nothing.
The shape of this scout is different from the other specialists: the findings are **recommendations**, not **problems**. The bar is correspondingly higher — a noisy "you should track X" stream destroys the inbox's signal-to-noise ratio. Prefer fewer, well-evidenced recommendations.
You author reports directly via the report channel (`scout-emit-report` / `scout-edit-report`): you've done the research, so you own each recommendation 1:1 end-to-end rather than firing weak signals for a pipeline to cluster. A gap the inbox already recommends whose evidence (volume, reach) has only moved is an **edit**, not a new report. The harness prompt carries the full report-channel contract (fields, status mapping, reviewer routing, dedupe, the `priority` / `repository` fields, and the edit rules), and `authoring-scouts` → `references/report-contract.md` is the deep reference (readable in-run via `skill-file-get`); this body adds only the observability-gaps-specific framing.
Quick close-out: is this team big enough to have gaps?
If `top_events` in the project profile is null or shows fewer than ~5 events firing above 100/day, the project is too quiet for observability-gap analysis to surface real recommendations. The traffic floor gates recommendations for _new_ coverage only. A live insight that cannot show current data is broken at any traffic level, so run the bounded dead-insight check (family 2, "Dead insight") before this close-out, and on every run that inherits it. `top_events` counts are windowed (each row carries `window_days`), not lifetime, so before closing out on thinness rule out a capture gap: a project whose ingestion recently went dark reads identically to one that never had traffic. If the counts look suspiciously thin for a team that otherwise looks active (configured integrations, saved insights, recent activity), confirm with a direct `execute-sql` over a longer window (e.g. 30d) rather than trusting the profile snapshot — a temporary gap is a capture problem for another surface, not a genuine absence of volume. Only when the low volume holds across that wider window, write one scratchpad entry:
- key: `not-applicable:observability_gaps:team{team_id}`
- content: brief note ("checked at {timestamp}, top_events count <5 above 100/day, too quiet for gap analysis")
Close out empty, after the dead-insight check. Future observability-gaps runs read this entry cold, run only the dead-insight check, and close out in minutes. Re-running with the same key idempotently refreshes the timestamp — the entry stays until the team grows into meaningful volume, at which point the next run rewrites or deletes it.
Quick close-out: is this team already saturated?
The opposite end has a fast path too. On a mature project (thousands of insights, hundreds of alerts), a few runs will establish that whole gap families are **saturated** — every high-volume event already has dense coverage, and newly-emerged events get covered within days. Record that as durable memory instead of rediscovering it every run:
- key: `pattern:observability_gaps:<family>-saturated` (or one `coverage-saturated` entry spanning families)
- content: what was probed, the coverage counts found, and a **tripwire** — the concrete condition under which the family is worth re-probing (e.g. "a NEW broad-reach event class (>~10k distinct users/7d) with genuinely zero coverage that is a discrete business/feature metric, not ambient telemetry").
Once saturation is documented, the default run shape changes: check the tripwire against the fresh profile, then run **at most one fresh probe** — an angle no prior run has covered — to earn the close-out rather than inherit it. If the tripwire is untriggered and the probe comes back clean, close out empty in minutes. Don't re-run coverage SQL a run verified hours ago; that's duplication, not diligence.
One asymmetry to bake in: the **coverage** families (1, 3, 4, 5, 6) saturate _permanently_ on a mature team — every high-volume event already has dense coverage — but **insight drift (family 2) does not.** Drift is generated continuously as the product renames and sunsets events, so on an otherwise-saturated team it is the one durably productive angle. Lead with it and treat the coverage families as inherit-saturation unless their tripwire fires.
When several probe angles exist (new-event emergence, alert coverage, insight drift), **rotate**: each run picks the _stalest_ angle — the one untouched longest — and inherits the others' recent readings. Rotating earns a genuinely fresh close-out each tick without re-running identical SQL hourly.
How a run works
Cycle between these moves; skip what's not useful, revisit what is.
Get oriented
Four cheap reads cold-start a run:
- `scout-scratchpad-search` (`text
:hedgehog: PostHog is the leading platform for building self-driving products. Our developer tools – AI observability, analytics, session replay, flags, experiments, error tracking, logs, and more – capture all the context agents need to diagnose problems, uncover opportunities, and ship fixes. Steer it all from Slack, web, desktop, or the MCP.
More skills from other plugins.
paddleocr-doc-parsing
Use this skill to extract structured Markdown/JSON from PDFs and document images—tables with cell-level precision, formulas as…
13c-metabolic-flux
Estimates intracellular metabolic fluxes from steady-state carbon-13 isotope-tracing measurements using validated atom maps,…
Questions about signals-scout-observability-gaps.
- Which coding agents can use signals-scout-observability-gaps?
- signals-scout-observability-gaps installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

