A collection of PostHog skills for enhancing AI-assisted workflows. Add this repo as a Claude Code plugin marketplace to get access to all PostHog skills: Then install individual plugins: Or browse available plugins: Copy any skill directory to .claude/skills/ in your project: Any directory under skills/ that contains a .claude-plugin/plugin.json is automatically discovered and added to the market
Add this skill
npx mdskills install PostHog/diagnosing-ci-and-merge-bottlenecks@PostHog? Sign in with GitHub to claim this listing.Exceptionally detailed instructions for CI analytics with strong guardrails and clear tool-routing logic
1---2name: diagnosing-ci-and-merge-bottlenecks3description: >4 Diagnoses CI and pull-request pipeline health for a GitHub repo using the engineering analytics MCP tools —5 pull-requests (PR list with CI status), workflow-health (per-workflow CI trends), and pr-lifecycle (a single PR's6 timeline). Use when asked whether CI is getting faster or slower, which GitHub Actions workflow is the slow or7 flaky long-pole, how long PRs take from open to merge, how an author's merge time compares to the cohort, which8 open PRs have failing or pending CI, or where a specific pull request is stuck. Triggers on "engineering9 analytics", "is CI getting slower", "slow workflow", "flaky CI", "time to merge", "cycle time", "PR throughput",10 "failing checks", "where is PR <n> stuck", "CI long pole", "what's holding up this PR".11---1213# Diagnosing CI and merge bottlenecks1415Engineering analytics treats a pull request like product analytics treats a user: a PR moves through a pipeline16(`opened → CI → review → merged → deployed`) and the job is to find where it slows down. The surface is **three17named MCP tools** — you call them, you don't write SQL. Dogfooded on `PostHog/posthog`; the same tools serve18autonomous agents (e.g. PostHog Code) reasoning about their own PRs.1920## The tools2122- **`pull-requests`** — the PR workhorse. Open PRs plus anything merged or closed since `date_from` (default23 `-30d`), newest first. Each row carries `author` (nested object: `handle`, `display_name`, `is_bot`), `repo`24 (nested: `owner`, `name`), `state`, `is_draft`, `labels`, `open_to_merge_seconds`, and a `ci` rollup25 (`runs` / `passing` / `failing` / `pending`) from the head-SHA join. Answers most PR-level questions:26 which PRs have failing or pending CI, which are stuck open longest, per-author or per-repo triage, and27 time-to-merge stats (aggregate `open_to_merge_seconds` over the returned merged rows yourself — median and p95,28 never a mean).29- **`workflow-health`** — per-workflow CI health over a window (`date_from` / `date_to`, default last 30 days):30 `run_count`, `success_rate`, `p50_seconds`, `p95_seconds`, `last_failure_at`. Answers "is CI getting faster or31 slower" and "which workflow is the slow or flaky long pole". There is no built-in trend — call it over two32 adjacent windows and compare. `success_rate` / `p50_seconds` / `p95_seconds` cover completed runs only and are33 `null` when a window has no completed runs — guard for null before comparing two windows (a workflow can have34 runs in one and none in the other).35- **`pr-lifecycle`** — a single PR's timeline: a header plus ordered events — opened, then a CI started/finished36 pair **per workflow run** (many on a multi-workflow repo, interleaved by time), then merged/closed. Answers37 "where is PR N stuck". `metric_quality` is `partial`.3839There is no aggregate time-to-merge tool and no "counts" tool — derive those from `pull-requests` (the stuck/failing40counts, the merge-time percentiles).4142## Caveats you must carry into every answer4344These are structural limits of today's snapshot data — state them, don't paper over them.4546- **`open_to_merge_seconds` is coarse.** It fuses _draft_ time and _ready-for-review_ time into one figure. Report47 it as "open to merge", never "cycle time" or "review time". Flag it when long-lived drafts inflate a number.48- **CI status can be stale.** The CI source syncs on a watermark and does not refresh a run that completes after49 newer runs land (until the `workflow_run` webhook ships). Treat a `pending` count as unsettled, not as a settled50 failure; lead with status, not a verdict.51- **CI for a PR is the head-SHA join, nothing else.** The `ci` rollup reflects only the latest commit's runs. There52 is no other link between a PR and its checks.53- **No reviews, approvals, per-check/job, or deploys yet.** Don't infer review behaviour or DORA metrics from their54 absence; that data hasn't landed. `pr-lifecycle` is `partial` for the same reason.55- **Bots and drafts are present in `pull-requests` output, excluded by convention.** Filter out `author.is_bot`56 (nested under `author`, not a row-level field) and `is_draft` for throughput / merge-time questions; keep them in57 for bot-impact questions.58- **`pull-requests` returns a capped page.** At most `limit` rows (newest first); `truncated` is `true` when more59 match, and there is no repo or limit filter to narrow the call. When `truncated` is `true`, any percentile or60 count you derive covers only the newest page — not the whole window — so say so and shrink `date_from` until the61 real set fits under the cap.6263## Choosing a tool6465| The question | Tool | How |66| ------------------------------------------------------ | ----------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |67| Is CI getting slower? Which workflow is the long pole? | `workflow-health` | Call over two adjacent windows (e.g. `date_from=-14d`, then `date_from=-28d` `date_to=-14d`); compare `p50_seconds` and `p95_seconds` per workflow. Lead with the median but always check p95 separately — they move independently. |68| Which open PRs have failing or pending CI? | `pull-requests` | Keep rows where `ci.failing > 0` or `ci.pending > 0`. `pending` means unsettled (or stale) — not a settled failure. |69| Which PRs are stuck open longest? | `pull-requests` | Keep `state = open`, not `is_draft`, not `author.is_bot`; sort by `created_at` ascending (oldest first). |70| How long are PRs taking to merge? Per author? | `pull-requests` | Over merged rows (`merged_at` set, not bot, not draft), aggregate `open_to_merge_seconds` — median and p95. Group by `author.handle` for **cohort context, not a ranking** (per-developer surveillance is an explicit non-goal). Trend it by calling with two `date_from` windows. |71| Where is PR N stuck? | `pr-lifecycle` | Walk the sorted events: `opened → first CI started`, the CI span (first start → last finish; one pair per workflow), `last CI finished → merged`. The largest gap is the bottleneck. A long open→merge with quick CI points at review/idle time the `partial` data can't itemize yet — say so. |7273## The high-value chain7475Mirror how a human investigates: aggregate signal → confirm → concrete PR.7677```text78workflow-health (find the slow/flaky long-pole workflow)79 → pull-requests (confirm it's dragging merge time; list the affected PRs)80 → pr-lifecycle (open a representative stuck PR and show the gap)81```8283"CI median rose because `e2e-playwright` p95 doubled; that workflow is the long pole on PR #1234, which sat 47m in84CI before merging."8586## Output expectations8788- Lead with the verdict in one line, then the supporting numbers.89- Carry the coarse / partial / staleness caveat whenever the distinction matters.90- For multi-window or multi-workflow comparisons, a short table beats prose. Report median and p95 side by side —91 never collapse them into one "average".9293## What NOT to do9495- Don't call `open_to_merge_seconds` cycle time or review time — it's coarse open-to-merge.96- Don't report a CI count as a settled failure when `pending > 0` — it may be unsettled or stale.97- Don't infer reviews, approvals, per-check counts, or deploys — that data isn't ingested yet.98- Don't turn per-author buckets into a leaderboard — they're for finding stuck work, not ranking people.99- Don't reach for these tools to fetch raw PR contents or diffs — they surface pipeline signal, not the PR thread.100
Full transparency — inspect the skill content before installing.