ci: bind release evidence to artifact hashes

This commit is contained in:
Joseph Magly
2026-08-22 10:59:08 -04:00
parent feda78fbbb
commit 7b7109feb5
22 changed files with 413 additions and 43 deletions
+1 -1
View File
@@ -28,7 +28,7 @@ When a user asks whether AIWG is active or engaged in this project, run or read
### Tracker Authority Protocol
- Source of truth: [.aiwg/aiwg.config](./.aiwg/aiwg.config)
- Source of truth: [.aiwg/aiwg.config](./aiwg.config)
- Internal/canonical tracker: `origin` (github; https://github.com/elder-plinius/OBLITERATUS.git)
- Customer issue tracker: not configured
- Primary repo remote: `origin`; CI remote: `origin`
+9 -7
View File
@@ -49,16 +49,16 @@
"bt6-maintainer": {
"version": "0.3.0",
"source": "project-local",
"installedAt": "2026-08-21T22:00:58.629Z",
"installedAt": "2026-08-22T14:56:47.190Z",
"deployedTo": {
"codex": {
"agents": 5,
"commands": 0,
"skills": 6,
"skills": 7,
"rules": 1
}
},
"manifestHash": "sha256:d14e8bdea0e1f845155d35a74251651ace95ee65a052eeb303e6a8148d8d9948",
"manifestHash": "sha256:870a24c7c362c7e71884381a4bc171deef54139ae50e9c76cac3aa967a9fc368",
"localPath": ".aiwg/plugins/bt6-maintainer/",
"localType": "plugin",
"manifestVersion": "1",
@@ -68,13 +68,14 @@
"agents/bt6-pr-auditor.md": "4d0b3f19e70a0406f0ace424f281a2444c98677d05fe7875ee0b389b75985e3e",
"agents/bt6-provider-assessor.md": "39cc61c35cea9be9dd7f9330ec82d7cef99d9a1f8a384f9313e8df9aafc98b30",
"agents/bt6-release-integrator.md": "e66bd1bf158d53265600c3a96240865dd716ff947a1be0a3a1bd384ca9a0bce7",
"rules/bt6-maintainer-guardrails.md": "68baf7dd88b856615377edbba51530c6d001421d4fc6fbcfbe3c8caf0d5c8014",
"rules/bt6-maintainer-guardrails.md": "081d398443b7f1c6e37e75b7bd0b9a68a24195eee7b96cc60d34d3febd62c694",
"skills/bt6-issue-steward/SKILL.md": "187e6cb41e71cc3811dfcf3aa8dcb5e49429aaa5087dbb0c3fd8816751b4f02e",
"skills/bt6-merge-train/SKILL.md": "87e2cfd9a84c6f2d1ddb3d054ff794d1afe242f67dd2803caaeea9e39a3242ba",
"skills/bt6-pr-audit/SKILL.md": "38be15ba6c6c12f958c7ced0bf6152654dc6df53ddc17156fda84083ae990ea9",
"skills/bt6-provider-review/SKILL.md": "a95ac6d2be20847626bb94e5038358148d4a19c25e00ade6049526f8a16d0c15",
"skills/bt6-queue-audit/SKILL.md": "aaa77f2e14b46a2f8329025923ed54745152cea6896c947580f7a1babff81312",
"skills/bt6-release-validation/SKILL.md": "e38c817001aecf9e0ab695875a41ad1a7ef55f6ffd7641e2646a3189f202b964"
"skills/bt6-release-readiness/SKILL.md": "b51881662f27604c518c67e009187b3b0bad1d0755116efae1b0d1505dbb3dfe",
"skills/bt6-release-validation/SKILL.md": "3ecf342ad12cd1eed2f38ed8eb5b7fb4e396a4e25c79b54e5f649eef0c10c866"
},
"deployedArtifactHashes": {
"codex": {
@@ -83,13 +84,14 @@
"agents/bt6-pr-auditor.md": "541754bb5acf433e4bd2b85a93cfbb40f3f28d3c84ed577f92242f9041b9252b",
"agents/bt6-provider-assessor.md": "716c78830e8d5c987683b2ff240eb0f04eefddd628d763a3c5adaf371d2ec8dd",
"agents/bt6-release-integrator.md": "5cadf095ef64c24dbcab36c991f7c9a26d793eddc20be28fe6b73435253d9df1",
"rules/bt6-maintainer-guardrails.md": "68baf7dd88b856615377edbba51530c6d001421d4fc6fbcfbe3c8caf0d5c8014",
"rules/bt6-maintainer-guardrails.md": "081d398443b7f1c6e37e75b7bd0b9a68a24195eee7b96cc60d34d3febd62c694",
"skills/bt6-issue-steward/SKILL.md": "1889afb3c068765806d895949d38f1b0888f72e59a5dedee1bc9b728910561f2",
"skills/bt6-merge-train/SKILL.md": "2e01a84f578b53d4cc1c7dbf0ae2395004fab45b8175b104ccc31d74f3d9aa3b",
"skills/bt6-pr-audit/SKILL.md": "9a1e55bfd6972f3168f884d54cd6ede3673b541940b54352120ed4c0a4c49f2c",
"skills/bt6-provider-review/SKILL.md": "2de8b37f546dda852bee88d023caf82877baab988aebc219fd83a784c2bf58a3",
"skills/bt6-queue-audit/SKILL.md": "e0bdb36c8f8f85a2e9dff0180de2f502972bb8af9b7b13c4661be065354ef893",
"skills/bt6-release-validation/SKILL.md": "c25e1600aea5102374616f89efb7f28b0cefd0d52f346414012560776cbb5407"
"skills/bt6-release-readiness/SKILL.md": "e609a2f2197fd8c65239f563a0f8cc594ad0d420e4d18da5ba8362f26574ff52",
"skills/bt6-release-validation/SKILL.md": "942cd70729c5c13c384532214ebfff1763fd9374a85abda18925932b6dc79167"
}
}
}
+12 -2
View File
@@ -25,18 +25,28 @@ validation:
- "python scripts/check_coverage_thresholds.py test-results/coverage-pr-core.json --min-line 0 --min-branch 0 --min-changed 50 --base-ref origin/main"
- "python scripts/check_conditional_policy.py && python scripts/check_test_risk_map.py"
full:
- "python -m pytest"
- "mkdir -p test-results && python -m pytest -m 'not slow and not gpu and not mps and not mlx and not network and not download and not remote and not operator_ui' --cov-branch --cov-fail-under=0 --cov-report=json:test-results/coverage-release.json"
- "python scripts/check_coverage_thresholds.py test-results/coverage-release.json --min-line 75 --min-branch 60 --min-file obliteratus/device.py=70 --min-file obliteratus/models/loader.py=70 --min-file obliteratus/architecture_profiles.py=70 --min-file obliteratus/cli.py=70 --min-file obliteratus/mlx_backend.py=70 --min-file obliteratus/evaluation/metrics.py=70 --min-file obliteratus/evaluation/advanced_metrics.py=70 --min-file obliteratus/reporting/report.py=70 --min-file obliteratus/community.py=70 --min-file obliteratus/telemetry.py=70"
- "python scripts/check_quality_policy.py --policy ci/test-quality-policy.json --coverage test-results/coverage-release.json && python scripts/check_conditional_policy.py && python scripts/check_test_risk_map.py"
- "python -m build --sdist --wheel"
- "python -c 'import obliteratus; print(obliteratus.__version__)'"
- "python -m obliteratus --help"
qualityPolicy:
pullRequestChangedLineCoverageFloor: 50
requireBehaviorTests: true
fullSuiteTrigger: "tagged-release"
fullSuiteTrigger: "release-readiness-and-tagged-validation"
documentation:
- "python -m ruff check --select F app.py obliteratus tests scripts/check_coverage_thresholds.py scripts/check_supply_chain_policy.py scripts/gemma4_12b_recursive_loop.py"
researchIntegrity:
- "python -m pytest tests/test_advanced_metrics.py tests/test_breakthrough_modules.py tests/test_community.py"
releaseEvidence:
hashAlgorithm: "sha256"
provenanceFormat: "slsa-v1"
attestationFormat: "in-toto"
signingMode: "sigstore-keyless"
sbomFormat: "cyclonedx"
buildOnce: true
verifyBeforePromotion: true
riskSurfaces:
- id: "model-loading"
paths: ["obliteratus/models/**", "obliteratus/device.py", "scripts/**"]
@@ -15,7 +15,7 @@ Use project-local capabilities before generic AIWG workflows when they apply.
## bt6-maintainer
Cross-repository maintenance, external-provider review, and tagged-release validation for BT6 research and support tooling.
Cross-repository maintenance, release readiness, and exact-tag validation for BT6 research and support tooling.
- Discover: `aiwg discover "bt6-maintainer"`
- Discover: `aiwg discover "bt6"`
@@ -9,7 +9,7 @@
"entries": [
{
"title": "bt6-maintainer",
"summary": "Cross-repository maintenance, external-provider review, and tagged-release validation for BT6 research and support tooling.",
"summary": "Cross-repository maintenance, release readiness, and exact-tag validation for BT6 research and support tooling.",
"discover": [
"bt6-maintainer",
"bt6",
+7 -5
View File
@@ -2,8 +2,8 @@
Cross-repository maintenance for BT6 research and support tooling. The plugin
provides queue audit, pull-request audit, external-provider assessment, issue
stewardship, conservative merge-train workflows, and exact-tag release
validation that adapt to each repository's configured tracker, delivery policy,
stewardship, conservative merge-train workflows, pre-tag release hardening, and
exact-tag release validation that adapt to each repository's configured tracker, delivery policy,
validation commands, and research/data risk surfaces.
## What this is
@@ -70,9 +70,11 @@ the profile's `validation.quick` core suite, require relevant tests for behavior
changes, and enforce a 50% changed-line coverage floor where coverage is
measurable. Genuine but incomplete tests may be completed through
`maintainer-assist`; behavior changes with zero relevant tests remain blocked.
The exhaustive `validation.full` suite runs through `bt6-release-validation`
against an exact tag and blocks artifact promotion until the release gate is
green.
Before tagging, `bt6-release-readiness` inventories merged risk, runs the
exhaustive locally applicable gates, and repairs test, coverage, correctness,
documentation, and policy gaps. After tagging, `bt6-release-validation` binds
the same higher bar plus hosted and platform evidence to the exact immutable
tag. Readiness never substitutes for tagged certification.
Inspect health:
```bash
+3 -1
View File
@@ -3,7 +3,7 @@
"type": "plugin",
"name": "bt6-maintainer",
"version": "0.3.0",
"description": "Cross-repository maintenance, external-provider review, and tagged-release validation for BT6 research and support tooling.",
"description": "Cross-repository maintenance, release readiness, and exact-tag validation for BT6 research and support tooling.",
"manifestVersion": "1",
"platforms": {
"claude": "full",
@@ -19,6 +19,8 @@
"external-providers",
"trust-boundaries",
"merge-train",
"release-readiness",
"release-validation",
"plugin",
"repository-operations"
],
@@ -13,10 +13,12 @@ support codebases with consistent evidence and safety gates.
triage.
- `bt6-merge-train` — explicitly authorized, one-at-a-time merges with queue
refresh and linked-issue reconciliation.
- `bt6-release-readiness` — pre-tag audit and repair from the bounded PR bar to
the exhaustive release bar.
- `bt6-release-validation` — exact-tag certification before artifact promotion.
Five matching agents orchestrate those skills. Five declarative capability
flows describe queue audit, PR audit, provider review, issue stewardship, and
merge train contracts.
The release integrator orchestrates both release workflows. Declarative
capability flows describe every workflow contract.
## Repository profile
@@ -0,0 +1,52 @@
apiVersion: ops.aiwg.io/v1
kind: OpsCapability
metadata:
name: bt6-release-readiness-flow
labels:
category: release-management
scope: cross-repository
annotations:
blast-radius: "repository-local repairs only; tagging and publication are out of scope"
spec:
description: Audit and harden an untagged candidate from the bounded PR bar to the exhaustive BT6 release bar.
version: "0.3.0"
inputs:
- name: candidate
type: string
required: true
description: Exact candidate commit to harden.
- name: comparison_base
type: string
required: true
description: Previous release or configured exact base used to inventory merged change.
outputs:
- name: gap_inventory
type: list
description: Failed gates, coverage regressions, untested behavior, and unavailable evidence.
- name: repairs
type: list
description: Authorized code, test, documentation, and policy corrections with verification.
- name: decision
type: string
description: ready-to-tag, not-ready, or hold.
target_requirements:
os: [linux, macos]
capabilities: [git]
agent: bt6-release-integrator
idempotent: true
steps:
- name: resolve-candidate
description: Bind repository authority, candidate, comparison base, profile, and authorization.
- name: inventory-merged-risk
description: Map merged production changes to relevant tests, owners, public contracts, and risk surfaces.
- name: run-pre-tag-gates
description: Run the full locally applicable release suite, coverage, quality-depth, packaging, and integrity checks.
- name: repair-gaps
description: Add outcome-oriented tests and correct underlying implementation or policy defects without weakening thresholds.
- name: rerun-complete-gate
description: Re-run focused checks and then the complete applicable pre-tag suite.
- name: decide
description: Declare ready-to-tag only with green pre-tag evidence; exact-tag validation remains mandatory.
verification:
command: "git rev-parse --verify <candidate>^{commit} >/dev/null"
expect: "report binds the gap inventory, repairs, and final evidence to the exact candidate and comparison base"
@@ -91,13 +91,35 @@
"properties": {
"pullRequestChangedLineCoverageFloor": { "const": 50 },
"requireBehaviorTests": { "const": true },
"fullSuiteTrigger": { "const": "tagged-release" }
"fullSuiteTrigger": { "const": "release-readiness-and-tagged-validation" }
}
},
"documentation": { "$ref": "#/$defs/commands" },
"researchIntegrity": { "$ref": "#/$defs/commands" }
}
},
"releaseEvidence": {
"type": "object",
"additionalProperties": false,
"required": [
"hashAlgorithm",
"provenanceFormat",
"attestationFormat",
"signingMode",
"sbomFormat",
"buildOnce",
"verifyBeforePromotion"
],
"properties": {
"hashAlgorithm": { "const": "sha256" },
"provenanceFormat": { "const": "slsa-v1" },
"attestationFormat": { "const": "in-toto" },
"signingMode": { "enum": ["sigstore-keyless", "project-defined"] },
"sbomFormat": { "enum": ["cyclonedx", "spdx"] },
"buildOnce": { "const": true },
"verifyBeforePromotion": { "const": true }
}
},
"riskSurfaces": {
"type": "array",
"items": {
@@ -3,7 +3,7 @@
"type": "addon",
"name": "bt6-maintainer",
"version": "0.3.0",
"description": "Cross-repository queue, review, issue, provider-trust, merge, and tagged-release validation for BT6 research and support tooling.",
"description": "Cross-repository queue, review, issue, provider-trust, merge, release-readiness, and exact-tag validation for BT6 research and support tooling.",
"manifestVersion": "1",
"platforms": {
"claude": "full",
@@ -20,6 +20,8 @@
"external-providers",
"trust-boundaries",
"merge-train",
"release-readiness",
"release-validation",
"provenance"
],
"deployment": {
@@ -35,8 +35,8 @@ report.
11. Apply the shared two-tier quality model consistently. Pull requests run the
profile's fast `validation.quick` core-system commands and must reach at
least 50% changed-line coverage for measurable production-code changes.
Tagged-release validation runs `validation.full`; do not make that
exhaustive suite an ordinary contributor PR requirement.
Pre-tag readiness and tagged-release validation run `validation.full`; do
not make that exhaustive suite an ordinary contributor PR requirement.
12. Every behavior change needs a relevant outcome-oriented test. A material
behavior change with zero relevant tests is never merge-ready, regardless
of aggregate coverage. Documentation-only, metadata-only, and other
@@ -51,3 +51,7 @@ report.
profile's `validation.full` commands and applicable documentation,
research-integrity, risk-surface, packaging, and platform checks pass for
that exact tagged commit.
15. After merges and before tagging, run `bt6-release-readiness` from the
previous release or configured comparison base. Audit merged behavior,
repair release-depth gaps without weakening thresholds, and then run
`bt6-release-validation` after the immutable tag is created.
@@ -0,0 +1,72 @@
---
namespace: bt6-maintainer
name: bt6-release-readiness
platforms: [all]
description: Harden an untagged BT6 release candidate to the exhaustive release bar after pull requests were accepted through the bounded contributor gate.
triggers:
- prepare a BT6 release
- harden a BT6 release candidate
- audit merged PRs for release
- improve coverage before release
requires:
- candidate-reference: an exact candidate commit and comparison base
- repository-context: canonical repository, CI remote, and validation profile resolvable from project state
ensures:
- release-gaps-audited: merged behavior and risk surfaces are checked against the full release policy
- maintainer-gaps-repaired: authorized test and correctness gaps are fixed before tagging
- candidate-not-certified: readiness evidence never substitutes for exact-tag validation
---
# BT6 Release Readiness
Prepare a release candidate after normal pull requests have passed the bounded
`validation.quick` contributor gate. Apply `bt6-maintainer-guardrails`. This
workflow may improve code, tests, documentation, and repository-owned release
policy when the operator authorizes implementation. It does not create or
promote a tag.
## Required context
1. Resolve the canonical repository, base branch, CI remote, profile, candidate
commit, comparison base, and current authorization.
2. Require a clean or explicitly understood working tree. Preserve unrelated
work and use an isolated checkout when validation could overwrite it.
3. Inventory merged changes since the previous release or configured comparison
base. Map production changes to behavior tests, ownership, and risk surfaces.
4. Treat PR acceptance as evidence of reviewability only. Do not infer release
readiness from quick checks, aggregate coverage, or merge status.
## Hardening loop
1. Run `validation.full` plus applicable documentation, research-integrity,
risk-surface, packaging, compatibility, supply-chain, repeat, mutation, and
conditional-platform checks that can run before tagging.
2. Measure repository line and branch coverage, configured mature/critical
scope, changed or touched-module regression, and new-module floors. Record
skipped, unavailable, or stale evidence explicitly.
3. Prioritize failures and coverage gaps by release risk, recent change, public
contract, trust boundary, and defect history—not by raw uncovered-line count.
4. For each blocking gap, add outcome-oriented tests and correct the underlying
implementation or policy defect. Never weaken a release threshold to make a
candidate pass.
5. Re-run focused checks after each repair, then re-run the complete applicable
pre-tag gate. Stop when all locally executable hard gates pass or a required
external/platform gate remains unresolved.
6. When `releaseEvidence` is configured, require one canonical SHA-256 manifest
for the build-once release set, a bound SBOM, SLSA/in-toto provenance, and
the configured signature mechanism. Downstream gates must consume the same
artifact bytes rather than rebuilding them.
## Decision
- `ready-to-tag` only when every applicable pre-tag hard gate passes and all
unavailable evidence is intentionally deferred to an exact-tag hosted gate.
- `not-ready` when any required check fails or a correctness, security,
integrity, compatibility, or coverage gap remains.
- `hold` when the candidate, comparison base, authority, profile, or required
environment cannot be resolved safely.
Use `templates/bt6-release-readiness-report.md`. A `ready-to-tag` result becomes
stale on any candidate commit, dependency lock, policy, test, platform, or
release-configuration change. After tagging, always run `bt6-release-validation`
against the exact immutable tag; readiness is never release certification.
@@ -53,6 +53,10 @@ and does not publish a release without separate explicit authorization.
5. Treat warnings, flakes, skips, coverage changes, and conditional-gate gaps
according to repository release policy; do not inherit the relaxed PR
turnaround budget as a release exemption.
6. When `releaseEvidence` is configured, verify every artifact against the
canonical checksum manifest, authenticate its SLSA/in-toto attestation,
validate the SBOM binding, and prove promotion uses the tested build-once
bytes. A checksum without authenticated provenance is incomplete evidence.
## Decision
@@ -0,0 +1,44 @@
---
title: BT6 Release Readiness Report
description: Pre-tag audit and hardening report for moving a candidate from the bounded PR bar to the exhaustive release bar.
---
# BT6 release readiness: `<candidate>`
## Context
- Repository: `<canonical repository>`
- Candidate commit: `<sha>`
- Comparison base: `<previous release or exact base>`
- Profile: `<path/version>`
- Authorization: `<read-only | repairs authorized>`
## Merged-risk inventory
| Surface | Changed behavior | Relevant tests/evidence | Risk | Status |
| --- | --- | --- | --- | --- |
| `<path/component>` | `<behavior>` | `<tests/artifacts>` | `<high/medium/low>` | `<covered/gap>` |
## Release-depth gates
| Gate | Threshold or expectation | Result | Evidence |
| --- | --- | --- | --- |
| Full validation | `<profile validation.full>` | `<pass/fail/not run>` | `<artifact/log>` |
| Coverage and regression | `<repository/scope/module floors>` | `<pass/fail>` | `<coverage report>` |
| Quality depth | `<repeat/mutation/warnings>` | `<pass/fail/not run>` | `<artifact/log>` |
| Packaging and supply chain | `<policy>` | `<pass/fail/not run>` | `<artifact/log>` |
| Conditional/platform checks | `<policy>` | `<pass/fail/deferred>` | `<artifact/CI URL>` |
## Repairs
| Finding | Correction | Verification | Residual risk |
| --- | --- | --- | --- |
| `<gap>` | `<code/test/policy change>` | `<command/result>` | `<risk>` |
## Decision
`<ready-to-tag | not-ready | hold>`
This report is pre-tag evidence only. Any candidate, dependency, test, policy,
platform, or release-configuration change invalidates it. Exact-tag
`bt6-release-validation` remains required before artifact promotion.
@@ -29,11 +29,19 @@ validation:
qualityPolicy:
pullRequestChangedLineCoverageFloor: 50
requireBehaviorTests: true
fullSuiteTrigger: "tagged-release"
fullSuiteTrigger: "release-readiness-and-tagged-validation"
documentation:
- "<docs/link/citation check>"
researchIntegrity:
- "<provenance/corpus/reproducibility check>"
releaseEvidence:
hashAlgorithm: "sha256"
provenanceFormat: "slsa-v1"
attestationFormat: "in-toto"
signingMode: "sigstore-keyless"
sbomFormat: "cyclonedx"
buildOnce: true
verifyBeforePromotion: true
riskSurfaces:
- id: "ingestion"
paths: ["<ingestion or parser paths>"]
+65 -16
View File
@@ -28,6 +28,11 @@ jobs:
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
runs-on: ubuntu-latest
timeout-minutes: 15
permissions:
artifact-metadata: write
attestations: write
contents: read
id-token: write
env:
BUILD_TOOLS: /tmp/obliteratus-ci-tools
@@ -90,7 +95,31 @@ jobs:
run: |
mkdir -p package-evidence
"$BUILD_TOOLS/bin/python" -m twine check dist/* | tee package-evidence/twine-check.txt
sha256sum dist/* | tee package-evidence/SHA256SUMS
- name: Generate and bind CycloneDX SBOM
run: |
uv --preview-features sbom-export export \
--locked \
--format cyclonedx1.5 \
--all-extras \
--no-dev \
--no-editable \
--output-file package-evidence/obliteratus.cdx.unbound.json
mapfile -t wheels < <(find dist -maxdepth 1 -type f -name '*.whl' -print)
if [ "${#wheels[@]}" -ne 1 ]; then
echo "expected exactly one wheel, found ${#wheels[@]}"
exit 1
fi
python scripts/check_supply_chain_policy.py sbom \
--input package-evidence/obliteratus.cdx.unbound.json \
--wheel "${wheels[0]}" \
--output package-evidence/obliteratus.cdx.json
rm package-evidence/obliteratus.cdx.unbound.json
- name: Generate canonical release checksums
run: >-
sha256sum dist/* package-evidence/obliteratus.cdx.json |
tee package-evidence/SHA256SUMS
- name: Verify installed wheel contract
run: |
@@ -154,6 +183,27 @@ jobs:
"$sdist_env/bin/python" -I -m obliteratus --help > "$GITHUB_WORKSPACE/package-evidence/sdist-module-help.txt"
"$sdist_env/bin/obliteratus" --help > "$GITHUB_WORKSPACE/package-evidence/sdist-console-help.txt"
- name: Attest release-set SLSA provenance
id: provenance
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-checksums: package-evidence/SHA256SUMS
- name: Attest wheel SBOM
id: sbom-attestation
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-path: dist/*.whl
sbom-path: package-evidence/obliteratus.cdx.json
- name: Retain Sigstore attestation bundles
run: |
cp "${{ steps.provenance.outputs.bundle-path }}" \
package-evidence/slsa-provenance.sigstore.json
cp "${{ steps.sbom-attestation.outputs.bundle-path }}" \
package-evidence/sbom-attestation.sigstore.json
sha256sum -c package-evidence/SHA256SUMS
- name: Upload distributions and package evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
@@ -706,6 +756,7 @@ jobs:
supply-chain:
name: Supply chain
if: github.event_name == 'workflow_dispatch' || startsWith(github.ref, 'refs/tags/v')
needs: package
runs-on: ubuntu-latest
timeout-minutes: 30
env:
@@ -719,6 +770,12 @@ jobs:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Download attested release set
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: distributions-py3.12
path: /tmp/supply-chain-evidence/release
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
@@ -784,27 +841,19 @@ jobs:
echo "$status" > "$EVIDENCE/uv-audit-py${version}.status"
done
- name: Build wheel and bind CycloneDX SBOM
- name: Verify attested release set and bound CycloneDX SBOM
run: |
mkdir -p "$EVIDENCE/dist"
"$SUPPLY_TOOLS/bin/python" -m build --wheel --outdir "$EVIDENCE/dist"
uv --preview-features sbom-export export \
--locked \
--format cyclonedx1.5 \
--all-extras \
--no-dev \
--no-editable \
--output-file "$EVIDENCE/obliteratus.cdx.unbound.json"
mapfile -t wheels < <(find "$EVIDENCE/dist" -maxdepth 1 -type f -name '*.whl' -print)
cd "$EVIDENCE/release"
sha256sum -c package-evidence/SHA256SUMS
mapfile -t wheels < <(find dist -maxdepth 1 -type f -name '*.whl' -print)
if [ "${#wheels[@]}" -ne 1 ]; then
echo "expected exactly one wheel, found ${#wheels[@]}"
exit 1
fi
python scripts/check_supply_chain_policy.py sbom \
--input "$EVIDENCE/obliteratus.cdx.unbound.json" \
python "$GITHUB_WORKSPACE/scripts/check_supply_chain_policy.py" sbom \
--input package-evidence/obliteratus.cdx.json \
--wheel "${wheels[0]}" \
--output "$EVIDENCE/obliteratus.cdx.json"
sha256sum "${wheels[0]}" > "$EVIDENCE/distribution.SHA256SUM"
--output "$EVIDENCE/verified-obliteratus.cdx.json"
- name: Collect packaged-dependency license inventory
run: >-
+12
View File
@@ -59,6 +59,12 @@ regression and 80%/75% new-module floors; 94%/84% mature CPU-scope coverage;
selective mutation at 85%; repeat and duration budgets; Windows checkpoint
contracts; packaging; and supply-chain certification.
Before a tag is created, run the BT6 release-readiness workflow against the
previous release or configured comparison base. It inventories merged behavior,
runs all locally applicable release-depth gates, and repairs coverage,
correctness, documentation, packaging, and policy gaps. After tagging, run
exact-tag release validation; pre-tag readiness is never promotion evidence.
Canonical integrations must retain a verifiable commit signature. The repository
profile permits merge integration, not GitHub rebase integration, because rebase
can recreate an audited signed head as an unsigned canonical commit. Verify the
@@ -69,6 +75,12 @@ in an independent environment outside the checkout, exercises both CLI entry
paths, and retains the distributions plus evidence. Immutable CI action/tool
pins are recorded in [ci/digests.txt](ci/digests.txt).
The package job is the sole release-artifact producer. It binds wheel, sdist,
and CycloneDX SBOM digests into `SHA256SUMS`, creates keyless Sigstore-backed
SLSA and SBOM attestations, and retains their bundles. Downstream supply-chain
and publication jobs must verify and reuse those exact bytes rather than
rebuilding equivalent-looking artifacts.
The source-to-test ownership graph is versioned in
[ci/test-risk-map.json](ci/test-risk-map.json). Coverage, JUnit, repeat, and
mutation trends are normalized into project-owned JSON and retained for 90
+2
View File
@@ -2,6 +2,8 @@
action actions/checkout 3d3c42e5aac5ba805825da76410c181273ba90b1 v7.0.1 2026-08-14 baseline pin (#59)
action actions/setup-python 5fda3b95a4ea91299a34e894583c3862153e4b97 v7.0.0 2026-08-14 baseline pin (#59)
action actions/upload-artifact 043fb46d1a93c77aae656e7c1c64a875d1fc6a0a v7.0.1 2026-08-14 test/package evidence (#64, #65)
action actions/download-artifact 3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c v8.0.1 2026-03-11 immutable release-set reuse (#142)
action actions/attest 1e69f48acb82d1966a394da916b4c1698aa569d6 v4.2.2 2026-08-04 SLSA provenance and SBOM attestations (#142)
tool rhysd/actionlint sha256:8aca8db96f1b94770f1b0d72b6dddcb1ebb8123cb3712530b08cc387b349a3d8 v1.7.12 2026-08-14 workflow syntax/policy gate (#65)
tool astral-sh/uv pypi:0.12.4 v0.12.4 2026-08-14 locked dependency and SBOM engine (#66)
tool gitleaks/gitleaks sha256:551f6fc83ea457d62a0d98237cbad105af8d557003051f41f3e7ca7b3f2470eb v8.30.1 2026-08-14 redacted checkout secret scan (#66)
+30
View File
@@ -9,6 +9,36 @@ CI uses exact Python tool versions and checksum-pinned standalone binaries.
`ci/digests.txt` records executable and GitHub Action pins; build, test, and
license-tool transitive dependencies are covered by `uv.lock`.
## Digest-bound release evidence
Release artifacts use a build-once evidence chain. The release package job is
the sole producer of the wheel and source distribution. It also emits a bound
CycloneDX SBOM and a canonical `SHA256SUMS` manifest covering both distributions
and the SBOM.
GitHub's keyless Sigstore-backed attestation service signs two in-toto
statements for that release set:
- SLSA build provenance for every subject named by `SHA256SUMS`;
- an SBOM attestation binding the CycloneDX document to the wheel digest.
The supply-chain job downloads the package job's retained artifact, verifies
`SHA256SUMS`, and revalidates the SBOM binding. It must not rebuild a substitute
wheel. Publication must use these same tested and attested bytes. A commit,
dependency lock, build instruction, artifact, checksum manifest, SBOM, or
release-policy change invalidates the evidence.
Consumers can perform the portable integrity check with:
```bash
sha256sum --check SHA256SUMS
```
For authenticity and provenance, verify each distribution against the canonical
repository with GitHub's attestation verifier. A checksum without its signed
provenance proves byte integrity only; it does not prove who built the artifact
or which source and build instructions produced it.
## Required evidence
The Supply chain job retains these artifacts for 14 days:
+30 -1
View File
@@ -56,7 +56,7 @@ def test_bt6_maintainer_installation_matches_project_plugin():
assert installation["deployedTo"]["codex"] == {
"agents": 5,
"commands": 0,
"skills": 6,
"skills": 7,
"rules": 1,
}
assert "skills/bt6-release-validation/SKILL.md" in installation["artifactHashes"]
@@ -113,3 +113,32 @@ def test_delivery_profile_preserves_signed_canonical_history():
assert profile["delivery"]["defaultMergeMethod"] == "merge"
assert profile["delivery"]["allowedMergeMethods"] == ["merge"]
def test_release_profile_enforces_cpu_coverage_without_collecting_hardware_gates():
profile = yaml.safe_load(
(ROOT / ".aiwg" / "bt6-maintainer.yaml").read_text(encoding="utf-8"),
)
commands = "\n".join(profile["validation"]["full"])
assert "--cov-branch" in commands
assert "--min-line 75" in commands
assert "--min-branch 60" in commands
assert "scripts/check_quality_policy.py" in commands
assert "scripts/check_conditional_policy.py" in commands
assert "scripts/check_test_risk_map.py" in commands
for marker in ("gpu", "mps", "mlx", "network", "download", "remote", "operator_ui"):
assert f"not {marker}" in commands
assert profile["validation"]["qualityPolicy"]["fullSuiteTrigger"] == (
"release-readiness-and-tagged-validation"
)
assert profile["releaseEvidence"] == {
"hashAlgorithm": "sha256",
"provenanceFormat": "slsa-v1",
"attestationFormat": "in-toto",
"signingMode": "sigstore-keyless",
"sbomFormat": "cyclonedx",
"buildOnce": True,
"verifyBeforePromotion": True,
}
+22
View File
@@ -41,6 +41,28 @@ def test_every_external_action_is_sha_pinned_and_manifested():
assert entries[("action", name)] == (pin, version)
def test_release_artifacts_are_built_once_attested_and_reused():
workflow = WORKFLOW.read_text(encoding="utf-8")
package = workflow.split(" package:\n", maxsplit=1)[1].split(
" lint:\n", maxsplit=1,
)[0]
supply_chain = workflow.split(" supply-chain:\n", maxsplit=1)[1]
assert "artifact-metadata: write" in package
assert "attestations: write" in package
assert "id-token: write" in package
assert "package-evidence/SHA256SUMS" in package
assert "package-evidence/obliteratus.cdx.json" in package
assert package.count("uses: actions/attest@") == 2
assert "subject-checksums: package-evidence/SHA256SUMS" in package
assert "sbom-path: package-evidence/obliteratus.cdx.json" in package
assert "needs: package" in supply_chain
assert "uses: actions/download-artifact@" in supply_chain
assert "sha256sum -c package-evidence/SHA256SUMS" in supply_chain
assert "-m build" not in supply_chain
def test_actionlint_version_and_checksum_match_manifest():
workflow = WORKFLOW.read_text(encoding="utf-8")
pin, version = _manifest_entries()[("tool", "rhysd/actionlint")]