From 24650785ca1908d73f1d60f8aa5416448230ee64 Mon Sep 17 00:00:00 2001 From: Leif Date: Wed, 29 Jul 2026 07:09:53 -0600 Subject: [PATCH 1/3] fix(release): remove duplicate post-release authentication --- .github/workflows/release.yml | 5 +---- Scripts/test-release-distribution.sh | 5 ++++- Scripts/test-release-provenance.sh | 14 ++++++++------ 3 files changed, 13 insertions(+), 11 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 382c4d4..5aa03cf 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -257,13 +257,10 @@ jobs: - name: Verify remote tag after publication env: ATTEST_BIN: ${{ steps.attest.outputs.binary }} - GITHUB_TOKEN: ${{ github.token }} RELEASE_TAG: ${{ needs.provenance.outputs.tag }} RELEASE_COMMIT: ${{ needs.provenance.outputs.commit }} run: | - authorization="$(printf 'x-access-token:%s' "$GITHUB_TOKEN" | base64)" - git -c "http.https://github.com/.extraheader=AUTHORIZATION: basic ${authorization}" \ - fetch --force origin \ + git fetch --force origin \ "refs/tags/${RELEASE_TAG}:refs/tags/${RELEASE_TAG}" ./Scripts/release-provenance-gate.sh \ "$RELEASE_TAG" "$RELEASE_COMMIT" diff --git a/Scripts/test-release-distribution.sh b/Scripts/test-release-distribution.sh index e4d0d3e..abba362 100755 --- a/Scripts/test-release-distribution.sh +++ b/Scripts/test-release-distribution.sh @@ -33,7 +33,10 @@ grep -Fq 'APS_VERSION="${RELEASE_TAG#v}"' "$workflow" grep -Fq 'test "$RELEASE_TAG" = "v$(cat VERSION)"' "$workflow" grep -Fq 'test "$("$BIN_DIR/aps" --version)" = "${RELEASE_TAG#v}"' "$workflow" test "$(grep -c 'persist-credentials: true' "$workflow")" -eq 2 -! grep -Fq 'authorization="$(printf' "$workflow" +if grep -Fq 'authorization="$(printf' "$workflow"; then + echo "release workflow constructs a manual Authorization header" >&2 + exit 1 +fi grep -Fq 'fetch aps-linux-x86_64-portable.tar.gz' "$formula_workflow" grep -Fq 'Scripts/render-homebrew-formula.py' "$formula_workflow" grep -Fq 'Homebrew formula updates require a stable SemVer tag' "$formula_workflow" diff --git a/Scripts/test-release-provenance.sh b/Scripts/test-release-provenance.sh index 98705ef..d25e2ca 100755 --- a/Scripts/test-release-provenance.sh +++ b/Scripts/test-release-provenance.sh @@ -284,15 +284,17 @@ grep -Fq 'needs: [provenance, test]' "$workflow" grep -Fq "environment: release" "$workflow" grep -Fq "git merge-base --is-ancestor" "$workflow" grep -Fq "Verify remote tag after publication" "$workflow" -token_env_count="$(grep -Fc 'GITHUB_TOKEN: ${{ github.token }}' "$workflow")" -if [[ "$token_env_count" -ne 1 ]]; then - echo "release provenance contract: only remote tag verification needs an explicit job token" >&2 +token_env_count="$(grep -Fc 'GITHUB_TOKEN: ${{ github.token }}' "$workflow" || true)" +if [[ "$token_env_count" -ne 0 ]]; then + echo "release provenance contract: checkout-managed credentials must authenticate all release fetches" >&2 exit 1 fi # shellcheck disable=SC2016 -authenticated_fetch_count="$(grep -Fc 'http.https://github.com/.extraheader=AUTHORIZATION: basic ${authorization}' "$workflow")" -if [[ "$authenticated_fetch_count" -ne 1 ]]; then - echo "release provenance contract: only post-publication verification uses command-scoped authentication" >&2 +authenticated_fetch_count="$( + grep -Fc 'http.https://github.com/.extraheader=AUTHORIZATION: basic ${authorization}' "$workflow" || true +)" +if [[ "$authenticated_fetch_count" -ne 0 ]]; then + echo "release provenance contract: release fetches must not construct command-scoped authentication" >&2 exit 1 fi # shellcheck disable=SC2016 From 5cb652b0ad02d9ba16bde6bc552114908bc8634e Mon Sep 17 00:00:00 2001 From: Leif Date: Wed, 29 Jul 2026 07:16:12 -0600 Subject: [PATCH 2/3] fix(release): emit valid checksum sidecars --- .github/workflows/release.yml | 3 ++- .../change.md | 4 ++-- .../state.json | 4 ++-- .../tasks.md | 1 + .../testing.md | 6 ++++-- Scripts/test-release-distribution.sh | 12 ++++++++++++ 6 files changed, 23 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5aa03cf..573f480 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -221,7 +221,8 @@ jobs: cd artifacts for file in ./*; do [ -f "$file" ] || continue - sha256sum "$file" | sed "s|.*/||" > "${file}.sha256" + sha256sum "$file" > "${file}.sha256" + sha256sum --check "${file}.sha256" done cat -- ./*.sha256 diff --git a/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/change.md b/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/change.md index ab717ca..eeeeab2 100644 --- a/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/change.md +++ b/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/change.md @@ -17,8 +17,8 @@ Fix release workflow fetch authentication so signed tags and attest notes can be ## Acceptance Criteria -- Release fetches use one checkout-managed credential, the release distribution contract rejects manual duplicate Authorization headers, and a v1.1.0 workflow dispatch passes provenance. +- Release fetches use one checkout-managed credential, the release distribution contract rejects manual duplicate Authorization headers, generated checksum sidecars begin with valid SHA-256 digests, and a v1.1.0 workflow dispatch passes through publication. ## No-spec Rationale -This repairs CI authentication plumbing without changing the aps CLI contract or release artifact semantics. +This repairs CI authentication and checksum-generation plumbing without changing the aps CLI contract or release artifact semantics. diff --git a/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/state.json b/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/state.json index f15432b..d895027 100644 --- a/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/state.json +++ b/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/state.json @@ -19,9 +19,9 @@ ".specsync/change-sequence.json" ], "no_spec_change": true, - "no_spec_change_rationale": "This repairs CI authentication plumbing without changing the aps CLI contract or release artifact semantics.", + "no_spec_change_rationale": "This repairs CI authentication and checksum-generation plumbing without changing the aps CLI contract or release artifact semantics.", "acceptance_criteria": [ - "Release fetches use one checkout-managed credential, the release distribution contract rejects manual duplicate Authorization headers, and a v1.1.0 workflow dispatch passes provenance." + "Release fetches use one checkout-managed credential, the release distribution contract rejects manual duplicate Authorization headers, generated checksum sidecars begin with valid SHA-256 digests, and a v1.1.0 workflow dispatch passes through publication." ], "selected_artifacts": [ "context", diff --git a/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/tasks.md b/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/tasks.md index 32b1191..9c40677 100644 --- a/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/tasks.md +++ b/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/tasks.md @@ -7,5 +7,6 @@ artifact: tasks - [x] Replace manual Authorization headers with checkout-managed credentials. - [x] Add a regression contract for the release authentication configuration. +- [x] Generate and validate complete SHA-256 sidecars for release assets. - [x] Run the local verification lane. - [ ] Merge the repair and dispatch the existing v1.1.0 tag. diff --git a/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/testing.md b/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/testing.md index 360ffc0..b254867 100644 --- a/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/testing.md +++ b/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/testing.md @@ -6,7 +6,9 @@ artifact: testing # Testing - `Scripts/test-release-distribution.sh` asserts both release checkouts persist - their job credential and rejects manual Authorization-header construction. + their job credential, rejects manual Authorization-header construction, and + exercises the checksum sidecar format consumed by the formula updater. - `fledge lanes run verify` exercises the release distribution contract. - A `workflow_dispatch` run for `v1.1.0` proves tag, default-branch, and attest - note fetches succeed on the GitHub-hosted runner. + note fetches succeed on the GitHub-hosted runner and replaces the release + assets with verified checksum sidecars. diff --git a/Scripts/test-release-distribution.sh b/Scripts/test-release-distribution.sh index abba362..5604f09 100755 --- a/Scripts/test-release-distribution.sh +++ b/Scripts/test-release-distribution.sh @@ -37,6 +37,18 @@ if grep -Fq 'authorization="$(printf' "$workflow"; then echo "release workflow constructs a manual Authorization header" >&2 exit 1 fi +grep -Fq 'sha256sum "$file" > "${file}.sha256"' "$workflow" +grep -Fq 'sha256sum --check "${file}.sha256"' "$workflow" + +checksum_fixture="$fixture_root/checksum-fixture" +printf 'aps release fixture\n' > "$checksum_fixture" +sha256sum "$checksum_fixture" > "$checksum_fixture.sha256" +sha256sum --check "$checksum_fixture.sha256" +checksum_value="$(awk '{print $1}' "$checksum_fixture.sha256")" +if [[ ! "$checksum_value" =~ ^[0-9a-f]{64}$ ]]; then + echo "release checksum sidecar does not begin with a SHA-256 digest" >&2 + exit 1 +fi grep -Fq 'fetch aps-linux-x86_64-portable.tar.gz' "$formula_workflow" grep -Fq 'Scripts/render-homebrew-formula.py' "$formula_workflow" grep -Fq 'Homebrew formula updates require a stable SemVer tag' "$formula_workflow" From 2f7636c27eb7b6204ed97a20813fcb877f87397c Mon Sep 17 00:00:00 2001 From: Leif Date: Wed, 29 Jul 2026 07:17:59 -0600 Subject: [PATCH 3/3] chore(specsync): refresh release recovery approval --- .../approvals.json | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/approvals.json b/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/approvals.json index 903df2f..fbb934a 100644 --- a/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/approvals.json +++ b/.specsync/changes/CHG-0064-fix-release-workflow-fetch-authentication-so-signed-tags-and-attest-notes-can-be/approvals.json @@ -13,6 +13,13 @@ "timestamp": 1785303960, "digest": "88f806418c29a76c109b528f669ea49b8ecef20b3bfab2d16fb8a15626339ff3", "note": "Refreshed after adding the provenance regression contract to affected paths." + }, + { + "gate": "definition", + "actor": "codex", + "timestamp": 1785331046, + "digest": "bcc2722fe679c60135b60195f92a084146a758b34a1a1d38cebe7bebfb02d439", + "note": "Refreshed after expanding the release recovery contract to validate checksum sidecars." } ], "reopenings": []