Catch the deploy that broke errors and sign-ups in the same hour

Each morning and after a deploy: every production release lined up with the Sentry issues it introduced and the key event rate before and after it.

Runs
Daily at 8:00, and after each deploy
Posts
Report card

What lands on your board

acme-webDeploy to error to conversion chain · Claude Code

Sign-ups down 18% since PR 123 shipped

PR 123 went live at 14:02. Sentry issue WEB-4F1 was first seen at 14:09 in that release. Sign-ups since: 141, against 172 in the same hours last week (-18%).

  1. 14:02 PR 123 "New sign-up form validation" live in productionCommit 9f2c41e, release 9f2c41e
  2. 14:09 WEB-4F1 TypeError: email.trim is not a functionFirst seen in release 9f2c41e; 212 events, 168 users
  3. 14:00 to 20:00 sign-ups 141 vs 172 last week-18% on the same hours 7 days earlier
DeployLiveNew issuesSign-upsVerdict
PR 123Today 14:02WEB-4F1 (212 events)-18%Suspect
PR 121Today 09:40None+2%Clear
PR 119Yesterday 17:15API-2C0 (9 events)-3%Watch

Roll back PR 123 or ship a fix for WEB-4F1 first: the error fires on the sign-up form submit, which matches the drop.

ResolveFailed
An example with made-up numbers. Your agent posts your real ones.

What it does

For developers and PMs who have watched a sign-up rate sag and spent an afternoon working out which release did it. The deploy time is in GitHub or Vercel, the new error is in Sentry, and the drop is in PostHog or GA4. Each tool is right on its own; none of them puts the three on one clock.

The agent takes every production deploy of the last 24 hours, finds the PR behind it, the Sentry issues that first appeared after it, and the hourly key event count around it, set against the same hours a week earlier. When a deploy lines up with a new error and a drop, the card lands in Needs you with the PR number on it.

