<< All versions

Skill v1.0.0

currentLLM-judged scan90/100
konflux-ci/diffused/new-scanner
──Details
PublishedOctober 23, 2026 at 01:40 PM
Content Hashsha256:69a9068d222a7c90...
Git SHA6890b36e2544
──Files
Files (1 file, 3.9 KB)
SKILL.md3.9 KBactive
SKILL.md · 94 lines · 3.9 KB

version: "1.0.0" name: new-scanner description: Scaffold a new vulnerability scanner implementation with tests following the project's existing pattern. Use when adding support for a new scanner tool. allowed-tools: Bash Read Write Edit arguments: [name, cli, example_image, example_sbom] argument-hint: <scanner-name> <cli-executable> "<image scan command>" "<sbom scan command>"


New Scanner

Scaffold a complete scanner implementation for $name using the $cli CLI tool.

Validate `$name` first: it must be a valid Python identifier (lowercase letters, numbers, underscores only). If it contains dashes, spaces, or other invalid characters, normalize it (e.g., my-scanner becomes my_scanner) and use the normalized form for file names, class names, and method names throughout.

Step 1: Discover the CLI

Run $cli --help to learn available subcommands and flags. Identify:

  • The version flag (e.g., --version, version)
  • How to scan an SBOM file
  • How to scan a container image
  • How to get JSON output

Step 2: Discover the JSON structure

Run both example commands provided by the user:

Image scan:

$example_image

SBOM scan:

$example_sbom

Inspect the JSON output from each and identify:

  • Where vulnerability entries live in the JSON hierarchy
  • The field name for the vulnerability/CVE ID
  • The field names for package name and installed version

Step 3: Read the existing pattern

Read these files to understand the conventions:

  • diffused/diffused/scanners/base.py — abstract base class with 4 required methods
  • diffused/diffused/scanners/trivy.py — reference implementation
  • diffused/diffused/scanners/registry.py — the SCANNERS map where scanners are registered
  • diffused/tests/scanners/test_trivy.py — reference test structure
  • diffused/tests/conftest.py — shared fixtures (test_image, test_sbom_path)

Step 4: Create the scanner implementation

Create diffused/diffused/scanners/$name.py:

  • Subclass BaseScanner
  • Implement all 4 abstract methods using the discovered CLI commands and JSON structure:
  • scan_sbom() — run the scanner on self.sbom, parse JSON into self.raw_result
  • scan_image() — run the scanner on self.image, parse JSON into self.raw_result
  • process_result() — parse self.raw_result into self.processed_result (a defaultdict[str, set[Package]] mapping CVE IDs to sets of Package objects)
  • get_version() — static method, return the scanner version string
  • Add a _run_$name_command(self, cmd, operation) helper with 120s timeout
  • Follow the error handling convention: store errors in self.error, do not raise from scan/process methods
  • Use logging for all log messages

Step 5: Create the test file

Create diffused/tests/scanners/test_$name.py:

  • Use the discovered JSON output as sample test data in fixtures
  • Cover: initialization, scan_sbom, scan_image, process_result, get_version
  • Use unittest.mock (patch, MagicMock) for subprocess mocking
  • Reuse fixtures from conftest.py (test_image, test_sbom_path)
  • Follow the same test structure as test_trivy.py

Step 6: Register the scanner

Edit diffused/diffused/scanners/registry.py:

  • Add an import for the new scanner class
  • Add an entry to the SCANNERS dict (used by get_scanner_class(), which both VulnerabilityDiffer and ScanReport select scanners through)

Edit diffusedcli/diffusedcli/cli.py:

  • Add $name to the click.Choice list in the --scanner option
  • Check for any scanner-specific restrictions in the CLI commands (e.g., SBOM scanning guards) and update them if the new scanner supports those features

Step 7: Run tests

Run tox -e py39-pytest,py39-pytest-cli and fix any failures until tests pass with 100% code coverage on the new scanner file.

Step 8: Summary

Present a summary:

  • Files created and modified
  • CLI commands and JSON fields discovered
  • Any manual steps remaining
All versions