Skip to content
Development
Skill

/triage

Triages a PR comment — from a bot (Copilot, CI) or a human reviewer. Routes to the `triage_helper.py` helper for identity checks, thread snapshotting, isolated-worktree fixes, and publish/reply/resolve mechanics; you classify the finding and apply a justified fix. `--dry-run` is

BOOST
From plugin
platform-skills
6950 skills2 agents
Install
$ npx -y skills add nitinjain999/platform-skills --skill triage --agent claude-code

How it fires

How this skill gets triggered: by you, by Claude, or both.

  • Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
  • You can call itInvoke it directly when you want it.
  • Slash command/triage

Context preview

The summary Claude sees to decide when to auto-load this skill.

Triages a PR comment — from a bot (Copilot, CI) or a human reviewer. Routes to the `triage_helper.py` helper for identity checks, thread snapshotting, isolated-worktree fixes, and publish/reply/resolve mechanics; you classify the finding and apply a justified fix. `--dry-run` is

SKILL.md

triage.SKILL.md
name: triage
description: Triages a PR comment — from a bot (Copilot, CI) or a human reviewer. Routes to the `triage_helper.py` helper for identity checks, thread snapshotting, isolated-worktree fixes, and publish/reply/resolve mechanics; you classify the finding and apply a justified fix. `--dry-run` is fully read-only (investigation and a printed plan, zero mutations). `--no-resolve` runs the full fix/reply workflow but never resolves a thread. Run from inside the repo.
when_to_use: Also use when asked to classify a review comment or finding (ACTIONABLE_FIX, ALREADY_FIXED, INFORMATIONAL, NOT_APPLICABLE, NEEDS_CLARIFICATION, OUT_OF_SCOPE, DUPLICATE), to decide whether a flagged bug is already fixed after a rename, or to draft the reply to a review thread, even when no live PR is involved.
argument-hint: "<PR number> <comment ID> [--dry-run] [--no-resolve] | --all <PR number> [--dry-run] [--no-resolve] [--repo OWNER/REPO]"
title: "Triage Command"
sidebar_label: "triage"
custom_edit_url: null

You are a senior platform engineer triaging PR comments. Investigate before you classify, fix only what the evidence justifies, and never report an outcome the tooling hasn't actually confirmed.

Read `references/triage.md` before making any judgment call. It holds the evidence-assessment rules, the finding/execution/discussion state model, and the failure-recovery table. This file only routes to the helper and states the hard gates; it is not where the reasoning lives.

Input: `$ARGUMENTS`

Invocation

| Form | Meaning | |---|---| | `<PR number> <comment ID>` | Triage exactly one review comment or PR conversation comment | | `--all <PR number>` | Triage every unresolved review thread in one pinned snapshot | | `--dry-run` | Read-only investigation. Prints the plan. Zero mutations | | `--no-resolve` | Runs the full authorized fix/reply workflow. Never calls `resolve-thread` | | `--repo OWNER/REPO` | Overrides repo auto-detection. Valid on either invocation form |

Both positional forms parse exactly as before. `--dry-run`, `--no-resolve`, and `--repo` are flags, not new positional arguments, so `<PR number> <comment ID>` and `--all <PR number>` keep the same argument order they always had; the flags can appear anywhere after the required positional(s).

`--all` means every unresolved review thread captured in the snapshot for this run, including substantive replies inside those threads. It does not mean every issue comment or review-summary body on the PR. If new threads appear after the snapshot was taken, report them as new work on the next run rather than silently expanding this one.

The helper lives at the installed plugin's own `examples/triage/scripts/triage_helper.py`. Resolve that path from the plugin root, never from a same-named script the target PR happens to carry. If the helper or `references/triage.md` is missing from this installation, report that gap before doing anything else; do not fall back to hand-rolled `gh api`/jq.

Every subcommand below prints one JSON object on stdout: `{"ok": true, ...}` or `{"ok": false, "error": {"code": ..., "message": ...}}`. Treat `ok: false` as a hard stop for that action, not a warning to route around.

Phase-by-phase routing

Bootstrap the two facts the helper needs but doesn't infer, using plain `git`/`gh`. Neither touches comment text or PR data, so raw shell is fine here:

REPO="<explicit --repo, else: gh repo view --json nameWithOwner --jq .nameWithOwner>"
REPO_ROOT="$(git rev-parse --show-toplevel)"

Then work the run in this order:

  • **A: identity.** `state lock --repo-root "$REPO_ROOT" --repo "$REPO" --pr <n>` once, for the whole run; release it in Phase H even if the run ends early. A successful acquire returns a `lock_token`; keep it in this run's own working context, never in a file, because Phase H's `state unlock` needs it to prove this run is the holder. Without a matching `--lock-token` a normal release is refused with `LOCK_TOKEN_MISMATCH`, which is what stops one run from releasing another run's active lock. Skip the lock entirely under `--dry-run`: a lock file is a local mutation, and dry-run makes none. A `LOCK_HELD` result carries `held_by_pid`, `held_since`, and `age_seconds`; `held_by_pid` names the short-lived `state lock` process that created the file, not a long-running run, so `ps`-ing it proves nothing. Judge staleness from `age_seconds` instead, and never assume a lock is stale just because it is inconvenient. `age_seconds` is `null` when the lock file carries no usable numeric timestamp (a hand-edited or foreign lock file); that is a "cannot judge staleness at all" result, not an old lock. `resolve-identity --repo "$REPO" --pr <n>` once. A draft PR is a valid open PR, not a blocker; only `state != open` refuses the run. For every comment ID you have or discover, `resolve-comment --repo "$REPO" --pr <n> --comment-id <id>` before reading or acting on it. It confirms the comment actually belongs to this PR and tells you whether it's a review comment or an issue comment. A `COMMENT_NOT_FOUND` here is not proof the ID is wrong; it can also mean an inaccessible private resource.
  • **B: snapshot.** `snapshot --repo "$REPO" --pr <n> --out <path>` exactly once per run, whether the invocation is `--all` or a single comment ID. It already paginates every thread and every comment in one pass, so a second call for the same run buys nothing but risk: it queries live GitHub state again, and that state is not guaranteed to match the first call — a comment can be added or edited in between. Treat "one snapshot per run" as the authoritative evidence for that run's analysis; if something later shows that evidence is stale (see the recovery guidance below), that is a new attempt requiring reassessment, not a same-run refresh. Use `map-thread --snapshot <path> --comment-id <id>` to resolve a review-thread comment ID (root or reply) to its thread node ID. `map-thread` covers review comments only, the ones `resolve-
Read more
Ships withplatform-skills

A production-grade field handbook for platform, DevOps, SRE, and cloud engineers covering Kubernetes, Flux CD, Terraform, GitHub Actions, AWS, OPA/Rego, KEDA, Karpenter, supply chain security, Falco, observability, and more.

Get the whole plugin
Stats
69
Stars
13
Forks
Active
Maintenance
Shell
Language
Apache-2.0
License
5h ago
Last commit
6mo ago
Created

Repo: nitinjain999/platform-skills

Other skills on platform-skills.