Skip to content

feat(release): publish commit-bound deterministic runtime SBOM - #2894

Closed
tang-vu wants to merge 3 commits into
Osmantic:mainfrom
tang-vu:feat/runtime-cyclonedx-sbom
Closed

tang-vu wants to merge 3 commits into
Osmantic:mainfrom
tang-vu:feat/runtime-cyclonedx-sbom

Conversation

@tang-vu

@tang-vu tang-vu commented Aug 21, 2026 •

Copy link
Copy Markdown
Contributor

Why this matters

ODS ships a large composable container surface, but operators and downstream forks lacked a machine-readable inventory tying runtime image references to source. The original branch generated a reproducible CycloneDX inventory, yet two commits sharing the same ODS version and image set produced indistinguishable published artifacts. A release receipt must identify the exact candidate it describes.

The published workflow now embeds the full Git object ID in CycloneDX metadata, names the artifact with that SHA, and ships a SHA-256 receipt beside it. This remains an offline source inventory; it does not claim registry attestation, image signing, or build provenance it did not perform.

Overlap check

Searched open and closed upstream PRs for SBOMs, CycloneDX, source-commit binding, checksums, runtime inventory, and provenance, plus all changed files. The only open PR changing the workflow, generator, or regression file is this canonical PR. Merged #1449 is documentation/roadmap only. No competing implementation or file owner was found.

Production and release contract

  • discover every shipped Compose/Dockerfile image through the repository's existing dependency scanner
  • deduplicate by resolved reference while retaining raw expressions, source paths, and runtime/library scopes
  • emit byte-stable CycloneDX 1.5 JSON and write output atomically
  • accept only a full 40- or 64-character hexadecimal --source-commit; reject moving names and abbreviated refs
  • record ods:source-commit and an exact GitHub VCS reference in metadata
  • generate twice in CI for byte comparison, then publish the inventory plus SHA-256 receipt in an artifact named with ${{ github.sha }}

Regression coverage

Public CLI tests prove deterministic stdout, one component per source image, root dependency coverage, atomic output parity, exact source-commit metadata/VCS linkage, and rejection of main or abbreviated references.

Concrete pre-change evidence: --source-commit <sha> exited with argparse status 2 because no source identity contract existed.

Validation

  • python -m pytest -q tests/test_runtime_sbom.py — 5 passed.
  • python tests/test_runtime_sbom.py — standalone CI path passed all 5 contracts.
  • python scripts/check-dependency-pins.py — passed.
  • Python compile and workflow YAML parse — passed.
  • git diff --check — passed.

An attempt to reproduce the workflow's Bash wrapper locally used WSL against /mnt/c and was stopped after the source scans exceeded 90 seconds due that filesystem boundary. The regression suite compares stdout and atomic file bytes directly with native Python; the Ubuntu GitHub Actions run remains the authoritative check for the literal cmp/sha256sum wrapper.

Tradeoffs and rollback

--source-commit is optional for exported source trees without Git metadata, but CI always supplies the exact candidate SHA. The checksum proves transport/content equality for this generated inventory only; it is not a signature. Rollback removes the artifact/metadata contract without changing runtime images, installation behavior, or release state.

@tang-vu tang-vu changed the title feat(release): publish deterministic runtime SBOM feat(release): publish commit-bound deterministic runtime SBOM Aug 23, 2026
@tang-vu

tang-vu commented Aug 23, 2026

Copy link
Copy Markdown
Contributor Author

Batch compatibility receipt (2026-08-24)

Built the inspectable synthetic branch tang-vu:validation/batch-20260824-architecture from upstream main (6ff9b4fc) and merged exact candidate heads in this order:

  1. fix(dashboard): keep extension progress polls single-flight #3065 bad25e7f
  2. feat(extensions): preview and confirm lifecycle change plans #2903 829dd48f
  3. feat(observability): stream scoped service health transitions #2911 d8aed4c6
  4. feat(extensions): inspect and gate dependency graphs #2909 6e9bd227
  5. feat(release): publish commit-bound deterministic runtime SBOM #2894 9115d147
  6. refactor(cli): extract read-only formatting primitives #3071 bff5cbfc

No manual merge resolution was required, including the shared Extensions.jsx / Extensions.test.jsx surface in #3065 and #2903. Synthetic head: 2c82aaec.

Combined validation:

  • Dashboard: 28 files / 262 tests passed; ESLint passed; production Vite build passed
  • Dashboard API: 350 passed, 5 skipped across service events, main routing, extension plans, lifecycle, and dependency suites
  • dependency graph + manifest gates: 4 pytest cases, 8 shell cases, full canonical/library schema contract passed
  • runtime SBOM: 5 tests passed; shipped dependency-pin validation passed
  • CLI: JSON public boundary, Phase C smoke, Bash syntax, ShellCheck, 4/4 BATS formatting contract, and enable/reconciliation fixture passed

The stale Browserslist notice and authentication-dependent Phase C skips are unchanged environmental disclosures. #2903 remains draft because synthetic compatibility does not replace its declared live host-agent lifecycle gate and independent human review.

@Lightheartdevs

Copy link
Copy Markdown
Collaborator

Thanks for this contribution. We're closing outside-contributor pull requests that have had no activity for 14 days or more, so the queue reflects work that can still land. This isn't a judgment on the change itself. If it's still needed, please rebase onto main and reopen it or open a focused PR. See #7253 for details and the contribution policy.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants