@kungfu-tech/buildchain 4.0.1-alpha.28 → 4.0.1-alpha.29

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "name": "Buildchain",
6
6
  "package": "@kungfu-tech/buildchain",
7
- "version": "4.0.1-alpha.28",
7
+ "version": "4.0.1-alpha.29",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "majorLine": "v4",
@@ -2211,7 +2211,7 @@
2211
2211
  "manual entries carry source file digests so downstream sites and agents can detect stale hand-written documentation"
2212
2212
  ],
2213
2213
  "breakingDigest": "sha256:7d0d2819e3a3e72989d9c57b5efe9d0bc0a79bc0f2c82a0c7b9d6c5a211a91f2",
2214
- "auditDigest": "sha256:9ac244b89ab685df5c1d43ebcb9195c9133261b77d2ce948e3d4083e8651f086"
2214
+ "auditDigest": "sha256:3364a1cbb6d6131b9d8bfef296034759e0ae0d6d91d02a95eb5efc67eb853a09"
2215
2215
  },
2216
2216
  {
2217
2217
  "contractVersion": 1,
@@ -5308,5 +5308,5 @@
5308
5308
  "compatibilityFactCutRoot": "sha256:f61b975d4a96c921cc4bd37fb3ed9a0596b47004fe34dc7219979d697e3707f9",
5309
5309
  "compatibilityProofRegistryRoot": "sha256:b7194b811e4d3af2df4390bc4d1731e16a86215bd64ee18cb630dd5492f4fb63",
5310
5310
  "compatibilityDigest": "sha256:5de1c69386510b74b17eb70141b8bdd07063d62c504f91db5e84b67c6d4b64a2",
5311
- "contractDigest": "sha256:62e5a481e28ba6397b3a08ea610eea9a5777a162cade57b491b4273ab96ef561"
5311
+ "contractDigest": "sha256:70a9a84556986cd7e5a608f6c3d597bbf6ec72f332eab8dd8d37dde816586abe"
5312
5312
  }
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-bundle",
4
- "generatedAt": "2026-08-23T13:40:22.242Z",
5
- "publishedAt": "2026-08-23T13:40:22.242Z",
4
+ "generatedAt": "2026-08-23T14:42:39.277Z",
5
+ "publishedAt": "2026-08-23T14:42:39.277Z",
6
6
  "reproducible": true,
7
7
  "timestampPolicy": "ci-injected",
8
8
  "deterministicInputs": [
@@ -19,7 +19,7 @@
19
19
  "declared Buildchain surface manifest contract"
20
20
  ],
21
21
  "sourceDateEpoch": "0",
