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
3 changes: 3 additions & 0 deletions .github/workflows/sbom-diff-and-risk-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,9 @@ jobs:
if [[ "${RELEASE_TAG}" == *"rc"* ]]; then
create_args+=(--prerelease --latest=false)
edit_args+=(--prerelease)
else
create_args+=(--latest)
edit_args+=(--latest)
fi

if [ -f "${notes_file}" ]; then
Expand Down
23 changes: 18 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# scientific-computing-toolkit

This repository is a portfolio space for scientific-computing infrastructure,
systems tooling, and supply-chain-security experiments that favor deterministic
behavior, auditable outputs, and clear release evidence.
This repository centers on a release-facing supply-chain review tool that
favors deterministic behavior, auditable outputs, and clear release evidence.
The scientific diagnostics projects remain bounded supporting material.

## Current Flagship Tool

Expand All @@ -11,6 +11,14 @@ current flagship tool. It compares SBOMs and dependency manifests, produces
JSON, Markdown, and SARIF review artifacts, supports local policy checks, and
can optionally record PyPI provenance and OpenSSF Scorecard evidence.

### Supply-chain non-claims

- not a CVE scanner
- not a malware scanner
- not a package safety verdict engine

These boundaries apply to the CLI, its reports, and its policy decisions.

For the clearest reviewer route, start with the
[`sbom-diff-and-risk` reviewer path](tools/sbom-diff-and-risk/docs/reviewer-path.md);
it separates orientation, artifact inspection, local reproduction, and release
Expand Down Expand Up @@ -72,7 +80,8 @@ Project:
[`sbom-diff-and-risk`](tools/sbom-diff-and-risk/README.md)

Status:
Released at `v1.0-rc.1` as a release candidate.
Main is the `v1.0.0` final candidate. The currently published release remains
`v1.0-rc.1` until the final tag is explicitly approved and created.

What to review:
Deterministic SBOM/dependency diffing, JSON/Markdown/SARIF output, local policy
Expand All @@ -86,6 +95,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)
- [v1.0.0 release notes draft][release-notes-v100]
- [v1.0-rc.1 release notes][release-notes-v10rc1]
- [Examples](tools/sbom-diff-and-risk/examples/)

Expand Down Expand Up @@ -212,10 +222,13 @@ the review question:

## Status

- Current flagship release candidate: `sbom-diff-and-risk` `v1.0-rc.1`
- Current published flagship release candidate: `sbom-diff-and-risk` `v1.0-rc.1`
- GitHub Release assets: available for `v1.0-rc.1`
- GitHub Latest may still show `v0.9.0` because `v1.0-rc.1` is a release candidate.
- Next release policy: GitHub `v1.0.0` final, with production PyPI still deferred
- Main package metadata: `1.0.0` final candidate
- TestPyPI Trusted Publishing dry-run: completed
- Production PyPI publishing: intentionally deferred

