pm-triage
Use this skill to triage a raw or untriaged issue — one that lacks a type tag, an execution-mode label, or template structure — and turn it into workable, labeled, reviewed work. pm-triage orchestrates classification (pm-templates), structural review (pm-review), and enrichment (pm-improve), then applies the type and hitl/afk labels on the operator's confirmation, and hands the now-workable issue off to pm-organize so it leaves the Triage state instead of parking there. It is the action counterpart to pm-status's triage view. Trigger whenever the user says "triage this issue", "triage NTH-42", "triage the backlog", "clean up untriaged issues", "what needs triage", "/pm-triage", or when pm-status has just surfaced Untriaged / Unknown-tag / Needs-info buckets and the operator wants to act on them. Also use it proactively after a pm-status briefing flags untriaged work, and whenever an issue clearly needs labels plus a structural pass before it can be picked up — even if the user never says the word "triage".
What this skill does
# PM Triage
Take a raw or untriaged issue and make it workable. pm-triage is the **action counterpart to the triage *view*** that `pm-status` renders: pm-status *finds* what needs triage (the Untriaged / Unknown-tag / Needs-info buckets); pm-triage *performs* it.
## Usage
```
/pm-triage [<issue-id>]
```
- `<issue-id>` *(issue key e.g. `FUNC-12`, optional)* — the issue to triage; omit to work the whole triage backlog.
Writes are confirmation-gated: the type + `hitl`/`afk` labels (and any enrichment comment) are applied only on the operator's confirmation.
It does that by orchestrating three skills that already exist — it does not reimplement them:
- `pm-templates` — classify the issue's type tag
- `pm-review` — structural check against that tag's template
- `pm-improve` — enrichment (repo context, related issues, clarifying questions)
…and then it adds the one thing none of those three do: on the operator's confirmation, it **applies the triage decision** — the type-tag label and the `hitl`/`afk` execution-mode label — so the issue actually leaves the untriaged state. (`pm-review` only *flags* a missing execution-mode label; `pm-improve` only posts a comment. Neither labels the issue. That gap is pm-triage's reason to exist.)
## When to use this
- An issue is raw — filed by a stakeholder, auto-mirrored from GitHub, or filed in a hurry — and lacks a type tag, an execution-mode label, or template structure.
- `pm-status` surfaced a triage bucket and the operator wants to act on it.
- The operator says "triage this issue", "triage NTH-42", "clean up the triage backlog", "/pm-triage".
**When not to use it.** If the issue is already tagged, labeled, and structured, there is nothing to triage — running pm-triage just produces noise. If the operator wants *only* a structural review, that is `pm-review`; *only* enrichment, that is `pm-improve`. pm-triage is the bundle — reach for it when you want the whole pass, not one slice.
## The triage pipeline (one issue)
Steps 1-6 are read-only and run without confirmation — they cost nothing but tokens, and the operator needs the whole proposal before deciding anything. Step 7 applies the labels (always confirmed). Step 8 hands the now-workable issue off to `pm-organize` so it leaves the Triage state — also confirmed, and routed entirely through `pm-organize`'s existing write path (pm-triage adds no new write codepath of its own).
### Step 1: Fetch the issue
Read it from the tracker — the same fetch `pm-review` uses (`linear issue view <ID> --json` / `gh issue view <NUM> --repo <org/repo> --json ...`). If the tracker is unreachable, stop with a transport error; do not triage from cached state — the cache can carry stale labels, and triage decisions hinge on the current label set.
### Step 2: Classify the type tag
Delegate to `pm-templates`' classifier (the logic lives there — do not duplicate it). It resolves in order: an explicit `[tag]` title prefix → a tracker label that maps to a manifest tag → inference from the body against each tag's `description`.
The classification result determines the path:
- **Explicit or label-matched** → the tag is firm; continue.
- **Inferred** → a *soft* classification. Surface it — "I read this as a `bug`; confirm or correct" — and wait. Everything downstream (which template `pm-review` checks against, which enrichment streams `pm-improve` weights) depends on the tag being right, so a wrong guess wastes the whole pass.
- **A tag-shaped signal that is not in the manifest** (e.g. a `[migration]` prefix, but the project's manifest has no `migration` tag) → this is the *Unknown-tag* case. Do not invent a tag. Surface it as a taxonomy decision: register the tag via `pm-templates`, or re-classify the issue under an existing tag. pm-triage stops here for this issue until the operator decides.
- **No signal at all** → propose the best-fit tag from the manifest descriptions and confirm before continuing.
### Step 3: Structural review
Run `pm-review` against the issue at the classified tag. Capture its findings — which required sections are present, missing, or placeholder-only; whether the acceptance criteria are testable.
pm-triage does **not** rewrite the body to close those gaps. Carry the gap list into the proposal instead — the operator decides which gaps to fill, and fills them by editing the issue (a `pm-issues` update) or by answering the clarifying questions from the next step. Auto-rewriting someone's issue body is a surprise; reporting what is missing is a service.
### Step 4: Enrichment
Run `pm-improve` against the issue. Capture its enrichment draft — repo context, related issues, clarifying questions. Hold it as a *proposed comment*; do not post it yet.
### Step 5: Propose an execution mode
Every workable issue carries a `hitl` (human-in-the-loop) or `afk` (agent-runnable) label. `pm-review` deliberately refuses to guess this for an existing issue — and it is right not to, because a silent guess that lands wrong routes work to the wrong queue.
pm-triage's job is to *propose*, not to guess silently. Start from the tag's `hitl_default_hint` in the manifest, then adjust for what the issue actually says:
- Needs manual verification, a design decision, or UX judgment → `hitl`.
- Well-specified, mechanically checkable, no judgment call → `afk`.
Present the proposal **with its reason** so the operator can correct it in one word. The reason is what makes the proposal reviewable instead of a coin flip.
### Step 6: Assemble the triage proposal
Combine Steps 2-5 into one proposal (format below) — one screen with everything the operator needs to say yes or adjust.
### Step 7: Confirm and apply
Show the proposal. On the operator's confirmation:
- **Apply the labels.** Add the type-tag label (the canonical/first entry from the manifest's `labels.<tracker>`) and the chosen `hitl`/`afk` label to the issue:
- Linear: `node "$CLAUDE_PLUGIN_ROOT/hooks/bin/pm-issue.js" update --id <ID> --add-label "<type>" --add-label "<hitl|afk>"`
The verb fetches existing labels via GraphQL, merges (idempotent on both add and remove), and writes the union back in one call. Do **not** call `linear issue update --label` directly — its `--label` flag is replace-semantics, not add-semantics, and any labels not explicitly listed are silently dropped (NTH-511).
- GitHub: `gh issue edit <NUM> --repo <org/repo> --add-label "<type>" --add-label "<hitl|afk>"`
`gh` has native add/remove flags, so the raw CLI is safe here.
- If a label does not exist in the tracker yet, create it first (`linear label create -n <name>` / `gh label create <name>`) — a label named in the manifest but absent from the tracker matches nothing.
- **Offer the enrichment comment separately.** Posting the `pm-improve` draft as a comment is a second, distinct write — ask for it on its own ("post the enrichment as a comment on <ID>?"), because the operator may want the labels without the comment.
- **Verify the apply landed (optional, Linear only).** If verification is needed, run `node "$CLAUDE_PLUGIN_ROOT/hooks/bin/pm-cache.js" verify-issue --slug <slug> --id <ID>` — it fetches fresh state via GraphQL, compares to the cache, and reports any divergence. Add `--update` to also merge the fresh state back so the next briefing sees it without a full delta-sync.
For a single issue, one confirmation covers the labels and the enrichment comment is its own yes/no. For a batch, see below.
> Label application on Linear MUST go through `pm-issue.js update` (NTH-511, landed in 0.28.0). The verb wraps the fetch+merge so the replace-semantics of `linear issue update --label` can't accidentally drop labels. GitHub's `gh issue edit --add-label/--remove-label` are add/remove-semantics natively, so the raw `gh` call is fine.
### Step 8: Hand off to pm-organize
Labeling makes the issue *workable*. It does not move it out of the tracker's **Triage** state — without this step the issue stays parked in Triage even thoughRelated in Code Review
gstack
IncludedFast headless browser for QA testing and site dogfooding. Navigate pages, interact with elements, verify state, diff before/after, take annotated screenshots, test responsive layouts, forms, uploads, dialogs, and capture bug evidence. Use when asked to open or test a site, verify a deployment, dogfood a user flow, or file a bug with screenshots. (gstack)
startup-due-diligence
IncludedLegal due diligence review for seed-stage and Series A startups (US, Delaware C-Corp focus). Supports both investor and founder perspectives. Capabilities include: (1) Interactive document review and issue spotting; (2) Document request list generation; (3) Cap table and SAFE/convertible note analysis; (4) Red flag identification with severity ratings; (5) Diligence report generation. TRIGGERS: due diligence, DD, startup investment, cap table review, Series A, seed round, investor diligence, legal review startup, SAFE analysis, convertible note, 409A, founder vesting.
interview-master
IncludedThis skill should be used when the user asks to "generate interview questions", "prepare for interview", "optimize resume", "conduct mock interview", "analyze git commits for resume", "generate resume from code", "review my resume", or mentions interview preparation, career assistance, or extracting project experience from git history. Provides comprehensive interview and career development guidance for both job seekers and interviewers.
fix-issue
IncludedFixes GitHub issues using parallel analysis agents for root cause investigation, code exploration, and regression detection. Reads issue context from gh CLI, searches codebase and memory for related patterns, generates a fix with tests, and links the resolution back to the issue via PR. Includes prevention analysis to avoid recurrence. Use when debugging errors, resolving regressions, fixing bugs, or triaging issues.
sf-apex
IncludedGenerates and reviews Salesforce Apex code with 150-point scoring. TRIGGER when: user writes, reviews, or fixes Apex classes, triggers, test classes, batch/queueable/schedulable jobs, or touches .cls/.trigger files. DO NOT TRIGGER when: LWC JavaScript (use sf-lwc), Flow XML (use sf-flow), SOQL-only queries (use sf-soql), or non-Salesforce code.
swift-development
IncludedComprehensive Swift development for building, testing, and deploying iOS/macOS applications. Use when Claude needs to: (1) Build Swift packages or Xcode projects from command line, (2) Run tests with XCTest or Swift Testing framework, (3) Manage iOS simulators with simctl, (4) Handle code signing, provisioning profiles, and app distribution, (5) Format or lint Swift code with SwiftFormat/SwiftLint, (6) Work with Swift Package Manager (SPM), (7) Implement Swift 6 concurrency patterns (async/await, actors, Sendable), (8) Create SwiftUI views with MVVM architecture, (9) Set up Core Data or SwiftData persistence, or any other Swift/iOS/macOS development tasks.