How it works

  1. 1List production deploys and their PRs

    From whichever you use: GET /repos/{owner}/{repo}/deployments?environment=production with each deployment's success status time from /deployments/{id}/statuses, or Vercel GET /v7/deployments?projectId=<id>&target=production&state=READY&since=<ms> using ready and meta.githubCommitSha. Map each SHA to its PR with GET /repos/{owner}/{repo}/commits/{sha}/pulls. Keep the last 24 hours (or the one deploy that triggered this run).

  2. 2Get the new errors

    Call GET /api/0/organizations/{org}/issues/?query=is:unresolved firstSeen:-24h&environment=production&statsPeriod=24h&sort=freq. Keep shortId, title, firstSeen, count, userCount and the first release (from the issue detail's firstRelease.version).

  3. 3Pull the key event by hour

    In PostHog, POST a HogQL query to /api/projects/:id/query/: SELECT toStartOfHour(timestamp) AS hour, count() FROM events WHERE event = 'signed_up' AND timestamp > now() - INTERVAL 8 DAY GROUP BY hour ORDER BY hour. In GA4 instead, runReport with dimension dateHour, metric keyEvents and a filter on eventName. Whichever you use, cover 8 days so last week's same hours are there.

  4. 4

    4Line them up on one clock

    Convert everything to UTC (GA4 dateHour is in the property's time zone). Tie a Sentry issue to a deploy when its first release matches the deploy SHA or version, or, with no release set, when it was first seen within 60 minutes after that deploy and before the next one. For each deploy, compare key events from the deploy hour until the next deploy or now against the same hours 7 days earlier; a drop of 10% or more on at least 30 baseline events counts. Deploys with no new issue and no drop are listed as clear.

  5. 5

    5Post the chain

    One row per deploy: PR, live time, new issues, key event change and a verdict (suspect, watch, clear). When a deploy has both a new issue and a drop, set work_state: failed and put the PR, the issue and the drop in the title.

  6. Post it to the board

    With BRIEFKIN_TOKEN set, the agent sends the result as one card that updates in place every run. Without it, you get the report in the chat.

What you get

  • The verdict: the deploy that lines up with a new error and a drop, or "all clear".
  • Per deploy: PR, live time, new Sentry issues (events, users), key event change against the same hours last week.
  • The timeline for the suspect deploy: deploy, first error, and the hourly key event count.
  • One line on what to do first, for example "Roll back PR 123 or fix WEB-4F1 on the sign-up form".

Install and run it

Pick your agent, where the data comes from and how to schedule it; the commands below follow.

Agent
Data
Schedule
  1. Install the skill

    One command. It puts the SKILL.md in ~/.claude/skills and in ~/.agents/skills, which Codex, Cursor, Gemini CLI, Copilot CLI and OpenCode read too.

    shellcurl -fsSL https://briefkin.dev/skills/github-deploy-error-conversion-chain/install | sh
  2. Run it

    Ask Claude Code:

    promptRun the github-deploy-error-conversion-chain skill

    Or paste the prompt instead of installing:

    promptList my production deploys from the last 24 hours (GitHub deployments for <owner/repo>, or Vercel deployments with target production) and map each commit SHA to its PR. From Sentry, get unresolved production issues first seen in the last 24 hours with first seen time, first release, events and users. From PostHog (HogQL) or GA4 (dateHour), get the hourly count of my key event <signed_up> for the last 8 days. Put everything in UTC. Tie a Sentry issue to a deploy when its first release matches the deploy SHA, or it was first seen within 60 minutes after the deploy and before the next one. For each deploy, compare the key event count from the deploy hour to the next deploy (or now) with the same hours 7 days earlier; a drop of 10% or more on at least 30 baseline events counts. Show a table per deploy: PR, live time, new issues, key event change, verdict (suspect, watch, clear). End with the one thing to do first.
  3. Put it on a schedule

    Daily at 8:00, and after each deploy, from cron on any machine where Claude Code is signed in:

    crontab0 8 * * * claude -p "Run the github-deploy-error-conversion-chain skill"

    Add it with crontab -e. A laptop asleep at that time runs it when it wakes if you use launchd or Task Scheduler instead; GitHub Actions works for the API route.

  4. Send it to your board

    Connect Briefkin once with curl -fsSL https://briefkin.dev/install | sh and every run lands on your board as a report card. How setup works

View the SKILL.mdRaw file
SKILL.md---
name: github-deploy-error-conversion-chain
description: "Each morning and after a deploy: every production release lined up with the Sentry issues it introduced and the key event rate before and after it. Use when the user asks for this, or when it runs on a schedule."
---

# Deploy to error to conversion chain

Each morning and after a deploy: every production release lined up with the Sentry issues it introduced and the key event rate before and after it.

For developers and PMs who have watched a sign-up rate sag and spent an afternoon working out which release did it. The deploy time is in GitHub or Vercel, the new error is in Sentry, and the drop is in PostHog or GA4. Each tool is right on its own; none of them puts the three on one clock.

The agent takes every production deploy of the last 24 hours, finds the PR behind it, the Sentry issues that first appeared after it, and the hourly key event count around it, set against the same hours a week earlier. When a deploy lines up with a new error and a drop, the card lands in Needs you with the PR number on it.

## Two ways to get the data

Use the API or MCP route when you have an MCP server, a CLI or an API token for the app. Otherwise, if you can drive a browser the user is signed in to (Claude in Chrome, a Playwright or Chrome DevTools MCP server), use the browser route. Say which one you used.

## Route A: API or MCP server

### What you need

- Read access to deployments in GitHub (`gh` or `GITHUB_TOKEN` with Deployments: Read) or to the Vercel project (Vercel MCP or `VERCEL_TOKEN`), whichever records your production deploys.
- A Sentry token with `event:read` and `project:read`, or the Sentry MCP server; releases set to the commit SHA make the match exact.
- PostHog (`query:read`) or GA4 (Viewer) access, and the name of the one key event to watch, such as `signed_up` or `sign_up`.

If something is missing, say what and stop; do not invent numbers.

### Steps

1. **List production deploys and their PRs** (GitHub): From whichever you use: `GET /repos/{owner}/{repo}/deployments?environment=production` with each deployment's `success` status time from `/deployments/{id}/statuses`, or Vercel `GET /v7/deployments?projectId=<id>&target=production&state=READY&since=<ms>` using `ready` and `meta.githubCommitSha`. Map each SHA to its PR with `GET /repos/{owner}/{repo}/commits/{sha}/pulls`. Keep the last 24 hours (or the one deploy that triggered this run).
2. **Get the new errors** (Sentry): Call `GET /api/0/organizations/{org}/issues/?query=is:unresolved firstSeen:-24h&environment=production&statsPeriod=24h&sort=freq`. Keep `shortId`, `title`, `firstSeen`, `count`, `userCount` and the first release (from the issue detail's `firstRelease.version`).
3. **Pull the key event by hour** (PostHog): In PostHog, POST a HogQL query to `/api/projects/:id/query/`: `SELECT toStartOfHour(timestamp) AS hour, count() FROM events WHERE event = 'signed_up' AND timestamp > now() - INTERVAL 8 DAY GROUP BY hour ORDER BY hour`. In GA4 instead, `runReport` with dimension `dateHour`, metric `keyEvents` and a filter on `eventName`. Whichever you use, cover 8 days so last week's same hours are there.
4. **Line them up on one clock**: Convert everything to UTC (GA4 `dateHour` is in the property's time zone). Tie a Sentry issue to a deploy when its first release matches the deploy SHA or version, or, with no release set, when it was first seen within 60 minutes after that deploy and before the next one. For each deploy, compare key events from the deploy hour until the next deploy or now against the same hours 7 days earlier; a drop of 10% or more on at least 30 baseline events counts. Deploys with no new issue and no drop are listed as clear.
5. **Post the chain**: One row per deploy: PR, live time, new issues, key event change and a verdict (suspect, watch, clear). When a deploy has both a new issue and a drop, set `work_state: failed` and put the PR, the issue and the drop in the title.

## Route B: the browser

### What you need

- Signed in to GitHub (or Vercel) with access to the project's deployments, to Sentry as an organization member, and to PostHog or GA4 with view access.

If something is missing, say what and stop; do not invent numbers.

### Steps

Start at https://github.com/. The user is signed in already; never type passwords or codes, and ask if a sign-in page appears.

1. **Find the production deploys**: Open the repository, then **Deployments** in the right sidebar (or `https://vercel.com/` > the project > **Deployments**, filtered to Production). Note each deploy of the last 24 hours, its time and commit, and open the commit to find its PR number.
2. **Read the new Sentry issues**: In `https://sentry.io/`, open **Issues**, set the environment to production and the date to the last 24 hours, search `is:unresolved firstSeen:-24h` and sort by Events. For each issue, open it and note the first seen time and the first release shown in the sidebar.
3. **Read the key event by hour**: In PostHog, create a Trends insight on your key event, interval **Hour**, last 8 days. In GA4, use Explore with dimensions Date + hour (YYYYMMDDHH) and Event name, filtered to the key event. Note counts from each deploy hour onward and the same hours 7 days earlier.
4. **Line them up**: Put all times in one time zone. Tie an issue to a deploy when its first release is that deploy's commit, or it was first seen within 60 minutes after it. Call a deploy suspect when it has a new issue and the key event fell 10% or more on at least 30 baseline events.

Note: The UI shows Sentry and PostHog times in your profile's time zone and GA4 in the property's, so check both before lining them up. GA4 Explore can lag several hours. This route is fine for one suspect deploy; for a day with many deploys the API route is faster and less error-prone.

## The report

- **The verdict**: the deploy that lines up with a new error and a drop, or "all clear".
- **Per deploy**: PR, live time, new Sentry issues (events, users), key event change against the same hours last week.
- **The timeline** for the suspect deploy: deploy, first error, and the hourly key event count.
- One line on what to do first, for example "Roll back PR 123 or fix WEB-4F1 on the sign-up form".

## Post it to Briefkin

When `BRIEFKIN_TOKEN` is set, or `~/.config/briefkin/env` exists (the installer from https://briefkin.dev/docs writes it), also send the result to the user's Briefkin board as one card. Keep the `item_key` the same on every run so the card updates in place, use a new `event_id` per run, and put today's real numbers in place of the example ones. If the request fails, say so once and carry on.

```bash
[ -n "${BRIEFKIN_TOKEN:-}" ] || . ~/.config/briefkin/env
curl -sS -X POST "${BRIEFKIN_URL:-https://briefkin.dev}/v1/events" \
  -H "authorization: Bearer $BRIEFKIN_TOKEN" \
  -H "content-type: application/json" \
  -d @- <<'JSON'
{
  "v": 1,
  "event_id": "github-deploy-error-conversion-chain/<date of this run, e.g. 2026-10-16>",
  "item_key": "github-deploy-error-conversion-chain",
  "project": "acme-web",
  "source": "Deploy to error to conversion chain skill",
  "kind": "update",
  "title": "Sign-ups down 18% since PR 123 shipped",
  "summary": "PR 123 went live at **14:02**. Sentry issue **WEB-4F1** was first seen at **14:09** in that release. Sign-ups since: **141**, against 172 in the same hours last week (**-18%**).",
  "work_state": "failed",
  "widget": [
    {
      "type": "Steps",
      "props": {
        "items": [
          {
            "label": "14:02 PR 123 \"New sign-up form validation\" live in production",
            "state": "done",
            "note": "Commit 9f2c41e, release 9f2c41e"
          },
          {
            "label": "14:09 WEB-4F1 TypeError: email.trim is not a function",
            "state": "failed",
            "note": "First seen in release 9f2c41e; 212 events, 168 users"
          },
          {
            "label": "14:00 to 20:00 sign-ups 141 vs 172 last week",
            "state": "failed",
            "note": "-18% on the same hours 7 days earlier"
          }
        ]
      }
    },
    {
      "type": "Table",
      "props": {
        "columns": [
          "Deploy",
          "Live",
          "New issues",
          "Sign-ups",
          "Verdict"
        ],
        "align": [
          "left",
          "left",
          "left",
          "right",
          "left"
        ],
        "rows": [
          [
            "PR 123",
            "Today 14:02",
            "WEB-4F1 (212 events)",
            "-18%",
            "Suspect"
          ],
          [
            "PR 121",
            "Today 09:40",
            "None",
            "+2%",
            "Clear"
          ],
          [
            "PR 119",
            "Yesterday 17:15",
            "API-2C0 (9 events)",
            "-3%",
            "Watch"
          ]
        ]
      }
    },
    {
      "type": "Callout",
      "props": {
        "text": "Roll back PR 123 or ship a fix for WEB-4F1 first: the error fires on the sign-up form submit, which matches the drop.",
        "tone": "bad"
      }
    }
  ]
}
JSON
```

Widgets come from the Briefkin catalog (https://briefkin.dev/v1/catalog). Without a token, just give the user the report.

## Run it on a schedule

Suggested: Daily at 8:00, and after each deploy (`0 8 * * *`). From cron, with the agent signed in on that machine:

```bash
0 8 * * * claude -p "Run the github-deploy-error-conversion-chain skill"
# Codex: codex exec, Gemini CLI: gemini -p, Copilot CLI: copilot -p, OpenCode: opencode run
```

Or use the agent's own scheduler (Claude Code routines, Codex automations, Claude or ChatGPT scheduled tasks): https://briefkin.dev/skills/github-deploy-error-conversion-chain#schedule

Source: https://briefkin.dev/skills/github-deploy-error-conversion-chain

What your agent needs

  • Read access to deployments in GitHub (gh or GITHUB_TOKEN with Deployments: Read) or to the Vercel project (Vercel MCP or VERCEL_TOKEN), whichever records your production deploys.

  • A Sentry token with event:read and project:read, or the Sentry MCP server; releases set to the commit SHA make the match exact.

  • PostHog (query:read) or GA4 (Viewer) access, and the name of the one key event to watch, such as signed_up or sign_up.

Connecting GitHub

  1. GitHub MCP Server, GitHub's official server, hosted at https://api.githubcopilot.com/mcp/. Sign in with OAuth or a personal access token; add /readonly to the URL, or use a toolset URL such as https://api.githubcopilot.com/mcp/x/pull_requests/readonly, to expose only read tools. It also runs locally (source).
  2. The gh CLI. Run gh auth login once, or set GH_TOKEN for scheduled runs. gh pr list --search "review-requested:@me" --json number,title,url,createdAt and gh api repos/{owner}/{repo}/dependabot/alerts cover most reports.
  3. REST and GraphQL with a fine-grained token. Store it in GITHUB_TOKEN, limit it to the repositories in the report, and grant Read on Metadata, Contents, Pull requests and Issues, plus Dependabot alerts if you report on them.

With every permission on a fine-grained token set to Read, the agent can't push, merge, comment or close anything.

Connecting Sentry

  1. Sentry MCP server, Sentry's official remote server at https://mcp.sentry.dev/mcp, signed in with OAuth. Add Sentry from Claude's connector directory, or run claude mcp add --transport http sentry https://mcp.sentry.dev/mcp. It searches issues and events and pulls stack traces.
  2. sentry-cli. Mostly a release and source map tool, but sentry-cli issues list --project <slug> lists issues when a quick terminal check is enough.
  3. API with an auth token. Create an organization or personal token, store it in SENTRY_AUTH_TOKEN with SENTRY_ORG, and grant org:read, project:read and event:read.

Those three read scopes cover every report here; leave out event:write, which lets a token resolve and assign issues.

Connecting PostHog

  1. PostHog MCP server, PostHog's official remote server at https://mcp.posthog.com/mcp. Sign in with OAuth, or let the PostHog Wizard install it in your client; it routes to the US or EU cloud based on your account. Clients without OAuth can send a personal API key made with the MCP Server preset as a Bearer token (docs).
  2. Query API with a personal API key. Create one in your PostHog account settings, store it in POSTHOG_API_KEY with POSTHOG_PROJECT_ID and POSTHOG_HOST (https://us.posthog.com or https://eu.posthog.com), and give it the query:read scope, plus insight:read or feature_flag:read if the report uses them.

Add ?readonly=true to the MCP URL (or send x-posthog-read-only: true) to drop every tool that creates, updates or deletes; on the API, read scopes alone do the same.

Connecting Google Analytics

  1. Google Analytics MCP server, Google's own open-source server (analytics-mcp on PyPI, source). It runs locally with pipx run analytics-mcp, offers run_report, run_realtime_report and get_account_summaries, and Google labels it experimental.
  2. Data API with a service account. Enable the Google Analytics Data API in a Google Cloud project, create a service account, add its email as a Viewer on the GA4 property, and point GOOGLE_APPLICATION_CREDENTIALS at its JSON key. The skill also reads GA4_PROPERTY_ID.
  3. Your own Google login. gcloud auth application-default login --scopes https://www.googleapis.com/auth/analytics.readonly,https://www.googleapis.com/auth/cloud-platform --client-id-file=client.json gives the MCP server or a script your user's access without a key file.

Request only analytics.readonly and keep the service account at Viewer: none of these reports needs Editor.

Connecting Vercel

  1. Vercel MCP, Vercel's official remote server at https://mcp.vercel.com, signed in with OAuth. It lists projects and deployments, reads build and runtime logs, and searches Vercel's docs.
  2. The vercel CLI. vercel ls <project> lists recent deployments, vercel inspect <deployment-url> --logs prints the build log, and vercel logs <deployment-url> shows runtime logs. Pass --token $VERCEL_TOKEN and --scope <team> in scheduled runs.
  3. REST API with an access token created under Account Settings > Tokens and scoped to the team, stored in VERCEL_TOKEN, with VERCEL_TEAM_ID sent as teamId.

Vercel tokens can be limited to one team and given an expiry but can't be made read-only, so use a short-lived token for reports and keep deploy and env var tasks out of the same skill.

Questions

How does it tell a real drop from a slow afternoon?

It compares each hour with the same hour a week earlier, which takes out the daily and weekly rhythm, and ignores windows with fewer than 30 events in the baseline. A holiday or a campaign last week can still skew it, so the card shows both numbers, not only the percentage.

Do the clocks really line up across GitHub, Sentry and GA4?

GitHub, Vercel, Sentry and PostHog return UTC timestamps. GA4 reports dateHour in the property's time zone, so the agent converts it first. GA4 also takes several hours to process recent data, so right after a deploy PostHog gives the faster read; the morning run is the reliable one for GA4.

Do I need Briefkin to use the Deploy to error to conversion chain skill?

No. The skill runs with your own agent and gives you the report in the chat. With a Briefkin token set, each run also posts it to your board as a report card, so you can glance at it instead of asking again.

Which agents can run it?

Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot CLI, OpenCode, Windsurf and Amp all read SKILL.md files. The install command puts it in ~/.claude/skills and ~/.agents/skills, where they look. ChatGPT, the Claude app and Grok take the prompt instead. Pick your agent under "Install and run it" and the commands change to match.

Can it work without an API or MCP server, from my browser?

Yes. Switch the data source to "Your browser" and the steps change to the GitHub, Sentry, PostHog, Google Analytics and Vercel pages themselves: the agent opens github.com in a browser you are signed in to and reads the numbers off the page. Claude Code, Codex, Cursor, Claude app and ChatGPT can drive a browser out of the box; Gemini CLI, Copilot CLI and OpenCode need a Playwright or Chrome DevTools MCP server first. It is slower than the API and needs you signed in, so it suits a report you run by hand or from a scheduler on your own computer.

Read this report on your board, not in a chat log

Skills are free to use with any agent. Briefkin is where their results land: one board for every report, number and question your agents send, with a ping when something needs you.

Free during the open beta. No card.