Skip to content
Back to skills

Composing Vulnerability Report

ASecurity

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 C...

  • 2,719 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 21, 2026
ai-agentspythongobashtestingsecurity

Works with

  • claude code

Security analysis

A100/100

Pro scans all 4 files and shows the line behind each finding

Scanned September 21, 2026

npx -y skills add jeremylongshore/claude-code-plugins-plus-skills --skill composing-vulnerability-report --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Composing Vulnerability Report?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Composing Vulnerability Report
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/jeremylongshore-composing-vulnerability-report-ab3420b7/badge)](https://www.skillsdirectory.com/skills/jeremylongshore-composing-vulnerability-report-ab3420b7)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
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:

1. **Header** — engagement ID, generation timestamp, source files
2. **Summary table** — finding count by severity
3. **Per-severity sections** — CRITICAL first, then HIGH, MEDIUM,
   LOW, INFO
4. **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)

## 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

```bash
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

```bash
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

```bash
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

```bash
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

```bash
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 / INFO
- `category` — `report-composition`
- `summary` — what went wrong (or right) during composition
- `evidence` — 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-based
- `references/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

Files in this skill

  • SKILL.md7.6 KB
  • references/PLAYBOOK.md6.7 KB
  • references/THEORY.md6.9 KB
  • scripts/compose_report.py13 KB

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.