22
- "sourceRevision": "3c83a3212470ef967cda326752d11a2c608ad473",
22
+ "sourceRevision": "3a76f52ca4b6a694c7bf501d1b806694b8c81dcd",
23
23
  "timestampPolicyDetails": {
24
24
  "contract": "kungfu-buildchain-surface-timestamp-policy",
25
25
  "timestampFields": [
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "package": {
39
39
  "name": "@kungfu-tech/buildchain",
40
- "version": "4.0.1-alpha.28",
40
+ "version": "4.0.1-alpha.29",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "source": {
@@ -3869,7 +3869,7 @@
3869
3869
  ],
3870
3870
  "maturity": "stable",
3871
3871
  "sourcePath": "docs/release-candidate.md",
3872
- "digest": "sha256:d76bbd75aab3c4dd94756c1c64562a125e74369c7c8b97342dbcacc5d7561602",
3872
+ "digest": "sha256:4e79bc9094c929e43c819045e2a2d4132430cd9b307db62e5e21573b7d0a6f53",
3873
3873
  "headings": [
3874
3874
  {
3875
3875
  "level": 1,
@@ -3887,7 +3887,7 @@
3887
3887
  "anchor": "resume-from-an-existing-candidate-run"
3888
3888
  }
3889
3889
  ],
3890
- "markdown": "# Release Candidate Passport\n\nThe release-candidate passport is the pre-promotion evidence contract produced\nafter a reusable build matrix succeeds and before any publish-gate side effects\nrun. It is different from the release passport:\n\n- `release-candidate-passport.json` proves which source SHA, channel, runtime,\n workflow run, and platform artifacts were verified before promotion.\n- `buildchain.release.json` is generated after publish finalization and remains\n the durable audit entrypoint for the published release.\n\nEnable it on the reusable build workflow:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v3\n with:\n artifact-name: libnode\n release-candidate: true\n publish-channel: alpha\n publish-source-ref: publish-gate/alpha/v22/v22.22/22.22.3-kf.3-alpha.7\n```\n\nWhen the platform matrix and aggregate summaries complete, Buildchain uploads:\n\n```text\n<artifact-name>-release-candidate-<publish-source-sha>\n```\n\nThe passport contract is `kungfu-buildchain-release-candidate-passport`. It\ncontains:\n\n- repository and pull request context;\n- target channel, target ref, and product version or a non-publish\n `source-<shortSha>` candidate label;\n- source head SHA, merge ref SHA, and the Git `HEAD^{tree}` SHA for PR merge\n equivalence after the channel PR lands;\n- Buildchain runtime ref/SHA and workflow shell ref;\n- workflow run id/attempt/url;\n- normalized platform matrix and artifact summaries;\n- the hash of the aggregate `build-summary.json`.\n\n## Initiative-family release evidence\n\nA consumer may pass `release-candidate-family-evidence-json` to the reusable\nbuild. Buildchain normalizes that value as\n`kungfu-buildchain-initiative-family-release-evidence/v1`, binds it into the\ncandidate hash, and carries it unchanged into publication authority. The\nenvelope can identify one Initiative family root plus the exact Initiative and\nAssignment responsible for the release; continuation evidence can also bind\nthe previous family root.\n\nThis is an adapter-edge release contract, not a second Work Control authority.\nThe immutable native Family State v1 projection and the additive Family State\nv2 typed envelope remain owned by Kungfu. Buildchain only proves that the\nrelease candidate consumed the caller-supplied family evidence exactly.\n\nPromotion workflows that should not rebuild artifacts can enable:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v3\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ needs.build.outputs.publish-source-sha }}\n target-ref: alpha/v22/v22.22\n promote-only-release-candidate: \"true\"\n release-candidate-passport-path: .buildchain/artifacts/release-candidate-passport.json\n release-candidate-build-summary-path: .buildchain/artifacts/build-summary.json\n release-candidate-family-evidence-required: \"true\"\n release-candidate-family-evidence-root: sha256:<initiative-family-root>\n release-candidate-family-initiative-id: 2026-07-30-example-initiative\n release-candidate-family-assignment-id: 2026-07-30-example-release\n```\n\nWith `promote-only-release-candidate: \"true\"`, promotion fails before\nversion-state, publish transaction, tag, or branch side effects when the\npassport does not match the repository, channel, source identity, platform\nmatrix, or build-summary hash. Source identity accepts the exact PR source SHA,\nthe PR merge ref SHA, or an exact Git tree match with the promoted channel HEAD;\nthis keeps post-merge channel commits strict without forcing a rebuild. The\nBuildchain-owned promotion workflow resolves the matching same-repository\nmerged channel PR and downloads its PR-stage RC passport automatically before\npromotion starts. The consumer wrapper defaults to a PR-stage workflow file\nnamed `build.yml` with display name `Build`, and filters the RC passport and\nbuild summary by the configured `artifact-name` before promotion. It also\ndownloads payload artifacts from the same PR-stage run, validates the required\npayload count, passes downloaded platform manifests into the release passport,\nand either forwards an explicit `publish-required-artifacts-json` value or\ngenerates one before calling `promote-buildchain-ref`. Before that call, the\nwrapper creates or updates `publish-gate/{alpha,release,major}` to the\npromotion channel commit and passes that ref, target SHA, and `locked=true` to\nthe promote action with `require-publish-source-lock: \"true\"`. Consumers using\nfloating `@v3` therefore get publish-side source-lock drift protection without\ncopying resolver or promote YAML. The default npm path\ngenerates that requirement list from the downloaded `.tgz` payloads themselves:\nBuildchain reads `package/package.json` inside each tarball for the real scoped\npackage name and version, computes npm-style `sha512-...` integrity over the\ntarball bytes, marks `publish-package-main` as `role: main`, and marks every\nother package as `role: platform`. Consumer workflows therefore stay\ndeclarative and do not need their own artifact download or publish-evidence\ngeneration scripts.\n\nWhen `release-candidate-family-evidence-required` is true, the promotion\nboundary additionally requires the exact family root and may require the\nInitiative and Assignment ids. Missing, mismatched, or source-drifted family\nevidence fails before version-state, release-state, tag, or branch mutation.\n\nBecause a channel merge can trigger promotion before its PR-stage matrix has\nfinished uploading evidence, the resolver waits up to ten minutes for the exact\nmerged PR's successful workflow run and paired artifacts. Polling remains bound\nto the PR/head identity; timeout or a sibling run still fails closed.\n\nThe public promotion router preserves the requested `vN` or `vN-alpha` ref as\naudit metadata, but binds the router to GitHub's selected reusable-workflow SHA\nand resolves each remaining floating shell/runtime ref exactly once. Every\nlater checkout and delegated promotion receives those immutable SHAs, so a\nchannel tag moving during the run cannot mix two Buildchain revisions.\n\n## Resume from an existing candidate run\n\nDo not rely on `gh run rerun` after a reusable-workflow startup or router\nfailure. GitHub documents two different rerun behaviors: a full rerun may use a\ncalled workflow from the currently specified ref, while a failed-job rerun uses\nthe same called-workflow commit as the original attempt. Neither operation is a\nsupported way to create a job graph that GitHub failed to resolve at startup.\nSee GitHub's [reusable workflow rerun behavior](https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations#behavior-of-reusable-workflows-when-re-running-jobs)\nand [workflow rerun identity rules](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/re-run-workflows-and-jobs).\n\nThe supported recovery boundary is a new `workflow_dispatch` (or another new\ncaller event) that invokes `release-candidate-promote.yml` and supplies the old\ncandidate run explicitly:\n\n```yaml\nname: Resume release candidate\non:\n workflow_dispatch:\n inputs:\n candidate-run-id: { required: true, type: string }\n target-sha: { required: true, type: string }\n expected-tree: { required: true, type: string }\n candidate-runtime-sha: { required: true, type: string }\n buildchain-runtime-sha: { required: true, type: string }\n\njobs:\n resume:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@<exact-current-buildchain-sha>\n permissions:\n actions: write\n checks: write\n contents: write\n id-token: write\n pull-requests: write\n secrets: inherit\n with:\n buildchain-ref: ${{ inputs.buildchain-runtime-sha }}\n channel: alpha\n target-ref: alpha/v3/v3.0\n target-sha: ${{ inputs.target-sha }}\n artifact-name: product\n artifact-patterns: product-package-*\n release-candidate-workflow-file: build.yml\n release-candidate-workflow-name: Build\n resume-candidate-repository: ${{ github.repository }}\n resume-candidate-run-id: ${{ inputs.candidate-run-id }}\n resume-expected-workflow-file: build.yml\n resume-expected-workflow-name: Build\n resume-expected-source-tree: ${{ inputs.expected-tree }}\n resume-expected-candidate-runtime-sha: ${{ inputs.candidate-runtime-sha }}\n resume-buildchain-runtime-sha: ${{ inputs.buildchain-runtime-sha }}\n publish-transaction-override: true\n```\n\n`resume-expected-candidate-root` may replace `resume-expected-source-tree`, or\ncallers may provide both. `resume-transaction-id` is optional; when supplied it\nmust identify an already durable transaction before any provider mutation.\n\nRecovery downloads and checks the successful `pull_request` run, active\nworkflow file and name, same-repository merged PR, trusted repository\nassociation, target ancestry, promotion tree, Passport candidate root,\nbuild-summary root, controller receipts, platform matrix, artifact archive\nsize/digest, every manifest file, and every product payload byte. Tree equality\nalone is never admission. A different promotion commit is allowed only when all\nof those identities still agree.\n\nThe recovery path conditionally skips consumer dependency installation and all\nproduct `install`, `build`, `verify`, and platform-matrix jobs. It restores the\ndownloaded bytes as a content-addressed sealed bundle, so npm publication uses\nthe original `.tgz`. The explicit recovery entry binds the bundle identity to\nthe original candidate runtime recorded in the Passport; a newer recovery\ntooling SHA is recorded only in the recovery evidence and cannot perturb the\ndurable payload root. A transaction-only re-resolution remains a narrower\nfinalization path and is not a substitute for the candidate-run entry when the\noriginal complete artifact inventory must be reconstructed. Recovery may\nregenerate only Buildchain-owned receipts,\nattestations, signatures, Release Passport data, publication, and readback.\n\nSuccess emits `kungfu-buildchain-release-candidate-recovery/v1` with\n`action: reused`, the original run/source/tree, candidate and artifact roots,\nthe skipped stages, current tooling SHA, transaction identity/state, and an\nexact receipt root. The receipt is uploaded as an Actions artifact and staged\nwith immutable GitHub Release Passport assets.\n\nThe original candidate Passport is never rewritten when a reusable fixture or\nconsumer build records a product version different from the sealed publication\npackage. In that case the promote action validates the Passport without\ndiscarding its original target, then requires the immutable recovery receipt to\nbind the original candidate root and source/tree to the exact version read from\nthe sealed payload. Without that receipt, the existing direct Passport version\ncheck remains mandatory; receipt, candidate-root, target, or version drift fails\nbefore publication side effects.\n\nMissing or expired artifacts, archive or payload digest drift, tree/root,\nrepository/workflow/channel/target mismatch, untrusted run/PR provenance,\nincomplete controller evidence, and transaction conflict fail closed with an\nerror code and next action. Buildchain never converts recovery failure into a\nhidden full rebuild. A repository owner must choose a new candidate build\nexplicitly.\n\nWhen a durable transaction is absent, recovery seals one from the verified\ncandidate. Existing `sealed`, `publishing`, `package-published`, `finalizing`,\nand `complete` transactions use the normal idempotent state machine. Matching\nregistry and GitHub bytes are preserved, only missing publication work is\nperformed, and conflicting public digests enter `repair_required`.\n\nWhen the immutable recovery receipt proves that the transaction was already\n`complete` before the recovery run began, Buildchain verifies the existing\npublic Release Passport bundle in place and reports the GitHub Release action\nas `reused`. Buildchain-owned evidence regenerated by newer recovery tooling is\nkept in the new recovery artifact; it does not replace same-name evidence that\nwas sealed by the original completed publication. Every declared product\npayload is still compared byte-for-byte, a missing payload is uploaded from the\nrestored sealed bundle, and a conflicting payload digest fails closed. Ordinary\nduplicate publication without a complete recovery receipt retains the stricter\nsame-name/same-digest rule for all assets.\n\nAfter a transaction finalizes, the target branch can legitimately advance from\nthe original promotion SHA. Repeating explicit recovery accepts that movement\nonly when the caller supplies the exact durable transaction identity, the\ntransaction remains resumable, and GitHub proves the observed target head is a\ndescendant of the original transaction source. The recovery receipt records\nboth the immutable transaction SHA and the observed ref SHA. Missing identity,\nunrelated advancement, or a repair state fails closed.\n\nBy default, the wrapper forwards GitHub Release publication to the underlying\n`promote-buildchain-ref` semver model. Once the release transaction is complete,\nthe action creates or updates the public GitHub Release, applies\nprerelease/latest metadata from the authoritative publication channel (falling\nback to semver tag syntax only for ordinary callers without that intent), and\nuploads the publish evidence file together with the generated release passport\nassets. This keeps\nnpm/registry publication, Buildchain release passport persistence, and\n`release.published` propagation in one declarative reusable workflow. Consumers\nthat do not publish GitHub Releases can opt out with `github-release: false`.\nFor anchored/manual package releases, the public GitHub Release tag defaults to\n`v<publishedVersion>` while the internal transaction exact tag remains recorded\nin the release passport.\n\nStandalone binary publication is a separate consumer capability. The promotion\nwrapper does not assume that an npm-only repository provides\n`.github/workflows/binary-distribution.yml`. Repositories that own that workflow\nopt in with `standalone-binary-distribution: true`; Buildchain's self-promotion\ndoes so explicitly. Once enabled, a missing or invalid binary workflow remains a\nhard failure rather than being silently skipped.\n\nProducts that publish KFD release trust evidence can keep that path declarative\ntoo. Pass KFD-1 self contract witnesses, KFD-2 public claim files, and KFD-3\npre-build/artifact evidence into the wrapper:\n\n```yaml\njobs:\n promote:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@v3\n with:\n buildchain-channel: auto\n buildchain-alpha-contract-lock-path: .buildchain/alpha-contract-lock.json\n buildchain-stable-contract-lock-path: .buildchain/contract-lock.json\n channel: alpha\n artifact-name: libnode\n release-passport-kfd-1-witness-jsons: .buildchain/kfd/kfd-1/standard-contract.witness.json\n release-passport-kfd-2-claim-jsons: .buildchain/kfd/kfd-2/release-claims.json\n release-passport-kfd-3-prebuild-witness-jsons: .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json\n release-passport-kfd-3-artifact-verify-command: kungfu agent verify --json\n```\n\nBuildchain forwards those declarations into `promote-buildchain-ref`, verifies\nKFD-1 source/artifact contract surfaces, audits KFD-2 public release claims, and\ncompares KFD-3 declared shipped public surfaces with artifact-exposed public\nsurfaces. The release passport records the results under `kfd-1`, `kfd-2`, and\nthe KFD-provided `kfd-3` section.\n\nManaged consumers may also ask the promotion wrapper to assemble sealed\npublication evidence from the exact release candidate instead of producing\nshort-lived admission JSON in repository-specific workflow code:\n\n```yaml\n publication-auto-admission: true\n publication-auto-no-gate: true\n publication-publisher-workflow-path: .github/workflows/buildchain-ref-promotion.yml\n publication-product: Example Product\n publication-target: npm:@example/product\n publication-package-name: \"@example/product\"\n```\n\n`publication-auto-no-gate` is an explicit consumer decision, not a default. A\nconsumer with a Shifu Gate registry either supplies\n`publication-gate-aggregate-json`, or supplies a source-controlled\n`publication-gate-command` that writes the aggregate to\n`BUILDCHAIN_PUBLICATION_GATE_RESULT_PATH`. The command runs from the exact\nconsumer source in the credential-free sealed-authority job, after Buildchain\nhas downloaded the exact RC passport, summary, controller receipt, manifests,\nand payload bytes. It can read those inputs through\n`BUILDCHAIN_PUBLICATION_EVIDENCE_ROOT`; it receives no publication token, OIDC\npermission, or provider write permission. Buildchain validates the aggregate\ndigest and exact source binding before it seals a capability. Exactly one of\nthe supplied aggregate, consumer command, or explicit no-Gate decision is\nallowed. Buildchain still requires caller-owned RC evidence, an exact authority\nruntime and source SHA, a repository-local publisher workflow, matching npm\ntarget/package identity or exact caller-bound GitHub Release target, and a\nqualifying control-plane audit.\n\nPromotion resolves the complete PR-stage workflow, not only the first required\nstatus job that becomes green. `release-candidate-wait-seconds` bounds that\nwait and defaults to three hours so long native builds can finish controller,\npublication-tail, and retained-evidence jobs without racing a merged promotion.\nAn incomplete or failed workflow still fails closed; the longer bound does not\nturn a partial required-check result into candidate evidence.\n\nGitHub-Release-only consumers use the same managed admission without inventing\nan npm package identity:\n\n```yaml\n publication-auto-admission: true\n publication-auto-no-gate: true\n publication-publisher-workflow-path: .github/workflows/buildchain-ref-promotion.yml\n publication-product: Example Binary\n publication-target: github-release:example/example-binary\n publication-package-name: \"\"\n```\n\nThe target must exactly match the caller repository. Buildchain audits the\njob-scoped GitHub token, exact release-candidate payloads and manifests,\nprotected channel lineage, and public release transaction before allowing the\nGitHub Release mutation.\n\nA consumer that owns additional product qualification semantics can opt in to\nthe sealed handoff without teaching Buildchain those semantics:\n\n```yaml\n publication-consumer-predicate-id: kungfu.release-admission/v1\n publication-consumer-qualification-command: node scripts/qualify-release.mjs\n```\n\nThe command reads `BUILDCHAIN_PUBLICATION_CAPABILITY_PATH` and\n`BUILDCHAIN_PUBLICATION_GATE_AGGREGATE_PATH`, evaluates the complete aggregate,\nand writes a decision JSON document to\n`BUILDCHAIN_PUBLICATION_QUALIFICATION_RESULT_PATH`. It also receives\n`BUILDCHAIN_PUBLICATION_PREDICATE_ID` and\n`BUILDCHAIN_PUBLICATION_PREDICATE_DIGEST`. The separate qualification job has\nno write or OIDC permission and does not inherit publication secrets. A\nsuccessful deterministic receipt is rechecked by the provider action\nimmediately before mutation. Omitting both inputs preserves the existing\nconsumer contract; supplying only one fails closed."
3890
+ "markdown": "# Release Candidate Passport\n\nThe release-candidate passport is the pre-promotion evidence contract produced\nafter a reusable build matrix succeeds and before any publish-gate side effects\nrun. It is different from the release passport:\n\n- `release-candidate-passport.json` proves which source SHA, channel, runtime,\n workflow run, and platform artifacts were verified before promotion.\n- `buildchain.release.json` is generated after publish finalization and remains\n the durable audit entrypoint for the published release.\n\nEnable it on the reusable build workflow:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v3\n with:\n artifact-name: libnode\n release-candidate: true\n publish-channel: alpha\n publish-source-ref: publish-gate/alpha/v22/v22.22/22.22.3-kf.3-alpha.7\n```\n\nWhen the platform matrix and aggregate summaries complete, Buildchain uploads:\n\n```text\n<artifact-name>-release-candidate-<publish-source-sha>\n```\n\nThe passport contract is `kungfu-buildchain-release-candidate-passport`. It\ncontains:\n\n- repository and pull request context;\n- target channel, target ref, and product version or a non-publish\n `source-<shortSha>` candidate label;\n- source head SHA, merge ref SHA, and the Git `HEAD^{tree}` SHA for PR merge\n equivalence after the channel PR lands;\n- Buildchain runtime ref/SHA and workflow shell ref;\n- workflow run id/attempt/url;\n- normalized platform matrix and artifact summaries;\n- the hash of the aggregate `build-summary.json`.\n\n## Initiative-family release evidence\n\nA consumer may pass `release-candidate-family-evidence-json` to the reusable\nbuild. Buildchain normalizes that value as\n`kungfu-buildchain-initiative-family-release-evidence/v1`, binds it into the\ncandidate hash, and carries it unchanged into publication authority. The\nenvelope can identify one Initiative family root plus the exact Initiative and\nAssignment responsible for the release; continuation evidence can also bind\nthe previous family root.\n\nThis is an adapter-edge release contract, not a second Work Control authority.\nThe immutable native Family State v1 projection and the additive Family State\nv2 typed envelope remain owned by Kungfu. Buildchain only proves that the\nrelease candidate consumed the caller-supplied family evidence exactly.\n\nPromotion workflows that should not rebuild artifacts can enable:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v3\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ needs.build.outputs.publish-source-sha }}\n target-ref: alpha/v22/v22.22\n promote-only-release-candidate: \"true\"\n release-candidate-passport-path: .buildchain/artifacts/release-candidate-passport.json\n release-candidate-build-summary-path: .buildchain/artifacts/build-summary.json\n release-candidate-family-evidence-required: \"true\"\n release-candidate-family-evidence-root: sha256:<initiative-family-root>\n release-candidate-family-initiative-id: 2026-07-30-example-initiative\n release-candidate-family-assignment-id: 2026-07-30-example-release\n```\n\nWith `promote-only-release-candidate: \"true\"`, promotion fails before\nversion-state, publish transaction, tag, or branch side effects when the\npassport does not match the repository, channel, source identity, platform\nmatrix, or build-summary hash. Source identity accepts the exact PR source SHA,\nthe PR merge ref SHA, or an exact Git tree match with the promoted channel HEAD;\nthis keeps post-merge channel commits strict without forcing a rebuild. The\nBuildchain-owned promotion workflow resolves the matching same-repository\nmerged channel PR and downloads its PR-stage RC passport automatically before\npromotion starts. The consumer wrapper defaults to a PR-stage workflow file\nnamed `build.yml` with display name `Build`, and filters the RC passport and\nbuild summary by the configured `artifact-name` before promotion. It also\ndownloads payload artifacts from the same PR-stage run, validates the required\npayload count, passes downloaded platform manifests into the release passport,\nand either forwards an explicit `publish-required-artifacts-json` value or\ngenerates one before calling `promote-buildchain-ref`. Before that call, the\nwrapper creates or updates `publish-gate/{alpha,release,major}` to the\npromotion channel commit and passes that ref, target SHA, and `locked=true` to\nthe promote action with `require-publish-source-lock: \"true\"`. Consumers using\nfloating `@v3` therefore get publish-side source-lock drift protection without\ncopying resolver or promote YAML. The default npm path\ngenerates that requirement list from the downloaded `.tgz` payloads themselves:\nBuildchain reads `package/package.json` inside each tarball for the real scoped\npackage name and version, computes npm-style `sha512-...` integrity over the\ntarball bytes, marks `publish-package-main` as `role: main`, and marks every\nother package as `role: platform`. Consumer workflows therefore stay\ndeclarative and do not need their own artifact download or publish-evidence\ngeneration scripts.\n\nWhen `release-candidate-family-evidence-required` is true, the promotion\nboundary additionally requires the exact family root and may require the\nInitiative and Assignment ids. Missing, mismatched, or source-drifted family\nevidence fails before version-state, release-state, tag, or branch mutation.\n\nBecause a channel merge can trigger promotion before its PR-stage matrix has\nfinished uploading evidence, the resolver waits up to ten minutes for the exact\nmerged PR's successful workflow run and paired artifacts. Polling remains bound\nto the PR/head identity; timeout or a sibling run still fails closed.\n\nThe public promotion router preserves the requested `vN` or `vN-alpha` ref as\naudit metadata, but binds the router to GitHub's selected reusable-workflow SHA\nand resolves each remaining floating shell/runtime ref exactly once. Every\nlater checkout and delegated promotion receives those immutable SHAs, so a\nchannel tag moving during the run cannot mix two Buildchain revisions.\n\n## Resume from an existing candidate run\n\nDo not rely on `gh run rerun` after a reusable-workflow startup or router\nfailure. GitHub documents two different rerun behaviors: a full rerun may use a\ncalled workflow from the currently specified ref, while a failed-job rerun uses\nthe same called-workflow commit as the original attempt. Neither operation is a\nsupported way to create a job graph that GitHub failed to resolve at startup.\nSee GitHub's [reusable workflow rerun behavior](https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations#behavior-of-reusable-workflows-when-re-running-jobs)\nand [workflow rerun identity rules](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/re-run-workflows-and-jobs).\n\nThe supported recovery boundary is a new `workflow_dispatch` (or another new\ncaller event) that invokes `release-candidate-promote.yml` and supplies the old\ncandidate run explicitly:\n\n```yaml\nname: Resume release candidate\non:\n workflow_dispatch:\n inputs:\n candidate-run-id: { required: true, type: string }\n target-sha: { required: true, type: string }\n expected-tree: { required: true, type: string }\n candidate-runtime-sha: { required: true, type: string }\n buildchain-runtime-sha: { required: true, type: string }\n\njobs:\n resume:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@<exact-current-buildchain-sha>\n permissions:\n actions: write\n checks: write\n contents: write\n id-token: write\n pull-requests: write\n secrets: inherit\n with:\n buildchain-ref: ${{ inputs.buildchain-runtime-sha }}\n channel: alpha\n target-ref: alpha/v3/v3.0\n target-sha: ${{ inputs.target-sha }}\n artifact-name: product\n artifact-patterns: product-package-*\n release-candidate-workflow-file: build.yml\n release-candidate-workflow-name: Build\n resume-candidate-repository: ${{ github.repository }}\n resume-candidate-run-id: ${{ inputs.candidate-run-id }}\n resume-expected-workflow-file: build.yml\n resume-expected-workflow-name: Build\n resume-expected-source-tree: ${{ inputs.expected-tree }}\n resume-expected-candidate-runtime-sha: ${{ inputs.candidate-runtime-sha }}\n resume-buildchain-runtime-sha: ${{ inputs.buildchain-runtime-sha }}\n publish-transaction-override: true\n```\n\n`resume-expected-candidate-root` may replace `resume-expected-source-tree`, or\ncallers may provide both. `resume-transaction-id` is optional; when supplied it\nmust identify an already durable transaction before any provider mutation.\n\nRecovery downloads and checks the successful `pull_request` run, active\nworkflow file and name, same-repository merged PR, trusted repository\nassociation, target ancestry, promotion tree, Passport candidate root,\nbuild-summary root, controller receipts, platform matrix, artifact archive\nsize/digest, every manifest file, and every product payload byte. Tree equality\nalone is never admission. A different promotion commit is allowed only when all\nof those identities still agree.\n\nThe recovery path conditionally skips consumer dependency installation and all\nproduct `install`, `build`, `verify`, and platform-matrix jobs. It restores the\ndownloaded bytes as a content-addressed sealed bundle, so npm publication uses\nthe original `.tgz`. The explicit recovery entry binds the bundle identity to\nthe original candidate runtime recorded in the Passport; a newer recovery\ntooling SHA is recorded only in the recovery evidence and cannot perturb the\ndurable payload root. A transaction-only re-resolution remains a narrower\nfinalization path and is not a substitute for the candidate-run entry when the\noriginal complete artifact inventory must be reconstructed. Recovery may\nregenerate only Buildchain-owned receipts,\nattestations, signatures, Release Passport data, publication, and readback.\n\nSuccess emits `kungfu-buildchain-release-candidate-recovery/v1` with\n`action: reused`, the original run/source/tree, candidate and artifact roots,\nthe skipped stages, current tooling SHA, transaction identity/state, and an\nexact receipt root. The receipt is uploaded as an Actions artifact and staged\nwith immutable GitHub Release Passport assets.\n\nThe original candidate Passport is never rewritten when a reusable fixture or\nconsumer build records a product version different from the sealed publication\npackage. In that case the promote action validates the Passport without\ndiscarding its original target, then requires the immutable recovery receipt to\nbind the original candidate root and source/tree to the exact version read from\nthe sealed payload. Without that receipt, the existing direct Passport version\ncheck remains mandatory; receipt, candidate-root, target, or version drift fails\nbefore publication side effects.\n\nMissing or expired artifacts, archive or payload digest drift, tree/root,\nrepository/workflow/channel/target mismatch, untrusted run/PR provenance,\nincomplete controller evidence, and transaction conflict fail closed with an\nerror code and next action. Buildchain never converts recovery failure into a\nhidden full rebuild. A repository owner must choose a new candidate build\nexplicitly.\n\nWhen a durable transaction is absent, recovery seals one from the verified\ncandidate. Existing `sealed`, `publishing`, `package-published`, `finalizing`,\nand `complete` transactions use the normal idempotent state machine. Matching\nregistry and GitHub bytes are preserved, only missing publication work is\nperformed, and conflicting public digests enter `repair_required`.\n\nWhen the immutable recovery receipt proves that the transaction was already\n`complete` before the recovery run began, Buildchain verifies the existing\npublic Release Passport bundle in place and reports the GitHub Release action\nas `reused`. Buildchain-owned evidence regenerated by newer recovery tooling is\nkept in the new recovery artifact; it does not replace same-name evidence that\nwas sealed by the original completed publication. Every declared product\npayload is still compared byte-for-byte, a missing payload is uploaded from the\nrestored sealed bundle, and a conflicting payload digest fails closed. Ordinary\nduplicate publication without a complete recovery receipt retains the stricter\nsame-name/same-digest rule for all assets.\n\nIf that explicit complete recovery finds that the public Release Passport is\nabsent, it may restore the complete locally verified evidence closure. Before\nthe first upload, Buildchain rejects undeclared remote assets and compares every\nsame-name remote asset byte-for-byte; any unknown name or digest conflict fails\nclosed without mutation. Ordinary duplicate publication cannot enter this\nrepair path.\n\nAfter a transaction finalizes, the target branch can legitimately advance from\nthe original promotion SHA. Repeating explicit recovery accepts that movement\nonly when the caller supplies the exact durable transaction identity, the\ntransaction remains resumable, and GitHub proves the observed target head is a\ndescendant of the original transaction source. The recovery receipt records\nboth the immutable transaction SHA and the observed ref SHA. Missing identity,\nunrelated advancement, or a repair state fails closed.\n\nBy default, the wrapper forwards GitHub Release publication to the underlying\n`promote-buildchain-ref` semver model. Once the release transaction is complete,\nthe action creates or updates the public GitHub Release, applies\nprerelease/latest metadata from the authoritative publication channel (falling\nback to semver tag syntax only for ordinary callers without that intent), and\nuploads the publish evidence file together with the generated release passport\nassets. This keeps\nnpm/registry publication, Buildchain release passport persistence, and\n`release.published` propagation in one declarative reusable workflow. Consumers\nthat do not publish GitHub Releases can opt out with `github-release: false`.\nFor anchored/manual package releases, the public GitHub Release tag defaults to\n`v<publishedVersion>` while the internal transaction exact tag remains recorded\nin the release passport.\n\nStandalone binary publication is a separate consumer capability. The promotion\nwrapper does not assume that an npm-only repository provides\n`.github/workflows/binary-distribution.yml`. Repositories that own that workflow\nopt in with `standalone-binary-distribution: true`; Buildchain's self-promotion\ndoes so explicitly. Once enabled, a missing or invalid binary workflow remains a\nhard failure rather than being silently skipped.\n\nProducts that publish KFD release trust evidence can keep that path declarative\ntoo. Pass KFD-1 self contract witnesses, KFD-2 public claim files, and KFD-3\npre-build/artifact evidence into the wrapper:\n\n```yaml\njobs:\n promote:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@v3\n with:\n buildchain-channel: auto\n buildchain-alpha-contract-lock-path: .buildchain/alpha-contract-lock.json\n buildchain-stable-contract-lock-path: .buildchain/contract-lock.json\n channel: alpha\n artifact-name: libnode\n release-passport-kfd-1-witness-jsons: .buildchain/kfd/kfd-1/standard-contract.witness.json\n release-passport-kfd-2-claim-jsons: .buildchain/kfd/kfd-2/release-claims.json\n release-passport-kfd-3-prebuild-witness-jsons: .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json\n release-passport-kfd-3-artifact-verify-command: kungfu agent verify --json\n```\n\nBuildchain forwards those declarations into `promote-buildchain-ref`, verifies\nKFD-1 source/artifact contract surfaces, audits KFD-2 public release claims, and\ncompares KFD-3 declared shipped public surfaces with artifact-exposed public\nsurfaces. The release passport records the results under `kfd-1`, `kfd-2`, and\nthe KFD-provided `kfd-3` section.\n\nManaged consumers may also ask the promotion wrapper to assemble sealed\npublication evidence from the exact release candidate instead of producing\nshort-lived admission JSON in repository-specific workflow code:\n\n```yaml\n publication-auto-admission: true\n publication-auto-no-gate: true\n publication-publisher-workflow-path: .github/workflows/buildchain-ref-promotion.yml\n publication-product: Example Product\n publication-target: npm:@example/product\n publication-package-name: \"@example/product\"\n```\n\n`publication-auto-no-gate` is an explicit consumer decision, not a default. A\nconsumer with a Shifu Gate registry either supplies\n`publication-gate-aggregate-json`, or supplies a source-controlled\n`publication-gate-command` that writes the aggregate to\n`BUILDCHAIN_PUBLICATION_GATE_RESULT_PATH`. The command runs from the exact\nconsumer source in the credential-free sealed-authority job, after Buildchain\nhas downloaded the exact RC passport, summary, controller receipt, manifests,\nand payload bytes. It can read those inputs through\n`BUILDCHAIN_PUBLICATION_EVIDENCE_ROOT`; it receives no publication token, OIDC\npermission, or provider write permission. Buildchain validates the aggregate\ndigest and exact source binding before it seals a capability. Exactly one of\nthe supplied aggregate, consumer command, or explicit no-Gate decision is\nallowed. Buildchain still requires caller-owned RC evidence, an exact authority\nruntime and source SHA, a repository-local publisher workflow, matching npm\ntarget/package identity or exact caller-bound GitHub Release target, and a\nqualifying control-plane audit.\n\nPromotion resolves the complete PR-stage workflow, not only the first required\nstatus job that becomes green. `release-candidate-wait-seconds` bounds that\nwait and defaults to three hours so long native builds can finish controller,\npublication-tail, and retained-evidence jobs without racing a merged promotion.\nAn incomplete or failed workflow still fails closed; the longer bound does not\nturn a partial required-check result into candidate evidence.\n\nGitHub-Release-only consumers use the same managed admission without inventing\nan npm package identity:\n\n```yaml\n publication-auto-admission: true\n publication-auto-no-gate: true\n publication-publisher-workflow-path: .github/workflows/buildchain-ref-promotion.yml\n publication-product: Example Binary\n publication-target: github-release:example/example-binary\n publication-package-name: \"\"\n```\n\nThe target must exactly match the caller repository. Buildchain audits the\njob-scoped GitHub token, exact release-candidate payloads and manifests,\nprotected channel lineage, and public release transaction before allowing the\nGitHub Release mutation.\n\nA consumer that owns additional product qualification semantics can opt in to\nthe sealed handoff without teaching Buildchain those semantics:\n\n```yaml\n publication-consumer-predicate-id: kungfu.release-admission/v1\n publication-consumer-qualification-command: node scripts/qualify-release.mjs\n```\n\nThe command reads `BUILDCHAIN_PUBLICATION_CAPABILITY_PATH` and\n`BUILDCHAIN_PUBLICATION_GATE_AGGREGATE_PATH`, evaluates the complete aggregate,\nand writes a decision JSON document to\n`BUILDCHAIN_PUBLICATION_QUALIFICATION_RESULT_PATH`. It also receives\n`BUILDCHAIN_PUBLICATION_PREDICATE_ID` and\n`BUILDCHAIN_PUBLICATION_PREDICATE_DIGEST`. The separate qualification job has\nno write or OIDC permission and does not inherit publication secrets. A\nsuccessful deterministic receipt is rechecked by the provider action\nimmediately before mutation. Omitting both inputs preserves the existing\nconsumer contract; supplying only one fails closed."
3891
3891
  },
3892
3892
  {
3893
3893
  "id": "manual:release-flow",
@@ -5756,7 +5756,7 @@
5756
5756
  "path": "docs/release-candidate.md",
5757
5757
  "plane": "verify",
5758
5758
  "exists": true,
5759
- "digest": "sha256:d76bbd75aab3c4dd94756c1c64562a125e74369c7c8b97342dbcacc5d7561602"
5759
+ "digest": "sha256:4e79bc9094c929e43c819045e2a2d4132430cd9b307db62e5e21573b7d0a6f53"
5760
5760
  },
5761
5761
  {
5762
5762
  "id": "release-train",
@@ -21,7 +21,7 @@
21
21
  "contract": "kungfu-buildchain-public-surface-reverse-audit",
22
22
  "path": "dist/site/public-surface-audit.json",
23
23
  "status": "passed",
24
- "sha256": "755a10787512d04ca0c065414c3c9c3bbb0f33dc40a3b12debbcfd1b191fa35b",
24
+ "sha256": "6abec1955d8558f59ea7b96f49b8cb62d4b3d5014b01e8353c8a051e4a3758bf",
25
25
  "summary": {
26
26
  "cliCommandCount": 117,
27
27
  "workflowCount": 76,
@@ -246,7 +246,7 @@
246
246
  "contract": "kungfu-buildchain-public-surface-reverse-audit",
247
247
  "path": "dist/site/public-surface-audit.json",
248
248
  "status": "passed",
249
- "sha256": "755a10787512d04ca0c065414c3c9c3bbb0f33dc40a3b12debbcfd1b191fa35b",
249
+ "sha256": "6abec1955d8558f59ea7b96f49b8cb62d4b3d5014b01e8353c8a051e4a3758bf",
250
250
  "summary": {
251
251
  "cliCommandCount": 117,
252
252
  "workflowCount": 76,
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "id": "kungfu-tech-buildchain",
6
6
  "name": "@kungfu-tech/buildchain",
7
- "version": "4.0.1-alpha.28",
7
+ "version": "4.0.1-alpha.29",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "source": {
@@ -136,7 +136,7 @@
136
136
  "title": "Release Candidate Passport",
137
137
  "path": "docs/release-candidate.md",
138
138
  "plane": "verify",
139
- "digest": "sha256:d76bbd75aab3c4dd94756c1c64562a125e74369c7c8b97342dbcacc5d7561602",
139
+ "digest": "sha256:4e79bc9094c929e43c819045e2a2d4132430cd9b307db62e5e21573b7d0a6f53",
140
140
  "capabilityGroup": "reusable-build",
141
141
  "audience": [
142
142
  "release-operator",
@@ -3803,7 +3803,7 @@
3803
3803
  ],
3804
3804
  "maturity": "stable",
3805
3805
  "sourcePath": "docs/release-candidate.md",
3806
- "digest": "sha256:d76bbd75aab3c4dd94756c1c64562a125e74369c7c8b97342dbcacc5d7561602",
3806
+ "digest": "sha256:4e79bc9094c929e43c819045e2a2d4132430cd9b307db62e5e21573b7d0a6f53",
3807
3807
  "headings": [
3808
3808
  {
3809
3809
  "level": 1,
@@ -3821,7 +3821,7 @@
3821
3821
  "anchor": "resume-from-an-existing-candidate-run"
3822
3822
  }
3823
3823
  ],
3824
- "markdown": "# Release Candidate Passport\n\nThe release-candidate passport is the pre-promotion evidence contract produced\nafter a reusable build matrix succeeds and before any publish-gate side effects\nrun. It is different from the release passport:\n\n- `release-candidate-passport.json` proves which source SHA, channel, runtime,\n workflow run, and platform artifacts were verified before promotion.\n- `buildchain.release.json` is generated after publish finalization and remains\n the durable audit entrypoint for the published release.\n\nEnable it on the reusable build workflow:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v3\n with:\n artifact-name: libnode\n release-candidate: true\n publish-channel: alpha\n publish-source-ref: publish-gate/alpha/v22/v22.22/22.22.3-kf.3-alpha.7\n```\n\nWhen the platform matrix and aggregate summaries complete, Buildchain uploads:\n\n```text\n<artifact-name>-release-candidate-<publish-source-sha>\n```\n\nThe passport contract is `kungfu-buildchain-release-candidate-passport`. It\ncontains:\n\n- repository and pull request context;\n- target channel, target ref, and product version or a non-publish\n `source-<shortSha>` candidate label;\n- source head SHA, merge ref SHA, and the Git `HEAD^{tree}` SHA for PR merge\n equivalence after the channel PR lands;\n- Buildchain runtime ref/SHA and workflow shell ref;\n- workflow run id/attempt/url;\n- normalized platform matrix and artifact summaries;\n- the hash of the aggregate `build-summary.json`.\n\n## Initiative-family release evidence\n\nA consumer may pass `release-candidate-family-evidence-json` to the reusable\nbuild. Buildchain normalizes that value as\n`kungfu-buildchain-initiative-family-release-evidence/v1`, binds it into the\ncandidate hash, and carries it unchanged into publication authority. The\nenvelope can identify one Initiative family root plus the exact Initiative and\nAssignment responsible for the release; continuation evidence can also bind\nthe previous family root.\n\nThis is an adapter-edge release contract, not a second Work Control authority.\nThe immutable native Family State v1 projection and the additive Family State\nv2 typed envelope remain owned by Kungfu. Buildchain only proves that the\nrelease candidate consumed the caller-supplied family evidence exactly.\n\nPromotion workflows that should not rebuild artifacts can enable:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v3\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ needs.build.outputs.publish-source-sha }}\n target-ref: alpha/v22/v22.22\n promote-only-release-candidate: \"true\"\n release-candidate-passport-path: .buildchain/artifacts/release-candidate-passport.json\n release-candidate-build-summary-path: .buildchain/artifacts/build-summary.json\n release-candidate-family-evidence-required: \"true\"\n release-candidate-family-evidence-root: sha256:<initiative-family-root>\n release-candidate-family-initiative-id: 2026-07-30-example-initiative\n release-candidate-family-assignment-id: 2026-07-30-example-release\n```\n\nWith `promote-only-release-candidate: \"true\"`, promotion fails before\nversion-state, publish transaction, tag, or branch side effects when the\npassport does not match the repository, channel, source identity, platform\nmatrix, or build-summary hash. Source identity accepts the exact PR source SHA,\nthe PR merge ref SHA, or an exact Git tree match with the promoted channel HEAD;\nthis keeps post-merge channel commits strict without forcing a rebuild. The\nBuildchain-owned promotion workflow resolves the matching same-repository\nmerged channel PR and downloads its PR-stage RC passport automatically before\npromotion starts. The consumer wrapper defaults to a PR-stage workflow file\nnamed `build.yml` with display name `Build`, and filters the RC passport and\nbuild summary by the configured `artifact-name` before promotion. It also\ndownloads payload artifacts from the same PR-stage run, validates the required\npayload count, passes downloaded platform manifests into the release passport,\nand either forwards an explicit `publish-required-artifacts-json` value or\ngenerates one before calling `promote-buildchain-ref`. Before that call, the\nwrapper creates or updates `publish-gate/{alpha,release,major}` to the\npromotion channel commit and passes that ref, target SHA, and `locked=true` to\nthe promote action with `require-publish-source-lock: \"true\"`. Consumers using\nfloating `@v3` therefore get publish-side source-lock drift protection without\ncopying resolver or promote YAML. The default npm path\ngenerates that requirement list from the downloaded `.tgz` payloads themselves:\nBuildchain reads `package/package.json` inside each tarball for the real scoped\npackage name and version, computes npm-style `sha512-...` integrity over the\ntarball bytes, marks `publish-package-main` as `role: main`, and marks every\nother package as `role: platform`. Consumer workflows therefore stay\ndeclarative and do not need their own artifact download or publish-evidence\ngeneration scripts.\n\nWhen `release-candidate-family-evidence-required` is true, the promotion\nboundary additionally requires the exact family root and may require the\nInitiative and Assignment ids. Missing, mismatched, or source-drifted family\nevidence fails before version-state, release-state, tag, or branch mutation.\n\nBecause a channel merge can trigger promotion before its PR-stage matrix has\nfinished uploading evidence, the resolver waits up to ten minutes for the exact\nmerged PR's successful workflow run and paired artifacts. Polling remains bound\nto the PR/head identity; timeout or a sibling run still fails closed.\n\nThe public promotion router preserves the requested `vN` or `vN-alpha` ref as\naudit metadata, but binds the router to GitHub's selected reusable-workflow SHA\nand resolves each remaining floating shell/runtime ref exactly once. Every\nlater checkout and delegated promotion receives those immutable SHAs, so a\nchannel tag moving during the run cannot mix two Buildchain revisions.\n\n## Resume from an existing candidate run\n\nDo not rely on `gh run rerun` after a reusable-workflow startup or router\nfailure. GitHub documents two different rerun behaviors: a full rerun may use a\ncalled workflow from the currently specified ref, while a failed-job rerun uses\nthe same called-workflow commit as the original attempt. Neither operation is a\nsupported way to create a job graph that GitHub failed to resolve at startup.\nSee GitHub's [reusable workflow rerun behavior](https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations#behavior-of-reusable-workflows-when-re-running-jobs)\nand [workflow rerun identity rules](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/re-run-workflows-and-jobs).\n\nThe supported recovery boundary is a new `workflow_dispatch` (or another new\ncaller event) that invokes `release-candidate-promote.yml` and supplies the old\ncandidate run explicitly:\n\n```yaml\nname: Resume release candidate\non:\n workflow_dispatch:\n inputs:\n candidate-run-id: { required: true, type: string }\n target-sha: { required: true, type: string }\n expected-tree: { required: true, type: string }\n candidate-runtime-sha: { required: true, type: string }\n buildchain-runtime-sha: { required: true, type: string }\n\njobs:\n resume:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@<exact-current-buildchain-sha>\n permissions:\n actions: write\n checks: write\n contents: write\n id-token: write\n pull-requests: write\n secrets: inherit\n with:\n buildchain-ref: ${{ inputs.buildchain-runtime-sha }}\n channel: alpha\n target-ref: alpha/v3/v3.0\n target-sha: ${{ inputs.target-sha }}\n artifact-name: product\n artifact-patterns: product-package-*\n release-candidate-workflow-file: build.yml\n release-candidate-workflow-name: Build\n resume-candidate-repository: ${{ github.repository }}\n resume-candidate-run-id: ${{ inputs.candidate-run-id }}\n resume-expected-workflow-file: build.yml\n resume-expected-workflow-name: Build\n resume-expected-source-tree: ${{ inputs.expected-tree }}\n resume-expected-candidate-runtime-sha: ${{ inputs.candidate-runtime-sha }}\n resume-buildchain-runtime-sha: ${{ inputs.buildchain-runtime-sha }}\n publish-transaction-override: true\n```\n\n`resume-expected-candidate-root` may replace `resume-expected-source-tree`, or\ncallers may provide both. `resume-transaction-id` is optional; when supplied it\nmust identify an already durable transaction before any provider mutation.\n\nRecovery downloads and checks the successful `pull_request` run, active\nworkflow file and name, same-repository merged PR, trusted repository\nassociation, target ancestry, promotion tree, Passport candidate root,\nbuild-summary root, controller receipts, platform matrix, artifact archive\nsize/digest, every manifest file, and every product payload byte. Tree equality\nalone is never admission. A different promotion commit is allowed only when all\nof those identities still agree.\n\nThe recovery path conditionally skips consumer dependency installation and all\nproduct `install`, `build`, `verify`, and platform-matrix jobs. It restores the\ndownloaded bytes as a content-addressed sealed bundle, so npm publication uses\nthe original `.tgz`. The explicit recovery entry binds the bundle identity to\nthe original candidate runtime recorded in the Passport; a newer recovery\ntooling SHA is recorded only in the recovery evidence and cannot perturb the\ndurable payload root. A transaction-only re-resolution remains a narrower\nfinalization path and is not a substitute for the candidate-run entry when the\noriginal complete artifact inventory must be reconstructed. Recovery may\nregenerate only Buildchain-owned receipts,\nattestations, signatures, Release Passport data, publication, and readback.\n\nSuccess emits `kungfu-buildchain-release-candidate-recovery/v1` with\n`action: reused`, the original run/source/tree, candidate and artifact roots,\nthe skipped stages, current tooling SHA, transaction identity/state, and an\nexact receipt root. The receipt is uploaded as an Actions artifact and staged\nwith immutable GitHub Release Passport assets.\n\nThe original candidate Passport is never rewritten when a reusable fixture or\nconsumer build records a product version different from the sealed publication\npackage. In that case the promote action validates the Passport without\ndiscarding its original target, then requires the immutable recovery receipt to\nbind the original candidate root and source/tree to the exact version read from\nthe sealed payload. Without that receipt, the existing direct Passport version\ncheck remains mandatory; receipt, candidate-root, target, or version drift fails\nbefore publication side effects.\n\nMissing or expired artifacts, archive or payload digest drift, tree/root,\nrepository/workflow/channel/target mismatch, untrusted run/PR provenance,\nincomplete controller evidence, and transaction conflict fail closed with an\nerror code and next action. Buildchain never converts recovery failure into a\nhidden full rebuild. A repository owner must choose a new candidate build\nexplicitly.\n\nWhen a durable transaction is absent, recovery seals one from the verified\ncandidate. Existing `sealed`, `publishing`, `package-published`, `finalizing`,\nand `complete` transactions use the normal idempotent state machine. Matching\nregistry and GitHub bytes are preserved, only missing publication work is\nperformed, and conflicting public digests enter `repair_required`.\n\nWhen the immutable recovery receipt proves that the transaction was already\n`complete` before the recovery run began, Buildchain verifies the existing\npublic Release Passport bundle in place and reports the GitHub Release action\nas `reused`. Buildchain-owned evidence regenerated by newer recovery tooling is\nkept in the new recovery artifact; it does not replace same-name evidence that\nwas sealed by the original completed publication. Every declared product\npayload is still compared byte-for-byte, a missing payload is uploaded from the\nrestored sealed bundle, and a conflicting payload digest fails closed. Ordinary\nduplicate publication without a complete recovery receipt retains the stricter\nsame-name/same-digest rule for all assets.\n\nAfter a transaction finalizes, the target branch can legitimately advance from\nthe original promotion SHA. Repeating explicit recovery accepts that movement\nonly when the caller supplies the exact durable transaction identity, the\ntransaction remains resumable, and GitHub proves the observed target head is a\ndescendant of the original transaction source. The recovery receipt records\nboth the immutable transaction SHA and the observed ref SHA. Missing identity,\nunrelated advancement, or a repair state fails closed.\n\nBy default, the wrapper forwards GitHub Release publication to the underlying\n`promote-buildchain-ref` semver model. Once the release transaction is complete,\nthe action creates or updates the public GitHub Release, applies\nprerelease/latest metadata from the authoritative publication channel (falling\nback to semver tag syntax only for ordinary callers without that intent), and\nuploads the publish evidence file together with the generated release passport\nassets. This keeps\nnpm/registry publication, Buildchain release passport persistence, and\n`release.published` propagation in one declarative reusable workflow. Consumers\nthat do not publish GitHub Releases can opt out with `github-release: false`.\nFor anchored/manual package releases, the public GitHub Release tag defaults to\n`v<publishedVersion>` while the internal transaction exact tag remains recorded\nin the release passport.\n\nStandalone binary publication is a separate consumer capability. The promotion\nwrapper does not assume that an npm-only repository provides\n`.github/workflows/binary-distribution.yml`. Repositories that own that workflow\nopt in with `standalone-binary-distribution: true`; Buildchain's self-promotion\ndoes so explicitly. Once enabled, a missing or invalid binary workflow remains a\nhard failure rather than being silently skipped.\n\nProducts that publish KFD release trust evidence can keep that path declarative\ntoo. Pass KFD-1 self contract witnesses, KFD-2 public claim files, and KFD-3\npre-build/artifact evidence into the wrapper:\n\n```yaml\njobs:\n promote:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@v3\n with:\n buildchain-channel: auto\n buildchain-alpha-contract-lock-path: .buildchain/alpha-contract-lock.json\n buildchain-stable-contract-lock-path: .buildchain/contract-lock.json\n channel: alpha\n artifact-name: libnode\n release-passport-kfd-1-witness-jsons: .buildchain/kfd/kfd-1/standard-contract.witness.json\n release-passport-kfd-2-claim-jsons: .buildchain/kfd/kfd-2/release-claims.json\n release-passport-kfd-3-prebuild-witness-jsons: .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json\n release-passport-kfd-3-artifact-verify-command: kungfu agent verify --json\n```\n\nBuildchain forwards those declarations into `promote-buildchain-ref`, verifies\nKFD-1 source/artifact contract surfaces, audits KFD-2 public release claims, and\ncompares KFD-3 declared shipped public surfaces with artifact-exposed public\nsurfaces. The release passport records the results under `kfd-1`, `kfd-2`, and\nthe KFD-provided `kfd-3` section.\n\nManaged consumers may also ask the promotion wrapper to assemble sealed\npublication evidence from the exact release candidate instead of producing\nshort-lived admission JSON in repository-specific workflow code:\n\n```yaml\n publication-auto-admission: true\n publication-auto-no-gate: true\n publication-publisher-workflow-path: .github/workflows/buildchain-ref-promotion.yml\n publication-product: Example Product\n publication-target: npm:@example/product\n publication-package-name: \"@example/product\"\n```\n\n`publication-auto-no-gate` is an explicit consumer decision, not a default. A\nconsumer with a Shifu Gate registry either supplies\n`publication-gate-aggregate-json`, or supplies a source-controlled\n`publication-gate-command` that writes the aggregate to\n`BUILDCHAIN_PUBLICATION_GATE_RESULT_PATH`. The command runs from the exact\nconsumer source in the credential-free sealed-authority job, after Buildchain\nhas downloaded the exact RC passport, summary, controller receipt, manifests,\nand payload bytes. It can read those inputs through\n`BUILDCHAIN_PUBLICATION_EVIDENCE_ROOT`; it receives no publication token, OIDC\npermission, or provider write permission. Buildchain validates the aggregate\ndigest and exact source binding before it seals a capability. Exactly one of\nthe supplied aggregate, consumer command, or explicit no-Gate decision is\nallowed. Buildchain still requires caller-owned RC evidence, an exact authority\nruntime and source SHA, a repository-local publisher workflow, matching npm\ntarget/package identity or exact caller-bound GitHub Release target, and a\nqualifying control-plane audit.\n\nPromotion resolves the complete PR-stage workflow, not only the first required\nstatus job that becomes green. `release-candidate-wait-seconds` bounds that\nwait and defaults to three hours so long native builds can finish controller,\npublication-tail, and retained-evidence jobs without racing a merged promotion.\nAn incomplete or failed workflow still fails closed; the longer bound does not\nturn a partial required-check result into candidate evidence.\n\nGitHub-Release-only consumers use the same managed admission without inventing\nan npm package identity:\n\n```yaml\n publication-auto-admission: true\n publication-auto-no-gate: true\n publication-publisher-workflow-path: .github/workflows/buildchain-ref-promotion.yml\n publication-product: Example Binary\n publication-target: github-release:example/example-binary\n publication-package-name: \"\"\n```\n\nThe target must exactly match the caller repository. Buildchain audits the\njob-scoped GitHub token, exact release-candidate payloads and manifests,\nprotected channel lineage, and public release transaction before allowing the\nGitHub Release mutation.\n\nA consumer that owns additional product qualification semantics can opt in to\nthe sealed handoff without teaching Buildchain those semantics:\n\n```yaml\n publication-consumer-predicate-id: kungfu.release-admission/v1\n publication-consumer-qualification-command: node scripts/qualify-release.mjs\n```\n\nThe command reads `BUILDCHAIN_PUBLICATION_CAPABILITY_PATH` and\n`BUILDCHAIN_PUBLICATION_GATE_AGGREGATE_PATH`, evaluates the complete aggregate,\nand writes a decision JSON document to\n`BUILDCHAIN_PUBLICATION_QUALIFICATION_RESULT_PATH`. It also receives\n`BUILDCHAIN_PUBLICATION_PREDICATE_ID` and\n`BUILDCHAIN_PUBLICATION_PREDICATE_DIGEST`. The separate qualification job has\nno write or OIDC permission and does not inherit publication secrets. A\nsuccessful deterministic receipt is rechecked by the provider action\nimmediately before mutation. Omitting both inputs preserves the existing\nconsumer contract; supplying only one fails closed."
3824
+ "markdown": "# Release Candidate Passport\n\nThe release-candidate passport is the pre-promotion evidence contract produced\nafter a reusable build matrix succeeds and before any publish-gate side effects\nrun. It is different from the release passport:\n\n- `release-candidate-passport.json` proves which source SHA, channel, runtime,\n workflow run, and platform artifacts were verified before promotion.\n- `buildchain.release.json` is generated after publish finalization and remains\n the durable audit entrypoint for the published release.\n\nEnable it on the reusable build workflow:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v3\n with:\n artifact-name: libnode\n release-candidate: true\n publish-channel: alpha\n publish-source-ref: publish-gate/alpha/v22/v22.22/22.22.3-kf.3-alpha.7\n```\n\nWhen the platform matrix and aggregate summaries complete, Buildchain uploads:\n\n```text\n<artifact-name>-release-candidate-<publish-source-sha>\n```\n\nThe passport contract is `kungfu-buildchain-release-candidate-passport`. It\ncontains:\n\n- repository and pull request context;\n- target channel, target ref, and product version or a non-publish\n `source-<shortSha>` candidate label;\n- source head SHA, merge ref SHA, and the Git `HEAD^{tree}` SHA for PR merge\n equivalence after the channel PR lands;\n- Buildchain runtime ref/SHA and workflow shell ref;\n- workflow run id/attempt/url;\n- normalized platform matrix and artifact summaries;\n- the hash of the aggregate `build-summary.json`.\n\n## Initiative-family release evidence\n\nA consumer may pass `release-candidate-family-evidence-json` to the reusable\nbuild. Buildchain normalizes that value as\n`kungfu-buildchain-initiative-family-release-evidence/v1`, binds it into the\ncandidate hash, and carries it unchanged into publication authority. The\nenvelope can identify one Initiative family root plus the exact Initiative and\nAssignment responsible for the release; continuation evidence can also bind\nthe previous family root.\n\nThis is an adapter-edge release contract, not a second Work Control authority.\nThe immutable native Family State v1 projection and the additive Family State\nv2 typed envelope remain owned by Kungfu. Buildchain only proves that the\nrelease candidate consumed the caller-supplied family evidence exactly.\n\nPromotion workflows that should not rebuild artifacts can enable:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v3\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ needs.build.outputs.publish-source-sha }}\n target-ref: alpha/v22/v22.22\n promote-only-release-candidate: \"true\"\n release-candidate-passport-path: .buildchain/artifacts/release-candidate-passport.json\n release-candidate-build-summary-path: .buildchain/artifacts/build-summary.json\n release-candidate-family-evidence-required: \"true\"\n release-candidate-family-evidence-root: sha256:<initiative-family-root>\n release-candidate-family-initiative-id: 2026-07-30-example-initiative\n release-candidate-family-assignment-id: 2026-07-30-example-release\n```\n\nWith `promote-only-release-candidate: \"true\"`, promotion fails before\nversion-state, publish transaction, tag, or branch side effects when the\npassport does not match the repository, channel, source identity, platform\nmatrix, or build-summary hash. Source identity accepts the exact PR source SHA,\nthe PR merge ref SHA, or an exact Git tree match with the promoted channel HEAD;\nthis keeps post-merge channel commits strict without forcing a rebuild. The\nBuildchain-owned promotion workflow resolves the matching same-repository\nmerged channel PR and downloads its PR-stage RC passport automatically before\npromotion starts. The consumer wrapper defaults to a PR-stage workflow file\nnamed `build.yml` with display name `Build`, and filters the RC passport and\nbuild summary by the configured `artifact-name` before promotion. It also\ndownloads payload artifacts from the same PR-stage run, validates the required\npayload count, passes downloaded platform manifests into the release passport,\nand either forwards an explicit `publish-required-artifacts-json` value or\ngenerates one before calling `promote-buildchain-ref`. Before that call, the\nwrapper creates or updates `publish-gate/{alpha,release,major}` to the\npromotion channel commit and passes that ref, target SHA, and `locked=true` to\nthe promote action with `require-publish-source-lock: \"true\"`. Consumers using\nfloating `@v3` therefore get publish-side source-lock drift protection without\ncopying resolver or promote YAML. The default npm path\ngenerates that requirement list from the downloaded `.tgz` payloads themselves:\nBuildchain reads `package/package.json` inside each tarball for the real scoped\npackage name and version, computes npm-style `sha512-...` integrity over the\ntarball bytes, marks `publish-package-main` as `role: main`, and marks every\nother package as `role: platform`. Consumer workflows therefore stay\ndeclarative and do not need their own artifact download or publish-evidence\ngeneration scripts.\n\nWhen `release-candidate-family-evidence-required` is true, the promotion\nboundary additionally requires the exact family root and may require the\nInitiative and Assignment ids. Missing, mismatched, or source-drifted family\nevidence fails before version-state, release-state, tag, or branch mutation.\n\nBecause a channel merge can trigger promotion before its PR-stage matrix has\nfinished uploading evidence, the resolver waits up to ten minutes for the exact\nmerged PR's successful workflow run and paired artifacts. Polling remains bound\nto the PR/head identity; timeout or a sibling run still fails closed.\n\nThe public promotion router preserves the requested `vN` or `vN-alpha` ref as\naudit metadata, but binds the router to GitHub's selected reusable-workflow SHA\nand resolves each remaining floating shell/runtime ref exactly once. Every\nlater checkout and delegated promotion receives those immutable SHAs, so a\nchannel tag moving during the run cannot mix two Buildchain revisions.\n\n## Resume from an existing candidate run\n\nDo not rely on `gh run rerun` after a reusable-workflow startup or router\nfailure. GitHub documents two different rerun behaviors: a full rerun may use a\ncalled workflow from the currently specified ref, while a failed-job rerun uses\nthe same called-workflow commit as the original attempt. Neither operation is a\nsupported way to create a job graph that GitHub failed to resolve at startup.\nSee GitHub's [reusable workflow rerun behavior](https://docs.github.com/en/actions/reference/workflows-and-actions/reusing-workflow-configurations#behavior-of-reusable-workflows-when-re-running-jobs)\nand [workflow rerun identity rules](https://docs.github.com/en/actions/how-tos/manage-workflow-runs/re-run-workflows-and-jobs).\n\nThe supported recovery boundary is a new `workflow_dispatch` (or another new\ncaller event) that invokes `release-candidate-promote.yml` and supplies the old\ncandidate run explicitly:\n\n```yaml\nname: Resume release candidate\non:\n workflow_dispatch:\n inputs:\n candidate-run-id: { required: true, type: string }\n target-sha: { required: true, type: string }\n expected-tree: { required: true, type: string }\n candidate-runtime-sha: { required: true, type: string }\n buildchain-runtime-sha: { required: true, type: string }\n\njobs:\n resume:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@<exact-current-buildchain-sha>\n permissions:\n actions: write\n checks: write\n contents: write\n id-token: write\n pull-requests: write\n secrets: inherit\n with:\n buildchain-ref: ${{ inputs.buildchain-runtime-sha }}\n channel: alpha\n target-ref: alpha/v3/v3.0\n target-sha: ${{ inputs.target-sha }}\n artifact-name: product\n artifact-patterns: product-package-*\n release-candidate-workflow-file: build.yml\n release-candidate-workflow-name: Build\n resume-candidate-repository: ${{ github.repository }}\n resume-candidate-run-id: ${{ inputs.candidate-run-id }}\n resume-expected-workflow-file: build.yml\n resume-expected-workflow-name: Build\n resume-expected-source-tree: ${{ inputs.expected-tree }}\n resume-expected-candidate-runtime-sha: ${{ inputs.candidate-runtime-sha }}\n resume-buildchain-runtime-sha: ${{ inputs.buildchain-runtime-sha }}\n publish-transaction-override: true\n```\n\n`resume-expected-candidate-root` may replace `resume-expected-source-tree`, or\ncallers may provide both. `resume-transaction-id` is optional; when supplied it\nmust identify an already durable transaction before any provider mutation.\n\nRecovery downloads and checks the successful `pull_request` run, active\nworkflow file and name, same-repository merged PR, trusted repository\nassociation, target ancestry, promotion tree, Passport candidate root,\nbuild-summary root, controller receipts, platform matrix, artifact archive\nsize/digest, every manifest file, and every product payload byte. Tree equality\nalone is never admission. A different promotion commit is allowed only when all\nof those identities still agree.\n\nThe recovery path conditionally skips consumer dependency installation and all\nproduct `install`, `build`, `verify`, and platform-matrix jobs. It restores the\ndownloaded bytes as a content-addressed sealed bundle, so npm publication uses\nthe original `.tgz`. The explicit recovery entry binds the bundle identity to\nthe original candidate runtime recorded in the Passport; a newer recovery\ntooling SHA is recorded only in the recovery evidence and cannot perturb the\ndurable payload root. A transaction-only re-resolution remains a narrower\nfinalization path and is not a substitute for the candidate-run entry when the\noriginal complete artifact inventory must be reconstructed. Recovery may\nregenerate only Buildchain-owned receipts,\nattestations, signatures, Release Passport data, publication, and readback.\n\nSuccess emits `kungfu-buildchain-release-candidate-recovery/v1` with\n`action: reused`, the original run/source/tree, candidate and artifact roots,\nthe skipped stages, current tooling SHA, transaction identity/state, and an\nexact receipt root. The receipt is uploaded as an Actions artifact and staged\nwith immutable GitHub Release Passport assets.\n\nThe original candidate Passport is never rewritten when a reusable fixture or\nconsumer build records a product version different from the sealed publication\npackage. In that case the promote action validates the Passport without\ndiscarding its original target, then requires the immutable recovery receipt to\nbind the original candidate root and source/tree to the exact version read from\nthe sealed payload. Without that receipt, the existing direct Passport version\ncheck remains mandatory; receipt, candidate-root, target, or version drift fails\nbefore publication side effects.\n\nMissing or expired artifacts, archive or payload digest drift, tree/root,\nrepository/workflow/channel/target mismatch, untrusted run/PR provenance,\nincomplete controller evidence, and transaction conflict fail closed with an\nerror code and next action. Buildchain never converts recovery failure into a\nhidden full rebuild. A repository owner must choose a new candidate build\nexplicitly.\n\nWhen a durable transaction is absent, recovery seals one from the verified\ncandidate. Existing `sealed`, `publishing`, `package-published`, `finalizing`,\nand `complete` transactions use the normal idempotent state machine. Matching\nregistry and GitHub bytes are preserved, only missing publication work is\nperformed, and conflicting public digests enter `repair_required`.\n\nWhen the immutable recovery receipt proves that the transaction was already\n`complete` before the recovery run began, Buildchain verifies the existing\npublic Release Passport bundle in place and reports the GitHub Release action\nas `reused`. Buildchain-owned evidence regenerated by newer recovery tooling is\nkept in the new recovery artifact; it does not replace same-name evidence that\nwas sealed by the original completed publication. Every declared product\npayload is still compared byte-for-byte, a missing payload is uploaded from the\nrestored sealed bundle, and a conflicting payload digest fails closed. Ordinary\nduplicate publication without a complete recovery receipt retains the stricter\nsame-name/same-digest rule for all assets.\n\nIf that explicit complete recovery finds that the public Release Passport is\nabsent, it may restore the complete locally verified evidence closure. Before\nthe first upload, Buildchain rejects undeclared remote assets and compares every\nsame-name remote asset byte-for-byte; any unknown name or digest conflict fails\nclosed without mutation. Ordinary duplicate publication cannot enter this\nrepair path.\n\nAfter a transaction finalizes, the target branch can legitimately advance from\nthe original promotion SHA. Repeating explicit recovery accepts that movement\nonly when the caller supplies the exact durable transaction identity, the\ntransaction remains resumable, and GitHub proves the observed target head is a\ndescendant of the original transaction source. The recovery receipt records\nboth the immutable transaction SHA and the observed ref SHA. Missing identity,\nunrelated advancement, or a repair state fails closed.\n\nBy default, the wrapper forwards GitHub Release publication to the underlying\n`promote-buildchain-ref` semver model. Once the release transaction is complete,\nthe action creates or updates the public GitHub Release, applies\nprerelease/latest metadata from the authoritative publication channel (falling\nback to semver tag syntax only for ordinary callers without that intent), and\nuploads the publish evidence file together with the generated release passport\nassets. This keeps\nnpm/registry publication, Buildchain release passport persistence, and\n`release.published` propagation in one declarative reusable workflow. Consumers\nthat do not publish GitHub Releases can opt out with `github-release: false`.\nFor anchored/manual package releases, the public GitHub Release tag defaults to\n`v<publishedVersion>` while the internal transaction exact tag remains recorded\nin the release passport.\n\nStandalone binary publication is a separate consumer capability. The promotion\nwrapper does not assume that an npm-only repository provides\n`.github/workflows/binary-distribution.yml`. Repositories that own that workflow\nopt in with `standalone-binary-distribution: true`; Buildchain's self-promotion\ndoes so explicitly. Once enabled, a missing or invalid binary workflow remains a\nhard failure rather than being silently skipped.\n\nProducts that publish KFD release trust evidence can keep that path declarative\ntoo. Pass KFD-1 self contract witnesses, KFD-2 public claim files, and KFD-3\npre-build/artifact evidence into the wrapper:\n\n```yaml\njobs:\n promote:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@v3\n with:\n buildchain-channel: auto\n buildchain-alpha-contract-lock-path: .buildchain/alpha-contract-lock.json\n buildchain-stable-contract-lock-path: .buildchain/contract-lock.json\n channel: alpha\n artifact-name: libnode\n release-passport-kfd-1-witness-jsons: .buildchain/kfd/kfd-1/standard-contract.witness.json\n release-passport-kfd-2-claim-jsons: .buildchain/kfd/kfd-2/release-claims.json\n release-passport-kfd-3-prebuild-witness-jsons: .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json\n release-passport-kfd-3-artifact-verify-command: kungfu agent verify --json\n```\n\nBuildchain forwards those declarations into `promote-buildchain-ref`, verifies\nKFD-1 source/artifact contract surfaces, audits KFD-2 public release claims, and\ncompares KFD-3 declared shipped public surfaces with artifact-exposed public\nsurfaces. The release passport records the results under `kfd-1`, `kfd-2`, and\nthe KFD-provided `kfd-3` section.\n\nManaged consumers may also ask the promotion wrapper to assemble sealed\npublication evidence from the exact release candidate instead of producing\nshort-lived admission JSON in repository-specific workflow code:\n\n```yaml\n publication-auto-admission: true\n publication-auto-no-gate: true\n publication-publisher-workflow-path: .github/workflows/buildchain-ref-promotion.yml\n publication-product: Example Product\n publication-target: npm:@example/product\n publication-package-name: \"@example/product\"\n```\n\n`publication-auto-no-gate` is an explicit consumer decision, not a default. A\nconsumer with a Shifu Gate registry either supplies\n`publication-gate-aggregate-json`, or supplies a source-controlled\n`publication-gate-command` that writes the aggregate to\n`BUILDCHAIN_PUBLICATION_GATE_RESULT_PATH`. The command runs from the exact\nconsumer source in the credential-free sealed-authority job, after Buildchain\nhas downloaded the exact RC passport, summary, controller receipt, manifests,\nand payload bytes. It can read those inputs through\n`BUILDCHAIN_PUBLICATION_EVIDENCE_ROOT`; it receives no publication token, OIDC\npermission, or provider write permission. Buildchain validates the aggregate\ndigest and exact source binding before it seals a capability. Exactly one of\nthe supplied aggregate, consumer command, or explicit no-Gate decision is\nallowed. Buildchain still requires caller-owned RC evidence, an exact authority\nruntime and source SHA, a repository-local publisher workflow, matching npm\ntarget/package identity or exact caller-bound GitHub Release target, and a\nqualifying control-plane audit.\n\nPromotion resolves the complete PR-stage workflow, not only the first required\nstatus job that becomes green. `release-candidate-wait-seconds` bounds that\nwait and defaults to three hours so long native builds can finish controller,\npublication-tail, and retained-evidence jobs without racing a merged promotion.\nAn incomplete or failed workflow still fails closed; the longer bound does not\nturn a partial required-check result into candidate evidence.\n\nGitHub-Release-only consumers use the same managed admission without inventing\nan npm package identity:\n\n```yaml\n publication-auto-admission: true\n publication-auto-no-gate: true\n publication-publisher-workflow-path: .github/workflows/buildchain-ref-promotion.yml\n publication-product: Example Binary\n publication-target: github-release:example/example-binary\n publication-package-name: \"\"\n```\n\nThe target must exactly match the caller repository. Buildchain audits the\njob-scoped GitHub token, exact release-candidate payloads and manifests,\nprotected channel lineage, and public release transaction before allowing the\nGitHub Release mutation.\n\nA consumer that owns additional product qualification semantics can opt in to\nthe sealed handoff without teaching Buildchain those semantics:\n\n```yaml\n publication-consumer-predicate-id: kungfu.release-admission/v1\n publication-consumer-qualification-command: node scripts/qualify-release.mjs\n```\n\nThe command reads `BUILDCHAIN_PUBLICATION_CAPABILITY_PATH` and\n`BUILDCHAIN_PUBLICATION_GATE_AGGREGATE_PATH`, evaluates the complete aggregate,\nand writes a decision JSON document to\n`BUILDCHAIN_PUBLICATION_QUALIFICATION_RESULT_PATH`. It also receives\n`BUILDCHAIN_PUBLICATION_PREDICATE_ID` and\n`BUILDCHAIN_PUBLICATION_PREDICATE_DIGEST`. The separate qualification job has\nno write or OIDC permission and does not inherit publication secrets. A\nsuccessful deterministic receipt is rechecked by the provider action\nimmediately before mutation. Omitting both inputs preserves the existing\nconsumer contract; supplying only one fails closed."
3825
3825
  },
3826
3826
  {
3827
3827
  "id": "manual:release-flow",
@@ -8846,8 +8846,8 @@
8846
8846
  "workflowRegistryPath": "dist/site/workflow-registry.json",
8847
8847
  "pageRegistryPath": "dist/site/page-registry.json",
8848
8848
  "cliRegistryDigest": "ea47a31ce7ef3577f23e22055ab7be7715c3af494bcef63f76b426f2883086aa",
8849
- "workflowRegistryDigest": "5d343bb985329c655bab27298c7a9f0be50c296b6a764337428a45a3a6442647",
8850
- "pageRegistryDigest": "9d9d0590c8d3110fc5a95978852ee25337567f93980b2562cc1159f0d5219ade"
8849
+ "workflowRegistryDigest": "f602b7d8eaf472e6ca62516fe07590826600774710b22fdaba1f8f5338ad634c",
8850
+ "pageRegistryDigest": "619910e5c57fb8e94ea1525de1fb7699c412a8dafd7269bc9354cc6c4fe83f48"
8851
8851
  },
8852
8852
  "comparison": {
8853
8853
  "missingCliRegistry": [],
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-publication-release-registry",
4
- "generatedAt": "2026-08-23T13:40:22.242Z",
5
- "publishedAt": "2026-08-23T13:40:22.242Z",
4
+ "generatedAt": "2026-08-23T14:42:39.277Z",
5
+ "publishedAt": "2026-08-23T14:42:39.277Z",
6
6
  "reproducible": true,
7
7
  "timestampPolicy": "ci-injected",
8
8
  "deterministicInputs": [
@@ -19,7 +19,7 @@
19
19
  "declared Buildchain surface manifest contract"
20
20
  ],
21
21
  "sourceDateEpoch": "0",
22
- "sourceRevision": "3c83a3212470ef967cda326752d11a2c608ad473",
22
+ "sourceRevision": "3a76f52ca4b6a694c7bf501d1b806694b8c81dcd",
23
23
  "timestampPolicyDetails": {
24
24
  "contract": "kungfu-buildchain-surface-timestamp-policy",
25
25
  "timestampFields": [
@@ -32,7 +32,7 @@
32
32
  },
33
33
  "package": {
34
34
  "name": "@kungfu-tech/buildchain",
35
- "version": "4.0.1-alpha.28",
35
+ "version": "4.0.1-alpha.29",
36
36
  "versionSource": "package.json#version"
37
37
  },
38
38
  "sourceKind": "package-site-bundle",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-manifest",
4
- "generatedAt": "2026-08-23T13:40:22.242Z",
5
- "publishedAt": "2026-08-23T13:40:22.242Z",
4
+ "generatedAt": "2026-08-23T14:42:39.277Z",
5
+ "publishedAt": "2026-08-23T14:42:39.277Z",
6
6
  "reproducible": true,
7
7
  "timestampPolicy": "ci-injected",
8
8
  "deterministicInputs": [
@@ -19,7 +19,7 @@
19
19
  "declared Buildchain surface manifest contract"
20
20
  ],
21
21
  "sourceDateEpoch": "0",
22
- "sourceRevision": "3c83a3212470ef967cda326752d11a2c608ad473",
22
+ "sourceRevision": "3a76f52ca4b6a694c7bf501d1b806694b8c81dcd",
23
23
  "timestampPolicyDetails": {
24
24
  "contract": "kungfu-buildchain-surface-timestamp-policy",
25
25
  "timestampFields": [
@@ -37,7 +37,7 @@
37
37
  },
38
38
  "package": {
39
39
  "name": "@kungfu-tech/buildchain",
40
- "version": "4.0.1-alpha.28",
40
+ "version": "4.0.1-alpha.29",
41
41
  "versionSource": "package.json#version"
42
42
  },
43
43
  "entrypoint": "buildchain-site.json",
@@ -125,7 +125,7 @@
125
125
  "path": "docs/release-candidate.md",
126
126
  "plane": "verify",
127
127
  "exists": true,
128
- "digest": "sha256:d76bbd75aab3c4dd94756c1c64562a125e74369c7c8b97342dbcacc5d7561602"
128
+ "digest": "sha256:4e79bc9094c929e43c819045e2a2d4132430cd9b307db62e5e21573b7d0a6f53"
129
129
  },
130
130
  {
131
131
  "id": "release-train",
@@ -2027,7 +2027,7 @@
2027
2027
  "status": "preview",
2028
2028
  "owner": "buildchain-workflows",
2029
2029
  "maturity": "preview",
2030
- "introducedVersion": "4.0.1-alpha.28",
2030
+ "introducedVersion": "4.0.1-alpha.29",
2031
2031
  "compatibilityPromise": "preserved-through-the-v3-major-line",
2032
2032
  "deprecationReplacement": "",
2033
2033
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -2048,7 +2048,7 @@
2048
2048
  "status": "preview",
2049
2049
  "owner": "buildchain-workflows",
2050
2050
  "maturity": "preview",
2051
- "introducedVersion": "4.0.1-alpha.28",
2051
+ "introducedVersion": "4.0.1-alpha.29",
2052
2052
  "compatibilityPromise": "preserved-through-the-v3-major-line",
2053
2053
  "deprecationReplacement": "",
2054
2054
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -2069,7 +2069,7 @@
2069
2069
  "status": "preview",
2070
2070
  "owner": "buildchain-workflows",
2071
2071
  "maturity": "preview",
2072
- "introducedVersion": "4.0.1-alpha.28",
2072
+ "introducedVersion": "4.0.1-alpha.29",
2073
2073
  "compatibilityPromise": "preserved-through-the-v3-major-line",
2074
2074
  "deprecationReplacement": "",
2075
2075
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -2119,7 +2119,7 @@
2119
2119
  "status": "preview",
2120
2120
  "owner": "buildchain-workflows",
2121
2121
  "maturity": "preview",
2122
- "introducedVersion": "4.0.1-alpha.28",
2122
+ "introducedVersion": "4.0.1-alpha.29",
2123
2123
  "compatibilityPromise": "preserved-through-the-v3-major-line",
2124
2124
  "deprecationReplacement": "",
2125
2125
  "sunsetCondition": "explicit-breaking-change-review-in-a-future-major-line",
@@ -234,6 +234,13 @@ restored sealed bundle, and a conflicting payload digest fails closed. Ordinary
234
234
  duplicate publication without a complete recovery receipt retains the stricter
235
235
  same-name/same-digest rule for all assets.
236
236
 
237
+ If that explicit complete recovery finds that the public Release Passport is
238
+ absent, it may restore the complete locally verified evidence closure. Before
239
+ the first upload, Buildchain rejects undeclared remote assets and compares every
240
+ same-name remote asset byte-for-byte; any unknown name or digest conflict fails
241
+ closed without mutation. Ordinary duplicate publication cannot enter this
242
+ repair path.
243
+
237
244
  After a transaction finalizes, the target branch can legitimately advance from
238
245
  the original promotion SHA. Repeating explicit recovery accepts that movement
239
246
  only when the caller supplies the exact durable transaction identity, the
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "4.0.1-alpha.28",
3
+ "version": "4.0.1-alpha.29",
4
4
  "private": false,
5
5
  "description": "Buildchain Release Passport, release governance, CLI toolkit, and site facts.",
6
6
  "repository": "https://github.com/kungfu-systems/buildchain",