From d4cbfb259ed5eb4e8e3113bbc33ee4c5f8ab0e64 Mon Sep 17 00:00:00 2001 From: stacknil Date: Fri, 1 May 2026 23:49:43 +0800 Subject: [PATCH] Add summary-json example artifacts --- tools/sbom-diff-and-risk/README.md | 21 +++++++----- .../sbom-diff-and-risk/docs/report-schema.md | 2 +- .../docs/reviewer-evidence-pack.md | 33 +++++++++++-------- .../examples/sample-summary.json | 14 ++++++++ .../sbom-diff-and-risk/tests/test_reports.py | 12 ++++++- 5 files changed, 58 insertions(+), 24 deletions(-) create mode 100644 tools/sbom-diff-and-risk/examples/sample-summary.json diff --git a/tools/sbom-diff-and-risk/README.md b/tools/sbom-diff-and-risk/README.md index 11125f6..e7c2654 100644 --- a/tools/sbom-diff-and-risk/README.md +++ b/tools/sbom-diff-and-risk/README.md @@ -80,9 +80,10 @@ Offline `stale_package` evaluation is intentionally deferred. When enrichment is ## Output Formats -- `report.json` -- `report.md` -- `report.sarif` +- `report.json` +- `summary.json` when `--summary-json` is provided +- `report.md` +- `report.sarif` ## Install @@ -97,11 +98,12 @@ Generate reports from the bundled CycloneDX example inputs: ```bash sbom-diff-risk compare \ --before examples/cdx_before.json \ - --after examples/cdx_after.json \ - --format auto \ - --out-json outputs/report.json \ - --out-md outputs/report.md -``` + --after examples/cdx_after.json \ + --format auto \ + --out-json outputs/report.json \ + --summary-json outputs/summary.json \ + --out-md outputs/report.md +``` Generate reports from the `requirements.txt` examples: @@ -175,6 +177,8 @@ Offline mode remains the default. No network access occurs unless `--enrich-pypi `--summary-json PATH` writes only the stable `report.json["summary"]` object for compact machine consumption. It uses the same summary schema as the full JSON report. +The checked-in [examples/sample-summary.json](examples/sample-summary.json) artifact is generated from the bundled CycloneDX example with `--summary-json outputs/summary.json` and matches the `summary` object in [examples/sample-report.json](examples/sample-report.json). + ## Dependency Provenance Analysis (Opt-in) This section is about analyzing third-party package provenance signals. It is not about verifying the `sbom-diff-and-risk` tool's own release artifacts. @@ -268,6 +272,7 @@ The [examples/](examples/) directory includes: - provenance-aware policy examples at `examples/policy-provenance-minimal.yml` and `examples/policy-provenance-strict.yml` - a Scorecard-aware policy example at `examples/policy-scorecard-minimal.yml` - a sample pass JSON report at [sample-report.json](examples/sample-report.json) +- a sample summary-only JSON artifact at [sample-summary.json](examples/sample-summary.json) - a sample pass Markdown report at [sample-report.md](examples/sample-report.md) - sample policy-warn reports at [sample-policy-warn-report.json](examples/sample-policy-warn-report.json) and [sample-policy-warn-report.md](examples/sample-policy-warn-report.md) - sample policy-fail reports at [sample-policy-fail-report.json](examples/sample-policy-fail-report.json) and [sample-policy-fail-report.md](examples/sample-policy-fail-report.md) diff --git a/tools/sbom-diff-and-risk/docs/report-schema.md b/tools/sbom-diff-and-risk/docs/report-schema.md index d2f7f58..1a7f549 100644 --- a/tools/sbom-diff-and-risk/docs/report-schema.md +++ b/tools/sbom-diff-and-risk/docs/report-schema.md @@ -30,7 +30,7 @@ When provenance policy fields are relevant, reports may also include `provenance ## Summary contract -`summary` is the stable, compact entry point for automation that needs counts without walking the full report. The `--summary-json PATH` CLI option writes only this stable `report.json["summary"]` object. +`summary` is the stable, compact entry point for automation that needs counts without walking the full report. The `--summary-json PATH` CLI option writes only this stable `report.json["summary"]` object. The checked-in [../examples/sample-summary.json](../examples/sample-summary.json) artifact is the summary-only output for the default CycloneDX example and matches the `summary` object in [../examples/sample-report.json](../examples/sample-report.json). Base `summary` fields: diff --git a/tools/sbom-diff-and-risk/docs/reviewer-evidence-pack.md b/tools/sbom-diff-and-risk/docs/reviewer-evidence-pack.md index b06aeae..721a4e6 100644 --- a/tools/sbom-diff-and-risk/docs/reviewer-evidence-pack.md +++ b/tools/sbom-diff-and-risk/docs/reviewer-evidence-pack.md @@ -28,27 +28,32 @@ python -m pip install -e .[dev] Generate the default CycloneDX example reports: ```powershell -sbom-diff-risk compare ` - --before examples/cdx_before.json ` - --after examples/cdx_after.json ` - --format auto ` - --out-json outputs/report.json ` - --out-md outputs/report.md -``` +sbom-diff-risk compare ` + --before examples/cdx_before.json ` + --after examples/cdx_after.json ` + --format auto ` + --out-json outputs/report.json ` + --summary-json outputs/summary.json ` + --out-md outputs/report.md +``` Expected output files: -- `outputs/report.json` -- `outputs/report.md` +- `outputs/report.json` +- `outputs/summary.json` +- `outputs/report.md` Compare the outputs against the checked-in sample reports: ```powershell -Compare-Object (Get-Content examples/sample-report.json) (Get-Content outputs/report.json) -Compare-Object (Get-Content examples/sample-report.md) (Get-Content outputs/report.md) -``` - -No differences means the sample path reproduced the committed example output. +Compare-Object (Get-Content examples/sample-report.json) (Get-Content outputs/report.json) +Compare-Object (Get-Content examples/sample-summary.json) (Get-Content outputs/summary.json) +Compare-Object (Get-Content examples/sample-report.md) (Get-Content outputs/report.md) +``` + +No differences means the sample path reproduced the committed example output. + +`examples/sample-summary.json` is the summary-only artifact for the same run and is expected to match `examples/sample-report.json`'s `summary` object. Generate the strict-policy SARIF sample: diff --git a/tools/sbom-diff-and-risk/examples/sample-summary.json b/tools/sbom-diff-and-risk/examples/sample-summary.json new file mode 100644 index 0000000..8c255df --- /dev/null +++ b/tools/sbom-diff-and-risk/examples/sample-summary.json @@ -0,0 +1,14 @@ +{ + "added": 1, + "removed": 0, + "changed": 1, + "risk_counts": { + "new_package": 1, + "major_upgrade": 0, + "version_change_unclassified": 1, + "unknown_license": 0, + "stale_package": 0, + "suspicious_source": 0, + "not_evaluated": 2 + } +} diff --git a/tools/sbom-diff-and-risk/tests/test_reports.py b/tools/sbom-diff-and-risk/tests/test_reports.py index 5d715c4..5edb223 100644 --- a/tools/sbom-diff-and-risk/tests/test_reports.py +++ b/tools/sbom-diff-and-risk/tests/test_reports.py @@ -18,7 +18,7 @@ from sbom_diff_risk.policy_models import PolicyConfig from sbom_diff_risk.policy_parser import build_policy from sbom_diff_risk.normalize import normalize_input -from sbom_diff_risk.report_json import render_report_json +from sbom_diff_risk.report_json import render_report_json, render_summary_json from sbom_diff_risk.report_md import render_report_markdown from sbom_diff_risk.risk import evaluate_risks, summarize_risks @@ -32,6 +32,16 @@ def test_report_json_matches_cyclonedx_golden_pass() -> None: assert rendered == expected +def test_summary_json_matches_cyclonedx_golden_pass() -> None: + report = _build_report("cdx_before.json", "cdx_after.json") + + rendered = render_summary_json(report) + expected = _read_example("sample-summary.json") + + assert rendered == expected + assert json.loads(rendered) == json.loads(_read_example("sample-report.json"))["summary"] + + def test_report_markdown_matches_cyclonedx_golden_pass() -> None: report = _build_report("cdx_before.json", "cdx_after.json")