Merge pull request #143 from elder-plinius/feat/142-attest-release-artifacts

CI: bind release evidence to artifact hashes
This commit is contained in:
Joseph Magly
2026-08-22 11:33:59 -04:00
committed by GitHub
26 changed files with 476 additions and 179 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-22T15:28:11.760Z",
"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": "26c65c1f64ce29f947be8a90987489a499814c360f4789ed80ef35f711c3d4e0",
"skills/bt6-release-validation/SKILL.md": "9c0dfe72690bdcae273624be730751951b42bab36b538989a8708c0fb48f76d1"
},
"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": "db317a00f8f4198e93e0666a00af29ad645d4c3d50de2e42141d84d6e7c16eb1",
"skills/bt6-release-validation/SKILL.md": "e94720ea230a8206d7acf5b3c514c6bdf1b7f81865580b7b2c6df11472bdb384"
}
}
}
+14 -4
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"
- "python -m build --sdist --wheel"
- "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 -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:
artifactType: "source-zip"
hashAlgorithm: "sha256"
provenanceFormat: "slsa-v1"
attestationFormat: "in-toto"
signingMode: "sigstore-keyless"
sbomFormat: "cyclonedx"
snapshotOnce: true
verifyBeforePromotion: true
riskSurfaces:
- id: "model-loading"
paths: ["obliteratus/models/**", "obliteratus/device.py", "scripts/**"]
@@ -57,7 +67,7 @@ riskSurfaces:
- id: "ci-supply-chain"
paths: [".github/workflows/**", "ci/**", "docs/SUPPLY_CHAIN_POLICY.md", "pyproject.toml", "scripts/check_supply_chain_policy.py", "uv.lock"]
concerns: ["workflow-permissions", "dependency-pinning", "untrusted-pull-request-code"]
requiredChecks: ["uv lock --check", "python -m pytest tests/test_ci_policy.py tests/test_supply_chain_policy.py", "python -m build --sdist --wheel"]
requiredChecks: ["uv lock --check", "python -m pytest tests/test_ci_policy.py tests/test_supply_chain_policy.py"]
research:
corpusPaths: ["obliteratus/prompts.py", "community_results/**"]
evidencePaths: ["paper/**", "docs/**", "community_results/**"]
@@ -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,37 @@
"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": [
"artifactType",
"hashAlgorithm",
"provenanceFormat",
"attestationFormat",
"signingMode",
"sbomFormat",
"snapshotOnce",
"verifyBeforePromotion"
],
"properties": {
"artifactType": { "const": "source-zip" },
"hashAlgorithm": { "const": "sha256" },
"provenanceFormat": { "const": "slsa-v1" },
"attestationFormat": { "const": "in-toto" },
"signingMode": { "enum": ["sigstore-keyless", "project-defined"] },
"sbomFormat": { "enum": ["cyclonedx", "spdx"] },
"snapshotOnce": { "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,74 @@
---
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 deterministic source ZIP
of the tested commit, a canonical SHA-256 manifest, a bound source SBOM,
SLSA/in-toto provenance, and the configured signature mechanism. Do not
compile or publish installable packages unless a repository explicitly
overrides the source-snapshot policy. Downstream gates must consume the same
ZIP bytes rather than recreating 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.
@@ -45,14 +45,19 @@ and does not publish a release without separate explicit authorization.
1. Run every repository-profile `validation.full` command at the exact tagged
commit.
2. Run applicable `documentation`, `researchIntegrity`, and risk-surface checks.
3. Run repository-defined packaging, artifact-integrity, compatibility, and
supported-platform checks. Verify generated artifacts come from the tagged
source rather than an unrelated checkout.
3. Run repository-defined source-snapshot integrity, compatibility, and
supported-platform checks. Verify the release ZIP comes from the tagged
source rather than an unrelated checkout; do not require a compiled package.
4. Compare local evidence with CI for the same tag and commit. Record missing or
stale evidence as incomplete, not passing.
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 source-SBOM binding, and prove promotion uses the tested
snapshot-once ZIP 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>` |
| Source snapshot and supply chain | `<policy>` | `<pass/fail/not run>` | `<ZIP/evidence/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.
@@ -33,7 +33,7 @@ Profile: `<path and hash>`
| Documentation | `<pass/fail/n-a>` | `<details>` |
| Research and provenance | `<pass/fail/n-a>` | `<details>` |
| Risk-surface checks | `<pass/fail/n-a>` | `<details>` |
| Packaging and artifact integrity | `<pass/fail/n-a>` | `<details>` |
| Source ZIP and artifact integrity | `<pass/fail/n-a>` | `<details>` |
| Supported platforms | `<pass/fail/incomplete>` | `<details>` |
## Decision
@@ -29,11 +29,20 @@ 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:
artifactType: "source-zip"
hashAlgorithm: "sha256"
provenanceFormat: "slsa-v1"
attestationFormat: "in-toto"
signingMode: "sigstore-keyless"
sbomFormat: "cyclonedx"
snapshotOnce: true
verifyBeforePromotion: true
riskSurfaces:
- id: "ingestion"
paths: ["<ingestion or parser paths>"]
+80 -123
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
@@ -44,123 +49,76 @@ jobs:
pyproject.toml
uv.lock
- name: Install build tooling
- name: Install release evidence tooling
run: |
python -m pip install "uv==${UV_VERSION}"
UV_PROJECT_ENVIRONMENT="$BUILD_TOOLS" uv sync --locked --only-group ci
- name: Build source and wheel distributions
- name: Create deterministic tested-source snapshot
run: |
mkdir -p release package-evidence
snapshot="release/OBLITERATUS-${GITHUB_SHA}.zip"
git archive \
--format=zip \
--prefix="OBLITERATUS-${GITHUB_SHA}/" \
--output="$snapshot" \
"$GITHUB_SHA"
test "$(find release -maxdepth 1 -type f -name '*.zip' | wc -l)" -eq 1
unzip -t "$snapshot" | tee package-evidence/source-zip-check.txt
- name: Generate and bind source 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 snapshots < <(find release -maxdepth 1 -type f -name '*.zip' -print)
if [ "${#snapshots[@]}" -ne 1 ]; then
echo "expected exactly one source snapshot, found ${#snapshots[@]}"
exit 1
fi
python scripts/check_supply_chain_policy.py sbom \
--input package-evidence/obliteratus.cdx.unbound.json \
--artifact "${snapshots[0]}" \
--output package-evidence/obliteratus.cdx.json
rm package-evidence/obliteratus.cdx.unbound.json
- name: Generate canonical release checksums
run: >-
"$BUILD_TOOLS/bin/python" -m build --sdist --wheel
sha256sum release/*.zip package-evidence/obliteratus.cdx.json |
tee package-evidence/SHA256SUMS
- name: Verify wheel contents and entry point
- name: Attest release-set SLSA provenance
id: provenance
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-checksums: package-evidence/SHA256SUMS
- name: Attest source snapshot SBOM
id: sbom-attestation
uses: actions/attest@1e69f48acb82d1966a394da916b4c1698aa569d6 # v4.2.2
with:
subject-path: release/*.zip
sbom-path: package-evidence/obliteratus.cdx.json
- name: Retain Sigstore attestation bundles
run: |
python - <<'PY'
from pathlib import Path
from zipfile import ZipFile
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
wheels = list(Path("dist").glob("*.whl"))
if len(wheels) != 1:
raise SystemExit(f"expected one wheel, found: {wheels}")
with ZipFile(wheels[0]) as archive:
names = set(archive.namelist())
required = {
"app.py",
"obliteratus/__init__.py",
"obliteratus/local_ui.py",
}
missing = sorted(required - names)
if missing:
raise SystemExit(f"wheel is missing required modules: {missing}")
entry_points = [
name for name in names if name.endswith(".dist-info/entry_points.txt")
]
if len(entry_points) != 1:
raise SystemExit(f"expected one entry_points.txt, found: {entry_points}")
contents = archive.read(entry_points[0]).decode("utf-8")
if "obliteratus = obliteratus.cli:main" not in contents:
raise SystemExit("wheel is missing the obliteratus console entry point")
print(f"verified wheel contents: {wheels[0]}")
PY
- name: Validate distribution metadata
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: Verify installed wheel contract
run: |
mapfile -t wheels < <(find "$GITHUB_WORKSPACE/dist" -maxdepth 1 -type f -name '*.whl' -print)
if [ "${#wheels[@]}" -ne 1 ]; then
echo "expected exactly one wheel, found ${#wheels[@]}"
exit 1
fi
wheel_env="$RUNNER_TEMP/obliteratus-wheel-env"
wheel_cwd="$RUNNER_TEMP/obliteratus-wheel-cwd"
python -m venv "$wheel_env"
mkdir -p "$wheel_cwd"
"$wheel_env/bin/python" -m pip install --no-cache-dir "rich==15.0.0"
"$wheel_env/bin/python" -m pip install --no-cache-dir --no-deps "${wheels[0]}"
cd "$wheel_cwd"
"$wheel_env/bin/python" -I - <<'PY' | tee "$GITHUB_WORKSPACE/package-evidence/wheel-import.txt"
import importlib.metadata
from pathlib import Path
import obliteratus
origin = Path(obliteratus.__file__).resolve()
assert "site-packages" in origin.parts, origin
assert obliteratus.__version__ == importlib.metadata.version("obliteratus")
print(f"installed wheel import: {origin}")
print(f"version: {obliteratus.__version__}")
PY
"$wheel_env/bin/python" -I -m obliteratus --help > "$GITHUB_WORKSPACE/package-evidence/wheel-module-help.txt"
"$wheel_env/bin/obliteratus" --help > "$GITHUB_WORKSPACE/package-evidence/wheel-console-help.txt"
- name: Verify installed sdist contract
run: |
mapfile -t sdists < <(find "$GITHUB_WORKSPACE/dist" -maxdepth 1 -type f -name '*.tar.gz' -print)
if [ "${#sdists[@]}" -ne 1 ]; then
echo "expected exactly one sdist, found ${#sdists[@]}"
exit 1
fi
sdist_env="$RUNNER_TEMP/obliteratus-sdist-env"
sdist_cwd="$RUNNER_TEMP/obliteratus-sdist-cwd"
python -m venv "$sdist_env"
mkdir -p "$sdist_cwd"
"$sdist_env/bin/python" -m pip install --no-cache-dir "rich==15.0.0"
"$sdist_env/bin/python" -m pip install --no-cache-dir --no-deps "${sdists[0]}"
cd "$sdist_cwd"
"$sdist_env/bin/python" -I - <<'PY' | tee "$GITHUB_WORKSPACE/package-evidence/sdist-import.txt"
import importlib.metadata
from pathlib import Path
import obliteratus
origin = Path(obliteratus.__file__).resolve()
assert "site-packages" in origin.parts, origin
assert obliteratus.__version__ == importlib.metadata.version("obliteratus")
print(f"installed sdist import: {origin}")
print(f"version: {obliteratus.__version__}")
PY
"$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: Upload distributions and package evidence
- name: Upload tested source snapshot and release evidence
if: always()
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: distributions-py3.12
name: tested-source-snapshot-py3.12
path: |
dist/
release/
package-evidence/
if-no-files-found: error
retention-days: 14
@@ -706,6 +664,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 +678,12 @@ jobs:
- name: Check out repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Download attested tested-source snapshot
uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1
with:
name: tested-source-snapshot-py3.12
path: /tmp/supply-chain-evidence/release
- name: Set up Python
uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 # v7.0.0
with:
@@ -784,27 +749,19 @@ jobs:
echo "$status" > "$EVIDENCE/uv-audit-py${version}.status"
done
- name: Build wheel and bind CycloneDX SBOM
- name: Verify attested source snapshot 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)
if [ "${#wheels[@]}" -ne 1 ]; then
echo "expected exactly one wheel, found ${#wheels[@]}"
cd "$EVIDENCE/release"
sha256sum -c package-evidence/SHA256SUMS
mapfile -t snapshots < <(find release -maxdepth 1 -type f -name '*.zip' -print)
if [ "${#snapshots[@]}" -ne 1 ]; then
echo "expected exactly one source snapshot, found ${#snapshots[@]}"
exit 1
fi
python scripts/check_supply_chain_policy.py sbom \
--input "$EVIDENCE/obliteratus.cdx.unbound.json" \
--wheel "${wheels[0]}" \
--output "$EVIDENCE/obliteratus.cdx.json"
sha256sum "${wheels[0]}" > "$EVIDENCE/distribution.SHA256SUM"
python "$GITHUB_WORKSPACE/scripts/check_supply_chain_policy.py" sbom \
--input package-evidence/obliteratus.cdx.json \
--artifact "${snapshots[0]}" \
--output "$EVIDENCE/verified-obliteratus.cdx.json"
- name: Collect packaged-dependency license inventory
run: >-
+18 -6
View File
@@ -59,15 +59,27 @@ 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
actual `main` commit after every merge; never rewrite `main` to repair history.
Release CI additionally validates wheel and sdist metadata, installs each distribution
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).
Release CI creates one deterministic ZIP of the exact tested repository commit.
The ZIP is a source snapshot and release-quality marker, not an installable or
compiled distribution. Immutable CI action/tool pins are recorded in
[ci/digests.txt](ci/digests.txt).
The package job is the sole source-snapshot producer. It binds the ZIP and
CycloneDX source 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 that exact
ZIP rather than recreating an equivalent-looking archive.
The source-to-test ownership graph is versioned in
[ci/test-risk-map.json](ci/test-risk-map.json). Coverage, JUnit, repeat, and
@@ -79,8 +91,8 @@ flaking twice in 30 days requires an active owner/issue-linked quarantine.
Python CI resolution is locked by `uv.lock`, including the official CPU-only
PyTorch source for Linux and Windows. The required Supply chain job scans all
supported Python versions for known vulnerabilities, scans the checkout for
secrets with fully redacted evidence, enforces the packaged-dependency license
allow list, and binds a CycloneDX SBOM to the built wheel. Exception and update
secrets with fully redacted evidence, enforces the dependency license allow
list, and binds a CycloneDX source SBOM to the repository ZIP. Exception and update
rules are documented in [docs/SUPPLY_CHAIN_POLICY.md](docs/SUPPLY_CHAIN_POLICY.md).
GPU, MPS, MLX, model-download, external-evaluation, network, operator-UI, and
+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)
+33 -3
View File
@@ -9,15 +9,45 @@ 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
The release artifact is a deterministic ZIP snapshot of the tested repository
commit. No wheel, source distribution, executable, or other compiled package is
published. The release job creates the snapshot once with `git archive`, then
emits a bound CycloneDX source SBOM and a canonical `SHA256SUMS` manifest.
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 source ZIP digest.
The supply-chain job downloads the package job's retained artifact, verifies
`SHA256SUMS`, and revalidates the SBOM binding. It must not create a substitute
archive. Publication must use this same tested and attested ZIP. A commit,
dependency lock, snapshot 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 the source ZIP 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:
- one redacted Gitleaks JSON report for the checkout;
- OSV audit JSON and scanner status for Python 3.10, 3.11, and 3.12 on Linux;
- a JSON license inventory for all packaged extras;
- a CycloneDX 1.5 SBOM bound to the built wheel by SHA-256;
- the policy decisions and built wheel used by those checks.
- a JSON license inventory for all supported dependency extras;
- a CycloneDX 1.5 source SBOM bound to the repository ZIP by SHA-256;
- the policy decisions and exact tested source ZIP used by those checks.
Every secret finding and every OSV vulnerability is blocking by default. OSV
does not provide a normalized severity for every advisory, so the policy treats
+7 -7
View File
@@ -291,8 +291,8 @@ def evaluate_secrets(
}
def bind_sbom(sbom: object, wheel: Path) -> dict[str, Any]:
"""Bind a CycloneDX SBOM to the exact built wheel by SHA-256."""
def bind_sbom(sbom: object, artifact: Path) -> dict[str, Any]:
"""Bind a CycloneDX SBOM to the exact promoted source artifact by SHA-256."""
if not isinstance(sbom, dict) or sbom.get("bomFormat") != "CycloneDX":
raise ValueError("SBOM must be a CycloneDX JSON object")
if sbom.get("specVersion") != "1.5":
@@ -303,12 +303,12 @@ def bind_sbom(sbom: object, wheel: Path) -> dict[str, Any]:
component = metadata.get("component")
if not isinstance(component, dict) or component.get("name") != "obliteratus":
raise ValueError("SBOM metadata must describe obliteratus")
digest = hashlib.sha256(wheel.read_bytes()).hexdigest()
digest = hashlib.sha256(artifact.read_bytes()).hexdigest()
component["hashes"] = [{"alg": "SHA-256", "content": digest}]
properties = component.setdefault("properties", [])
if not isinstance(properties, list):
raise ValueError("SBOM component properties must be a list")
properties.append({"name": "obliteratus:distribution-file", "value": wheel.name})
properties.append({"name": "obliteratus:release-artifact", "value": artifact.name})
return sbom
@@ -343,7 +343,7 @@ def _parser() -> argparse.ArgumentParser:
licenses.add_argument("--decision", type=Path, required=True)
sbom = commands.add_parser("sbom")
sbom.add_argument("--input", type=Path, required=True)
sbom.add_argument("--wheel", type=Path, required=True)
sbom.add_argument("--artifact", type=Path, required=True)
sbom.add_argument("--output", type=Path, required=True)
return parser
@@ -354,9 +354,9 @@ def main() -> int:
failures = validate_policy(_read_json(args.policy))
return _write_decision(Path("/dev/null"), {"passed": not failures, "failures": failures})
if args.command == "sbom":
bound = bind_sbom(_read_json(args.input), args.wheel)
bound = bind_sbom(_read_json(args.input), args.artifact)
args.output.write_text(json.dumps(bound, indent=2) + "\n", encoding="utf-8")
print(f"bound SBOM to {args.wheel.name}")
print(f"bound SBOM to {args.artifact.name}")
return 0
policy = _read_json(args.policy)
+31 -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,33 @@ 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",
"artifactType": "source-zip",
"snapshotOnce": True,
"verifyBeforePromotion": True,
}
+30
View File
@@ -41,6 +41,36 @@ def test_every_external_action_is_sha_pinned_and_manifested():
assert entries[("action", name)] == (pin, version)
def test_tested_source_snapshot_is_created_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 'git archive \\' in package
assert '--format=zip' in package
assert 'subject-path: release/*.zip' in package
assert "python -m build" not in package
assert "*.whl" not in package
assert "*.tar.gz" not 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 "tested-source-snapshot-py3.12" in supply_chain
assert "find release -maxdepth 1 -type f -name '*.zip'" 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")]
+5 -1
View File
@@ -5,13 +5,17 @@ from __future__ import annotations
import importlib.metadata
import json
import sys
import tomllib
from pathlib import Path
from types import SimpleNamespace
import pytest
import yaml
try:
import tomllib
except ModuleNotFoundError: # pragma: no cover - exercised by the Python 3.10 CI lane
import tomli as tomllib
from scripts import jetson_support
from scripts import run_conditional_gate
from scripts import setup_jetson
+6 -6
View File
@@ -177,24 +177,24 @@ def test_secret_gate_requires_redaction_even_for_suppressed_finding():
assert any("not fully redacted" in failure for failure in decision["failures"])
def test_bind_sbom_adds_exact_wheel_hash(tmp_path):
wheel = tmp_path / "obliteratus-0.1.2-py3-none-any.whl"
wheel.write_bytes(b"wheel")
def test_bind_sbom_adds_exact_release_artifact_hash(tmp_path):
artifact = tmp_path / "OBLITERATUS-deadbeef.zip"
artifact.write_bytes(b"source snapshot")
sbom = {
"bomFormat": "CycloneDX",
"specVersion": "1.5",
"metadata": {"component": {"name": "obliteratus"}},
}
bound = MODULE.bind_sbom(sbom, wheel)
bound = MODULE.bind_sbom(sbom, artifact)
component = bound["metadata"]["component"]
assert component["hashes"] == [
{
"alg": "SHA-256",
"content": "ba59926159d2aa256eb8739b8da7e2b574b960e1202c6d624cbe981cef996c91",
"content": "41637c7875947b50775c0ab2bb30a28b292be748376a5713eb8f527d9953433c",
},
]
assert component["properties"] == [
{"name": "obliteratus:distribution-file", "value": wheel.name},
{"name": "obliteratus:release-artifact", "value": artifact.name},
]