[release-notes-v100]: tools/sbom-diff-and-risk/RELEASE_NOTES_v1.0.0.md
[release-notes-v10rc1]: tools/sbom-diff-and-risk/RELEASE_NOTES_v1.0-rc.1.md
21 changes: 20 additions & 1 deletion scripts/validate-reviewer-routes.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
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/release-provenance.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 @@ -95,6 +96,11 @@
"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",
"tools/sbom-diff-and-risk/examples/sample-policy-warn-report.sarif",
},
Path("tools/sbom-diff-and-risk/docs/release-provenance.md"): {
"tools/sbom-diff-and-risk/docs/pypi-production-publishing-decision.md",
"tools/sbom-diff-and-risk/docs/verification.md",
},
Path("tools/sbom-diff-and-risk/docs/reviewer-path.md"): {
".github/workflows/reviewer-route-contract-ci.yml",
Expand All @@ -109,6 +115,7 @@
"tools/sbom-diff-and-risk/examples/sample-report.json",
"tools/sbom-diff-and-risk/examples/sample-summary.json",
"tools/sbom-diff-and-risk/examples/sample-policy.json",
"tools/sbom-diff-and-risk/examples/sample-policy-warn-report.sarif",
"tools/sbom-diff-and-risk/examples/sample-sarif.sarif",
},
Path("projects/precipitation-anomaly-diagnostics/docs/reviewer-path.md"): {
Expand Down Expand Up @@ -164,6 +171,9 @@
REQUIRED_TEXT = {
Path("README.md"): (
"current flagship tool",
"not a CVE scanner",
"not a malware scanner",
"not a package safety verdict engine",
"not part of the `sbom-diff-and-risk` release surface",
"why the scientific-computing background helps",
"GitHub Latest may still show `v0.9.0` because `v1.0-rc.1` is a release candidate.",
Expand Down Expand Up @@ -223,8 +233,8 @@
"local_manifest_only",
"sbom_present",
"policy_matched",
"enrichment_recorded",
"provenance_recorded",
"scorecard_recorded",
"not a package safety verdict",
"not a CVE result",
),
Expand All @@ -248,10 +258,19 @@
"risk_finding_matched_policy_rule",
"severity_source",
"warn_on",
"sample-policy-warn-report.sarif",
"sdr.new_package",
"policy_level",
"not a package safety verdict",
"any CVE result",
"any malware verdict",
),
Path("tools/sbom-diff-and-risk/docs/release-provenance.md"): (
"publish `v1.0.0` as the stable GitHub Release contract",
"production PyPI publishing deferred",
"marks a final tag such as `v1.0.0` as GitHub Latest",
"workflow artifact attestation",
),
Path("tools/sbom-diff-and-risk/docs/reviewer-path.md"): (
"Artifact evidence map",
"Reviewer route contract",
Expand Down
16 changes: 10 additions & 6 deletions tools/sbom-diff-and-risk/README.md
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
# sbom-diff-and-risk

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.
Main is the `v1.0.0` Policy Evidence final candidate. The currently published
release remains `v1.0-rc.1` until the final tag is explicitly approved and
created. The selected release policy is a stable GitHub `v1.0.0` release while
production PyPI publishing remains intentionally deferred.

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

It uses conservative heuristics for change intelligence. By default it does not resolve CVEs, does not act as a reputation oracle, and does not perform hidden network enrichment.

## Supply-chain non-claims

- not a CVE scanner
- not a malware scanner
- not a package safety verdict engine

## Start Here

For the clearest reviewer route, start with
Expand Down
58 changes: 58 additions & 0 deletions tools/sbom-diff-and-risk/RELEASE_NOTES_v1.0.0.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
# sbom-diff-and-risk v1.0.0

`v1.0.0` is the Policy Evidence release.

The Python package metadata version for this tag is `1.0.0`.

## Theme

A stable, bounded release surface for dependency diff and local policy evidence.

## Highlights

- Provides minimal policy decision examples for `pass`, `warn`, `fail`, and
consumer-side `needs-review`.
- Stabilizes `evidence_confidence` as `local_manifest_only`, `sbom_present`,
`policy_matched`, `provenance_recorded`, or `scorecard_recorded`.
- Fixes one reviewer case from dependency diff to `new_package` policy warning
across JSON, Markdown, and SARIF artifacts.
- Records policy match metadata in direct SARIF risk results, including the
local policy level and rule ID.
- Keeps the three supply-chain non-claims visible: not a CVE scanner, not a
malware scanner, and not a package safety verdict engine.
- Keeps the minimal GitHub Actions consumer path for running policy, uploading
`policy.json`, and enforcing the tool's exit code.

## Release policy

- `v1.0.0` is the stable GitHub Release contract.
- GitHub Release assets are the distribution surface for this release.
- Production PyPI publishing remains intentionally deferred.
- The TestPyPI Trusted Publishing dry-run remains evidence of the test
publishing path only.

## Compatibility and boundaries

- 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 bounded local policy decisions.
- `enrichment_recorded` was an rc label and is replaced by the more specific
`scorecard_recorded` label in the final contract.

## 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. Final tags are
explicitly marked as GitHub Latest; rc tags remain prereleases.

Expected assets:

- `sbom_diff_and_risk-1.0.0-py3-none-any.whl`
- `sbom_diff_and_risk-1.0.0.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 @@ -69,7 +69,8 @@ python scripts/regenerate-example-artifacts.py --check --only requirements
## Boundaries

The regeneration script covers no-network JSON, Markdown, summary, policy
sidecar, and strict-policy SARIF examples produced through the public CLI.
sidecar, policy-warning SARIF, and strict-policy SARIF examples produced
through the public CLI.

It does not perform PyPI or Scorecard enrichment, does not call external
services, and does not make dependency safety claims. Provenance-aware,
Expand Down
10 changes: 7 additions & 3 deletions tools/sbom-diff-and-risk/docs/github-actions-consumer-example.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ Production PyPI publishing is intentionally deferred, so consumers should not
install `sbom-diff-and-risk` from production PyPI. Use a GitHub Release asset or
a local checkout instead.

The checked-in workflow pins the selected stable contract, `v1.0.0`. Before
that final release is published, use the currently available `v1.0-rc.1`
release asset instead.

## Minimal policy workflow

Replace the placeholder input and policy paths with files from the consumer
Expand Down Expand Up @@ -47,15 +51,15 @@ jobs:
GH_TOKEN: ${{ github.token }}
run: |
mkdir -p .tooling/sbom-diff-risk
gh release download v1.0-rc.1 \
gh release download v1.0.0 \
--repo stacknil/scientific-computing-toolkit \
--pattern "sbom_diff_and_risk-1.0rc1-py3-none-any.whl" \
--pattern "sbom_diff_and_risk-1.0.0-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-1.0rc1-py3-none-any.whl
.tooling/sbom-diff-risk/sbom_diff_and_risk-1.0.0-py3-none-any.whl

- name: Run dependency policy
id: compare
Expand Down
20 changes: 17 additions & 3 deletions tools/sbom-diff-and-risk/docs/policy-warning-reviewer-case.md
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ sbom-diff-risk compare `
--after examples/cdx_after.json `
--policy examples/policy-minimal.yml `
--out-json outputs/policy-warn-report.json `
--out-md outputs/policy-warn-report.md
--out-md outputs/policy-warn-report.md `
--out-sarif outputs/policy-warn-report.sarif
```

Reference inputs and policy:
Expand All @@ -42,6 +43,7 @@ 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)
- [`examples/sample-policy-warn-report.sarif`](../examples/sample-policy-warn-report.sarif)

The fixed JSON facts for this case are:

Expand All @@ -59,6 +61,16 @@ The fixed JSON facts for this case are:
| `warning_findings[0].severity_source` | `warn_on` |
| `warning_findings[0].observed_value` | `new_package` |

The fixed SARIF facts for the same decision are:

| Field | Value |
| --- | --- |
| `runs[0].results[0].ruleId` | `sdr.new_package` |
| `runs[0].results[0].level` | `warning` |
| `runs[0].results[0].properties.component_name` | `urllib3` |
| `runs[0].results[0].properties.policy_matched` | `true` |
| `runs[0].results[0].properties.policy_level` | `warn` |

## Explanation

The after input contains `urllib3` `2.2.1`, which is not present in the before
Expand All @@ -73,10 +85,12 @@ 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
## Bounded decision

This case proves that local policy matching can explain why a dependency diff
triggered a warning.
triggered a warning and can preserve that decision in Markdown and SARIF. The
bounded decision is: review the added dependency under local policy; do not
convert the warning into a security verdict.

It does not prove:

Expand Down
14 changes: 14 additions & 0 deletions tools/sbom-diff-and-risk/docs/release-provenance.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,20 @@ This document is about the second surface: verifying a GitHub Release and a down

This page is only about the `sbom-diff-and-risk` tool's own GitHub Releases. If you want the quick "which verification page do I need?" guide, start with [verification.md](verification.md).

## v1.0 release policy

Chosen policy: publish `v1.0.0` as the stable GitHub Release contract while
keeping production PyPI publishing deferred.

For `v1.0.0`, stability applies to the CLI, report schemas, policy decision
examples, evidence-confidence labels, reviewer case, and GitHub Release asset
verification path. It does not claim production PyPI availability. Until the
final tag is explicitly approved and created, `v1.0-rc.1` remains the current
published release candidate.

The tag workflow marks rc tags as prereleases and not Latest. It explicitly
marks a final tag such as `v1.0.0` as GitHub Latest.

Release assets produced by the updated workflow also include a deterministic SHA256 checksum manifest named `sbom-diff-and-risk-SHA256SUMS.txt`. The manifest is written with filenames sorted in a stable order. It is not a separate provenance system; it is a local byte-integrity check that helps reviewers confirm downloaded wheel and source distribution files match the hashes published with the same GitHub Release.

## What the release workflow now does
Expand Down
7 changes: 6 additions & 1 deletion tools/sbom-diff-and-risk/docs/report-schema.md
Original file line number Diff line number Diff line change
Expand Up @@ -130,8 +130,13 @@ not a CVE result. The same value appears at top level, in `summary`, and in
| `local_manifest_only` | The report was produced from local manifest-style inputs without SBOM input, policy matches, or enrichment evidence. |
| `sbom_present` | At least one input is an SBOM format such as CycloneDX JSON or SPDX JSON. |
| `policy_matched` | Local policy evaluation produced at least one blocking, warning, or suppressed policy match. |
| `enrichment_recorded` | Optional non-provenance enrichment evidence, such as OpenSSF Scorecard evidence, was recorded for the report. |
| `provenance_recorded` | PyPI provenance evidence or provenance-enrichment metadata was recorded for the report. |
| `scorecard_recorded` | OpenSSF Scorecard evidence or Scorecard-enrichment metadata was recorded for the report. |

When both provenance and Scorecard evidence are recorded, the single summary
label is deterministically `scorecard_recorded`. This precedence keeps the
field stable; it does not rank package safety or claim that one evidence source
is universally stronger than another.

`summary.policy` appears only when a policy is applied. Absence of
`summary.policy` means policy was not used, not that policy evaluation failed.
Expand Down
5 changes: 4 additions & 1 deletion tools/sbom-diff-and-risk/docs/reviewer-brief.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

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

Main is the `v1.0.0` final candidate. The chosen release policy is a stable
GitHub final release while production PyPI remains deferred.

For the shortest ordered review route, use
[reviewer-path.md](reviewer-path.md).

Expand All @@ -32,7 +35,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. |
| How does one dependency diff trigger a policy warning? | [policy-warning-reviewer-case.md](policy-warning-reviewer-case.md) fixes the input, JSON/Markdown/SARIF 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
5 changes: 3 additions & 2 deletions tools/sbom-diff-and-risk/docs/reviewer-evidence-pack.md
Original file line number Diff line number Diff line change
Expand Up @@ -134,8 +134,8 @@ and suppressions.
For a fixed one-page policy warning case, see
[policy-warning-reviewer-case.md](policy-warning-reviewer-case.md). It traces
the checked-in CycloneDX example pair and `policy-minimal.yml` from added
dependency to `new_package` warning without turning the warning into a package
safety verdict.
dependency to a `new_package` warning in JSON, Markdown, and SARIF without
turning the warning into a package safety verdict.

For CI job-summary examples that consume policy decision metadata, see
[policy-decision-ci-cookbook.md](policy-decision-ci-cookbook.md).
Expand Down Expand Up @@ -255,6 +255,7 @@ The SARIF output is designed for GitHub code scanning consumption. Start with:
The SARIF renderer intentionally emits a conservative subset:

- selected heuristic findings such as suspicious source, unknown license, and major upgrade
- policy-matched `new_package` warnings with explicit policy metadata
- explicit blocking policy decisions
- selected provenance or Scorecard policy violations when policy turns them into findings

Expand Down
Loading