anthropics/defending-code-reference-harness3 files

Triage

Triage a batch of raw security findings. Verify each is real,

Specification
Skill ID
anthropics/defending-code-reference-harness/triage
Publisher
anthropics
Repository
defending-code-reference-harness
Installs
0
Files
3
Synced
Sep 23, 2026
How to use it

Open any RiverX project, open the Skills panel in the chat, and search for this identifier. The files are fetched from the source repository at install time.

anthropics/defending-code-reference-harness/triageInstalls these files
  • README.md
  • SKILL.md
  • fixtures/canary-findings.json

What this skill tells the agent

triage

Adversarial triage of raw security-scanner output. Does four jobs: verify each finding is real, deduplicate across runs and scanners, rank survivors by derived exploitability rather than the scanner's claimed severity, and route each to a component owner. Output is a short, ranked, owned list instead of a raw dump.

Invoke with /triage <findings-path> [--auto] [--votes N] [--repo PATH] [--fp-rules FILE].

Arguments (parse from $ARGUMENTS; positional $1/$2 expansion is not stable across runtimes):

  • findings path (first positional, required): a JSON file, a directory of JSON files, a VULN-FINDINGS.json, an INCIDENTS.json, a pipeline results/<target>/<ts>/ directory, or a markdown report.
  • --auto: skip the interview and use defaults. Default mode is interactive.
  • --votes N: verifier votes per finding (default 3; use 1 for a quick pass, 5 for high-stakes batches).
  • --repo PATH: path to the target codebase, read-only (default cwd). Verification needs source access; the skill stops with an error if the cited files aren't reachable.
  • --fp-rules FILE: append the contents of FILE to the verifier's exclusion-rule list (Phase 3a). Use for org-specific precedents: "we use Prisma ORM everywhere — raw-query SQLi only", "k8s resource limits cover DoS", etc. Plain text, one rule per line or paragraph.
  • --fresh: ignore any existing checkpoint in ./.triage-state/ and start from Phase 0. Without this flag the skill resumes from the last completed phase if a checkpoint is present.

Tools: Read, Glob, Grep, Write, Task, AskUserQuestion. Bash is permitted only for git, find, wc, ls, jq, and python3 .claude/skills/_lib/checkpoint.py (checkpoint I/O).

Do not execute target code. No building, running, installing dependencies, or sending requests. A proof-of-concept that accidentally works against something real is unacceptable, and "couldn't write a working PoC" is weak evidence of non-exploitability. Every conclusion comes from reading source. This applies to the orchestrator and every subagent; include the constraint in every Task prompt. For high-confidence HIGH findings, recommend a human-built PoC as a follow-up instead.

Do not reach the network. No package-registry lookups, CVE-database queries, or upstream-commit fetches.


Checkpointing (runs before Phase 0 and after every phase)

On large finding batches a full run can exhaust context or hit rate limits mid-way — particularly Phase 3, which spawns candidates × votes verifiers. Phase state persists to ./.triage-state/ so a fresh /triage session can resume without re-asking the interview or re-spawning verifiers.

All checkpoint I/O goes through python3 .claude/skills/_lib/checkpoint.py (atomic writes, JSON-validated). Never use the Write tool for progress.json directly. Never pass payload via heredoc or stdin; target-derived strings could collide with the heredoc delimiter and break out to shell. The Write→--from pattern keeps repo-derived bytes out of Bash argv.

State files in ./.triage-state/:

  • progress.json — single source of truth for resume position: {"status": "running"|"complete", "phase_done": N, "shards_done": [...]}. Resume decisions read ONLY this file, never a glob of phase*.json or shard files (stale files from a prior run must not be trusted).
  • phaseN.json — data payload for phase N (schemas at the tail of each phase section below).
  • _chunk.tmp — transient payload buffer; overwritten before every save/shard/append call.

