/dd-unblock-pr
Load when investigating a failing PR CI pipeline or checking PR health. Attributes each CI failure as flaky, infra, or regression, proposes a targeted action, and reports code coverage.
Claude Code
$ npx -y skills add DataDog/pup --skill dd-unblock-pr --agent claude-code
Codex
$ npx skills add DataDog/pup --skill dd-unblock-pr -a codex -y
Cursor
$ npx skills add DataDog/pup --skill dd-unblock-pr -a cursor -y
Gemini CLI
$ npx skills add DataDog/pup --skill dd-unblock-pr -a gemini-cli -y
GitHub Copilot
$ npx skills add DataDog/pup --skill dd-unblock-pr -a github-copilot -y
OpenCode
$ npx skills add DataDog/pup --skill dd-unblock-pr -a opencode -y
Windsurf
$ npx skills add DataDog/pup --skill dd-unblock-pr -a windsurf -y
SKILL.md
dd-unblock-pr.SKILL.mdname: dd-unblock-pr
description: Load when investigating a failing PR CI pipeline or checking PR health. Attributes each CI failure as flaky, infra, or regression, proposes a targeted action, and reports code coverage.
metadata:
version: "1.2.0"
author: datadog-labs
repository: https://github.com/datadog-labs/agent-skills
tags: datadog,ci,cicd,flaky,flaky-tests,pipeline
alwaysApply: "false"
Unblock PR
One-line summary: Investigate a failing PR CI pipeline — attribute each failure as flaky, infra, or regression and propose a targeted action.
Requires: `dd-pup` skill (pup CLI installed and authenticated), `dd-triage-flaky-test` skill (for flaky failure deep investigation).
---
Input
| Parameter | Description | |---|---| | PR branch | The branch under investigation (e.g. `my-feature-branch`) | | Repository | Lowercase, no-schema URL (e.g. `github.com/org/repo`). Derive from `git remote get-url origin` if not provided. |
---
Workflow
STEP 0 — Parse Input
Derive repository ID and default branch from git if not provided:
# Repository ID: fully lowercase, no-schema URL (the API rejects mixed-case)
git remote get-url origin
# Strip protocol and trailing .git, normalize SSH git@host:org/repo to host/org/repo, then lowercase
# e.g. https://github.com/DataDog/my-repo.git → github.com/datadog/my-repo
# Default branch
git symbolic-ref refs/remotes/origin/HEAD
# Strip refs/remotes/origin/ prefix — fall back to main if unset
STEP 1 — Get PR CI Summary
**Pipeline failures (job level):**
pup cicd events search \
--query "ci_level:job @ci.status:error @git.branch:<branch> @git.repository.id_v2:\"<repo>\"" \
--from 24h \
--limit 50
**Test failures** (only if pipeline results include test-runner jobs):
pup cicd tests search \
--query "test_level:test @test.status:fail @git.branch:<branch> @git.repository.id_v2:\"<repo>\"" \
--from 24h \
--limit 50
Collect all distinct `@test.service` values from test event results. If more than one distinct service is found, note each separately in the triage brief — do not collapse them into a single service filter. Skip the test query for purely infrastructure jobs (build, lint, deploy with no test output), then continue the job-level blame guard and classification.
STEP 1.5 — Fetch Code Coverage (run in parallel with STEP 1)
This step runs unconditionally — coverage context is valuable whether CI is red or green.
The `--repo` value must be fully lowercase (the API rejects mixed-case). Normalize before calling:
repo_lower=$(echo "<repo>" | tr '[:upper:]' '[:lower:]')
pup code-coverage branch-summary \
--repo "$repo_lower" \
--branch "<branch>"
If the command returns no data or exits with an error, report "No data available" for Coverage in the PR Health section.
Note: Code quality and security violation counts are not available in pup — those lines always show "No data available".
STEP 2 — Blame Guard per Failing Job
First check whether `@error_classification.domain` / `@error_classification.type` are present on job events from STEP 1 — if populated, use them as primary classification signals.
For each failing job where classification is still needed, run both checks in parallel:
**Default branch check** — was this job already failing before this PR?
pup cicd events aggregate \
--query "ci_level:job @ci.status:error @ci.job.name:\"<job>\" @git.branch:<default-branch> @git.repository.id_v2:\"<repo>\"" \
--compute count \
--from 24h
**Blast radius check** — is this job failing on other branches too?
pup cicd events aggregate \
--query "ci_level:job @ci.status:error @ci.job.name:\"<job>\" @git.repository.id_v2:\"<repo>\"" \
--compute count \
--group-by "@git.branch" \
--from 24h
Performance fallback: if the blast radius query is slow or times out, skip it and rely on the default branch check alone.
STEP 3 — Classify Each Failure
Load [references/failure-classification.md](references/failure-classification.md) for detailed heuristics and insufficient-data cases.
**Priority order:** 1. If `@error_classification.domain` / `@error_classification.type` present → use as primary signal 2. If test failure AND test appears in flaky tests with `flaky_test_state:active`:
pup cicd flaky-tests search \
--query "flaky_test_state:active @test.name:\"<test-name>\" @git.repository.id_v2:\"<repo>\""→ **flaky** 3. Use blame guard results:
| Failing on default branch? | Failing on ≥3 other branches? | Classification | |---|---|---| | Yes | Yes | **infra** (pre-existing, widespread) | | Yes | No | **infra** (pre-existing on default branch) | | No | No | **regression** (introduced by this PR) | | No | Yes | **flaky** (intermittent, cross-branch) | | Insufficient data | — | **unknown** |
STEP 4 — Produce Triage Brief
One entry per failing job:
PR CI Triage Brief
==================
Branch: <branch>
Repo: <repo>
Job: <job-name>
Classification: <flaky | infra | regression | unknown>
Evidence: <1 key data point — error message, pipeline count, or test result>
Confidence: <high | medium | low>
Recommended: <action>
[repeat for each failing job]
Overall: <N> failures — <e.g. "1 regression, 1 flaky, 1 infra">
PR Health
=========
Coverage: <X>% on <branch> | No data available
Quality: No data available
Security: No data available
All three lines always appear.
STEP 5 — Propose Actions
**regression** → Prompt user to investigate their code changes. No write action available.
**flaky** → Load `dd-triage-flaky-test` for deep investigation once per distinct failing test, passing its name, suite/module or `fingerprint_fqn` when known, and repository. That skill will:
- Determine whether the flake is self-introduced, pre-existing, or undetermined, with failure history taking precedence over diff overlap or stated authorship.
- Surface an exis
Read more
name: dd-unblock-pr description: Load when investigating a failing PR CI pipeline or checking PR health. Attributes each CI failure as flaky, infra, or regression, proposes a targeted action, and reports code coverage. metadata: version: "1.2.0" author: datadog-labs repository: https://github.com/datadog-labs/agent-skills tags: datadog,ci,cicd,flaky,flaky-tests,pipeline alwaysApply: "false"
Unblock PR
One-line summary: Investigate a failing PR CI pipeline — attribute each failure as flaky, infra, or regression and propose a targeted action.
Requires: `dd-pup` skill (pup CLI installed and authenticated), `dd-triage-flaky-test` skill (for flaky failure deep investigation).
---
Input
| Parameter | Description | |---|---| | PR branch | The branch under investigation (e.g. `my-feature-branch`) | | Repository | Lowercase, no-schema URL (e.g. `github.com/org/repo`). Derive from `git remote get-url origin` if not provided. |
---
Workflow
STEP 0 — Parse Input
Derive repository ID and default branch from git if not provided:
# Repository ID: fully lowercase, no-schema URL (the API rejects mixed-case) git remote get-url origin # Strip protocol and trailing .git, normalize SSH git@host:org/repo to host/org/repo, then lowercase # e.g. https://github.com/DataDog/my-repo.git → github.com/datadog/my-repo # Default branch git symbolic-ref refs/remotes/origin/HEAD # Strip refs/remotes/origin/ prefix — fall back to main if unset
STEP 1 — Get PR CI Summary
**Pipeline failures (job level):**
pup cicd events search \ --query "ci_level:job @ci.status:error @git.branch:<branch> @git.repository.id_v2:\"<repo>\"" \ --from 24h \ --limit 50
**Test failures** (only if pipeline results include test-runner jobs):
pup cicd tests search \ --query "test_level:test @test.status:fail @git.branch:<branch> @git.repository.id_v2:\"<repo>\"" \ --from 24h \ --limit 50
Collect all distinct `@test.service` values from test event results. If more than one distinct service is found, note each separately in the triage brief — do not collapse them into a single service filter. Skip the test query for purely infrastructure jobs (build, lint, deploy with no test output), then continue the job-level blame guard and classification.
STEP 1.5 — Fetch Code Coverage (run in parallel with STEP 1)
This step runs unconditionally — coverage context is valuable whether CI is red or green.
The `--repo` value must be fully lowercase (the API rejects mixed-case). Normalize before calling:
repo_lower=$(echo "<repo>" | tr '[:upper:]' '[:lower:]') pup code-coverage branch-summary \ --repo "$repo_lower" \ --branch "<branch>"
If the command returns no data or exits with an error, report "No data available" for Coverage in the PR Health section.
Note: Code quality and security violation counts are not available in pup — those lines always show "No data available".
STEP 2 — Blame Guard per Failing Job
First check whether `@error_classification.domain` / `@error_classification.type` are present on job events from STEP 1 — if populated, use them as primary classification signals.
For each failing job where classification is still needed, run both checks in parallel:
**Default branch check** — was this job already failing before this PR?
pup cicd events aggregate \ --query "ci_level:job @ci.status:error @ci.job.name:\"<job>\" @git.branch:<default-branch> @git.repository.id_v2:\"<repo>\"" \ --compute count \ --from 24h
**Blast radius check** — is this job failing on other branches too?
pup cicd events aggregate \ --query "ci_level:job @ci.status:error @ci.job.name:\"<job>\" @git.repository.id_v2:\"<repo>\"" \ --compute count \ --group-by "@git.branch" \ --from 24h
Performance fallback: if the blast radius query is slow or times out, skip it and rely on the default branch check alone.
STEP 3 — Classify Each Failure
Load [references/failure-classification.md](references/failure-classification.md) for detailed heuristics and insufficient-data cases.
**Priority order:** 1. If `@error_classification.domain` / `@error_classification.type` present → use as primary signal 2. If test failure AND test appears in flaky tests with `flaky_test_state:active`:
pup cicd flaky-tests search \
--query "flaky_test_state:active @test.name:\"<test-name>\" @git.repository.id_v2:\"<repo>\""→ **flaky** 3. Use blame guard results:
| Failing on default branch? | Failing on ≥3 other branches? | Classification | |---|---|---| | Yes | Yes | **infra** (pre-existing, widespread) | | Yes | No | **infra** (pre-existing on default branch) | | No | No | **regression** (introduced by this PR) | | No | Yes | **flaky** (intermittent, cross-branch) | | Insufficient data | — | **unknown** |
STEP 4 — Produce Triage Brief
One entry per failing job:
PR CI Triage Brief ================== Branch: <branch> Repo: <repo> Job: <job-name> Classification: <flaky | infra | regression | unknown> Evidence: <1 key data point — error message, pipeline count, or test result> Confidence: <high | medium | low> Recommended: <action> [repeat for each failing job] Overall: <N> failures — <e.g. "1 regression, 1 flaky, 1 infra"> PR Health ========= Coverage: <X>% on <branch> | No data available Quality: No data available Security: No data available
All three lines always appear.
STEP 5 — Propose Actions
**regression** → Prompt user to investigate their code changes. No write action available.
**flaky** → Load `dd-triage-flaky-test` for deep investigation once per distinct failing test, passing its name, suite/module or `fingerprint_fqn` when known, and repository. That skill will:
- Determine whether the flake is self-introduced, pre-existing, or undetermined, with failure history taking precedence over diff overlap or stated authorship.
- Surface an exis
Every AI agent needs a loyal companion. Meet Pup — the CLI that gives your agents full access to Datadog's observability platform (because even autonomous agents need good tooling, not just tricks).
Other skills on pup.
More skills from other plugins.
install
Kubeshark installation and deployment skill. Use this skill whenever the user wants to install Kubeshark, deploy Kubeshark to a…
phone-input
Call the user on the phone for real-time voice conversations. Use this when you need input, want to report on completed work, or…
Questions about dd-unblock-pr.
- Which coding agents can use dd-unblock-pr?
- dd-unblock-pr installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.

