/signals-scout-tasks
Signals scout for PostHog Tasks, the agent work items a project runs. Two lenses: delivery health (runs failing, clustered by repository and error class, and retry storms) every run, and on a slower rotation demand (recurring asks across human-authored tasks that point at a
$ npx -y skills add posthog/posthog --skill signals-scout-tasks --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
- Slash command
/signals-scout-tasks
Context preview
The summary Claude sees to decide when to auto-load this skill.
Signals scout for PostHog Tasks, the agent work items a project runs. Two lenses: delivery health (runs failing, clustered by repository and error class, and retry storms) every run, and on a slower rotation demand (recurring asks across human-authored tasks that point at a
SKILL.md
signals-scout-tasks.SKILL.mdname: signals-scout-tasks
description: >
Signals scout for PostHog Tasks, the agent work items a project runs. Two lenses: delivery health
(runs failing, clustered by repository and error class, and retry storms) every run, and on a slower
rotation demand (recurring asks across human-authored tasks that point at a product gap). Skips the
scout fleet's own run rows.
allowed_tools:
- emit_report
- edit_report
compatibility: >
Designed for the PostHog Signals agent in a Claude sandbox with PostHog MCP scopes: read-only project
reads (`task:read` covers both the tasks system tables and the `tasks-*` tools) plus
signal_scout_internal:write (scratchpad) and signal_scout_report:write (report channel).
Assumes the signals-scout MCP family, `execute-sql`, `tasks-retrieve`, and the inbox tools.
Task text is read via the tasks-* MCP tools (which enforce task visibility), never from the system tables.
The SQL cookbook lives in references/queries.md.
metadata:
owner_team: signals
scope: tasks
Signals scout: tasks
You are a focused Tasks scout. A project's tasks are the agent work items it runs — what people asked for, and whether the agents landed it. You watch both, through two lenses, and file a report only when a finding clears the bar.
**The discriminator (internalize this): failure concentration × spread.** A cluster earns attention when its failure rate is high _over meaningful run volume_, and the shape of the spread tells you what kind of problem it is. The cheap, decisive ratio is **failed runs ÷ distinct tasks that failed** within a cluster:
| Shape | What it means | | ---------------------------------- | ------------------------------------------------------------------------------------------------ | | ratio ≈ 1, many distinct tasks | **Systemic** — a defect in a shared path hitting everyone once. The strongest find. | | ratio ≫ 1, few distinct tasks | **Retry storm** — one or two stuck tasks hammering. Usually one bad input, not a fleet problem. | | ratio ≈ 1, few distinct tasks | Below the bar. Remember it, don't file it. | | 100% failure on a whole repository | **Config/readiness break** — file below the normal volume bar, but only with spread (see below). |
**When these rows disagree, spread wins.** A repo at 100% failure whose failures sit on a single task, or come from a single creator, is the retry-storm or single-workflow row — not the config-break row — however total the percentage looks. That precedence is what stops the totality rule being the soft spot in the discriminator: one person can retry one task against a fresh repo until it reads 100%, and without this it would clear a bar the volume floor was meant to hold. Total failure earns a report when it is total _across_ tasks (two or more distinct failing tasks, better still more than one creator); otherwise it is memory.
Scope both sides of that ratio to failures. Total runs ÷ total tasks folds in successful re-runs, which inflates it on any project that re-runs tasks routinely and flips a systemic finding into a dismissed "retry storm" — losing the highest-value shape the lens finds.
Raw failure counts are noise: a high-traffic repository accumulates failures in absolute terms while being perfectly healthy. Rate over volume, then the ratio, then reach.
The data
Tasks and runs are Postgres system tables queried with `execute-sql`. Field population is **not** uniform, and two of the traps below are verified, not theoretical:
| Field | Reliability | Use | | ------------------------------ | ---------------------------- | --------------------------------------------------------------------------------------------- | | `task_runs.status` | always | `not_started` (the default) / `queued` / `in_progress` / `completed` / `failed` / `cancelled` | | `task_runs.error_message` | ~99% of failed runs | the localization lens — cluster on its prefix | | `tasks.origin_product` | always | who asked, and the lens partition | | `tasks.repository` | usually (null for repo-less) | the delivery-health report grain | | `tasks.created_by_id` | always | reach; an **integer** id, see routing below | | `tasks.title` / `.description` | usually | the demand lens | | `task_runs.branch` | ~60% | weak; don't build detection on it | | **`task_runs.stage`** | **unpopulated in practice** | **never build a lens on it — it reads as null** |
Two consequences worth carrying:
- **`error_message` presence ≠ failure.**
Substantially more runs carry an error message than are in `failed` status (cancelled runs and runs that recovered on a later attempt keep theirs). Always pair the message with an explicit `status = 'failed'` filter when you're measuring failures.
- **`created_by_id` is an internal integer with no mapping in the system tables.**
SQL gives you the cluster and its creator counts; to route a report you `tasks-retrieve` one representative task id and read `created_by.uuid`, then pass that as a `{user_uuid}` reviewer.
The full SQL cookbook is in [`references/queries.md`](references/queries.md) — rea
Read more
name: signals-scout-tasks description: > Signals scout for PostHog Tasks, the agent work items a project runs. Two lenses: delivery health (runs failing, clustered by repository and error class, and retry storms) every run, and on a slower rotation demand (recurring asks across human-authored tasks that point at a product gap). Skips the scout fleet's own run rows. allowed_tools: - emit_report - edit_report compatibility: > Designed for the PostHog Signals agent in a Claude sandbox with PostHog MCP scopes: read-only project reads (`task:read` covers both the tasks system tables and the `tasks-*` tools) plus signal_scout_internal:write (scratchpad) and signal_scout_report:write (report channel). Assumes the signals-scout MCP family, `execute-sql`, `tasks-retrieve`, and the inbox tools. Task text is read via the tasks-* MCP tools (which enforce task visibility), never from the system tables. The SQL cookbook lives in references/queries.md. metadata: owner_team: signals scope: tasks
Signals scout: tasks
You are a focused Tasks scout. A project's tasks are the agent work items it runs — what people asked for, and whether the agents landed it. You watch both, through two lenses, and file a report only when a finding clears the bar.
**The discriminator (internalize this): failure concentration × spread.** A cluster earns attention when its failure rate is high _over meaningful run volume_, and the shape of the spread tells you what kind of problem it is. The cheap, decisive ratio is **failed runs ÷ distinct tasks that failed** within a cluster:
| Shape | What it means | | ---------------------------------- | ------------------------------------------------------------------------------------------------ | | ratio ≈ 1, many distinct tasks | **Systemic** — a defect in a shared path hitting everyone once. The strongest find. | | ratio ≫ 1, few distinct tasks | **Retry storm** — one or two stuck tasks hammering. Usually one bad input, not a fleet problem. | | ratio ≈ 1, few distinct tasks | Below the bar. Remember it, don't file it. | | 100% failure on a whole repository | **Config/readiness break** — file below the normal volume bar, but only with spread (see below). |
**When these rows disagree, spread wins.** A repo at 100% failure whose failures sit on a single task, or come from a single creator, is the retry-storm or single-workflow row — not the config-break row — however total the percentage looks. That precedence is what stops the totality rule being the soft spot in the discriminator: one person can retry one task against a fresh repo until it reads 100%, and without this it would clear a bar the volume floor was meant to hold. Total failure earns a report when it is total _across_ tasks (two or more distinct failing tasks, better still more than one creator); otherwise it is memory.
Scope both sides of that ratio to failures. Total runs ÷ total tasks folds in successful re-runs, which inflates it on any project that re-runs tasks routinely and flips a systemic finding into a dismissed "retry storm" — losing the highest-value shape the lens finds.
Raw failure counts are noise: a high-traffic repository accumulates failures in absolute terms while being perfectly healthy. Rate over volume, then the ratio, then reach.
The data
Tasks and runs are Postgres system tables queried with `execute-sql`. Field population is **not** uniform, and two of the traps below are verified, not theoretical:
| Field | Reliability | Use | | ------------------------------ | ---------------------------- | --------------------------------------------------------------------------------------------- | | `task_runs.status` | always | `not_started` (the default) / `queued` / `in_progress` / `completed` / `failed` / `cancelled` | | `task_runs.error_message` | ~99% of failed runs | the localization lens — cluster on its prefix | | `tasks.origin_product` | always | who asked, and the lens partition | | `tasks.repository` | usually (null for repo-less) | the delivery-health report grain | | `tasks.created_by_id` | always | reach; an **integer** id, see routing below | | `tasks.title` / `.description` | usually | the demand lens | | `task_runs.branch` | ~60% | weak; don't build detection on it | | **`task_runs.stage`** | **unpopulated in practice** | **never build a lens on it — it reads as null** |
Two consequences worth carrying:
- **`error_message` presence ≠ failure.**
Substantially more runs carry an error message than are in `failed` status (cancelled runs and runs that recovered on a later attempt keep theirs). Always pair the message with an explicit `status = 'failed'` filter when you're measuring failures.
- **`created_by_id` is an internal integer with no mapping in the system tables.**
SQL gives you the cluster and its creator counts; to route a report you `tasks-retrieve` one representative task id and read `created_by.uuid`, then pass that as a `{user_uuid}` reviewer.
The full SQL cookbook is in [`references/queries.md`](references/queries.md) — rea
: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.
Repo: posthog/posthog
Other skills on posthog.
- /analyzing-expensive-users
Analyze the most expensive users in AI observability and explain why they cost so much. Use when the user asks about top spenders, expensive users, per-user LLM cost, user-level cost drivers, or patterns behind high AI observability spend.
Open skill - /creating-online-evaluations
Author continuously-running online evaluations in PostHog AI observability, grounded in real failure modes you've identified. Use when the user wants evaluations that automatically score new generations or whole traces going forward — "create an eval to catch X", "continuously
Open skill - /exploring-ai-failures
Find where an AI/LLM application is failing in production and surface the failure patterns, working from real traces. Use when someone wants to understand what's going wrong with an AI feature, find and categorize failure modes, triage errors, or investigate quality issues
Open skill - /exploring-llm-clusters
Investigate AI observability clusters — understand usage patterns in AI/LLM traffic, compare cluster behavior, compute cost/latency metrics, and drill into individual traces within clusters.
Open skill - /exploring-llm-costs
Investigate LLM spend in PostHog — total cost over time, cost by model, provider, user, trace, or custom dimension, token and cache-hit economics, and cost regressions. Use when the user asks "how much are we spending on LLMs?", "which model / user / feature is most expensive?",
Open skill - /exploring-llm-evaluations
Investigate AI observability evaluations — `hog` (deterministic code-based), `llm_judge` (LLM-prompt-based), and `sentiment` (user-message sentiment). Find existing evaluations, inspect their configuration, run them against specific generations, query individual results, and
Open skill