Start of run — resume check. Bash: python3 .claude/skills/_lib/checkpoint.py load ./.triage-state

  • status == "absent" OR "complete", OR --fresh in $ARGUMENTS → fresh start. Bash: python3 .claude/skills/_lib/checkpoint.py reset ./.triage-state, then proceed to Phase 0.
  • status == "running" with phase_done == N → resume. Read ./.triage-state/phase0.json through phaseN.json in order (and any shard_*.json files listed in shards_done), merging keys into working state (later files override earlier — checkpoints may be deltas). Print Resuming from checkpoint: Phase N complete (./.triage-state/phaseN.json), and skip directly to Phase N+1.

End of every phase N. Two tool calls:

  1. Write tool → ./.triage-state/_chunk.tmp containing the phase's output JSON (schema at the tail of each phase section).
  2. Bash → python3 .claude/skills/_lib/checkpoint.py save ./.triage-state <N> <name> --from ./.triage-state/_chunk.tmp

End of run. After writing TRIAGE.json and TRIAGE.md, Bash: python3 .claude/skills/_lib/checkpoint.py done ./.triage-state 6


Phase 0: Mode select and interview

0a. Parse arguments

From $ARGUMENTS: extract the findings path (first positional), --auto flag, --votes N (default 3), --repo PATH (default .), --fp-rules FILE (default none). If no findings path was given, ask for one and stop. If --fp-rules was given, Read the file now and carry its contents as context.extra_fp_rules for injection into the Phase 3a verifier prompt.

0b. Interactive mode (default): interview the user

Unless --auto was passed, use AskUserQuestion to gather context that shapes verification and ranking. Batch into one or two calls of up to four questions. Expect free-text answers via "Other"; the multiple-choice options are prompts, not constraints.

Round 1 (single AskUserQuestion call):

  1. Environment & trust boundary (header Environment, single-select) What kind of system are these findings from, and where does untrusted input enter it? Options: Internet-facing web service (HTTP is untrusted), Internal service (callers are authenticated peers), Library / SDK (caller is the trust boundary), CLI / batch tool (operator inputs trusted, file inputs not), Embedded / firmware (physical access in scope). Reachability is judged against this boundary; "command injection from env var" is a true positive in a multi-tenant web service and a rule-8 false positive in an operator CLI.
  1. Threat model (header Threat model, multi-select) What does a worst-case attacker look like for this system, and what must never happen? Free text is best. Options: Unauthenticated remote code execution, Tenant-to-tenant data leakage, Privilege escalation to admin, Supply-chain compromise of downstream users, Denial of service against a paid SLA, Compliance-scoped data exposure (PII / PCI / PHI). Phase 4 boosts findings that map onto a stated threat.
  1. Scoring standard (header Scoring, single-select) How should severity be expressed in the output? Options: Derived HIGH/MEDIUM/LOW from preconditions (default), CVSS v3.1 vector + base score, CVSS v4.0 vector + base score, OWASP Risk Rating (likelihood x impact), Organization bug-bar (describe in Other). The precondition rule is always computed; this controls what severity_label additionally shows.
  1. Noise tolerance (header Noise tolerance, single-select) When verifiers disagree, which way should ties break? Options: Precision: drop anything not majority-confirmed (fewer FPs, may miss real bugs), Recall: keep split votes as needs_manual_test (more to review, fewer misses), Ask me per-finding when it happens.

Round 2 (conditional): if the threat-model answer was empty or generic, or the scoring answer was Organization bug-bar, ask one targeted follow-up.

Record the answers as a context dict carried through every phase and echoed in the output under triage_context.

0c. Auto mode defaults

When --auto is set, do not call AskUserQuestion. Use:

  • Environment: Unknown. Treat any externally-reachable entry point as untrusted; flag trust-boundary assumptions explicitly in rationale.
  • Threat model: empty (no boost).

Use this skill in a project

Open any RiverX project, search the Skills panel for anthropics/defending-code-reference-harness/triage, and install it in one click.

Use this skill