ci-triage
Find and diagnose RED CI with the gh CLI — answer "is anything failing?" and "why?" correctly, without being handed a URL.
Skill by nubjs
Install
Works with Claude Code, Claude apps, Codex, Cursor, Gemini CLI, GitHub Copilot, VS Code, OpenCode, Goose, Windsurf. Read the repository before you give any tool access to your data.
npx agentmarket install skill/nubjs-ci-triage
Asks which of your tools to add it to (Claude Code, Codex, Cursor, VS Code, Windsurf, Gemini CLI, Claude Desktop) and shows the change first. See https://agentmart.dev/cli.
Get the weekly diff
The weekly diff: one email a week with new agent tools, notable updates and grade changes, plus security alerts for tools you follow. Double opt-in, one-click unsubscribe.
About
Use cases: design, testing, devops, productivity, ci-cd
Reviews
Write a reviewNo reviews yet. Installed it? Reviews come from verified installers only. How reviews work
Permissions
What this skill can do and what it asks for, from its SKILL.md. Checked Oct 25, 2026.
- Tools
- No tools found
- Secrets
- None asked for
- Install scripts
- None found
Network hosts it talks to 1
codeload.github.com· found in install command
Files it touches
~/.claude/skills/ci-triage
What's inside
- Skill name
ci-triage- Description
- Find and diagnose RED CI with the gh CLI — answer "is anything failing?" and "why?" correctly, without being handed a URL. Invoke (via the Skill tool) whenever you need to check whether a branch, commit, or PR is green, whenever someone reports failing CI, before cutting a release, and before claiming any commit is green. THE FAILURE THIS SKILL EXISTS TO PREVENT: `gh run list` reports a RUN-level `conclusion`, and a run whose rollup is `cancelled` can contain a job whose conclusion is `failure` — so filtering runs on `conclusion=="failure"` silently misses real red, and taking the latest run per workflow hides an older failed run on the same SHA. The authoritative instrument is the commit's CHECK-RUNS, which is what the GitHub UI renders. Pairs with `ci-watch` (blocking until a run is terminal) and `ci-adhoc-test` (running a probe on a real OS).
- License
- MIT
- Instructions
- 103 lines in SKILL.md · view on GitHub
Files (1)
- SKILL.md
SKILL.md (first lines)
# Investigating CI
`ci-watch` answers *"has it finished, and did it pass?"* for one run you are waiting on. This skill answers the two questions you get asked cold: **"is anything red?"** and **"why is this red?"** — starting from a branch name or a commit, never from a URL someone hands you.
## The rule
**Never answer "is it green?" from run-level `conclusion`. Query the commit's check-runs.**
A GitHub Actions *run* rolls up its jobs into one conclusion, and that rollup is lossy in the exact case that matters:
| What happened | Run `conclusion` | Job conclusions | `gh run list` shows |
| --- | --- | --- | --- |
| A job failed | `failure` | one `failure` | ✅ red — you see it |
| **A job failed inside a run that also got cancelled** | **`cancelled`** | **one `failure`** | ❌ **nothing — filtered out** |
| Superseded by `cancel-in-progress` | `cancelled` | all `cancelled` | ❌ nothing (correctly) |
The middle row is real and it is what the UI paints red on the commit. It happens whenever a workflow has an aggregation/gate job that runs after its matrix legs: `concurrency: cancel-in-progress` cancels the legs, the gate still runs, sees `cancelled`, and **fails**. The run rolls up `cancelled`; the gate job is `failure`.
## The one command that is always correct
```bash
SHA=$(git rev-parse origin/main) # or a PR head, or any commit
gh api repos/nubjs/nub/commits/$SHA/check-runs --paginate \
--jq '.check_runs[] | select(.conclusion != "success" and .conclusion != "skipped" and .conclusion != "neutral")
| "\(.conclusion // .status) | \(.name) | \(.html_url)"'
```
Empty output means genuinely green. Anything else is exactly what a human sees in the Actions tab, with a clickable URL per finding. This endpoint is the source of truth because it is what the UI renders — run-level data is downstream of it.
### Counting, and the `--paginate` trap
**`--paginate` runs `--jq` once PER PAGE.** A per-item filter like the one above is fine — each page emits its own lines and they concatenate. But any *aggregation* (`length`, `add`, `group_by`) silently returns one result per page instead of a total:
```bash
# WRONG — prints "0" then "1" on a 2-page response. Reads like 0 if you only look at line 1.
gh api repos/nubjs/nub/commits/$SHA/check-runs --paginate --jq '[.check_runs[]|select(.conclusion=="failure")]|length'
```
Use `--slurp` to get one array across pages, and pipe to external `jq` — `--slurp` is rejected together with `--jq`:
```bash
# RIGHT — one number for the whole commit.
gh api repos/nubjs/nub/commits/$SHA/check-runs --paginate --slurp \
| jq '[.[].check_runs[] | select(.conclusion=="failure")] | length'
```
This is not hypothetical: a release commit here carried **192 check-runs across 2 pages**, and the naive count printed `0` on the first line.
## Diagnosing one failure
Given a failing check, get the run, then the job, then the log — in that order.
```bash
gh run view <run-id> --json name,status,conclusion,headBranch,headSha,event,createdAt
gh run view <run-id> --json jobs --jq '.jobs[] | "\(.conclusion // .status) | \(.name)"'
gh run view <run-id> --log-failed > /tmp/fail.log 2>&1; echo "EXIT=$?"
sed -e 's/\x1b\[[0-9;]*m//g' /tmp/fail.log | grep -viE '^\s*$' | tail -40
```
Strip ANSI escapes (`sed -e 's/\x1b\[[0-9;]*m//g'`) or the log is unreadable. `--log-failed` returns only failing steps, which is usually 40 lines rather than 40,000.
**Read the `event` and `createdAt` fields before concluding anything.** They tell you whether the run was superseded, and by what.
## Superseded-run triage — is this red REAL?
A red check on a commit is not automatically a broken commit. Decide with this:
1. **List every run of that workflow on that SHA.** More than one is the tell.
```bash
gh run list --workflow <file>.yml --limit 30 \
--json databaseId,status,conclusion,headSha,headBranch,event,createdAt \
--jq '.[] | select(.headSha=="'"$SHA"'") | "id=\(.databaseId) | \(.conclusion // .status) | \(.event) | \(.createdAt)"'
```
2. **If a later run of the same workflow on the same SHA is fully green, the code is fine** — the red one was superseded. The commit still *shows* red, which is a workflow defect worth fixing, not a code defect.
3. **Check the concurrency group.** `group: ${{ github.workflow }}-${{ github.ref }}` means a `schedule` run and a `push` run on `main` share a group and will cancel each other, because both carry `refs/heads/main`. That is a common and surprising source of self-inflicted red.
## The gate-job anti-pattern, and its fix
A gate job that aggregates matrix legs must treat `cancelled` as *not a verdict*. This is wrong:
```bash
[[ "$smoke" == "success" || "$smoke" == "skipped" ]] || { echo "smoke failed"; exit 1; }
```
A superseded run sets `smoke=cancelled`, so the gate fails and paints the commit red forever. Accept `cancelled` too — it does not mask a real failure, because a genuinely failing leg aggregates to `failure`, not `cancelled`:
```bash
[[ "$smoke" == "success" || "$smoke" == "skipped" || "$smoke" == "cancelled" ]] || { echo "smoke failed"; exit 1; }
```
## What NOT to do
- **Do not** filter `gh run list` on `conclusion=="failure"` and call the absence of hits "green". That is the whole bug this skill exists for.
- **Do not** take the latest run per workflow (`group_by(.name) | max_by(.createdAt)`). A later scheduled run can hide an earlier failed push run on the same SHA.
- **Do not** trust `--branch main` alone to find everything; a check can be attached by an app or a `workflow_run`. Check-runs on the SHA catch all of them.
- **Do not** conclude "not failing" from a bot issue being absent. The trunk-red bot files on its own schedule and its silence proves nothing.
- **Do not** read an exit code through a pipe (`gh ... | head` then `$?`). Redirect, capture `$?` on its own line, then inspect.
## Reporting a finding
State the commit, the check name, the run URL, whether a later run on the same SHA passed, and the mechanism. "CI is red" without those is not a diagnosis. If a superseded run is the cause, say so plainly and name the fix — the commit is still red in the UI and someone has to look at it.From nubjs/nub, MIT.
More from nubjs/nub
- 0.848score
nub-charts
nubjs
Build a performance chart for nubjs.com — the SVG bar figures in blog posts, docs pages and social posts (a runtime augmentation against plain node, an…
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.844score
disk-reduction
nubjs
Reclaim disk on the maintainer's Mac when the volume is full or filling — ENOSPC, "no space left on device", a failed build or agent harness, or a routine…
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.844score
cpu-reduction
nubjs
Diagnose and clear CPU, memory, and disk contention on the maintainer's dev host.
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
pm-perf-tracing
nubjs
Performance-trace Nub package-manager installs using the existing phase timings, structured diagnostics, and sampling-profiler workflow.
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
release
nubjs
Cut a Nub patch release end-to-end in one invocation.
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
probe-platforms
nubjs
Bring a test harness or probe up on a NEW operating system (Windows or Linux), or debug one that fails there.
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
visual-review
nubjs
Verify UI/layout/styling changes are correct by computing occlusion, clipping, and alignment from the browser's resolved paint order via the chrome-devtools…
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
type-declarations
nubjs
Add, audit, or update @nubjs/types declarations for Nub runtime APIs.
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
address-issue
nubjs
End-to-end playbook for working a GitHub issue (or bug-fix PR) on nubjs/nub: triage → acknowledge an external report with an "Investigating" comment →…
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
windows-vm-test
nubjs
Run ad-hoc Nub tests and debugging probes in the maintainer's existing local Windows 11 ARM64 QEMU/HVF VM when its external disk and runbook are present.
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
research-thread
nubjs
Use when the deliverable is a FACT — not code, not a design, not a gap catalog.
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
plan-thread
nubjs
Use when an effort's APPROACH isn't settled yet and needs collaborative design BEFORE implementation — fleshing out how a feature/change should work, weighing…
SkillAFreshness: A★ 4.4KClaude Code +9
Signals
- Stars
- 4,417
- Forks
- 70
- Open issues
- 27
- Last commit (this folder)
- Aug 5, 2026 (2 months ago)
- Last release
- Oct 19, 2026 (8 days ago)
From GitHub (fetched Oct 24, 2026).
Details
- License
- MIT
- Repository
- github.com/nubjs/nub
- Website
- nubjs.com
- First seen
- Oct 24, 2026
- Last checked
- Oct 24, 2026
- Source
- GitHubgithub-graphql
More from nubjs
- 0.848score
nub-charts
nubjs
Build a performance chart for nubjs.com — the SVG bar figures in blog posts, docs pages and social posts (a runtime augmentation against plain node, an…
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.844score
disk-reduction
nubjs
Reclaim disk on the maintainer's Mac when the volume is full or filling — ENOSPC, "no space left on device", a failed build or agent harness, or a routine…
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.844score
cpu-reduction
nubjs
Diagnose and clear CPU, memory, and disk contention on the maintainer's dev host.
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
windows-vm-test
nubjs
Run ad-hoc Nub tests and debugging probes in the maintainer's existing local Windows 11 ARM64 QEMU/HVF VM when its external disk and runbook are present.
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
address-issue
nubjs
End-to-end playbook for working a GitHub issue (or bug-fix PR) on nubjs/nub: triage → acknowledge an external report with an "Investigating" comment →…
SkillAFreshness: A★ 4.4KClaude Code +9 - 0.843score
visual-review
nubjs
Verify UI/layout/styling changes are correct by computing occlusion, clipping, and alignment from the browser's resolved paint order via the chrome-devtools…
SkillAFreshness: A★ 4.4KClaude Code +9
Cite this page
ci-triage skill. Agent Mart. https://agentmart.dev/skills/nubjs-ci-triage (last updated 2026-10-24)