Composing vulnerability report
Skill jeremylongshore/claude-code-plugins-plus-skills/skills/.curated/composing-vulnerability-report
425 plugins, 2,810 skills, 200 agents for Claude Code. Open-source marketplace at tonsofskills.com with the ccpi CLI package manager.
npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill composing-vulnerability-reportAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
What its author says it does
Copied from the file, not written here
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".
The file declares its own license as MIT. That is the author’s claim about this one file, and it is not the same thing as the license GitHub reports for the repository, which is listed with the other numbers below.
SKILL.md
7.6 KB, as published. Nobody here has run it
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.pyschema)
Instructions
Step 1 — Gather findings sources
By default the skill reads every file matching
engagement/findings/*.json and engagement/findings/*.jsonl.
Override with --source FILE (repeatable).
Step 2 — Run the composer
python3 ./scripts/compose_report.py engagements/acme-2026-q2/
Options:
Usage: compose_report.py PATH [OPTIONS]
Options:
--source FILE Specific findings file (repeatable; overrides default glob)
--report-output FILE Write the composed report here (default:
PATH/reports/vulnerability-report.md)
--engagement-id ID Override the engagement ID (default: parse from PATH/roe.yaml)
--output FILE Operational findings output (this skill's own findings)
--format FMT json | jsonl | markdown (default: markdown)
--min-severity SEV Filter report to findings at or above this severity
--include-info Include INFO-severity findings in the report (default: omit)
Step 3 — Review the report
The output report has a predictable structure. The header identifies the engagement, the source files, and the generation timestamp. The summary table shows finding counts by severity. Per-severity sections follow.
Each finding subsection includes a stable anchor (the fingerprint) so cross-references from later artifacts (executive summary, OWASP mapping) resolve into the report cleanly.
Step 4 — Verify against sources
python3 ./scripts/compose_report.py engagements/acme-2026-q2/ --format json --output /tmp/compose-findings.json
jq '.[] | select(.severity == "high")' /tmp/compose-findings.json
If the report references a finding the operator didn't expect,
trace back via the finding's skill_id + target to the source
file.
Examples
Example 1 — End-of-engagement report
python3 ./scripts/compose_report.py engagements/acme-2026-q2/ \
--report-output engagements/acme-2026-q2/reports/vulnerability-report.md
Example 2 — Interim report mid-engagement
python3 ./scripts/compose_report.py engagements/acme-2026-q2/ \
--min-severity high \
--report-output engagements/acme-2026-q2/reports/interim-2026-06-15.md
--min-severity high produces an interim report covering only
HIGH and CRITICAL findings — useful for in-engagement customer
syncs.
Example 3 — Regenerate after OWASP mapping
python3 ./scripts/compose_report.py engagements/acme-2026-q2/ \
--source engagements/acme-2026-q2/findings/all-findings-with-owasp.jsonl \
--report-output engagements/acme-2026-q2/reports/vulnerability-report-v2.md
Re-run after mapping-findings-to-owasp-top10 has enriched each
finding with its OWASP category; the regenerated report includes
the OWASP tag in each per-finding subsection.
Output
JSON / JSONL / Markdown per lib/report.py for the skill's own
operational findings. The PRIMARY output is the composed
vulnerability report, written as standalone Markdown to the
--report-output path.
Each operational Finding includes:
id—compose::<issue>::<source-file>severity— CRITICAL / HIGH / MEDIUM / INFOcategory—report-compositionsummary— what went wrong (or right) during compositionevidence— source files, finding counts, dedup stats
Error Handling
- PATH missing or empty → emits CRITICAL operational finding, exits 1.
- Source file unparseable → emits HIGH operational finding, skips the file, continues with remaining sources.
- No findings files found → emits HIGH operational finding, exits 1.
- Output report path not writable → emits HIGH operational finding, exits 1.
- Finding missing required fields → emits HIGH operational finding, omits that record from the report, continues.
Resources
references/THEORY.md— Vulnerability-report structure history (NIST SP 800-115, OWASP Testing Guide), CVSS v3.1 vector composition, severity scoring tradeoffs (CVSS vs intrinsic vs EPSS), finding-deduplication theory, why fingerprint-based dedup beats title-basedreferences/PLAYBOOK.md— Report-template variants per audience (technical, executive, regulatory), per-finding remediation phrasing patterns, evidence-redaction patterns for distributed reports, cross-reference protocol with the OWASP-mapping and exec-summary skills