Goal
Make the release tooling and the documented release checklist actually require
a compatibility BOM when a release opts into the governed path, instead of
relying on the coordinator to remember --bom.
Background
From the 2026-09-09 deep review of the release-BOM feature (Base 1.9.0):
docs/release-bom.md states "Base 1.9.0 is the first Base release that
requires this governed release path" and that release publish "refuses to
publish when the BOM is missing, invalid, or does not match the reviewed
release identity".
- In practice
--bom is optional everywhere. With no --bom,
cli/python/base_release/release_readiness.py::bom_finding returns
("ok", "bom", "No release BOM was requested for this check.") and
release publish succeeds silently. "Missing" only covers the case where
--bom is supplied but the file is absent.
- The Base Release Checklist in
docs/release-process.md (steps 7-8) shows
basectl release publish --version X.Y.Z --dry-run and
basectl release publish --version X.Y.Z with no --bom, and no step to
dispatch the Ecosystem Release BOM workflow or download its
base-release-bom-<version> artifact.
- v1.9.0 shipped with
release-bom.json / release-bom.sha256 attached only
because the maintainer ran the workflow and passed --bom by hand. For a
bus-factor-1 release path this should be enforced, not remembered.
Scope
base_manifest.yaml + base_setup.manifest_model.ReleaseConfig (and its
loader): add an opt-in release.bom.required: true (or equivalent) field.
cli/python/base_release/release_readiness.py::bom_finding: when the
manifest requires a BOM and ctx.bom_path is None, return an error
finding instead of ok.
cli/python/base_release/release_parser.py / engine.py: reflect the
requirement in usage text and in publish --dry-run output.
docs/release-process.md: add checklist steps -- dispatch Ecosystem Release BOM at the exact release commit, download the artifact, pass
--bom <artifact> to the dry-run and the publish steps.
docs/release-bom.md: align the wording with the now-enforced behavior.
- Tests: manifest parsing of the new field;
bom_finding "required but
missing" case; any tests/test_*docs* that assert release-checklist
content.
Acceptance Criteria
Validation
python -m pytest cli/python/base_release/tests -q
python -m pytest -q -k "manifest and release"
bin/base-test
git diff --check
Non-Goals
- Not making the
Ecosystem Release BOM workflow a pull_request-triggered
required status check.
- No change to the BOM schema or
validate_bom rules.
basectl does not gain the ability to run the Ecosystem Release BOM
workflow itself; dispatch stays a manual coordinator step.
Project Fields
- Status: Backlog
- Priority: P2
- Size: M
- Area: Packaging
- Initiative: Contract Hardening
- Milestone: v1.10.0
Agent Assignment
Human first. Touches the manifest model, release readiness logic, and two
maintained release docs; needs a maintainer decision on the opt-in field name
and shape before implementation.
Goal
Make the release tooling and the documented release checklist actually require
a compatibility BOM when a release opts into the governed path, instead of
relying on the coordinator to remember
--bom.Background
From the 2026-09-09 deep review of the release-BOM feature (Base 1.9.0):
docs/release-bom.mdstates "Base 1.9.0 is the first Base release thatrequires this governed release path" and that
release publish"refuses topublish when the BOM is missing, invalid, or does not match the reviewed
release identity".
--bomis optional everywhere. With no--bom,cli/python/base_release/release_readiness.py::bom_findingreturns("ok", "bom", "No release BOM was requested for this check.")andrelease publishsucceeds silently. "Missing" only covers the case where--bomis supplied but the file is absent.docs/release-process.md(steps 7-8) showsbasectl release publish --version X.Y.Z --dry-runandbasectl release publish --version X.Y.Zwith no--bom, and no step todispatch the
Ecosystem Release BOMworkflow or download itsbase-release-bom-<version>artifact.release-bom.json/release-bom.sha256attached onlybecause the maintainer ran the workflow and passed
--bomby hand. For abus-factor-1 release path this should be enforced, not remembered.
Scope
base_manifest.yaml+base_setup.manifest_model.ReleaseConfig(and itsloader): add an opt-in
release.bom.required: true(or equivalent) field.cli/python/base_release/release_readiness.py::bom_finding: when themanifest requires a BOM and
ctx.bom_path is None, return anerrorfinding instead of
ok.cli/python/base_release/release_parser.py/engine.py: reflect therequirement in usage text and in
publish --dry-runoutput.docs/release-process.md: add checklist steps -- dispatchEcosystem Release BOMat the exact release commit, download the artifact, pass--bom <artifact>to the dry-run and the publish steps.docs/release-bom.md: align the wording with the now-enforced behavior.bom_finding"required butmissing" case; any
tests/test_*docs*that assert release-checklistcontent.
Acceptance Criteria
release.bom.required: true,release checkandrelease publishrun without
--bomproduce a blockingbomfinding and non-zero exit.historical manifests and past releases remain inspectable.
base_manifest.yamlsets the opt-in so Base's own releases require aBOM.
docs/release-process.mdchecklist covers workflow dispatch -> artifactdownload ->
--bomon dry-run and publish.docs/release-bom.mdno longer implies enforcement that does not exist.Validation
python -m pytest cli/python/base_release/tests -q python -m pytest -q -k "manifest and release" bin/base-test git diff --checkNon-Goals
Ecosystem Release BOMworkflow apull_request-triggeredrequired status check.
validate_bomrules.basectldoes not gain the ability to run theEcosystem Release BOMworkflow itself; dispatch stays a manual coordinator step.
Project Fields
Agent Assignment
Human first. Touches the manifest model, release readiness logic, and two
maintained release docs; needs a maintainer decision on the opt-in field name
and shape before implementation.