Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 17 additions & 5 deletions .github/workflows/sbom-diff-and-risk-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -170,6 +170,7 @@ jobs:
assets=( $(printf '%s\n' "${assets[@]}" | LC_ALL=C sort) )
unset IFS
checksum_manifest="release-assets/${SBOM_DIFF_RISK_CHECKSUM_MANIFEST}"
notes_file="tools/sbom-diff-and-risk/RELEASE_NOTES_${RELEASE_TAG}.md"

if [ "${#assets[@]}" -ne 2 ]; then
echo "Expected exactly one wheel and one source distribution in release-assets/." >&2
Expand All @@ -188,6 +189,19 @@ jobs:
assets+=( "${checksum_manifest}" )

title="${RELEASE_TITLE_PREFIX} ${RELEASE_TAG}"
create_args=(--draft --verify-tag --title "${title}")
edit_args=(--draft=false --title "${title}")
notes_args=(--notes "Release assets for ${RELEASE_TAG}. See docs/release-provenance.md for provenance verification guidance.")

if [[ "${RELEASE_TAG}" == *"rc"* ]]; then
create_args+=(--prerelease --latest=false)
edit_args+=(--prerelease)
fi

if [ -f "${notes_file}" ]; then
notes_args=(--notes-file "${notes_file}")
edit_args+=(--notes-file "${notes_file}")
fi

if gh release view "${RELEASE_TAG}" --repo "${GH_REPO}" >/dev/null 2>&1; then
is_draft="$(gh release view "${RELEASE_TAG}" --repo "${GH_REPO}" --json isDraft -q .isDraft)"
Expand All @@ -198,11 +212,9 @@ jobs:
else
gh release create "${RELEASE_TAG}" \
--repo "${GH_REPO}" \
--draft \
--verify-tag \
--title "${title}" \
--notes "Release assets for ${RELEASE_TAG}. See docs/release-provenance.md for provenance verification guidance."
"${create_args[@]}" \
"${notes_args[@]}"
fi

gh release upload "${RELEASE_TAG}" "${assets[@]}" --repo "${GH_REPO}"
gh release edit "${RELEASE_TAG}" --repo "${GH_REPO}" --draft=false --title "${title}"
gh release edit "${RELEASE_TAG}" --repo "${GH_REPO}" "${edit_args[@]}"
10 changes: 5 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ Project:
[`sbom-diff-and-risk`](tools/sbom-diff-and-risk/README.md)

Status:
Released at `v0.9.0`.
Released at `v1.0-rc.1` as a release candidate.

What to review:
Deterministic SBOM/dependency diffing, JSON/Markdown/SARIF output, local policy
Expand All @@ -86,7 +86,7 @@ Useful entry points:
- [Reviewer path](tools/sbom-diff-and-risk/docs/reviewer-path.md)
- [Reviewer brief](tools/sbom-diff-and-risk/docs/reviewer-brief.md)
- [Reviewer evidence pack](tools/sbom-diff-and-risk/docs/reviewer-evidence-pack.md)
- [v0.9.0 release notes][release-notes-v090]
- [v1.0-rc.1 release notes][release-notes-v10rc1]
- [Examples](tools/sbom-diff-and-risk/examples/)

Project:
Expand Down Expand Up @@ -212,9 +212,9 @@ the review question:

## Status

- Current flagship release: `sbom-diff-and-risk` `v0.9.0`
- GitHub Release assets: available for `v0.9.0`
- Current flagship release candidate: `sbom-diff-and-risk` `v1.0-rc.1`
- GitHub Release assets: available for `v1.0-rc.1`
- TestPyPI Trusted Publishing dry-run: completed
- Production PyPI publishing: intentionally deferred

[release-notes-v090]: tools/sbom-diff-and-risk/RELEASE_NOTES_v0.9.0.md
[release-notes-v10rc1]: tools/sbom-diff-and-risk/RELEASE_NOTES_v1.0-rc.1.md
26 changes: 26 additions & 0 deletions scripts/validate-reviewer-routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
Path("docs/risk-model-boundary.md"),
Path("tools/sbom-diff-and-risk/docs/report-schema.md"),
Path("tools/sbom-diff-and-risk/docs/github-actions-consumer-example.md"),
Path("tools/sbom-diff-and-risk/docs/policy-warning-reviewer-case.md"),
Path("tools/sbom-diff-and-risk/docs/reviewer-path.md"),
Path("projects/precipitation-anomaly-diagnostics/docs/reviewer-path.md"),
Path("projects/precipitation-anomaly-diagnostics-lab/docs/reviewer-path.md"),
Expand Down Expand Up @@ -86,10 +87,20 @@
"tools/sbom-diff-and-risk/docs/policy-decision-ci-cookbook.md",
"tools/sbom-diff-and-risk/examples/github-actions-policy-consumer.yml",
},
Path("tools/sbom-diff-and-risk/docs/policy-warning-reviewer-case.md"): {
"docs/risk-model-boundary.md",
"tools/sbom-diff-and-risk/docs/policy-decision-explainability.md",
"tools/sbom-diff-and-risk/examples/cdx_after.json",
"tools/sbom-diff-and-risk/examples/cdx_before.json",
"tools/sbom-diff-and-risk/examples/policy-minimal.yml",
"tools/sbom-diff-and-risk/examples/sample-policy-warn-report.json",
"tools/sbom-diff-and-risk/examples/sample-policy-warn-report.md",
},
Path("tools/sbom-diff-and-risk/docs/reviewer-path.md"): {
".github/workflows/reviewer-route-contract-ci.yml",
"docs/risk-model-boundary.md",
"scripts/validate-reviewer-routes.py",
"tools/sbom-diff-and-risk/docs/policy-warning-reviewer-case.md",
"tools/sbom-diff-and-risk/examples/github-actions-policy-consumer.yml",
"tools/sbom-diff-and-risk/docs/reviewer-brief.md",
"tools/sbom-diff-and-risk/docs/reviewer-evidence-pack.md",
Expand Down Expand Up @@ -225,6 +236,21 @@
"not a CVE scanner",
"not a dependency safety oracle",
),
Path("tools/sbom-diff-and-risk/docs/policy-warning-reviewer-case.md"): (
"Policy warning reviewer case",
"how does a dependency diff produce a local policy warning?",
"summary.policy.status",
"warn",
"policy_matched",
"new_package",
"urllib3",
"risk_finding_matched_policy_rule",
"severity_source",
"warn_on",
"not a package safety verdict",
"any CVE result",
"any malware verdict",
),
Path("tools/sbom-diff-and-risk/docs/reviewer-path.md"): (
"Artifact evidence map",
"Reviewer route contract",
Expand Down
15 changes: 10 additions & 5 deletions tools/sbom-diff-and-risk/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
# sbom-diff-and-risk

v0.9.0 is the policy JSON sidecar and consumer integration usability release.
It adds optional `--policy-json PATH` output, checked-in policy sidecar
examples, and copyable GitHub Actions consumer guidance. It keeps dependency
analysis local and deterministic by default, preserves the completed TestPyPI
dry-run story, and keeps production PyPI publishing intentionally deferred.
v1.0-rc.1 is the Policy Evidence release candidate. It fixes the reviewer path
for policy decision examples, evidence-confidence labels, a one-page policy
warning case, and copyable GitHub Actions consumer guidance. It keeps
dependency analysis local and deterministic by default, preserves the completed
TestPyPI dry-run story, and keeps production PyPI publishing intentionally
deferred.

`sbom-diff-and-risk` is a local, deterministic CLI for comparing two SBOMs or dependency manifests and producing JSON plus Markdown reports.

Expand All @@ -29,6 +30,9 @@ explainability fields, see
[docs/policy-decision-explainability.md](docs/policy-decision-explainability.md).
For CI consumption of policy decision fields, see
[docs/policy-decision-ci-cookbook.md](docs/policy-decision-ci-cookbook.md).
For a fixed one-page case showing how a dependency diff triggers a policy
warning, see
[docs/policy-warning-reviewer-case.md](docs/policy-warning-reviewer-case.md).
For CI consumption of summary-only output, see
[docs/summary-json-ci-cookbook.md](docs/summary-json-ci-cookbook.md).
For a consumer-facing GitHub Actions example, see
Expand Down Expand Up @@ -319,6 +323,7 @@ The [examples/](examples/) directory includes:
- 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)
- a sample policy-only sidecar at [sample-policy.json](examples/sample-policy.json)
- compact policy-decision examples at [examples/policy-decisions](examples/policy-decisions/README.md)
- a one-page policy warning reviewer case at [docs/policy-warning-reviewer-case.md](docs/policy-warning-reviewer-case.md)
- a sample SARIF export at [sample-sarif.sarif](examples/sample-sarif.sarif)
- provenance-aware sample reports at [sample-provenance-report.json](examples/sample-provenance-report.json), [sample-provenance-report.md](examples/sample-provenance-report.md), and [sample-provenance-report.sarif](examples/sample-provenance-report.sarif)
- Scorecard-aware sample reports at [sample-scorecard-report.json](examples/sample-scorecard-report.json), [sample-scorecard-report.md](examples/sample-scorecard-report.md), and [sample-scorecard-report.sarif](examples/sample-scorecard-report.sarif)
Expand Down
56 changes: 56 additions & 0 deletions tools/sbom-diff-and-risk/RELEASE_NOTES_v1.0-rc.1.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# sbom-diff-and-risk v1.0-rc.1

`v1.0-rc.1` is the Policy Evidence release candidate.

The Python package metadata version for this tag is `1.0rc1`, which is the
PEP 440 form used in the wheel and source distribution filenames.

## Theme

Reviewer-stable policy evidence without expanding the tool's claims.

This release candidate turns the post-`v0.9.0` policy work into a tighter
review surface: fixed policy decision examples, explicit evidence-confidence
labels, a risk-model boundary, and a minimal CI consumer path.

## Highlights

- Added policy decision examples for `pass`, `warn`, `fail`, and
consumer-side `needs-review`.
- Added `summary.evidence_confidence` and top-level `evidence_confidence`
labels for `local_manifest_only`, `sbom_present`, `policy_matched`,
`enrichment_recorded`, and `provenance_recorded`.
- Added a one-page policy warning reviewer case that traces an added
dependency from diff input to local policy warning.
- Strengthened the risk-model boundary with explicit non-claims: not a CVE
scanner, not a malware scanner, and not a package safety verdict engine.
- Added a minimal GitHub Actions consumer workflow that runs the tool, uploads
`policy.json`, and fails or passes from the local policy result.
- Added repository scope and scientific-computing background notes to keep the
repository from widening beyond the flagship SBOM release surface.

## Compatibility and boundaries

- This is a release candidate, not the final `v1.0.0`.
- Production PyPI publishing remains intentionally deferred.
- The GitHub Release assets are the expected distribution surface for this rc.
- Default analysis remains local-file based and deterministic.
- No default network enrichment was added.
- No CVE lookup, advisory resolution, malware scanning, or package safety
verdict was added.
- Policy warnings and failures remain local policy decisions for review.

## Release evidence

The tag-gated GitHub Actions workflow builds the wheel and source distribution,
generates a SHA256 checksum manifest, records workflow artifact attestations,
and publishes the same built files as GitHub Release assets.

Expected assets:

- `sbom_diff_and_risk-1.0rc1-py3-none-any.whl`
- `sbom_diff_and_risk-1.0rc1.tar.gz`
- `sbom-diff-and-risk-SHA256SUMS.txt`

Use `docs/verification.md`, `docs/release-provenance.md`, and
`docs/self-provenance.md` for the correct verification path.
Original file line number Diff line number Diff line change
Expand Up @@ -47,15 +47,15 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: |
mkdir -p .tooling/sbom-diff-risk
gh release download v0.9.0 \
gh release download v1.0-rc.1 \
--repo stacknil/scientific-computing-toolkit \
--pattern "sbom_diff_and_risk-0.9.0-py3-none-any.whl" \
--pattern "sbom_diff_and_risk-1.0rc1-py3-none-any.whl" \
--dir .tooling/sbom-diff-risk

- name: Install sbom-diff-risk
run: |
python -m pip install \
.tooling/sbom-diff-risk/sbom_diff_and_risk-0.9.0-py3-none-any.whl
.tooling/sbom-diff-risk/sbom_diff_and_risk-1.0rc1-py3-none-any.whl

- name: Run dependency policy
id: compare
Expand Down
94 changes: 94 additions & 0 deletions tools/sbom-diff-and-risk/docs/policy-warning-reviewer-case.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
# Policy warning reviewer case

This one-page case fixes a single reviewer question: how does a dependency diff
produce a local policy warning?

It uses the checked-in CycloneDX example pair and the minimal policy. No
network enrichment, CVE lookup, malware scan, or package safety verdict is
involved.

## Fixed input

Run from `tools/sbom-diff-and-risk`:

