Skip to content

fix(release): bind provenance to the triggering CI head, not the built commit - #2647

Merged
namastex888 merged 1 commit into
devfrom
fix/provenance-trigger-sha
Jul 25, 2026
Merged

namastex888 merged 1 commit into
devfrom
fix/provenance-trigger-sha

Conversation

@namastex888

Copy link
Copy Markdown
Contributor

Every dev release has failed silently since 2026-07-25

v5.260725.1, .2, and .4 all died at sign-attest: verify_exact exits 1 with no error message, immediately after printing PASSED: SLSA verification passed. All four Sign jobs fail, publish is skipped, no manifest advances.

Root cause: comparing two deliberately-different commits

verify_automated_event asserted:

$run.head_sha == $source_sha

$run is the CI workflow_run that triggered the release. source_sha is documented as "Exact CI-approved commit that produced the tarballs". Those are never equal on an automated release — auto-version commits the version bump after CI, and the build runs from the bump commit:

commit
CI run 30173890949 head_sha 7b084992
SOURCE_SHA (built) 0466b433
parent of 0466b433 7b084992

They differ by exactly one commit, always. The assertion is unsatisfiable by construction, and jq -e fails silently, which is why the log shows a bare exit code 1.

release-publish.yml carried the same defect one stage later — it compares the generic descriptor's sourceSha (also the trigger head) against SOURCE_SHA. It would have failed the moment signing was fixed.

Fix

  • Plumb trigger_sha (github.event.workflow_run.head_sha) through version.yml → release.yml → sign-attest.yml + release-publish.yml. Optional input, so the stable dispatch path is unaffected (it records source_sha directly and is already self-consistent).
  • verify_automated_event binds head_sha to TRIGGER_SHA, and requires a well-formed one whenever exact verification is demanded. No binding is lost — the run id still pins the admitting run exactly, and head_sha is an attribute of that same run.
  • release-publish.yml compares the generic descriptor against TRIGGER_SHA for dev/homolog and SOURCE_SHA for stable. The native predicate records source_sha directly and stays compared against it.

Why it shipped

The test fixture set head_sha: SOURCE_SHA — modelling a world that cannot occur. It now models the real one, plus a regression test asserting the old shape is rejected and covering forged, absent, and malformed trigger SHAs.

Attribution

Not caused by the GitHub App change (#2643). The first failure was 16:55; that fix only reached main at 20:01. This regression arrived with the verification tightening promoted in #2624.

Verification: release-generic-provenance.test.ts 6 pass, plus release-docs + release-native-predicate — 48 pass / 0 fail. bash -n clean, all four workflows valid YAML. (bun run check also reports 2 pre-existing doctor.ts complexity errors that are present on clean dev and unrelated to this change.)

…t commit

Every dev release since 2026-07-25 has failed at sign-attest, silently:
verify_exact exits 1 with no message immediately after 'PASSED: SLSA
verification passed', killing all four Sign jobs and skipping publish.

verify_automated_event asserted $run.head_sha == $source_sha, where
$run is the CI workflow_run that TRIGGERED the release and source_sha is
the commit the tarballs were built from. Those are never equal on an
automated release: auto-version commits the version bump after CI, and
the build runs from that bump commit. Observed on v5.260725.4 — CI run
30173890949 head 7b08499, SOURCE_SHA 0466b43, whose parent is exactly
7b08499. The assertion is unsatisfiable by construction.

release-publish.yml carried the same defect one stage later, comparing
the generic descriptor's sourceSha (also the trigger head) against
SOURCE_SHA — it would have failed as soon as signing was fixed.

- plumb trigger_sha (github.event.workflow_run.head_sha) through
  version.yml -> release.yml -> sign-attest.yml + release-publish.yml,
  optional so the stable dispatch path is unaffected
- verify_automated_event binds head_sha to TRIGGER_SHA and requires a
  well-formed one whenever exact verification is demanded; run id still
  pins the admitting run exactly, so no binding is lost
- release-publish.yml compares the generic descriptor against TRIGGER_SHA
  for dev/homolog and SOURCE_SHA for stable; the native predicate records
  source_sha directly and stays compared against it
- the test fixture set head_sha = SOURCE_SHA, modelling an impossible
  world, which is why this shipped; it now models the real one and gains
  a regression test covering forged, absent, and malformed triggers

Not caused by the App-token change: the first failure (16:55) predates
that fix reaching main (20:01).
@gemini-code-assist

Copy link
Copy Markdown
Contributor

Caution

The consumer version of Gemini Code Assist on GitHub has been sunset. All code review activity has officially ceased.

@coderabbitai

coderabbitai Bot commented Jul 25, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on base/target branches other than the default branch.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 1a5d05cf-3073-49b0-b6b5-f638a6117e0a

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch fix/provenance-trigger-sha

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: b3128bb67d

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

SOURCE_SHA: ${{ inputs.source_sha }}
SOURCE_BRANCH: ${{ inputs.source_branch }}
SOURCE_CI_RUN_ID: ${{ inputs.source_ci_run_id }}
TRIGGER_SHA: ${{ inputs.trigger_sha }}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Pass trigger SHA to the generic provenance self-check

For every automated dev or homolog release, verify_automated_event now requires a valid TRIGGER_SHA, but this value is exported only to the native-predicate step here; the later “Verify SLSA provenance (self-check)” step exports SOURCE_SHA, SOURCE_BRANCH, and SOURCE_CI_RUN_ID without TRIGGER_SHA. Because step environments are isolated, release-generic-provenance.sh verify-exact exits 2, so signing fails before any automated tarball can be promoted. Pass the input into that verification step as well.

AGENTS.md reference: AGENTS.md:L43-L45

Useful? React with 👍 / 👎.

@namastex888
namastex888 merged commit 08f9527 into dev Jul 25, 2026
12 checks passed
@automagik-genie
automagik-genie deleted the fix/provenance-trigger-sha branch September 25, 2026 04:50
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant