Skills
Skill 43 of 56
Investigates a firing or recently fired observability alert: finds the firing and replays the value it evaluated, decides whether the alert is chronic noise or a new problem…
5 minutes · 1,085 words · 11 sections
Install
npx skills add launchdarkly/ai-tooling --skill alert-investigationnpx skills add launchdarkly/ai-tooling/plugin marketplace add launchdarkly/ai-toolingThe first command installs just this skill, by the name in its SKILL.md; the second installs the whole repository.
You are explaining why an alert fired, whether it matters, and what to do. Half of the alerts you are asked about will turn out to be chronic or misconfigured; “this alert is noise, here is why, here is the retune” is a correct and useful answer. Do not invent a root cause for an alert that has fired every day for a week.
This skill requires the remotely hosted LaunchDarkly MCP server. Tools it uses:
get-alerts: what is firing, and one alert’s full configurationget-alert-firing-history: when it fired, per group, with replay arguments for each firingget-investigation: the automatic investigation that ran for a firing, if anysearch-aggregations: replay the alert’s value, compare against a baseline, break it downget-changes: deploys, flag changes and alert state changes around the onsetget-trace, search-traces, search-logs, search-log-patterns, search-error-groups, get-error-group, search-sessions: evidencesearch-service-map, get-keys, get-incidentsThe investigation itself follows the “first five minutes” in investigate. This skill covers the alert-specific steps around it.
get-alerts with alertId for its query, product type, function, grouping, threshold and window.get-alerts with state: "Alert". One call lists every alert whose most urgent group is in Alert now. Use search to match an alert by name.get-alert-firing-history with the alertId and lookbackDays: 7. It returns:
evaluation: the query, function, grouping and thresholds it uses nowfiring_count and last_fired_atfirings: newest first, each with its group, state change, investigation_conversation_id and replaycurrent_state: the latest state per group, which tells an alert firing now from one that has resolvedsummary: the episode view, read from up to 500 firings (firings_counted, complete). See step 3.Name the group that fired (for example task.type=5), not just the alert. current_state leaves out groups that have been Normal and unchanged for 14 days (idle_groups_omitted; set includeIdleGroups: true to see them). On an older server those groups are listed; ignore entries that have not changed for weeks.
Each firing’s replay is a ready set of search-aggregations arguments that recompute the value the alert compared with its threshold. Pass it as is. Then make two changes, one at a time:
compareTo: "1w" (or "1d"): is the value now different from the same window last week?Count expression next to the alert’s function so you know how many rows the value rests on, and set exact: true if the result says estimated: true and the window is a few hours or less.If config_changed_since is true on a firing, the alert was edited after it fired and the replay uses today’s config; say so when you quote the value.
A current state of NoData means the alert’s query matches nothing: the service was renamed or stopped emitting. That is the finding.
Decide this before you look for a cause. Start from the firing history’s summary:
chronic and chronic_reason: chronic: true means it fired on more than 4 of the last 7 days.episodes (start, end, firings, span_minutes, group_by_key, investigation_conversation_id) and episode_count: firings close together are merged (episode_gap_minutes). One long episode is one problem; ten short ones a day is flapping.flaps, firings_per_day (last 7 days), days_fired (whole lookback) and groups (firings, first and last per group).value_source: the value at each firing is not stored; it says how to recompute it (pass that firing’s replay to search-aggregations, step 2). time_in_alert_note explains why time in Alert is not given.get-changes shows the same alert as alert_episode rows on the service’s timeline, next to deploys and flag changes. On a server without summary, count firings per day from firings yourself.
Other signs of a chronic or noisy alert:
compareTo value from last week.low_sample block on the replay says so directly; see “Sampling and percentiles” in investigate.bucketCount 24 to 48 and see how often it is crossed.If it is chronic, say so, show the numbers, and still explain what the tail is made of (one get-trace of the slowest span usually does it). Recommend a concrete retune: a lower percentile (P95), a higher threshold, a minimum count, a longer window, or excluding the group.
If it is new, the onset is the start of the current episode; carry on.
If the firing has an investigation_conversation_id, call get-investigation with it. Cite its conclusion as its conclusion, and check the key claims against current data before you repeat them. If it says the investigation is not shared with you, do not retry.
Run steps 3 to 6 of the first five minutes in investigate, scoped to the alert’s query and the onset window:
get-changes for the service the alert’s query names, from 1 to 2 hours before the onset. Pass the alert’s ID in alertIds to see its own alert_episode rows on the same timeline.host.name, the version key, http.route, and the flag variation, each with compareTo. If the alert is grouped, compare the firing group with its sibling groups too.search-service-map with include: ["health"] for the service.Load the per-product companion for the alert’s product type (below) for the evidence step.
logs.md: log count or log pattern alertstraces.md: latency, span error-rate, and span-specific alertserrors.md: error-count, new-error-group, crash-rate alertssessions.md: session-health and user-facing-error alertsmetrics.md: OpenTelemetry metric thresholds and composite alertsIf the alert crosses products (a metric alert driven by errors), load both.
Alert investigations feed notifications and on-call handoffs. Use this structure.
## What triggered
<Alert name and ID, the group that fired, the function and threshold, the replayed value and how many rows it rests on, and when it fired (UTC).>
## Verdict
<New problem, chronic condition, or noise, with the evidence: chronic_reason or firings in the last 7 days, episodes, value vs the same window last week.>
## Likely cause
<Root cause with the numbers: the slice that is over-represented (share of failures vs share of traffic), the change that preceded the onset, and trace IDs, error group IDs and log templates. Say what was ruled out.>
## Scope
<Affected requests, error rate, users or sessions, routes, downstream services, and the time window of impact.>
## Next steps
<1 to 3 concrete actions: roll back version X, turn flag Y off in production, drain host Z, retune the alert to P95 > 1 s with a minimum of 200 spans. If the cause is not established, name the exact query or data that would establish it.>duration is in nanoseconds; quote thresholds and values in ms or s.observability/alert-management and observability/create-alert (hosted MCP guides): retune, mute or rebuild the alert after the diagnosis.Investigates a firing or recently fired observability alert: finds the firing and replays the value it evaluated, decides whether the alert is chronic noise or a new problem, reuses any automatic investigation, then finds the cause (what changed, which host, version or route is over-represented) and returns a structured diagnosis with cause, scope and next steps.
The verbatim description from this skill’s front matter — the string an agent matches on to decide whether to load it.
skills/observability/alert-investigation/SKILL.mdmain, last pushed 7 November 2026.SKILL.md, not by matching a directory convention. 10 distinct layouts observed: skills/agentcontrol/*/SKILL.md, skills/aws-devops-agent/*/SKILL.md, skills/experiments/*/SKILL.md, skills/feature-flags/*/SKILL.md, skills/metrics/*/SKILL.md, skills/observability/*/SKILL.md, skills/onboarding/*/SKILL.md, skills/onboarding/sdk-install/*/SKILL.md, skills/*/SKILL.md, skills/release-autopilot/*/SKILL.md.h1 and no skipped levels:.claude-plugin/marketplace.json by LaunchDarkly, declaring 1 plugin. It is read for editorial metadata only — never as the skill index, which is always the repository tree./launchdarkly/ai-tooling.md, and each skill at its own .md URL.5 files · 10 KB
Everything this skill ships beside its prose. All of it is set here, as subchapters of skill 43.
Everything else published alongside the skill.