agentsclimarketplace

Triage

Skill robzilla1738/roberts-skills/plugins/bughunt-suite/skills/triage

Provider-agnostic agent skills and plugins for AI coding assistants. By Robert Courson.

Install
npx -y skills add robzilla1738/roberts-skills --skill triage

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 5 stars5 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Triage a suspected bug or a set of findings into a ranked, evidence-backed report: assign severity and confidence, build a minimal reproduction or failing test, and emit the standard finding schema (markdown + JSON). Use when the user invokes /triage, hands you a crash or suspicious behavior to assess, or when bughunt needs to score, prove, baseline-diff, and report findings.

SKILL.md

12.0 KB, as published. Nobody here has run it

Triage & Repro

Companion skill that converts raw suspicion into a precise, ranked, evidence-backed report. It owns the finding schema, the severity × confidence model, and the discipline of building a minimal reproduction before anything is called Confirmed.

Use it standalone on a single suspected bug, or as the scoring/reporting stage of bughunt.

First principle: evidence or it didn't happen

A finding is a claim that specific code does the wrong thing under a specific condition. Every finding must carry:

  • Locationfile:line (the exact site, not "somewhere in this module").
  • Trace — the data/control path from cause to effect.
  • Trigger — the concrete condition or input that makes it fire.
  • Impact — what actually goes wrong (crash, corruption, wrong result, leak, exposure).

If you cannot state all four, the item is a question, not a finding. Demote it or investigate further. A short list of real bugs beats a long list of maybes — noise destroys trust in the report.

Severity rubric

Rate impact if triggered, independent of how likely it is.

SeverityMeaning
CriticalData loss/corruption, RCE, auth bypass, secret disclosure, crash on common path
HighWrong result users rely on, privilege issue, leak/exhaustion under normal load, crash on a real edge
MediumIncorrect behavior on an uncommon-but-reachable path; degraded reliability; recoverable
LowMinor correctness/robustness issue, narrow edge, cosmetic-but-wrong

Impact rubric (what "severity" means per finding class)

bughunt hunts more than security bugs. A finding's impactClass tells you which yardstick to hold its severity against, so a pain-point or inefficiency isn't force-fit into a security frame (and isn't dismissed because it isn't a CVE). Same four severity levels, calibrated per class:

impactClassWhat Critical/High looks like hereWhat Low looks like
securityauth bypass, RCE, secret/PII disclosure, injection on a reachable paththeoretical issue behind strong guards
correctnesswrong result users act on; silent data divergencewrong only on a contrived edge
reliabilitycrash/hang/outage under normal load; fail-opendegrades only under rare conditions
performanceO(n²)/N+1/unbounded growth that breaks at real scaleconstant-factor waste on a cold path
data-integritydestructive/irreversible migration, corruption, lost writesrecoverable, narrow-window skew
dxbroken build/test, footgun that routinely costs dev hoursstale TODO, cosmetic friction
uxuser can't recover (white screen, silent failure, double-charge)minor polish / missing affordance
supply-chainknown-vulnerable/typosquat dep on a reachable pathunpinned but low-risk dev dep

Score by user/operator/developer impact, not by how clever the bug is. A High-severity DX or UX finding is legitimate and belongs above a Low-severity security nit.

Confidence rubric

Rate how sure you are it's real, independent of severity.

ConfidenceBar to clear
ConfirmedReproduced — a failing test, a runtime repro, or an unambiguous trace with no plausible guard
ProbableStrong static evidence; you traced it end to end but did not execute it
SpeculativePattern looks wrong but a guard, invariant, or caller you can't see might save it

Speculative findings are quarantined in their own section, never mixed with Confirmed or Probable findings. A verified.verdict of uncertain is always Speculative after merge. When a defect is independently flagged by two different lenses, raise its confidence one step (cross-validation).

Building a minimal reproduction

For every Critical/High finding, try to produce proof, cheapest first:

  1. Failing unit/property test — preferred; it's a regression guard the team can keep. Use the project's existing test runner and conventions.
  2. Runtime repro — drive the real app/CLI to the failure. Hand off to the verify skill (/verify) when the bug only shows at runtime.
  3. Traced argument — when neither is feasible (e.g. requires prod data), write the exact step-by-step trace with concrete values so a human can reproduce in minutes.

Minimize: strip the repro to the smallest input and fewest steps that still fail. Note what you could not reproduce and why — never imply proof you don't have.

Filtering false positives

Before reporting, attack your own finding:

  • Is there a guard, early return, type constraint, or invariant upstream that prevents it?
  • Is the "untrusted" input actually trusted/validated at the boundary?
  • Does a test already cover this path passing?
  • Is this intended behavior documented somewhere?

If the finding survives, report it. If it dies, drop it (or demote to Speculative with the caveat stated).

Finding schema

Each finding has two equivalent shapes: the markdown block below (what humans read) and a JSON object (what the toolkit dedupes, fingerprints, baselines, and exports). They are the same finding — bughunt.py render produces the markdown from the JSON, so you can author either. The JSON contract lives at bughunt/scripts/schema/finding.schema.json; see the toolkit.

Emit each finding in this exact markdown shape so reports are scannable and mergeable:

### [SEV-CONF] <short title>
- **ID:** BH-001
- **Location:** path/to/file.ext:142
- **Lens:** concurrency            <!-- which discipline surfaced it -->
- **Severity:** High
- **Confidence:** Probable
- **Trigger:** <the condition/input that fires it>
- **Trace:** <cause -> ... -> effect, with file:line hops>
- **Impact:** <what goes wrong>
- **Repro:** <failing test / runtime steps / traced values, or "not reproduced: why">
- **Fix sketch:** <one or two lines; the direction, not a full patch>

SEV-CONF tag examples: [Critical-Confirmed], [High-Probable], [Low-Speculative].

JSON ⇄ label mapping. In JSON, confidence is a float 0.0–1.0; the label you show is derived (≥0.85 → Confirmed, ≥0.5 → Probable, else Speculative). Set impactClass (see the impact rubric) so non-security findings sort correctly. Candidate JSON does not need an id; bughunt.py merge assigns/renumbers IDs and fingerprints. The mandatory verify pass records its result in verified.verdict (upheld/refuted/uncertain); merge quarantines refuted findings into a report appendix and caps uncertain findings to Speculative. You do not fingerprint, dedupe, or cluster by hand — merge owns that, including collapsing the same bug seen by multiple lenses into one finding with an alsoFlaggedBy list. See verification.md and orchestration.md.

Report layout

This is the canonical report bughunt produces and what /triage emits for a set:

# Bug report — <target> — <date>

## Summary
<N findings: X critical, Y high, Z medium, W low. K confirmed, ... One-line headline.>

## Baseline diff            <!-- only when a baseline exists; from `bughunt.py merge` -->
<N new, M fixed, K suppressed since the last baselined run. List the fixed ones.>

## Confirmed & Probable findings
<findings, sorted by severity then confidence, using the schema above>

## Speculative (needs a human eye)
<lower-confidence items, clearly separated>

## Refuted (appendix)       <!-- candidates the verify pass killed; transparency only -->
<title, location, and why it was refuted>

## Coverage & gaps
<what was hunted (lenses x areas), what was NOT examined and why>

## Recommended next step
<e.g. "fix BH-001/BH-003 then run /review (autoreview)">

bughunt.py render emits exactly this layout from the merged findings JSON (Baseline diff and Refuted sections appear only when there's something to show). Single-bug /triage runs skip the multi-finding sections and emit one finding plus its repro.

Worked example

A filled-in finding (note the concrete evidence and the failing test as repro):

### [High-Confirmed] IDOR: any user can read any invoice
- **ID:** BH-001
- **Location:** routes/invoices.js:42
- **Lens:** auth-access
- **Severity:** High
- **Confidence:** Confirmed
- **Trigger:** authenticated user requests GET /invoices/:id with another user's id
- **Trace:** route handler reads `req.params.id` (routes/invoices.js:42) → `Invoice.findById(id)`
  (db/invoices.js:18) → returns row with no `WHERE user_id = req.user.id` filter
- **Impact:** horizontal privilege escalation — full read of any customer's invoice data
- **Repro:** test "user A cannot read user B's invoice" — log in as A, GET /invoices/{B's id},
  expect 403/404, actual 200 with B's data (tests/invoices.idor.test.js)
- **Fix sketch:** scope the query to the caller (`WHERE id = ? AND user_id = ?`) or assert ownership

And a small report assembled from a hunt:

# Bug report — billing-service — 2026-06-06

## Summary
3 findings: 0 critical, 2 high, 1 medium. 1 confirmed, 2 probable.
Headline: an IDOR exposes all invoices; discount math overcharges.

## Confirmed & Probable findings
### [High-Confirmed] IDOR: any user can read any invoice
... (as above) ...

### [High-Probable] Discount applied after tax → wrong total
- **ID:** BH-002 · **Location:** lib/pricing.js:67 · **Lens:** logic-correctness
- **Trigger:** any order with a discount code
- **Trace:** `applyTax()` runs before `applyDiscount()`; discount taken on the taxed amount
- **Impact:** customers overcharged; totals disagree with quoted price
- **Repro:** subtotal=100, tax=10%, discount=10% → expected 90.00, got 99.00
- **Fix sketch:** apply discount to subtotal before tax

### [Medium-Probable] N+1 query loading invoice line items
- **ID:** BH-003 · **Location:** db/invoices.js:55 · **Lens:** resource-performance
- **Trigger:** listing an invoice with many line items
- **Trace:** loops rows issuing one SELECT per line item instead of a join/batch
- **Impact:** latency grows linearly with line items; slow under load
- **Repro:** invoice with 200 items → 201 queries (query log)
- **Fix sketch:** single join or batched `IN (...)`

## Speculative (needs a human eye)
- None.

## Coverage & gaps
Hunted: auth-access, taint, logic-correctness, resource-performance over routes/invoices.js,
lib/pricing.js, db/invoices.js. Not examined: the admin console, background jobs.

## Recommended next step
Fix BH-001 and BH-002 first, then run `/review` (autoreview) before merging.

Report-only by default

Triage assesses and proves; it does not edit product code (beyond writing a repro/test when asked). To fix, hand off to the human or to the autoreview skill (/review).

Related skills

  • bughunt — the orchestrator that feeds findings here
  • fuzz — generate a harness to turn a Probable finding into Confirmed
  • the autoreview skill (/review) — the fix/quality gate after findings are accepted
  • verify / /verify — drive the real app to reproduce a runtime-only bug

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.