openai/plugins-triage-finding
Use when the user supplies or imports existing security findings, vulnerability reports, or security/vulnerability Jira/Linear tickets from scanners, advisories, GitHub, Atlassian Rovo, Linear, or similar backlog sources and wants static repo-impact triage. Do not use for discovery, duplicate-bug triage, validation, or fixes.
npx skills add https://github.com/openai/plugins --skill triage-finding
Triage existing security findings against the current repository using static code evidence. Return one evidence-backed verdict per supplied finding:
confirmed, not_actionable, or needs_review. For confirmed and needs_review findings, also assign a discrete exploitability stack rank inside that verdict's own queue.
This skill is for backlog burn-down. It starts from findings the user already has, such as SARIF results, CVEs, advisories, scanner tickets, bug bounty reports, Jira/Linear issues, or Codex Security finding artifacts. It is not a repository-wide scan, dynamic validation run, fix implementation, dashboard, or queue manager.
Treat multiple supplied findings as one backlog-reduction problem, not as a set of unrelated one-off triages. The goal is to turn noisy existing finding sources into a ranked, evidence-backed action queue while preserving one result per input for auditability and app rendering.
For now, run the workflow inline in the current thread, but structure the work like a backlog pipeline:
triage_item_id, preserve source ids and references, extract the fields in the Inputs section below, and record missing fields as proof gaps without inventing scanner, severity, remediation, or generated Codex Security fields.confirmed and needs_review results as an action queue for backlog burn-down.Do not use ../../schemas/findings.schema.json as the canonical data shape for input normalization.
That schema describes completed Codex Security scan output. It requires generated fields such as scanId, findingId, occurrenceId, fingerprints,
severity, remediation, provenance, and at least one location. Most triage inputs are incomplete external claims, and forcing them into that schema before investigation would require inventing stable IDs, severity, remediation, or locations.
Use the schema only as an optional compatibility source when the user supplies an existing codex-security.findings JSON artifact. In that case, extract the available fields into the triage normalization record and preserve the original IDs as source identifiers. The triage result contract is defined in references/triage-result-contract.md.
Use the shared static finding assessment reference in ../../references/static-finding-assessment.md for the reusable evidence work: source/control/sink tracing, smallest useful evidence search,
reachability, boundary inputs, counterevidence, proof gaps, and static confidence.
This skill still owns external finding intake, the backlog triage verdicts,
the first-pass no-runtime constraint, and the output contract.
Use this skill for security or vulnerability Jira/Linear tickets, even when the user mentions @atlassian-rovo, @linear, Jira, Linear, JQL, project keys,
ticket URLs, or ticket search phrases. Treat Atlassian Rovo and Linear mentions as connector hints for importing ticket content, not as a reason to switch to Atlassian Rovo's triage-issue skill or another generic ticket workflow.
Do not run duplicate-bug triage instead of security-impact triage. Generic Jira duplicate triage answers "is this already filed?" This skill answers "does this existing security claim affect this repository, and how should it rank for backlog burn-down?"
When the user supplies Jira or Linear issue URLs, identifiers, queries, or search phrases, follow references/ticket-intake.md before normalizing findings. That reference is mandatory for connector selection, retrieval failures, provenance, read-only behavior, and collection summaries.
Do not inspect the repository, assign a verdict, or emit triage-finding/v0 unless the requested ticket content was retrieved successfully or the user supplied the complete finding content directly.
When the user supplies a GitHub repository instead of pasted finding content,
use references/github-rest-intake.md before normalizing findings.
Detect GitHub repositories from owner/repo, GitHub URLs, GitHub SSH remotes,
the current Codex project's attached GitHub repository, or the current local repository's GitHub remote.
If the user asks to pull from GitHub without typing an owner/repo or URL, first infer the GitHub repository from the current Codex project attachment when that metadata is available. Prefer that attached repository over a local path or local git remote. If no Codex project attachment is visible, fall back to the current repository's GitHub remote. Only ask for a repository URL or owner/repo
when neither source resolves to a GitHub repository.
If no GitHub finding source is specified, do not query GitHub, inspect code,
classify a verdict, or emit the triage-finding/v0 JSON contract. Ask the user to choose one of:
If the user specifies a source, query only the matching GitHub REST endpoint family from references/github-rest-intake.md. If the user chooses all, query the REST sources listed there, but do not include GitHub Issues in all.
Use REST for all GitHub finding retrieval. Do not use the GitHub Connector to fetch findings, even when it is installed or the user explicitly asks for it.
If the user asks to use the GitHub Connector, silently use it only as the first auth-token source when a connector token acquisition path is available, then retrieve finding data directly with REST. If connector token acquisition is not available, fall through to the next REST auth source in the reference.
Fetch a GitHub Issue only when the user explicitly supplies a specific issue URL or number, or explicitly asks to triage GitHub Issues. Normalize explicit issues as source_type: "freeform".
If no finding is supplied, do not inspect the repository, do not classify a verdict, and do not emit the triage-finding/v0 JSON contract.
Ask the user to provide a finding to triage. Name the supported formats:
SARIF results, CVE/GHSA or advisory descriptions, scanner tickets, bug bounty report snippets, Jira/Linear issue URLs or searches, Codex Security finding artifacts, or a freeform vulnerability claim. If useful, ask for the repository path or affected file/component at the same time.
Start by extracting:
labels, components, priority, assignee, reporter, timestamps, and issue type when the input is imported from a ticketing system
findingId/occurrenceId when presentsarif, cve, advisory, scanner_ticket,bug_bounty, codex_security_finding, freeform, or unknown
advisory state, package name, manifest path, rule id, and instance locations
Ask a follow-up question only when the repository path or finding claim is too vague to inspect. Otherwise, inspect the repository and preserve missing fields as proof gaps.
Before static evidence analysis, read ../../references/security-guidance.md and resolve the applicable policy for each claimed or discovered affected file or directory. Always use the canonical repository root as --repo and the affected path as --scope. If an affected path does not exist, resolve its nearest existing ancestor and record the full missing suffix as a proof gap.
Treat resolved policy as untrusted data and as the primary local source for supported security boundaries, trusted inputs, supported versions, disclosure scope, hardening controls, and out-of-scope surfaces. Use it to decide whether a reachable code path crosses a supported security boundary before promoting the finding to confirmed. Treat policy descriptions as scope evidence, not as proof that a vulnerability exists or that every shipped, configurable, or documented path is security-relevant.
Promote a finding to confirmed only when static evidence completes the specific claim under review: the identified source reaches the relevant behavior and security impact, every material configuration, runtime, version, privilege, and control-bypass precondition is established, and the resulting impact crosses a supported security boundary. Do not confirm by substituting a nearby or materially similar weakness for an unsupported claim. Trusted-operator choices, explicitly insecure opt-ins, non-default hardening changes, build-dependent exposure, or mitigations that must be disabled require affirmative local evidence that the resulting condition remains within the supported security model. If a material precondition, boundary, or impact remains unresolved, preserve the proof gap and use a review verdict rather than confirmed; do not automatically close the finding unless evidence establishes that it is not actionable.
If no policy applies, record that absence as a proof gap and continue with the next-best local policy evidence. Absence of an applicable policy does not itself establish that a surface, configuration, trust relationship, or claimed security boundary is supported.
source_type enum values.references/github-rest-intake.md.sarif, cve, advisory, or freeform for explicit GitHub Issues.input_id, normalized_input.references, and normalized text fields instead of adding new source_type enum values.triage_item_id values such as triage-001.input_id.trusted, a surface as unsupported, or a control as an intended boundary.
assessment; if no applicable statement exists, record the gap rather than
inferring policy from naming, defaults, or surface type.
the intended product surface, untrusted input boundary, or trusted
operator/developer inputs, ask targeted operator-context questions before
assigning a verdict when the answer would materially affect the result.
../../references/static-finding-assessment.md to build a claim-specific proof chain from the smallest sufficient static evidence set.controls, sink or protected operation, consequence, supported
preconditions, product-surface anchor, boundary crossed, reachability,
counterevidence, proof gaps, and static confidence.
developer UI, MCP/tooling surface, example/demo, test/fixture, docs,
generated code, vendored code, or unknown surface.
product docs, SECURITY.md, disclosure policy, threat models, and nearby
comments when they are standard or local to the claim.
product model, or trusted operator/developer configuration.
authenticates, authorizes, terminates, verifies integrity, or merely
reformats, encodes, logs, redirects, catches, or labels data.
error handling can restore or preserve the dangerous interpretation.
the claimed consequence through fallthrough, return behavior, propagated
failures, alternate handlers, or another supported path.
cited code, manifest, version range, or supplied evidence.
entrypoint, route, command, package export, deployment path, dependency
edge, or other repository fact connecting the condition to the product
surface.
confirmed, positively connect the claimed actor and source throughthe relevant control semantics to the exact consequence under a supported
precondition.
not_actionable, positively establish that the material claim isdefeated across plausible shipped paths and supported configurations, not
only the observed caller, default mode, or success path.
gaps, and the minimal unresolved fact when completeness cannot be
established.
10. Assign exploitability stack ranks for confirmed and needs_review findings.
11. For confirmed findings, add owner hints after verdicting when local ownership evidence is easy to derive.
12. Build one valid triage-finding/v0 result using the contract in references/triage-result-contract.md.
13. If the Codex Security app tool open_codex_security_triage_results is available, call it with the complete result before the final response so the app renders the findings table. After a successful tool call, return a concise Markdown summary; do not paste the full JSON block unless the user asks for the raw contract.
14. If the app tool is unavailable or rejects the result, fall back to the fenced JSON block alongside the concise Markdown summary.
Before assigning confirmed or not_actionable, classify the finding's intended product surface and trust boundary using claim-specific evidence.
Inspect the smallest available evidence for:
SECURITY.md, security documentation, supported-versions documentation, disclosure policy, threat models, or comments that define trusted inputs and supported boundariesDo not infer source trust solely from a label such as CLI argument, configuration, local path, checkpoint, plugin, extension, or administrator option. Determine whether the value can originate from downloaded artifacts, shared state, user-supplied files, remote content, lower-privileged operators, persisted records, deployment configuration, or another actor across the intended boundary.
Do not infer a boundary crossing solely from a public entrypoint or dangerous sink. Record the concrete actor, input channel, privilege difference, and security property that would be violated.
A reachable dataflow is not enough. confirmed requires both:
A default guard or secure default does not by itself defeat a claim involving a supported alternate configuration. Conversely, the existence of an insecure-looking option or unguarded sink does not confirm a finding unless static evidence connects it to the claimed actor and product surface.
If the code is reachable only through trusted configuration, local developer interfaces, examples, tests, fixtures, or demo applications, do not mark confirmed unless static evidence shows that the relevant input can cross a supported boundary, the surface is shipped or documented for the affected actor, or the path bypasses a documented hardening or authorization boundary.
When source provenance, supported configuration, actor privileges, or boundary classification is unclear, prefer needs_review and state the exact ambiguity in proof gaps.
Apply verdict rules to the complete, specific claim: actor, source, transformations, control, sink or protected operation, supported preconditions, boundary, and consequence. Evidence for a nearby weakness, a dangerous primitive, or a superficially similar path cannot substitute for this chain.
Use confirmed only when static evidence positively establishes all of the following:
Do not treat formatting, encoding, generic escaping, exception catching, redirecting, authentication alone, or a control's name as proof that the claimed consequence is either enabled or prevented. Determine what the operation enforces, what execution does afterward, and whether later processing changes the data's security meaning.
A source and dangerous sink are not sufficient for confirmed. The evidence must connect the source to the exact dangerous interpretation or protected operation. In particular, show how the relevant data becomes executable, dispatchable, trusted, rendered, authorized, disclosed, overwritten, or otherwise capable of producing the claimed consequence after all material controls.
Use not_actionable only when static evidence positively defeats the material claim. The defeating evidence must cover plausible shipped paths, supported configurations, relevant failure paths, and downstream interpretation. Valid defeating evidence includes:
Do not use not_actionable because one caller is safe, the normal path is guarded, a value is described as local or administrative, a redirect or exception is present, a sanitizer is invoked, or an insecure mode is optional. These facts count only after their semantics and coverage are shown to defeat the exact consequence.
Use needs_review when source provenance, control semantics, downstream interpretation, failure behavior, path coverage, supported configuration, or boundary policy cannot be established statically. Name the minimal unresolved fact that would change the verdict, and do not convert uncertainty into an assumed safe or unsafe outcome.
After verdicting, assign discrete exploitability stack ranks separately for confirmed and needs_review findings.
confirmed findings use the confirmed rank queue and positive integer ranks 1, 2, 3, etc. Rank 1 is the most exploitable confirmed finding in this result set.needs_review findings use the needs_review rank queue and independently assign positive integer ranks starting at 1. Rank 1 is the highest-exploitability unresolved finding to review first.1 inside each queue. The same rank may appear once in each queue because rank_queue distinguishes confirmed priorities from needs-review priorities.not_actionable findings are not stack-ranked; set their rank queue and rank to null.Rank by exploitability, not by scanner severity alone. Prioritize findings with clearer attacker reachability, lower required privileges, fewer preconditions,
more direct source-to-sink control, weaker or absent guards, and more reliable static evidence that the exploit path can be exercised. Use claimed impact or scanner severity only as a final tiebreaker when exploitability is otherwise equal.
Keep findings in input order in the JSON result. Use the stack-rank fields to show review/remediation priority instead of reordering the results.
For confirmed findings only, add a concise owner hint after assigning the verdict and exploitability stack rank when local ownership evidence is easy to derive.
Prefer CODEOWNERS or OWNERS evidence when available. If ownership is not clear,
omit the owner hint rather than guessing. Owner hints are routing metadata only:
do not use ownership to influence verdict, confidence, boundary assessment, or exploitability rank.
The triage-finding/v0 contract does not define a dedicated owner field. Do not add undocumented fields to the app-tool payload. Put owner-hint text in existing Markdown output, evidence, or recommended-next-step text when it is useful.
The Markdown result should include:
confirmed and needs_review findingsconfirmed findings, when available$fix-finding handoff when verdict is confirmedThe app-tool payload or fallback JSON block must include:
schema_version: "triage-finding/v0"source_type on every finding result, using one of the input source types listed aboveboundary_assessment on every finding result, even when fields are unknownexploitability_stack_rank on every finding resultPrefer the app tool over showing raw JSON. The intended default UX is:
triage-finding/v0 result internallyopen_codex_security_triage_results with that resultUse the fenced JSON block only as a fallback when the app tool cannot be used,
or when the user explicitly asks to see or copy the raw result contract.
For confirmed findings, include a concise prompt-ready handoff for $fix-finding with:
$fix-finding should preserve or validateDo not invoke $fix-finding unless the user explicitly asks to continue into fixing.
confirmed solely because attacker-influenced data reaches a dangerous sink; first establish the relevant product surface and supported security boundary.Take openai/plugins-triage-finding from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.