```powershell
sbom-diff-risk compare `
--before examples/cdx_before.json `
--after examples/cdx_after.json `
--policy examples/policy-minimal.yml `
--out-json outputs/policy-warn-report.json `
--out-md outputs/policy-warn-report.md
```

Reference inputs and policy:

- [`examples/cdx_before.json`](../examples/cdx_before.json)
- [`examples/cdx_after.json`](../examples/cdx_after.json)
- [`examples/policy-minimal.yml`](../examples/policy-minimal.yml)

The minimal policy is intentionally small:

```yaml
version: 1
block_on:
- unknown_license
warn_on:
- new_package
```

## Fixed output

The checked-in reference outputs are:

- [`examples/sample-policy-warn-report.json`](../examples/sample-policy-warn-report.json)
- [`examples/sample-policy-warn-report.md`](../examples/sample-policy-warn-report.md)

The fixed JSON facts for this case are:

| Field | Value |
| --- | --- |
| `summary.added` | `1` |
| `summary.changed` | `1` |
| `summary.evidence_confidence` | `policy_matched` |
| `summary.policy.status` | `warn` |
| `summary.policy.blocking` | `0` |
| `summary.policy.warning` | `1` |
| `warning_findings[0].policy_rule` | `new_package` |
| `warning_findings[0].component_name` | `urllib3` |
| `warning_findings[0].decision_reason` | `risk_finding_matched_policy_rule` |
| `warning_findings[0].severity_source` | `warn_on` |
| `warning_findings[0].observed_value` | `new_package` |

## Explanation

The after input contains `urllib3` `2.2.1`, which is not present in the before
input. The local risk model classifies that component as `new_package`.

`examples/policy-minimal.yml` maps `new_package` to `warn_on`, so policy
evaluation adds one warning finding for `urllib3`. The tool exits successfully
because the warning does not become a blocking policy violation.

The `requests` version change is still visible in the report, but it is not the
source of this policy warning. It receives `version_change_unclassified` and
`not_evaluated` findings in offline mode, and the minimal policy does not warn
or block on either rule.

## Fixed boundary

This case proves that local policy matching can explain why a dependency diff
triggered a warning.

It does not prove:

- `urllib3` is unsafe
- `requests` is safe
- any CVE result
- any malware verdict
- not a package safety verdict
- current PyPI package truth
- current repository reputation

For field-level policy metadata, see
[policy-decision-explainability.md](policy-decision-explainability.md). For
the risk inputs and non-claims, see
[risk-model-boundary.md](../../../docs/risk-model-boundary.md).
4 changes: 2 additions & 2 deletions tools/sbom-diff-and-risk/docs/reviewer-brief.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

`sbom-diff-and-risk` is a local CLI for comparing two SBOMs or dependency manifests and producing deterministic review artifacts: JSON, Markdown, and SARIF. It is built for conservative supply-chain review, not for vulnerability scanning or package reputation scoring.

Current released version: `v0.9.0`.
Current released version: `v1.0-rc.1` release candidate.

For the shortest ordered review route, use
[reviewer-path.md](reviewer-path.md).
Expand Down Expand Up @@ -32,6 +32,7 @@ Dependency review often needs evidence that is stable enough for code review, CI
| How can a reviewer reproduce the core evidence? | [reviewer-evidence-pack.md](reviewer-evidence-pack.md) for demo, release, TestPyPI, and SARIF verification paths. |
| What is the stable JSON shape? | [report-schema.md](report-schema.md) documents the machine-readable report structure and `summary` contract. |
| How are policy findings explained? | [policy-decision-explainability.md](policy-decision-explainability.md) documents the policy decision metadata in JSON reports. |
| How does one dependency diff trigger a policy warning? | [policy-warning-reviewer-case.md](policy-warning-reviewer-case.md) fixes the input, output, explanation, and boundary for a `new_package` warning. |
| Can CI consume compact policy decisions? | [policy-decision-ci-cookbook.md](policy-decision-ci-cookbook.md), [examples/sample-policy.json](../examples/sample-policy.json), and [examples/github-actions-policy-consumer.yml](../examples/github-actions-policy-consumer.yml) show the policy sidecar path. |
| Are default runs offline? | CLI docs, tests for no-enrichment behavior, and explicit enrichment flags. |
| Can code scanning consume the output? | `docs/github-code-scanning.md` and `examples/sample-sarif.sarif`. |
Expand Down Expand Up @@ -64,4 +65,3 @@ Dependency review often needs evidence that is stable enough for code review, CI
## Resume / application wording

Built `sbom-diff-and-risk`, a deterministic SBOM and dependency diff CLI that produces JSON, Markdown, and SARIF review artifacts; supports local policy checks and optional provenance/Scorecard evidence; and documents a release verification story covering GitHub artifact attestations, GitHub Release assets, TestPyPI Trusted Publishing validation, and intentionally deferred production PyPI publishing.

Loading