| name | composing-vulnerability-report |
| description | Read findings JSONL files from cluster 1-4 skills, deduplicate
by fingerprint, group by severity, and compose a deliverable-
grade markdown vulnerability report with per-finding sections
(title, severity, target, detail, remediation, evidence) and a
top-level summary table. The canonical written artifact a customer
receives at engagement close; precise, reproducible, machine-
checkable against source findings.
Use when: closing an engagement, generating an interim report,
regenerating after CVE or OWASP enrichment, or producing the
input for generating-executive-summary.
Threshold: findings missing required fields are dropped. HIGH
and CRITICAL findings highlighted in the summary section.
Trigger with: "compose vuln report", "write pentest report",
"generate vulnerability deliverable", "render findings to report".
|
| allowed-tools | ["Read","Write","Bash(python3:*)","Glob"] |
| disallowed-tools | ["Bash(rm:*)","Bash(curl:*)","Bash(wget:*)","Write(.env)","Edit(.env)"] |
| version | 3.30.0 |
| author | Jeremy Longshore <jeremy@intentsolutions.io> |
| license | MIT |
| compatibility | Designed for Claude Code |
| tags | ["security","reporting","vulnerability-report","cvss","pentest"] |
Composing Vulnerability Report
Overview
After cluster 1-4 scan skills run, each one produces a Findings
file. A typical engagement ends up with eight to twenty such files
across the different skill categories. The customer wants ONE
vulnerability report — comprehensive, deduplicated, organized by
severity, with each finding cross-referenced to its source skill
and target.
This skill consumes one or more findings files (JSONL preferred,
JSON list also accepted), deduplicates entries by the canonical
fingerprint defined in lib/finding.py, enriches each finding
with a CVSS v3.1 vector when one isn't present (using a deterministic
heuristic based on severity + category — explicitly noted as
"derived, not assigned by NVD" in the output), and emits a single
markdown report with per-finding sections plus a top-level
summary table.
The report has a defined structure that downstream tools (next
two skills in cluster 6) consume:
- Header — engagement ID, generation timestamp, source files
- Summary table — finding count by severity
- Per-severity sections — CRITICAL first, then HIGH, MEDIUM,
LOW, INFO
- Per-finding subsections — title, severity, target, detail,
remediation, evidence, references
When the skill produces findings
| Finding | Severity | Threshold | Affected control |
|---|
| Source file unparseable | HIGH | JSON/JSONL parse fails | (operational) |
| Finding missing required field | HIGH | A finding record is missing title, severity, target, detail, or remediation | (operational) |
| Duplicate fingerprint across files | INFO | Same finding appears in N>1 sources; reported as deduplication count | (informational) |
| Source file has zero findings | INFO | Empty or all-info-only file; reported but not an error | (informational) |
| Report generated cleanly | INFO | Positive confirmation | (informational) |
Prerequisites
- Python 3.9+
- One or more findings files in JSON or JSONL format produced by
any cluster 1-4 scan skill (which all share
lib/finding.py
schema)