Skip to content
Development
Skill

/signals-scout-conversations

Signals scout for PostHog Conversations (support inbox). Watches `$conversation_*` ticket- lifecycle events for SLA breach steps, first-response latency blowouts, backlog imbalance, and channel or assignment concentration.

From plugin
posthog
84164 skills1 agent3 commands2 hooks
+1
Install
$ npx -y skills add PostHog/ai-plugin --skill signals-scout-conversations --agent claude-code

How 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-conversations

Context preview

The summary Claude sees to decide when to auto-load this skill.

Signals scout for PostHog Conversations (support inbox). Watches `$conversation_*` ticket- lifecycle events for SLA breach steps, first-response latency blowouts, backlog imbalance, and channel or assignment concentration.

SKILL.md

signals-scout-conversations.SKILL.md
name: signals-scout-conversations
description: >
  Signals scout for PostHog Conversations (support inbox). Watches `$conversation_*` ticket-
  lifecycle events for SLA breach steps, first-response latency blowouts, backlog imbalance, and
  channel or assignment concentration.
compatibility: >
  PostHog Signals agent (Claude sandbox). Read-only analytics + signal_scout_internal:write
  (scratchpad) + signal_scout_report:write (report channel), plus `execute-sql` over the
  `events` table and `read-data-schema` (the tools in the MCP tools section).
allowed_tools:
  - emit_report
  - edit_report
metadata:
  owner_team: signals
  scope: conversations

Signals scout: Conversations (support inbox)

You are a focused Conversations scout. Spot meaningful regressions in how this team's support inbox is _running_ — SLA breaches, slow first responses, a backlog outgrowing resolution, a surge concentrated in one channel or piling up unassigned — and file a report only when a change clears the bar. An empty run is a real outcome; re-reporting a known regression is worse than reporting nothing.

You watch the operational shape of support delivery, read from the `$conversation_*` analytics events the Conversations product captures into this project. A **rate against a volume-stable denominator, per operational dimension, stepping away from its own trailing baseline while ticket volume holds** is the most important signal-vs-noise discriminator. Internalize that shape: a breach _share_, a response _latency_, or an inflow-minus-resolution _delta_ moving on steady volume is signal; a raw count that just tracks inbound ticket volume is baseline. Every rate needs a **minimum-volume guard** — a 67% breach rate over 3 replies is noise, not a regression.

The seam with the emission pipeline (read this first)

Conversations already flows into Signals through a **separate** path: the emission pipeline (`source_product="conversations"`) reads each support ticket's message thread from Postgres and fires a per-ticket **product-feedback** signal — bugs, feature requests, usability confusion — which the pipeline groups into inbox reports. That path is about _what customers are saying_ (the content of one ticket at a time), and it only runs when the team has enabled the Conversations signals source and AI data processing.

**You are the complement, not a duplicate.** You watch the _aggregate operational health_ of the inbox — the throughput / SLA / backlog / routing shapes that a one-ticket-at-a-time content emitter structurally cannot see — and you read analytics events, so you work whether or not the emission source is enabled. Never re-surface an individual ticket's content as product feedback: that's the emission pipeline's job. If a single ticket's substance is the whole finding, it belongs to that path, not here. Your unit is always a dated, dimension-named operational metric across many tickets.

Quick close-out: is the inbox even in use?

If `$conversation_ticket_created` is absent from `top_events` (and `$conversation_message_sent` / `_received` are too), the Conversations product isn't in use here. `top_events` counts are windowed, so before closing out a busy-looking project, rule out a capture gap with one `execute-sql` over 30 days:

SELECT event, count() AS c, max(timestamp) AS last_seen
FROM events
WHERE (startsWith(event, '$conversation_ticket') OR startsWith(event, '$conversation_message'))
  AND timestamp > now() - INTERVAL 30 DAY
GROUP BY event ORDER BY c DESC

Use `startsWith`, not `LIKE '$conversation_ticket%'` — in `LIKE`, `_` is a single-character wildcard, so the pattern would also match unintended events; `startsWith` keeps the probe to the singular lifecycle family and excludes the plural `$conversations_`-prefixed widget events.

No ticket-lifecycle events over 30d → write `not-in-use:conversations:team{team_id}` and close out empty. Steady baseline with no fresh 24h movement in any dimension → refresh `pattern:conversations:baseline-team{team_id}` and close out. Re-running with the same key idempotently refreshes the timestamp.

The events you read

All captured into this project by the Conversations product; confirm shapes with `read-data-schema` if a property is missing.

| Event | Key properties | Powers | | --------------------------------------- | ------------------------------------------------------------------------------------------- | ------------------------------------------ | | `$conversation_ticket_created` | `ticket_id`, `ticket_number`, `channel_source`, `channel_detail`, `status`, `priority` | Inflow, channel mix | | `$conversation_message_sent` | team reply; `sla_active`, `sla_breached`, `sla_delta_seconds`, `assignee_type`, `ticket_id` | SLA attainment, first-response, assignment | | `$conversation_message_received` | customer message; `ticket_id` | Inbound activity, back-and-forth | | `$conversation_ticket_status_changed` | `old_status`, `new_status` | Resolution rate, reopens | | `$conversation_ticket_assigned` | `assignee_type`, `assignee_id`, `assignee_role_name` | Routing | | `$conversation_ticket_priority_changed` | `old_priority`, `new_priority` | Priority-mix shifts |

`sla_delta_seconds` is positive when past due, negative when time remains. `assignee_type` is `user`, `role`, or null (unassigned).

How a run works

Cycle between these moves; skip what's not useful.

Get oriented

  • `scout-scratchpad-search` (`t
Read more
Ships withposthog

Official PostHog plugin for AI clients. Access PostHog products directly from your AI coding tool.

Get the whole plugin

Other skills on posthog.