@kungfu-tech/buildchain 2.12.6 → 2.12.7-alpha.10
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.
- package/actions/promote-buildchain-ref/README.md +11 -3
- package/bin/buildchain.mjs +78 -0
- package/dist/site/agent-index.json +1 -0
- package/dist/site/artifact-schemas.json +1 -0
- package/dist/site/buildchain-contract.json +163 -38
- package/dist/site/buildchain-site.json +73 -17
- package/dist/site/capability-registry.json +6 -5
- package/dist/site/cli-registry.json +36 -0
- package/dist/site/controller-registry.json +121 -10
- package/dist/site/kfd-claims.json +305 -17
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +16 -2
- package/dist/site/node-api-registry.json +43 -4
- package/dist/site/page-registry.json +58 -11
- package/dist/site/public-surface-audit.json +212 -19
- package/dist/site/publication-authority-registry.json +778 -0
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +4 -0
- package/dist/site/site-manifest.json +15 -6
- package/dist/site/workflow-registry.json +173 -12
- package/docs/MAP.md +2 -1
- package/docs/publication-artifacts.md +25 -18
- package/docs/publication-authority.md +213 -0
- package/docs/release-governance.md +3 -1
- package/docs/shifu-gate-profiles.md +6 -0
- package/package.json +5 -1
- package/packages/core/buildchain-kfd-claims.js +5 -0
- package/packages/core/buildchain-publication-authority.js +80 -0
- package/packages/core/controller-evidence.js +8 -8
- package/packages/core/index.js +35 -0
- package/packages/core/publication-artifact-candidate.js +128 -0
- package/packages/core/publication-authority.js +764 -0
- package/packages/core/publication-control-plane-audit.js +135 -0
- package/scripts/assemble-publication-artifact-admission.mjs +190 -0
- package/scripts/assemble-self-publication-admission.mjs +183 -0
- package/scripts/audit-publication-control-plane.mjs +409 -0
- package/scripts/check-inventory.mjs +25 -2
- package/scripts/generate-site-bundle.mjs +16 -0
- package/scripts/publication-artifact-candidate.mjs +130 -0
- package/scripts/workflow-friction-report.mjs +13 -2
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-site-bundle",
|
|
4
|
-
"generatedAt": "2026-07-
|
|
5
|
-
"publishedAt": "2026-07-
|
|
4
|
+
"generatedAt": "2026-07-15T02:23:03.502Z",
|
|
5
|
+
"publishedAt": "2026-07-15T02:23:03.502Z",
|
|
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": "
|
|
22
|
+
"sourceRevision": "5f17ef81ba524233331ffcd0c15b1fb800b3fa82",
|
|
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": "2.12.
|
|
40
|
+
"version": "2.12.7-alpha.10",
|
|
41
41
|
"versionSource": "package.json#version"
|
|
42
42
|
},
|
|
43
43
|
"source": {
|
|
@@ -64,6 +64,7 @@
|
|
|
64
64
|
"node-api-registry.json",
|
|
65
65
|
"workflow-registry.json",
|
|
66
66
|
"controller-registry.json",
|
|
67
|
+
"publication-authority-registry.json",
|
|
67
68
|
"public-surface-audit.json",
|
|
68
69
|
"release-model.json",
|
|
69
70
|
"artifact-schemas.json",
|
|
@@ -178,7 +179,7 @@
|
|
|
178
179
|
],
|
|
179
180
|
"maturity": "stable",
|
|
180
181
|
"sourcePath": "actions/promote-buildchain-ref/README.md",
|
|
181
|
-
"digest": "sha256:
|
|
182
|
+
"digest": "sha256:0a1794dde5d99af7d505df1ab2ef5c6189fe560faa614f675856bab602813bbf",
|
|
182
183
|
"headings": [
|
|
183
184
|
{
|
|
184
185
|
"level": 1,
|
|
@@ -196,7 +197,7 @@
|
|
|
196
197
|
"anchor": "publish-transactions"
|
|
197
198
|
}
|
|
198
199
|
],
|
|
199
|
-
"markdown": "# promote-buildchain-ref\n\nInternal buildchain action for promoting verified buildchain release-line and\ncompatibility refs from buildchain release channels:\n\n- `alpha/v2/v2.0` creates or reuses the next exact prerelease tag such as\n `v2.0.1-alpha.0`, writes that version into package version state, points the\n alpha and dev channel branches at the version commit, then promotes\n `v2.0-alpha` and, when this is the highest published alpha minor, `v2-alpha`;\n- `release/v2/v2.0` creates or reuses the next exact release tag such as\n `v2.0.0`, writes that version into package version state, points the release\n channel branch and release tags at the release commit, then prepares a second\n source commit for the next exact prerelease tag such as `v2.0.1-alpha.0` and\n points the alpha/dev channel branches plus `v2.0-alpha` at that prerelease\n commit, and moves `v2-alpha` only if no higher v2 minor has published an alpha;\n- `publish-gate/major` accepts a reviewed PR from a production release line such\n as `release/v2/v2.0`, writes the next major production version such as\n `v3.0.0`, points `publish-gate/major`, `release/v3/v3.0`, `v3.0`, and `v3`\n at that release commit, then prepares `v3.0.1-alpha.0` for\n `alpha/v3/v3.0`, `dev/v3/v3.0`, `v3.0-alpha`, and `v3-alpha`. The older `major-gate`\n branch name is a compatibility alias only.\n\nThe release branch name defines the minor line. For example,\n`release/v2/v2.1` creates `v2.1.N`, promotes `v2.1`, and promotes `v2` only\nwhen the next minor tag such as `v2.2` does not already exist.\n\nThe action updates version state in `lerna.json`, root `package.json`, and\nworkspace package manifests discovered from package manager metadata\n(`package.json` workspaces, `lerna.json` packages, or `pnpm-workspace.yaml`).\nPackage manager detection is adaptive (`pnpm`, `npm`, or `yarn`) and is recorded\nin logs.\n\nRepositories can also provide `buildchain.toml` to declare version-state files\nand `lifecycle.verify`. TOML-configured version files take precedence over\npackage-manager discovery and can target JSON, TOML, or regex-based files. The\nversion commit itself is written through the GitHub Git Data API so the ref\ngraph is the durable source of truth. Repositories without any supported version\nstate degrade to ref-only promotion only when strict version state is disabled.\n\nJSON and TOML version entries whose declared key already matches the requested\nversion are treated as semantic no-ops. TOML changes use a parser-verified\nlossless key edit, so repository formatting is preserved and formatter-only\nrelease-preparation commits are not created. If a unique lossless edit cannot\nbe proven, promotion fails closed instead of rewriting the full TOML document.\n\n## Dry Run\n\nUse `dry-run: \"true\"` or the CLI `buildchain release --dry-run` before merging a\nchannel PR when you need to understand what Buildchain would do. This dry-run is\nat the Buildchain release-line level. It explains:\n\n- the legal source branch for the target channel;\n- exact release or alpha tags that would be created or reused;\n- floating tags and channel branches that would move;\n- version-state files and verification lifecycle that would apply;\n- branch protection, PR lineage, and release-from-alpha checks;\n- publish transaction behavior when `lifecycle.publish` or\n `publish-transaction` is enabled.\n\nIt does not move refs, move tags, write package files, run publish commands, or\npublish npm packages. The GitHub action dry-run still calls GitHub APIs to\nresolve the current target SHA and concrete pending ref updates, but every\nwrite is reported as a dry-run update.\n\nRepositories whose package version is anchored to an explicitly selected\nupstream release can opt into manual next-anchor behavior:\n\n```toml\n[version]\nrequired = true\nstrategy = \"anchored\"\nnext = \"manual\"\nmanifest = \"libnode.release.json\"\n```\n\nIn this mode, the action validates the configured version files and anchor\nmanifest through the repository's verify lifecycle, but it does not rewrite the\npackage version to match the Buildchain release tag. After a production\nrelease, it sets `next-anchor-required=true` and does not auto-create the next\nalpha branch or tag. The repository must create the next upstream anchor line\nexplicitly, then run the normal channel promotion flow for that line.\n\nWhen branch protection requires pull requests, generated version-state commits\nstill run through promotion automation first. The action updates\nBuildchain-managed channel protection before generated bookkeeping, adds the\nauthenticated promotion token user or app to the bypass allowlist, creates the\nconfigured required check on the exact generated version-state commit, then\ntries to apply that commit directly. If GitHub still rejects release\nfinalization bookkeeping, Buildchain creates or reuses a same-repository\n`buildchain/version-state/*` PR based on the current target channel head and\nreturns `finalization-needed=true`; a later idempotent promotion run can resume\nfrom the durable transaction state. Strict alpha promotion still fails with a\nconfiguration diagnostic instead of opening a post-publish human PR. Reusable\nwrapper callers should allow `checks: write` so the generated check is owned by\nGitHub Actions and matches the managed branch protection rule.\n\nStable promotion also protects concurrent development work. The reusable\nwrapper checks out the exact current `dev/vN/vN.M` head as a reconciliation\nworkspace. If next-alpha bookkeeping cannot fast-forward that branch, the\naction reruns the declared version-state generation and verification from that\ndev tree, creates a two-parent reconciliation commit from the regenerated\nfiles, and fails closed if the checkout moved before the mutation boundary.\nThis prevents generated projections from an older release tree from replacing\ncapabilities that reached dev while the release was in progress.\n\nFor Buildchain-owned automation, callers may pass\n`branch-protection-bypass-apps`, `branch-protection-bypass-users`, or\n`branch-protection-bypass-teams`. The action still configures managed\n`dev/vN/vN.M`, `alpha/vN/vN.M`, and `release/vN/vN.M` branches with one\nrequired approving review, strict GitHub Actions checks, admin enforcement,\nconversation resolution, no force pushes, and no deletions; the bypass\nallowance only lets the named automation identity apply generated version-state\nor channel bookkeeping without a second human review after the reviewed channel\nPR has already merged. Direct action calls automatically include the current\npromotion token's authenticated user or app when GitHub exposes it; explicit\ninputs are supplemental allowlist entries for less discoverable release\nauthorities.\n\n## Publish Transactions\n\nPromotion can also own external publish side effects. Enable this only from a\ntrusted channel workflow:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n generated-ref-update-token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ github.sha }}\n target-ref: release/v2/v2.0\n publish-transaction: \"true\"\n publish-mode: publish-final-version\n publish-auth: trusted-publishing\n publish-required-artifacts-json: >-\n [\n {\"kind\":\"npm\",\"name\":\"@kungfu-tech/buildchain\",\"ref\":\"2.0.0\",\"digest\":\"sha256:...\"}\n ]\n```\n\nFor anchored/manual package repositories that build through the reusable\nworkflow, keep the publish entrypoint on the `publish-gate/*` source-lock\ncontract:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ needs.build.outputs.publish-source-sha }}\n target-ref: release/v22/v22.22\n require-publish-source-lock: \"true\"\n publish-source-ref: ${{ needs.build.outputs.publish-source-ref }}\n publish-source-sha: ${{ needs.build.outputs.publish-source-sha }}\n publish-source-locked: ${{ needs.build.outputs.publish-source-locked }}\n publish-transaction: \"true\"\n publish-mode: publish-final-version\n publish-auth: trusted-publishing\n```\n\n`target-ref` remains the channel promotion target that must point at `sha`.\n`publish-source-ref` is the reviewed source-lock branch that authorized this\nspecific package publication. Direct `alpha/*` or `release/*` channel refs are\nnot valid publish source locks when `require-publish-source-lock` is enabled,\nand a mismatched `publish-source-sha` fails before any promotion or publish side effects begin.\nThe reusable promote workflow serializes non-dry-run promotion intents per\nrepository and re-reads `target-ref` before checkout, dependency installation,\nrelease-candidate resolution, or publish-gate writes. If a queued intent asks\nfor an older SHA after the protected channel has advanced, the workflow records\nthe requested/current SHA pair, verifies that the current target is ahead of\nthe requested commit, and exits successfully as a superseded no-op. Diverged,\nbehind, or unreadable comparisons still fail closed.\nAfter queued-intent revalidation, the reusable workflow runs the canonical\nrelease-candidate resolver in metadata-only mode before installing candidate\ndependencies or starting the full promotion job. The full job resolves and\ndownloads the evidence again before any publish-gate or publication mutation.\nThis preserves the final exact-evidence trust check while making missing or\nstale PR-stage evidence fail early.\nThe action repeats that check at its mutation boundary for governed promotion\ncalls, closing the race between workflow preflight and action start. Direct\nnon-governed calls and dry-runs keep the strict target mismatch error so local\ndiagnostics cannot silently reinterpret a stale request.\nExpected manual dry-run failures remain visible in the workflow result and do\nnot create automated workflow-friction issues; issue reporting is reserved for\nnon-dry-run promotion failures.\nThe reusable build workflow performs the cheaper channel-ref preflight earlier:\nafter source-lock resolution and before the build matrix, it requires the target\nchannel ref such as `alpha/v22/v22.22` or `release/v22/v22.22` to already point\nat the locked `publish-source-sha`. If not, maintainers should merge the source\ncommit through the channel PR first.\n\nFor promote-only release candidates, attach the PR-stage reusable build evidence\nand fail before publish-gate side effects if it no longer matches:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\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```\n\nThe action validates repository, channel, source identity, platform matrix, and\nthe aggregate build-summary hash before it writes version state, opens\nrelease-state, runs publish transaction logic, or moves tags/branches. Source\nidentity accepts the exact source SHA, the PR merge ref SHA, or the promoted\nchannel HEAD's Git tree SHA matching the passport tree hash. If validation\nfails, run or attach the verified channel PR build first instead of promoting a\nstale or unproven artifact set.\n\nWhen enabled, the action creates or resumes a release transaction keyed by\nrepository, version, source SHA, and target ref. It persists that transaction to\na machine-managed branch under `buildchain/release-state/<version>`, with\n`state.json` and, once available, `evidence.json`. Fresh GitHub runners read\nthat durable ref before running publish, so reruns do not depend on a previous\nrunner's local `.buildchain` directory.\n\nThe action runs `lifecycle.publish` from `buildchain.toml` or the explicit\n`publish-command` input, then validates publish evidence before exact tags and\nfloating refs move. If durable state persistence fails, the action fails closed\nbefore publish or public ref finalization.\n\n`publish-mode` defaults to `publish-final-version`, the token-free path for\nnormal npm Trusted Publishing. Same-version alpha-to-latest recovery must be\ndeclared as `publish-mode: promote-existing-version` and\n`publish-auth: npm-token`; Buildchain runs `npm whoami` before it creates\nrelease-state or moves any `npm dist-tag`. The Trusted Publishing mode is not\nallowed to perform `npm dist-tag add`.\n\nBuildchain itself uses this path for npm. Its `lifecycle.publish` runs\n`node scripts/npm-publish-transaction.mjs`, which publishes\n`@kungfu-tech/buildchain` through npm Trusted Publishing and writes npm\nartifact evidence into the transaction before release refs move. The separate\n`.github/workflows/npm-publish.yml` workflow is dry-run only.\n\nPublish lifecycle environment:\n\n```text\nBUILDCHAIN_VERSION\nBUILDCHAIN_CHANNEL\nBUILDCHAIN_SOURCE_SHA\nBUILDCHAIN_TARGET_REF\nBUILDCHAIN_RELEASE_STATE\nBUILDCHAIN_EVIDENCE_DIR\nBUILDCHAIN_RELEASE_SHA\nBUILDCHAIN_RELEASE_MATERIAL_SHA\nBUILDCHAIN_PUBLISH_TOOLING_SHA\nBUILDCHAIN_PUBLISH_EVIDENCE\nBUILDCHAIN_REQUIRED_ARTIFACTS\n```\n\n`BUILDCHAIN_REQUIRED_ARTIFACTS` is the normalized requirement array after the\naction resolves a missing artifact `ref` to `BUILDCHAIN_VERSION`, or expands an\noptional `ref_template` containing exactly one `{version}`, and binds any\ndeclared provenance to the current release coordinate. Template expansion\nhappens after exact version selection; ambiguous or unsupported templates fail\nbefore `lifecycle.publish`. Requirement descriptors may omit `digest`; final\npublish evidence may not.\n\nThe action outputs `transaction-id`, `transaction-state`,\n`transaction-exact-tag`, `public-release-tag`, `transaction-release-sha`,\n`transaction-state-ref`, `transaction-state-sha`, `transaction-state-path`,\n`publish-evidence-path`, and `release-passport-path`, `release-passport-output-dir`,\n`release-passport-state-sha`, and `finalization-needed`.\n`transaction-state-ref` is the durable recovery location.\n`release-passport-state-sha` is the durable ref commit after the generated\n`release-passport/*` files have been uploaded into that recovery ref.\n`finalization-needed=true` means publish evidence is valid, but protected branch\nor ref finalization needs a later idempotent promotion run. For release\nfinalization, Buildchain may create a same-repository generated version-state\nPR when GitHub rejects the direct protected ref update; that PR is Buildchain\nbookkeeping, not a consumer-authored release change.\nSet `github-release: \"true\"` when the semver promotion should also publish the\npublic GitHub Release. After the release transaction reaches `complete` and\n`finalization-needed` is false, the action creates or updates the GitHub Release\nfor `public-release-tag`, applies deterministic semver metadata\n(`prerelease=true` and `make_latest=false` for prerelease tags, latest for stable\ntags), and uploads the publish evidence file plus generated release passport\nassets. For anchored/manual package releases, `public-release-tag` is derived\nfrom the published package version, while `transaction-exact-tag` remains the\ninternal Buildchain transaction ref for recovery and audit. If the transaction is\nnot complete yet, the action defers GitHub Release publication to the next\nidempotent promotion run.\n\nAfter a publish transaction reaches `complete`, the action generates the unified\n`buildchain-release-passport` in `.buildchain/release-passport` by default and\npersists those files under `release-passport/` in the durable release-state ref.\nSet `release-passport-product-name` to record the consumer product name, for\nexample `Libnode`, instead of the default `Buildchain`.\nSet `release-passport-kfd-1-witness-jsons` to newline-separated KFD-1\ncontract-world witness JSON paths when released artifacts must prove\nbyte-for-byte KFD contract surfaces. Buildchain imports the KFD metadata from\n`@kungfu-tech/kfd`, freezes the witness, verifies artifact bytes, and writes the\nresult under the KFD-provided `kfd-1` passport section.\nSet `release-passport-kfd-2-claim-jsons` to newline-separated KFD-2 public\nrelease trust claim JSON paths when a release makes additional human/agent\nvisible claims. Buildchain requires each public claim to bind declared sources,\nmachine-readable evidence, hashes, artifact coordinates, verification results,\naudit boundary, responsibility state, and residual risk. Unbound claims fail\npassport verification; prose-only claims downgrade the KFD-2 audit.\nSet `release-passport-kfd-3-prebuild-witness-jsons` to newline-separated KFD-3\ncollaboration-interface pre-build witness paths, then provide artifact-side\nevidence with `release-passport-kfd-3-artifact-witness-jsons` or a\nproduct-owned `release-passport-kfd-3-artifact-verify-command` such as\n`kungfu agent verify --json`. Buildchain compares declared shipped public\nsurfaces with artifact-exposed public surfaces and writes the result under the\nKFD-provided `kfd-3` passport section.\nBuildchain's own release workflow sets `release-passport-buildchain-self-kfd:\n\"true\"`. In that mode the action generates Buildchain-owned KFD-1/2/3 witnesses\ninside the final version-state workspace, after the release transaction has\nmaterialized generated files such as `package.json` and `dist/site/*`. This\nkeeps self-hosted KFD witness hashes bound to the exact published package\ninstead of to a pre-promotion checkout.\nWhen present, the passport includes the aggregate build summary, platform\nartifact manifests, npm publish evidence, dist-tag promotion evidence, the\nrelease-state ref, trusted publishing metadata, and the Buildchain transaction\nresult. After the first passport upload, Buildchain backfills the durable\nrelease-state SHA into `buildchain.release.json` and persists the passport\nagain, so the consumer-side passport is a complete audit entrypoint. Set\n`release-passport: \"false\"` only for a controlled recovery run that must skip\npassport generation.\n\nFinalization recovery is anchored to the durable transaction, not to a single\nworkflow run SHA. After generated version-state bookkeeping is applied, the\ncurrent channel head can be the generated version-state commit or a historical\nmerge commit that contains or corresponds to the recorded `release_material_sha`;\nit does not have to equal the original `source_sha` or the transaction\n`release_sha`. Reruns accept exact tags that already point at the transaction\nrelease/material SHA or the finalized channel head, and continue moving any\nmissing floating tags or dev/alpha refs before marking the transaction\n`complete`.\n\nNormal reruns accept already-published artifacts only when evidence matches.\nMissing required artifacts can be published on the next run. Conflicting\nrefs, digests, or declared provenance put the transaction into\n`repair_required`; `abandoned` and\n`failed_permanently` also fail closed unless `publish-transaction-override` is\nset for a controlled repair.\n\nIn strict buildchain promotion, ref movement is also gated by the old ABV\ngovernance semantics:\n\n- the target channel branch protection details must be readable, must enforce\n protection for administrators, and must require approving PR review plus the\n strict `check` job from the `Verify` workflow;\n- alpha promotion must come from a merged same-repository PR\n `dev/vN/vN.M -> alpha/vN/vN.M`, or from a strict same-line\n `publish-gate/alpha/vN/vN.M/<version> -> alpha/vN/vN.M` source-lock PR;\n- release promotion must come from a merged same-repository PR\n `alpha/vN/vN.M -> release/vN/vN.M`, or from a strict same-line\n `publish-gate/release/vN/vN.M/<version> -> release/vN/vN.M` source-lock PR;\n- major promotion must come from a merged same-repository PR\n `release/vN/vN.M -> publish-gate/major`;\n- release promotion must have an exact alpha tag for the same patch line, and\n the release source tree must match that alpha tag tree, so release does not\n introduce new code after alpha;\n- anchored/manual release promotion may differ from that alpha tree only in\n declared `version.files` and the configured anchor manifest, and only when the\n checked-out release material has passed `lifecycle.verify` or the explicit\n `verification-command`;\n- generated release and next-alpha version-state trees can be verified locally\n with either the `verification-command` input or `buildchain.toml`\n `lifecycle.verify` before any tags or channel refs move.\n\nThe promotion workflow should use `BUILDCHAIN_PROMOTION_TOKEN` for non-dry-run\npromotion. The token is the buildchain equivalent of the old ABV runner release\nauthority: protected branch review and check rules guard human channel merges,\nwhile the reusable build trust gate now checks the source-lock channel HEAD and\nmerged same-repository PR lineage before heavy build runners start. This action\nstill independently rechecks PR lineage, alpha/release tree equivalence, and\ngenerated version-state verification before moving channel refs and tags.\nGenerated version-state direct ref updates can use a separate\n`generated-ref-update-token`; the reusable wrapper defaults it to\n`secrets.BUILDCHAIN_PROMOTION_TOKEN || github.token`. Consumers that protect\n`dev/*`, `alpha/*`, or `release/*` with one required review should configure\n`BUILDCHAIN_PROMOTION_TOKEN` as the bypass-capable release authority, so\npost-publish dev/alpha/release bookkeeping completes without a human PR.\nThe reusable `release-candidate-promote.yml` wrapper defaults\n`branch-protection-bypass-apps` to `github-actions`, so flow-internal promotion\ncan complete generated `dev`/`alpha`/`release` bookkeeping while ordinary human\npushes and PR merges remain governed by the one-review branch protection rule.\nThe promotion action also auto-discovers the current token's authenticated user\nor app and adds it to the managed bypass allowlist, so consumers do not have to\ndeclare the same release authority twice.\n\nThe tag names intentionally follow the old ABV release semantics:\nexact release tags are `vX.Y.Z`, exact alpha tags are `vX.Y.Z-alpha.N`, floating\nrelease tags are minor/major tags such as `v2.0` and `v2`, and floating alpha\ntags are minor-line tags such as `v2.0-alpha` plus cross-minor major tags such\nas `v2-alpha`. A major alpha tag only moves for the highest minor in that major\nwith a published alpha, so older-line maintenance cannot roll consumers back.\nBare tags such as `1.0.0` are not\nmaintained as buildchain release entrypoints.\n\nRepository rulesets should protect exact tags, not every `v*` tag. A ruleset\nsuch as `refs/tags/v*` also protects floating channel tags like `v2.0-alpha` and `v2-alpha`,\nwhich Buildchain must update after exact tags and publish evidence are durable.\nUse an exact-tag rule such as `refs/tags/v*.*.*` for immutable evidence tags and\nleave floating channel tags mutable for the promotion token."
|
|
200
|
+
"markdown": "# promote-buildchain-ref\n\nInternal buildchain action for promoting verified buildchain release-line and\ncompatibility refs from buildchain release channels:\n\n- `alpha/v2/v2.0` creates or reuses the next exact prerelease tag such as\n `v2.0.1-alpha.0`, writes that version into package version state, points the\n alpha and dev channel branches at the version commit, then promotes\n `v2.0-alpha` and, when this is the highest published alpha minor, `v2-alpha`;\n- `release/v2/v2.0` creates or reuses the next exact release tag such as\n `v2.0.0`, writes that version into package version state, points the release\n channel branch and release tags at the release commit, then prepares a second\n source commit for the next exact prerelease tag such as `v2.0.1-alpha.0` and\n points the alpha/dev channel branches plus `v2.0-alpha` at that prerelease\n commit, and moves `v2-alpha` only if no higher v2 minor has published an alpha;\n- `publish-gate/major` accepts a reviewed PR from a production release line such\n as `release/v2/v2.0`, writes the next major production version such as\n `v3.0.0`, points `publish-gate/major`, `release/v3/v3.0`, `v3.0`, and `v3`\n at that release commit, then prepares `v3.0.1-alpha.0` for\n `alpha/v3/v3.0`, `dev/v3/v3.0`, `v3.0-alpha`, and `v3-alpha`. The older `major-gate`\n branch name is a compatibility alias only.\n\nThe release branch name defines the minor line. For example,\n`release/v2/v2.1` creates `v2.1.N`, promotes `v2.1`, and promotes `v2` only\nwhen the next minor tag such as `v2.2` does not already exist.\n\nThe action updates version state in `lerna.json`, root `package.json`, and\nworkspace package manifests discovered from package manager metadata\n(`package.json` workspaces, `lerna.json` packages, or `pnpm-workspace.yaml`).\nPackage manager detection is adaptive (`pnpm`, `npm`, or `yarn`) and is recorded\nin logs.\n\nRepositories can also provide `buildchain.toml` to declare version-state files\nand `lifecycle.verify`. TOML-configured version files take precedence over\npackage-manager discovery and can target JSON, TOML, or regex-based files. The\nversion commit itself is written through the GitHub Git Data API so the ref\ngraph is the durable source of truth. Repositories without any supported version\nstate degrade to ref-only promotion only when strict version state is disabled.\n\nJSON and TOML version entries whose declared key already matches the requested\nversion are treated as semantic no-ops. TOML changes use a parser-verified\nlossless key edit, so repository formatting is preserved and formatter-only\nrelease-preparation commits are not created. If a unique lossless edit cannot\nbe proven, promotion fails closed instead of rewriting the full TOML document.\n\n## Dry Run\n\nUse `dry-run: \"true\"` or the CLI `buildchain release --dry-run` before merging a\nchannel PR when you need to understand what Buildchain would do. This dry-run is\nat the Buildchain release-line level. It explains:\n\n- the legal source branch for the target channel;\n- exact release or alpha tags that would be created or reused;\n- floating tags and channel branches that would move;\n- version-state files and verification lifecycle that would apply;\n- branch protection, PR lineage, and release-from-alpha checks;\n- publish transaction behavior when `lifecycle.publish` or\n `publish-transaction` is enabled.\n\nIt does not move refs, move tags, write package files, run publish commands, or\npublish npm packages. The GitHub action dry-run still calls GitHub APIs to\nresolve the current target SHA and concrete pending ref updates, but every\nwrite is reported as a dry-run update.\n\nRepositories whose package version is anchored to an explicitly selected\nupstream release can opt into manual next-anchor behavior:\n\n```toml\n[version]\nrequired = true\nstrategy = \"anchored\"\nnext = \"manual\"\nmanifest = \"libnode.release.json\"\n```\n\nIn this mode, the action validates the configured version files and anchor\nmanifest through the repository's verify lifecycle, but it does not rewrite the\npackage version to match the Buildchain release tag. After a production\nrelease, it sets `next-anchor-required=true` and does not auto-create the next\nalpha branch or tag. The repository must create the next upstream anchor line\nexplicitly, then run the normal channel promotion flow for that line.\n\nWhen branch protection requires pull requests, generated version-state commits\nstill run through promotion automation first. The action updates\nBuildchain-managed channel protection before generated bookkeeping, adds the\nauthenticated promotion token user or app to the bypass allowlist, creates the\nconfigured required check on the exact generated version-state commit, then\ntries to apply that commit directly. If GitHub still rejects release\nfinalization bookkeeping, Buildchain creates or reuses a same-repository\n`buildchain/version-state/*` PR based on the current target channel head and\nreturns `finalization-needed=true`; a later idempotent promotion run can resume\nfrom the durable transaction state. Strict alpha promotion still fails with a\nconfiguration diagnostic instead of opening a post-publish human PR. Reusable\nwrapper callers should allow `checks: write` so the generated check is owned by\nGitHub Actions and matches the managed branch protection rule.\n\nStable promotion also protects concurrent development work. The reusable\nwrapper checks out the exact current `dev/vN/vN.M` head as a reconciliation\nworkspace. If next-alpha bookkeeping cannot fast-forward that branch, the\naction reruns the declared version-state generation and verification from that\ndev tree, creates a two-parent reconciliation commit from the regenerated\nfiles, and fails closed if the checkout moved before the mutation boundary.\nThis prevents generated projections from an older release tree from replacing\ncapabilities that reached dev while the release was in progress.\n\nFor Buildchain-owned automation, callers may pass\n`branch-protection-bypass-apps`, `branch-protection-bypass-users`, or\n`branch-protection-bypass-teams`. The action still configures managed\n`dev/vN/vN.M`, `alpha/vN/vN.M`, and `release/vN/vN.M` branches with one\nrequired approving review, strict GitHub Actions checks, admin enforcement,\nconversation resolution, no force pushes, and no deletions; the bypass\nallowance only lets the named automation identity apply generated version-state\nor channel bookkeeping without a second human review after the reviewed channel\nPR has already merged. Direct action calls automatically include the current\npromotion token's authenticated user or app when GitHub exposes it; explicit\ninputs are supplemental allowlist entries for less discoverable release\nauthorities.\n\n## Publish Transactions\n\nPromotion can also own external publish side effects. Enable this only from a\ntrusted channel workflow:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n generated-ref-update-token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ github.sha }}\n target-ref: release/v2/v2.0\n publish-transaction: \"true\"\n publish-mode: publish-final-version\n publish-auth: trusted-publishing\n publish-required-artifacts-json: >-\n [\n {\"kind\":\"npm\",\"name\":\"@kungfu-tech/buildchain\",\"ref\":\"2.0.0\",\"digest\":\"sha256:...\"}\n ]\n```\n\nFor anchored/manual package repositories that build through the reusable\nworkflow, keep the publish entrypoint on the `publish-gate/*` source-lock\ncontract:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ needs.build.outputs.publish-source-sha }}\n target-ref: release/v22/v22.22\n require-publish-source-lock: \"true\"\n publish-source-ref: ${{ needs.build.outputs.publish-source-ref }}\n publish-source-sha: ${{ needs.build.outputs.publish-source-sha }}\n publish-source-locked: ${{ needs.build.outputs.publish-source-locked }}\n publish-transaction: \"true\"\n publish-mode: publish-final-version\n publish-auth: trusted-publishing\n```\n\n`target-ref` remains the channel promotion target that must point at `sha`.\n`publish-source-ref` is the reviewed source-lock branch that authorized this\nspecific package publication. Direct `alpha/*` or `release/*` channel refs are\nnot valid publish source locks when `require-publish-source-lock` is enabled,\nand a mismatched `publish-source-sha` fails before any promotion or publish side effects begin.\nThe reusable promote workflow serializes non-dry-run promotion intents per\nrepository and re-reads `target-ref` before checkout, dependency installation,\nrelease-candidate resolution, or publish-gate writes. If a queued intent asks\nfor an older SHA after the protected channel has advanced, the workflow records\nthe requested/current SHA pair, verifies that the current target is ahead of\nthe requested commit, and exits successfully as a superseded no-op. Diverged,\nbehind, or unreadable comparisons still fail closed.\nAfter queued-intent revalidation, the reusable workflow runs the canonical\nrelease-candidate resolver in metadata-only mode before installing candidate\ndependencies or starting the full promotion job. The full job resolves and\ndownloads the evidence again before any publish-gate or publication mutation.\nThis preserves the final exact-evidence trust check while making missing or\nstale PR-stage evidence fail early.\nThe action repeats that check at its mutation boundary for governed promotion\ncalls, closing the race between workflow preflight and action start. Direct\nnon-governed calls and dry-runs keep the strict target mismatch error so local\ndiagnostics cannot silently reinterpret a stale request.\nExpected manual dry-run failures remain visible in the workflow result and do\nnot create automated workflow-friction issues; issue reporting is reserved for\nnon-dry-run promotion failures.\nThe reusable build workflow performs the cheaper channel-ref preflight earlier:\nafter source-lock resolution and before the build matrix, it requires the target\nchannel ref such as `alpha/v22/v22.22` or `release/v22/v22.22` to already point\nat the locked `publish-source-sha`. If not, maintainers should merge the source\ncommit through the channel PR first.\n\nFor promote-only release candidates, attach the PR-stage reusable build evidence\nand fail before publish-gate side effects if it no longer matches:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\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```\n\nThe action validates repository, channel, source identity, platform matrix, and\nthe aggregate build-summary hash before it writes version state, opens\nrelease-state, runs publish transaction logic, or moves tags/branches. Source\nidentity accepts the exact source SHA, the PR merge ref SHA, or the promoted\nchannel HEAD's Git tree SHA matching the passport tree hash. If validation\nfails, run or attach the verified channel PR build first instead of promoting a\nstale or unproven artifact set.\n\nWhen enabled, the action creates or resumes a release transaction keyed by\nrepository, version, source SHA, and target ref. It persists that transaction to\na machine-managed branch under `buildchain/release-state/<version>`, with\n`state.json` and, once available, `evidence.json`. Fresh GitHub runners read\nthat durable ref before running publish, so reruns do not depend on a previous\nrunner's local `.buildchain` directory.\n\nThe action runs `lifecycle.publish` from `buildchain.toml` or the explicit\n`publish-command` input, then validates publish evidence before exact tags and\nfloating refs move. If durable state persistence fails, the action fails closed\nbefore publish or public ref finalization.\n\n`publish-mode` defaults to `publish-final-version`, the token-free path for\nnormal npm Trusted Publishing. Same-version alpha-to-latest recovery must be\ndeclared as `publish-mode: promote-existing-version` and\n`publish-auth: npm-token`; Buildchain runs `npm whoami` before it creates\nrelease-state or moves any `npm dist-tag`. The Trusted Publishing mode is not\nallowed to perform `npm dist-tag add`.\n\nBuildchain itself uses this path for npm. Its `lifecycle.publish` runs\n`node scripts/npm-publish-transaction.mjs`, which publishes\n`@kungfu-tech/buildchain` through npm Trusted Publishing and writes npm\nartifact evidence into the transaction before release refs move. The separate\n`.github/workflows/npm-publish.yml` workflow is dry-run only.\n\nPublish lifecycle environment:\n\n```text\nBUILDCHAIN_VERSION\nBUILDCHAIN_CHANNEL\nBUILDCHAIN_SOURCE_SHA\nBUILDCHAIN_TARGET_REF\nBUILDCHAIN_RELEASE_STATE\nBUILDCHAIN_EVIDENCE_DIR\nBUILDCHAIN_RELEASE_SHA\nBUILDCHAIN_RELEASE_MATERIAL_SHA\nBUILDCHAIN_PUBLISH_TOOLING_SHA\nBUILDCHAIN_PUBLISH_EVIDENCE\nBUILDCHAIN_REQUIRED_ARTIFACTS\n```\n\n`BUILDCHAIN_REQUIRED_ARTIFACTS` is the normalized requirement array after the\naction resolves a missing artifact `ref` to `BUILDCHAIN_VERSION`, or expands an\noptional `ref_template` containing exactly one `{version}`, and binds any\ndeclared provenance to the current release coordinate. Template expansion\nhappens after exact version selection; ambiguous or unsupported templates fail\nbefore `lifecycle.publish`. Requirement descriptors may omit `digest`; final\npublish evidence may not.\n\nThe action outputs `transaction-id`, `transaction-state`,\n`transaction-exact-tag`, `public-release-tag`, `transaction-release-sha`,\n`transaction-state-ref`, `transaction-state-sha`, `transaction-state-path`,\n`publish-evidence-path`, and `release-passport-path`, `release-passport-output-dir`,\n`release-passport-state-sha`, and `finalization-needed`.\n`transaction-state-ref` is the durable recovery location.\n`release-passport-state-sha` is the durable ref commit after the generated\n`release-passport/*` files have been uploaded into that recovery ref.\n`finalization-needed=true` means publish evidence is valid, but protected branch\nor ref finalization needs a later idempotent promotion run. For release\nfinalization, Buildchain may create a same-repository generated version-state\nPR when GitHub rejects the direct protected ref update; that PR is Buildchain\nbookkeeping, not a consumer-authored release change.\nSet `github-release: \"true\"` when the semver promotion should also publish the\npublic GitHub Release. After the release transaction reaches `complete` and\n`finalization-needed` is false, the action creates or updates the GitHub Release\nfor `public-release-tag`, applies deterministic semver metadata\n(`prerelease=true` and `make_latest=false` for prerelease tags, latest for stable\ntags), and uploads the publish evidence file plus generated release passport\nassets. For anchored/manual package releases, `public-release-tag` is derived\nfrom the published package version, while `transaction-exact-tag` remains the\ninternal Buildchain transaction ref for recovery and audit. If the transaction is\nnot complete yet, the action defers GitHub Release publication to the next\nidempotent promotion run.\n\nAfter a publish transaction reaches `complete`, the action generates the unified\n`buildchain-release-passport` in `.buildchain/release-passport` by default and\npersists those files under `release-passport/` in the durable release-state ref.\nSet `release-passport-product-name` to record the consumer product name, for\nexample `Libnode`, instead of the default `Buildchain`.\nSet `release-passport-kfd-1-witness-jsons` to newline-separated KFD-1\ncontract-world witness JSON paths when released artifacts must prove\nbyte-for-byte KFD contract surfaces. Buildchain imports the KFD metadata from\n`@kungfu-tech/kfd`, freezes the witness, verifies artifact bytes, and writes the\nresult under the KFD-provided `kfd-1` passport section.\nSet `release-passport-kfd-2-claim-jsons` to newline-separated KFD-2 public\nrelease trust claim JSON paths when a release makes additional human/agent\nvisible claims. Buildchain requires each public claim to bind declared sources,\nmachine-readable evidence, hashes, artifact coordinates, verification results,\naudit boundary, responsibility state, and residual risk. Unbound claims fail\npassport verification; prose-only claims downgrade the KFD-2 audit.\nSet `release-passport-kfd-3-prebuild-witness-jsons` to newline-separated KFD-3\ncollaboration-interface pre-build witness paths, then provide artifact-side\nevidence with `release-passport-kfd-3-artifact-witness-jsons` or a\nproduct-owned `release-passport-kfd-3-artifact-verify-command` such as\n`kungfu agent verify --json`. Buildchain compares declared shipped public\nsurfaces with artifact-exposed public surfaces and writes the result under the\nKFD-provided `kfd-3` passport section.\nBuildchain's own release workflow sets `release-passport-buildchain-self-kfd:\n\"true\"`. In that mode the action generates Buildchain-owned KFD-1/2/3 witnesses\ninside the final version-state workspace, after the release transaction has\nmaterialized generated files such as `package.json` and `dist/site/*`. This\nkeeps self-hosted KFD witness hashes bound to the exact published package\ninstead of to a pre-promotion checkout.\nWhen present, the passport includes the aggregate build summary, platform\nartifact manifests, npm publish evidence, dist-tag promotion evidence, the\nrelease-state ref, trusted publishing metadata, and the Buildchain transaction\nresult. After the first passport upload, Buildchain backfills the durable\nrelease-state SHA into `buildchain.release.json` and persists the passport\nagain, so the consumer-side passport is a complete audit entrypoint. Set\n`release-passport: \"false\"` only for a controlled recovery run that must skip\npassport generation.\n\nFinalization recovery is anchored to the durable transaction, not to a single\nworkflow run SHA. After generated version-state bookkeeping is applied, the\ncurrent channel head can be the generated version-state commit or a historical\nmerge commit that contains or corresponds to the recorded `release_material_sha`;\nit does not have to equal the original `source_sha` or the transaction\n`release_sha`. Reruns accept exact tags that already point at the transaction\nrelease/material SHA or the finalized channel head, and continue moving any\nmissing floating tags or dev/alpha refs before marking the transaction\n`complete`.\n\nNormal reruns accept already-published artifacts only when evidence matches.\nMissing required artifacts can be published on the next run. Conflicting\nrefs, digests, or declared provenance put the transaction into\n`repair_required`; `abandoned` and\n`failed_permanently` also fail closed unless `publish-transaction-override` is\nset for a controlled repair.\n\nIn strict buildchain promotion, ref movement is also gated by the old ABV\ngovernance semantics:\n\n- when detailed target branch protection is readable, it must enforce\n protection for administrators and require approving PR review plus the strict\n `check` job from the `Verify` workflow; when GitHub withholds that\n administration endpoint from the workflow token, the exact transaction must\n instead prove a protected current head, same-repository merged PR,\n independent approval, and the required successful `check` from its configured\n GitHub App;\n- post-publish channel reconciliation reuses an already qualifying\n provider-enforced policy when the workflow token cannot read or rewrite the\n administrative protection document, and fails closed if the public branch\n summary no longer carries the required check for everyone;\n- alpha promotion must come from a merged same-repository PR\n `dev/vN/vN.M -> alpha/vN/vN.M`, or from a strict same-line\n `publish-gate/alpha/vN/vN.M/<version> -> alpha/vN/vN.M` source-lock PR;\n- release promotion must come from a merged same-repository PR\n `alpha/vN/vN.M -> release/vN/vN.M`, or from a strict same-line\n `publish-gate/release/vN/vN.M/<version> -> release/vN/vN.M` source-lock PR;\n- major promotion must come from a merged same-repository PR\n `release/vN/vN.M -> publish-gate/major`;\n- release promotion must have an exact alpha tag for the same patch line, and\n the release source tree must match that alpha tag tree, so release does not\n introduce new code after alpha;\n- anchored/manual release promotion may differ from that alpha tree only in\n declared `version.files` and the configured anchor manifest, and only when the\n checked-out release material has passed `lifecycle.verify` or the explicit\n `verification-command`;\n- generated release and next-alpha version-state trees can be verified locally\n with either the `verification-command` input or `buildchain.toml`\n `lifecycle.verify` before any tags or channel refs move.\n\nThe promotion workflow should use `BUILDCHAIN_PROMOTION_TOKEN` for non-dry-run\npromotion. The token is the buildchain equivalent of the old ABV runner release\nauthority: protected branch review and check rules guard human channel merges,\nwhile the reusable build trust gate now checks the source-lock channel HEAD and\nmerged same-repository PR lineage before heavy build runners start. This action\nstill independently rechecks PR lineage, alpha/release tree equivalence, and\ngenerated version-state verification before moving channel refs and tags.\nGenerated version-state direct ref updates can use a separate\n`generated-ref-update-token`; the reusable wrapper defaults it to\n`secrets.BUILDCHAIN_PROMOTION_TOKEN || github.token`. Consumers that protect\n`dev/*`, `alpha/*`, or `release/*` with one required review should configure\n`BUILDCHAIN_PROMOTION_TOKEN` as the bypass-capable release authority, so\npost-publish dev/alpha/release bookkeeping completes without a human PR.\nThe reusable `release-candidate-promote.yml` wrapper defaults\n`branch-protection-bypass-apps` to `github-actions`, so flow-internal promotion\ncan complete generated `dev`/`alpha`/`release` bookkeeping while ordinary human\npushes and PR merges remain governed by the one-review branch protection rule.\nThe promotion action also auto-discovers the current token's authenticated user\nor app and adds it to the managed bypass allowlist, so consumers do not have to\ndeclare the same release authority twice.\n\nThe tag names intentionally follow the old ABV release semantics:\nexact release tags are `vX.Y.Z`, exact alpha tags are `vX.Y.Z-alpha.N`, floating\nrelease tags are minor/major tags such as `v2.0` and `v2`, and floating alpha\ntags are minor-line tags such as `v2.0-alpha` plus cross-minor major tags such\nas `v2-alpha`. A major alpha tag only moves for the highest minor in that major\nwith a published alpha, so older-line maintenance cannot roll consumers back.\nBare tags such as `1.0.0` are not\nmaintained as buildchain release entrypoints.\n\nRepository rulesets should protect exact tags, not every `v*` tag. A ruleset\nsuch as `refs/tags/v*` also protects floating channel tags like `v2.0-alpha` and `v2-alpha`,\nwhich Buildchain must update after exact tags and publish evidence are durable.\nUse an exact-tag rule such as `refs/tags/v*.*.*` for immutable evidence tags and\nleave floating channel tags mutable for the promotion token."
|
|
200
201
|
},
|
|
201
202
|
{
|
|
202
203
|
"id": "action:report-buildchain-issue",
|
|
@@ -839,7 +840,7 @@
|
|
|
839
840
|
],
|
|
840
841
|
"maturity": "stable",
|
|
841
842
|
"sourcePath": "docs/MAP.md",
|
|
842
|
-
"digest": "sha256:
|
|
843
|
+
"digest": "sha256:91dc800bafc31bc149680c86272827936c94e0f025d547bbabc10d58fe5f128e",
|
|
843
844
|
"headings": [
|
|
844
845
|
{
|
|
845
846
|
"level": 1,
|
|
@@ -867,7 +868,7 @@
|
|
|
867
868
|
"anchor": "how-this-map-is-maintained"
|
|
868
869
|
}
|
|
869
870
|
],
|
|
870
|
-
"markdown": "# Documentation Map\n\nStart here. Find the question you have; follow it to the document that answers\nit. This map is meant to be readable by both a person skimming for the right doc\nand an agent grounding a specific claim.\n\nEach row carries a **plane** - *why* (intent / rationale), *verify* (trust the\nrunning artifact), *use* (consume / extend) - and a **status**:\n\n- `stable` - current and holds.\n- `draft` - exists, rough or incomplete.\n- `to write` - planned; the material exists but is not yet a single doc.\n- `retired` - intentionally not part of the active Buildchain v2 surface.\n\n## Capability Coverage\n\nThis package should be usable by an agent from the npm artifact alone. The\nmachine-readable `dist/site/` bundle is the first fact source; the Markdown\nmanuals explain those facts and give operator examples.\n\n`dist/site/capability-registry.json` is the capability navigation entrypoint.\nIt groups the public surface into stable product areas so sites and agents do\nnot have to infer structure from file names. Each page, manual, CLI command,\nworkflow, action, and Node API export also carries a `capabilityGroup`,\n`audience`, and `maturity` field in its own registry.\n\n| Capability group | Primary facts | Primary manuals |\n| --- | --- | --- |\n| Getting Started | `capability-registry.json`, `product-mechanism.json` | [`install.md`](install.md), [`product-mechanism.md`](product-mechanism.md), [`cli.md`](cli.md) |\n| Release Passport and Trust | `release-model.json`, `artifact-schemas.json`, `kfd-claims.json` | [`release-passport.md`](release-passport.md), [`release-candidate.md`](release-candidate.md), [`publish-transaction.md`](publish-transaction.md), [`binary-distribution.md`](binary-distribution.md) |\n| Reusable Build and Lifecycle | `workflow-registry.json`, `controller-registry.json`, `release-model.json` | [`reusable-build-surface.md`](reusable-build-surface.md), [`controller-evidence.md`](controller-evidence.md), [`shifu-gate-profiles.md`](shifu-gate-profiles.md), [`lifecycle-protocol.md`](lifecycle-protocol.md) |\n| KFD Trust and Surface Closure | `kfd-claims.json`, `public-surface-audit.json`, `cli-registry.json`, `node-api-registry.json` | [`kfd-support.md`](kfd-support.md), [`release-passport.md`](release-passport.md) |\n| Site Bundle, Web Surfaces, and Propagation | `buildchain-site.json`, `site-manifest.json`, `page-registry.json`, `release-model.json` | [`site-bundle-contract.md`](site-bundle-contract.md), [`web-surface-deployments.md`](web-surface-deployments.md), [`release-propagation.md`](release-propagation.md) |\n| Publication Artifacts | `publication-registry.json`, `workflow-registry.json`, `node-api-registry.json`, `manual-registry.json`, `kungfu-buildchain-publication-artifact-registry` | [`publication-artifacts.md`](publication-artifacts.md), [`reusable-build-surface.md`](reusable-build-surface.md) |\n| Distribution Indexes and Badges | `badge-endpoint-registry.json`, `node-api-registry.json`, `manual-registry.json` | [`readme-badges.md`](readme-badges.md), [`homebrew.md`](homebrew.md) |\n| Build Facts, Observability, and Diagnostics | `cli-registry.json`, `node-api-registry.json`, lifecycle artifacts | [`build-facts.md`](build-facts.md), [`toolkit-observability.md`](toolkit-observability.md), [`consumer-issue-reporting.md`](consumer-issue-reporting.md) |\n| Governance, Versioning, and Runtime Drift | `buildchain-contract.json`, `workflow-registry.json`, `release-model.json` | [`release-governance.md`](release-governance.md), [`release-flow.md`](release-flow.md), [`versioning.md`](versioning.md), [`runtime-train-validation.md`](runtime-train-validation.md) |\n| CLI and Node API Reference | `cli-registry.json`, `node-api-registry.json`, `workflow-registry.json`, `manual-registry.json` | [`cli.md`](cli.md), [`../packages/core/README.md`](../packages/core/README.md) |\n\n| Capability | Machine-readable entry | Manual entry |\n| --- | --- | --- |\n| Capability-grouped KFD navigation | `dist/site/capability-registry.json`, `dist/site/page-registry.json`, `dist/site/manual-registry.json`, `dist/site/cli-registry.json`, `dist/site/node-api-registry.json` | this map, [`site-bundle-contract.md`](site-bundle-contract.md), [`kfd-support.md`](kfd-support.md) |\n| KFD-1 / KFD-2 / KFD-3 release-passport gates | `dist/site/kfd-claims.json`, `dist/site/buildchain-contract.json`, `dist/site/artifact-schemas.json` | [`release-passport.md`](release-passport.md) |\n| KFD-3 public surface reverse audit | `dist/site/public-surface-audit.json`, `dist/site/cli-registry.json`, `dist/site/workflow-registry.json`, `dist/site/page-registry.json` | [`cli.md`](cli.md), [`site-bundle-contract.md`](site-bundle-contract.md) |\n| KFD-1 / KFD-2 / KFD-3 first-class CLI and Node API | `.buildchain/kfd/kfd-3/surfaces.json`, `dist/site/kfd-claims.json`, `buildchain.release.json`, KFD schemas from `@kungfu-tech/kfd` | [`kfd-support.md`](kfd-support.md), [`cli.md`](cli.md#commands) |\n| Floating `@v2` drift detection and compatibility issues | `dist/site/buildchain-contract.json` | [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock) |\n| npm publish transactions, evidence, dist-tags, and recovery | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`publish-transaction.md`](publish-transaction.md) |\n| Git/source/version/module/product build facts | `dist/site/node-api-registry.json`, `dist/site/cli-registry.json`, `kungfu-buildchain-module-build-facts`, `kungfu-buildchain-product-build-facts` | [`build-facts.md`](build-facts.md) |\n| GitHub Release passport/evidence publication | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`release-governance.md`](release-governance.md), [`release-candidate.md`](release-candidate.md) |\n| release propagation for package/publication/site chains | `dist/site/release-model.json` | [`release-propagation.md`](release-propagation.md) |\n| publication artifact manifests, immutable archive registries, source bundles, and paper repository workflows | `dist/site/publication-registry.json`, `dist/site/workflow-registry.json`, `dist/site/node-api-registry.json`, `kungfu-buildchain-publication-artifact-manifest`, `kungfu-buildchain-publication-artifact-registry` | [`publication-artifacts.md`](publication-artifacts.md) |\n| Generated badge bundles, README badge blocks, and badge facts | `dist/site/node-api-registry.json`, `dist/site/manual-registry.json`, `kungfu-buildchain-badge-bundle-facts`, `kungfu-buildchain-readme-badge-facts` | [`readme-badges.md`](readme-badges.md) |\n| Homebrew tap distribution indexes | `dist/site/node-api-registry.json`, `dist/site/buildchain-contract.json` | [`homebrew.md`](homebrew.md) |\n| Buildchain CLI manual | `dist/site/cli-registry.json`, `dist/site/manual-registry.json` | [`cli.md`](cli.md) |\n| Node API / package exports | `dist/site/node-api-registry.json`, `dist/site/release-provenance.json` | [`cli.md`](cli.md#node-api-and-package-exports) |\n\n`dist/site/kfd-claims.json` is generated from\n`packages/core/buildchain-kfd-claims.js`. Treat that module and JSON file as the\nsource claim registry; this map and the manuals explain those claims but do not\nreplace them.\n\n## Map\n\n| Your question | Document | Plane | Status |\n| --- | --- | --- | --- |\n| What is Buildchain, in one idea? | [`../README.md`](../README.md) | - | stable |\n| Why is Buildchain a Release Passport mechanism rather than a generic workflow collection? | [`product-mechanism.md`](product-mechanism.md) | why | stable |\n| How do agents and contributors enter this repo? | [`../AGENTS.md`](../AGENTS.md) + [`../CONTRIBUTING.md`](../CONTRIBUTING.md) | use | stable |\n| How do I install a standalone binary or npm package? | [`install.md`](install.md) | use | stable |\n| How do I run the `buildchain` CLI? | [`cli.md`](cli.md) | use | stable |\n| How do I import Buildchain toolkit APIs from JavaScript build code? | [`toolkit-observability.md`](toolkit-observability.md) + [`../packages/core/README.md`](../packages/core/README.md) | use | stable |\n| How do I initialize a new repository? | [`cli.md`](cli.md) + [`lifecycle-protocol.md`](lifecycle-protocol.md) | use | stable |\n| Why does Buildchain use branch-driven release governance? | [`release-governance.md`](release-governance.md) | why | stable |\n| How do protected dev branches and scheduled ready-PR merging work? | [`release-governance.md`](release-governance.md#protected-dev-branches) | use | stable |\n| How do I run daily, weekly, or monthly repository patrols? | [`release-governance.md`](release-governance.md#buildchain-patrol) | use | stable |\n| How does Buildchain decide patch, minor, and major release lines? | [`versioning.md`](versioning.md) | why | stable |\n| What exact branch/tag state machine runs on alpha, release, and major gate? | [`release-flow.md`](release-flow.md) | verify | stable |\n| What did Buildchain migrate or retire from old action repositories? | [`migration-inventory.md`](migration-inventory.md) | verify | stable |\n| What is the active action and workflow source of truth? | [`ownership.md`](ownership.md) | verify | stable |\n| How do I declare version files and custom lifecycle commands? | [`lifecycle-protocol.md`](lifecycle-protocol.md) | use | stable |\n| How does publish evidence, recovery, and finalization work? | [`publish-transaction.md`](publish-transaction.md) | verify | stable |\n| How do I collect and verify module/product build facts from Git source, version files, and outputs? | [`build-facts.md`](build-facts.md) + [`cli.md`](cli.md) | use/verify | stable |\n| How do I publish or verify release passport artifacts? | [`release-passport.md`](release-passport.md) | use | stable |\n| How do I gate release artifacts with KFD-1 contract-world witnesses? | [`release-passport.md`](release-passport.md#kfd-1-contract-world-release-gate) | verify/use | stable |\n| How do I declare, render, and audit product KFD-2 release trust claims? | [`kfd-support.md`](kfd-support.md#kfd-2) + [`release-passport.md`](release-passport.md#kfd-2-release-trust-passport-audit) + [`cli.md`](cli.md) | verify/use | stable |\n| How do I gate KFD-3 collaboration-interface releases? | [`release-passport.md`](release-passport.md#kfd-3-collaboration-interface-release-gate) + [`cli.md`](cli.md) | verify/use | stable |\n| How do I detect, register, audit, witness, or query KFD-3 product surfaces? | [`kfd-support.md`](kfd-support.md) + [`cli.md`](cli.md) | verify/use | stable |\n| How do I keep `@v2` floating refs while detecting Buildchain contract drift? | [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock) | verify/use | stable |\n| How do reusable workflows bind controller intent, source/runtime identity, outcomes, and receipt evidence? | [`controller-evidence.md`](controller-evidence.md) | verify/use | draft |\n| How do I propagate finalized upstream releases to downstream package/site PRs? | [`release-propagation.md`](release-propagation.md) | use | preview |\n| How do paper or report repositories publish PDFs, metadata, source bundles, site-consumable manifests, npm packages, and GitHub Releases? | [`publication-artifacts.md`](publication-artifacts.md) | use | stable |\n| How do I generate KFD / Release Passport badge bundles without hand-maintaining Markdown? | [`readme-badges.md`](readme-badges.md) + [`cli.md`](cli.md) | use | stable |\n| How do I generate and verify a Homebrew tap from release passport evidence? | [`homebrew.md`](homebrew.md) + [`cli.md`](cli.md) | use/verify | stable |\n| How do I prove a PR-stage reusable build is the artifact source promoted later? | [`release-candidate.md`](release-candidate.md) + [`reusable-build-surface.md`](reusable-build-surface.md) | verify | stable |\n| Why are binary release assets archived by platform, and where is the single bundle? | [`binary-distribution.md`](binary-distribution.md) | verify | stable |\n| How do I add timestamped logs inside build scripts? | [`toolkit-observability.md`](toolkit-observability.md) | use | stable |\n| What package-owned facts should buildchain.libkungfu.dev render? | [`site-bundle-contract.md`](site-bundle-contract.md) | use | stable |\n| How do I call the reusable build workflow? | [`reusable-build-surface.md`](reusable-build-surface.md) | use | stable |\n| How does Buildchain schedule and aggregate a project-owned Shifu Gate profile? | [`shifu-gate-profiles.md`](shifu-gate-profiles.md) | use/verify | draft |\n| How do I use one build job that follows alpha during development and stable for releases? | [`reusable-build-surface.md`](reusable-build-surface.md#automatic-channel-router) | use | preview |\n| How do self-hosted runners relay large artifacts through S3 before GitHub artifacts? | [`reusable-build-surface.md`](reusable-build-surface.md#artifact-transfer-relay) | use | stable |\n| How do self-hosted runners reuse local Git checkout caches without weakening source locks? | [`reusable-build-surface.md`](reusable-build-surface.md#locked-source-checkout-cache) | use | stable |\n| How do I validate an unreleased Buildchain runtime train while keeping `@v2`? | [`runtime-train-validation.md`](runtime-train-validation.md) | use | stable |\n| How do I automatically qualify alpha candidates and publish the newest non-revoked qualified candidate at a fixed window? | [`stable-candidate-patrol.md`](stable-candidate-patrol.md) | use | preview |\n| How do I deploy a site/app preview, staging, or production surface? | [`web-surface-deployments.md`](web-surface-deployments.md) | use | stable |\n| How do I publish observed infrastructure contracts for downstream consumers? | [`infra-contract.md`](infra-contract.md) | use | preview |\n| How do I use the active actions directly? | [`../actions/validate-config/README.md`](../actions/validate-config/README.md), [`../actions/run-lifecycle/README.md`](../actions/run-lifecycle/README.md), [`../actions/promote-buildchain-ref/README.md`](../actions/promote-buildchain-ref/README.md), [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |\n| How can a consumer workflow report a Buildchain-owned failure back to Buildchain? | [`consumer-issue-reporting.md`](consumer-issue-reporting.md) + [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |\n| What do the fixture repositories demonstrate? | [`../fixtures/libnode-shaped/README.md`](../fixtures/libnode-shaped/README.md), [`../fixtures/publish-transaction-shaped/README.md`](../fixtures/publish-transaction-shaped/README.md), [`../fixtures/web-surface-shaped/README.md`](../fixtures/web-surface-shaped/README.md), [`../fixtures/publication-artifact-shaped/README.md`](../fixtures/publication-artifact-shaped/README.md) | verify | stable |\n| What license and contribution terms apply? | [`../LICENSE`](../LICENSE) + [`../LICENSE-POLICY.md`](../LICENSE-POLICY.md) | use | stable |\n| What trademark, official-service, and provider-compliance boundaries apply? | [`../TRADEMARK.md`](../TRADEMARK.md) + [`../ACCEPTABLE_USE.md`](../ACCEPTABLE_USE.md) + [`../PROVIDER_COMPLIANCE.md`](../PROVIDER_COMPLIANCE.md) | use | stable |\n| How do I report a vulnerability? | [`../SECURITY.md`](../SECURITY.md) | use | stable |\n\n## Also asking about\n\n- **ABV / old workflows / old action repositories** -> [`release-governance.md`](release-governance.md)\n and [`migration-inventory.md`](migration-inventory.md).\n- **v2 / v2-alpha / v2.0 / v2.0-alpha / exact tags / floating tags** ->\n [`release-governance.md`](release-governance.md) and\n [`release-flow.md`](release-flow.md).\n- **Buildchain self-dogfood / released alpha canary / stable compatibility lane** ->\n [`release-governance.md`](release-governance.md#buildchain-alpha-self-dogfood).\n- **qualified alpha ledger / scheduled stable selection / hold and revoke** ->\n [`stable-candidate-patrol.md`](stable-candidate-patrol.md).\n- **v2.1 vs v2.2 / when to open a new minor line** ->\n [`versioning.md`](versioning.md).\n- **dry-run / what would happen if this channel PR merges** -> [`cli.md`](cli.md)\n and [`release-flow.md`](release-flow.md).\n- **protected dev branches / scheduled ready-PR merge / daily-weekly-monthly patrol** ->\n [`release-governance.md`](release-governance.md#protected-dev-branches) and\n [`release-governance.md`](release-governance.md#buildchain-patrol).\n- **pnpm / npm / yarn / package-manager adapters** ->\n [`lifecycle-protocol.md`](lifecycle-protocol.md).\n- **pip / Conan / CMake / custom commands** -> [`lifecycle-protocol.md`](lifecycle-protocol.md)\n and [`reusable-build-surface.md`](reusable-build-surface.md).\n- **libnode / native artifacts / self-hosted runner matrix** ->\n [`reusable-build-surface.md`](reusable-build-surface.md) and\n [`../fixtures/libnode-shaped/README.md`](../fixtures/libnode-shaped/README.md).\n- **S3 artifact relay / self-hosted runner artifact transfer** ->\n [`reusable-build-surface.md`](reusable-build-surface.md#artifact-transfer-relay).\n- **local Git checkout cache / self-hosted source transport** ->\n [`reusable-build-surface.md`](reusable-build-surface.md#locked-source-checkout-cache).\n- **runtime train validation / temporary `buildchain-ref` override** ->\n [`runtime-train-validation.md`](runtime-train-validation.md) and\n [`reusable-build-surface.md`](reusable-build-surface.md).\n- **consumer workflow feedback / automatic Buildchain GitHub issues** ->\n [`consumer-issue-reporting.md`](consumer-issue-reporting.md).\n- **PR-stage RC artifacts / promote-only release candidates** ->\n [`release-candidate.md`](release-candidate.md) and\n [`reusable-build-surface.md`](reusable-build-surface.md).\n- **infra contract / observed infrastructure outputs / downstream contract propagation** ->\n [`infra-contract.md`](infra-contract.md).\n- **standalone binary install / platform archives / GitHub Release bundle** ->\n [`install.md`](install.md), [`binary-distribution.md`](binary-distribution.md),\n and [`release-passport.md`](release-passport.md).\n- **Trusted Publishing / npm / publish evidence / recovery** ->\n [`cli.md`](cli.md) and [`publish-transaction.md`](publish-transaction.md).\n- **Git source digest / module build facts / product build facts / legacy\n Kungfu build info** -> [`build-facts.md`](build-facts.md) and [`cli.md`](cli.md).\n- **release chains / upstream package or publication artifact as source of truth / site synchronization** ->\n [`release-propagation.md`](release-propagation.md).\n- **paper repositories / PDFs / publication manifests / immutable archive registries / source bundles** ->\n [`publication-artifacts.md`](publication-artifacts.md).\n- **README status badges / KFD badge bundles / badge facts JSON** ->\n [`readme-badges.md`](readme-badges.md) and [`cli.md`](cli.md).\n- **Homebrew taps / distribution indexes / Formula drift checks** ->\n [`homebrew.md`](homebrew.md) and [`cli.md`](cli.md).\n- **KFD-1 contract worlds / byte-for-byte release gates** ->\n [`release-passport.md`](release-passport.md#kfd-1-contract-world-release-gate).\n- **KFD-2 public release trust claim audit** ->\n [`release-passport.md`](release-passport.md#kfd-2-release-trust-passport-audit).\n- **KFD-3 collaboration-interface / agent-facing control surface closure** ->\n [`release-passport.md`](release-passport.md#kfd-3-collaboration-interface-release-gate).\n- **floating `@v2` / contract lock / compatible drift issue** ->\n [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock).\n- **GitHub Release passport / binary assets / artifact evidence / agent release checks** ->\n [`release-passport.md`](release-passport.md),\n [`binary-distribution.md`](binary-distribution.md), and [`cli.md`](cli.md).\n- **Buildchain logging / timestamps / consumer build phase timing** ->\n [`toolkit-observability.md`](toolkit-observability.md) for JavaScript API\n imports, and [`cli.md`](cli.md) for workflow or shell command usage.\n- **buildchain.libkungfu.dev / package-owned site facts** ->\n [`site-bundle-contract.md`](site-bundle-contract.md).\n- **sites / web previews / staging / production gates** ->\n [`web-surface-deployments.md`](web-surface-deployments.md).\n- **trademark / fork / official service / provider compliance / release\n evidence boundary** -> [`../TRADEMARK.md`](../TRADEMARK.md),\n [`../ACCEPTABLE_USE.md`](../ACCEPTABLE_USE.md), and\n [`../PROVIDER_COMPLIANCE.md`](../PROVIDER_COMPLIANCE.md).\n\n## How this map is maintained\n\n- A document becomes a row here when it is a stable entrypoint for a user,\n contributor, or workflow consumer.\n- A row's status must never claim more than the artifact delivers.\n- `why` documents explain intent and design pressure; `verify` and `use`\n documents should state what is guaranteed, where to verify it, and the current\n maturity of that guarantee."
|
|
871
|
+
"markdown": "# Documentation Map\n\nStart here. Find the question you have; follow it to the document that answers\nit. This map is meant to be readable by both a person skimming for the right doc\nand an agent grounding a specific claim.\n\nEach row carries a **plane** - *why* (intent / rationale), *verify* (trust the\nrunning artifact), *use* (consume / extend) - and a **status**:\n\n- `stable` - current and holds.\n- `draft` - exists, rough or incomplete.\n- `to write` - planned; the material exists but is not yet a single doc.\n- `retired` - intentionally not part of the active Buildchain v2 surface.\n\n## Capability Coverage\n\nThis package should be usable by an agent from the npm artifact alone. The\nmachine-readable `dist/site/` bundle is the first fact source; the Markdown\nmanuals explain those facts and give operator examples.\n\n`dist/site/capability-registry.json` is the capability navigation entrypoint.\nIt groups the public surface into stable product areas so sites and agents do\nnot have to infer structure from file names. Each page, manual, CLI command,\nworkflow, action, and Node API export also carries a `capabilityGroup`,\n`audience`, and `maturity` field in its own registry.\n\n| Capability group | Primary facts | Primary manuals |\n| --- | --- | --- |\n| Getting Started | `capability-registry.json`, `product-mechanism.json` | [`install.md`](install.md), [`product-mechanism.md`](product-mechanism.md), [`cli.md`](cli.md) |\n| Release Passport and Trust | `release-model.json`, `artifact-schemas.json`, `publication-authority-registry.json`, `kfd-claims.json` | [`release-passport.md`](release-passport.md), [`publication-authority.md`](publication-authority.md), [`release-candidate.md`](release-candidate.md), [`publish-transaction.md`](publish-transaction.md), [`binary-distribution.md`](binary-distribution.md) |\n| Reusable Build and Lifecycle | `workflow-registry.json`, `controller-registry.json`, `release-model.json` | [`reusable-build-surface.md`](reusable-build-surface.md), [`controller-evidence.md`](controller-evidence.md), [`shifu-gate-profiles.md`](shifu-gate-profiles.md), [`lifecycle-protocol.md`](lifecycle-protocol.md) |\n| KFD Trust and Surface Closure | `kfd-claims.json`, `public-surface-audit.json`, `cli-registry.json`, `node-api-registry.json` | [`kfd-support.md`](kfd-support.md), [`release-passport.md`](release-passport.md) |\n| Site Bundle, Web Surfaces, and Propagation | `buildchain-site.json`, `site-manifest.json`, `page-registry.json`, `release-model.json` | [`site-bundle-contract.md`](site-bundle-contract.md), [`web-surface-deployments.md`](web-surface-deployments.md), [`release-propagation.md`](release-propagation.md) |\n| Publication Artifacts | `publication-registry.json`, `workflow-registry.json`, `node-api-registry.json`, `manual-registry.json`, `kungfu-buildchain-publication-artifact-registry` | [`publication-artifacts.md`](publication-artifacts.md), [`reusable-build-surface.md`](reusable-build-surface.md) |\n| Distribution Indexes and Badges | `badge-endpoint-registry.json`, `node-api-registry.json`, `manual-registry.json` | [`readme-badges.md`](readme-badges.md), [`homebrew.md`](homebrew.md) |\n| Build Facts, Observability, and Diagnostics | `cli-registry.json`, `node-api-registry.json`, lifecycle artifacts | [`build-facts.md`](build-facts.md), [`toolkit-observability.md`](toolkit-observability.md), [`consumer-issue-reporting.md`](consumer-issue-reporting.md) |\n| Governance, Versioning, and Runtime Drift | `buildchain-contract.json`, `workflow-registry.json`, `release-model.json` | [`release-governance.md`](release-governance.md), [`release-flow.md`](release-flow.md), [`versioning.md`](versioning.md), [`runtime-train-validation.md`](runtime-train-validation.md) |\n| CLI and Node API Reference | `cli-registry.json`, `node-api-registry.json`, `workflow-registry.json`, `manual-registry.json` | [`cli.md`](cli.md), [`../packages/core/README.md`](../packages/core/README.md) |\n\n| Capability | Machine-readable entry | Manual entry |\n| --- | --- | --- |\n| Capability-grouped KFD navigation | `dist/site/capability-registry.json`, `dist/site/page-registry.json`, `dist/site/manual-registry.json`, `dist/site/cli-registry.json`, `dist/site/node-api-registry.json` | this map, [`site-bundle-contract.md`](site-bundle-contract.md), [`kfd-support.md`](kfd-support.md) |\n| KFD-1 / KFD-2 / KFD-3 release-passport gates | `dist/site/kfd-claims.json`, `dist/site/buildchain-contract.json`, `dist/site/artifact-schemas.json` | [`release-passport.md`](release-passport.md) |\n| KFD-3 public surface reverse audit | `dist/site/public-surface-audit.json`, `dist/site/cli-registry.json`, `dist/site/workflow-registry.json`, `dist/site/page-registry.json` | [`cli.md`](cli.md), [`site-bundle-contract.md`](site-bundle-contract.md) |\n| KFD-1 / KFD-2 / KFD-3 first-class CLI and Node API | `.buildchain/kfd/kfd-3/surfaces.json`, `dist/site/kfd-claims.json`, `buildchain.release.json`, KFD schemas from `@kungfu-tech/kfd` | [`kfd-support.md`](kfd-support.md), [`cli.md`](cli.md#commands) |\n| Floating `@v2` drift detection and compatibility issues | `dist/site/buildchain-contract.json` | [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock) |\n| npm publish transactions, evidence, dist-tags, and recovery | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`publish-transaction.md`](publish-transaction.md) |\n| Git/source/version/module/product build facts | `dist/site/node-api-registry.json`, `dist/site/cli-registry.json`, `kungfu-buildchain-module-build-facts`, `kungfu-buildchain-product-build-facts` | [`build-facts.md`](build-facts.md) |\n| GitHub Release passport/evidence publication | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`release-governance.md`](release-governance.md), [`release-candidate.md`](release-candidate.md) |\n| release propagation for package/publication/site chains | `dist/site/release-model.json` | [`release-propagation.md`](release-propagation.md) |\n| publication artifact manifests, immutable archive registries, source bundles, and paper repository workflows | `dist/site/publication-registry.json`, `dist/site/workflow-registry.json`, `dist/site/node-api-registry.json`, `kungfu-buildchain-publication-artifact-manifest`, `kungfu-buildchain-publication-artifact-registry` | [`publication-artifacts.md`](publication-artifacts.md) |\n| Generated badge bundles, README badge blocks, and badge facts | `dist/site/node-api-registry.json`, `dist/site/manual-registry.json`, `kungfu-buildchain-badge-bundle-facts`, `kungfu-buildchain-readme-badge-facts` | [`readme-badges.md`](readme-badges.md) |\n| Homebrew tap distribution indexes | `dist/site/node-api-registry.json`, `dist/site/buildchain-contract.json` | [`homebrew.md`](homebrew.md) |\n| Buildchain CLI manual | `dist/site/cli-registry.json`, `dist/site/manual-registry.json` | [`cli.md`](cli.md) |\n| Node API / package exports | `dist/site/node-api-registry.json`, `dist/site/release-provenance.json` | [`cli.md`](cli.md#node-api-and-package-exports) |\n\n`dist/site/kfd-claims.json` is generated from\n`packages/core/buildchain-kfd-claims.js`. Treat that module and JSON file as the\nsource claim registry; this map and the manuals explain those claims but do not\nreplace them.\n\n## Map\n\n| Your question | Document | Plane | Status |\n| --- | --- | --- | --- |\n| What is Buildchain, in one idea? | [`../README.md`](../README.md) | - | stable |\n| Why is Buildchain a Release Passport mechanism rather than a generic workflow collection? | [`product-mechanism.md`](product-mechanism.md) | why | stable |\n| How do agents and contributors enter this repo? | [`../AGENTS.md`](../AGENTS.md) + [`../CONTRIBUTING.md`](../CONTRIBUTING.md) | use | stable |\n| How do I install a standalone binary or npm package? | [`install.md`](install.md) | use | stable |\n| How do I run the `buildchain` CLI? | [`cli.md`](cli.md) | use | stable |\n| How do I import Buildchain toolkit APIs from JavaScript build code? | [`toolkit-observability.md`](toolkit-observability.md) + [`../packages/core/README.md`](../packages/core/README.md) | use | stable |\n| How do I initialize a new repository? | [`cli.md`](cli.md) + [`lifecycle-protocol.md`](lifecycle-protocol.md) | use | stable |\n| Why does Buildchain use branch-driven release governance? | [`release-governance.md`](release-governance.md) | why | stable |\n| How do protected dev branches and scheduled ready-PR merging work? | [`release-governance.md`](release-governance.md#protected-dev-branches) | use | stable |\n| How do I run daily, weekly, or monthly repository patrols? | [`release-governance.md`](release-governance.md#buildchain-patrol) | use | stable |\n| How does Buildchain decide patch, minor, and major release lines? | [`versioning.md`](versioning.md) | why | stable |\n| What exact branch/tag state machine runs on alpha, release, and major gate? | [`release-flow.md`](release-flow.md) | verify | stable |\n| What did Buildchain migrate or retire from old action repositories? | [`migration-inventory.md`](migration-inventory.md) | verify | stable |\n| What is the active action and workflow source of truth? | [`ownership.md`](ownership.md) | verify | stable |\n| How do I declare version files and custom lifecycle commands? | [`lifecycle-protocol.md`](lifecycle-protocol.md) | use | stable |\n| How does publish evidence, recovery, and finalization work? | [`publish-transaction.md`](publish-transaction.md) | verify | stable |\n| How do I collect and verify module/product build facts from Git source, version files, and outputs? | [`build-facts.md`](build-facts.md) + [`cli.md`](cli.md) | use/verify | stable |\n| How do I publish or verify release passport artifacts? | [`release-passport.md`](release-passport.md) | use | stable |\n| How is product publication authority sealed to an exact workflow, runner, control plane, nonce, and artifact? | [`publication-authority.md`](publication-authority.md) | verify | preview |\n| How do I gate release artifacts with KFD-1 contract-world witnesses? | [`release-passport.md`](release-passport.md#kfd-1-contract-world-release-gate) | verify/use | stable |\n| How do I declare, render, and audit product KFD-2 release trust claims? | [`kfd-support.md`](kfd-support.md#kfd-2) + [`release-passport.md`](release-passport.md#kfd-2-release-trust-passport-audit) + [`cli.md`](cli.md) | verify/use | stable |\n| How do I gate KFD-3 collaboration-interface releases? | [`release-passport.md`](release-passport.md#kfd-3-collaboration-interface-release-gate) + [`cli.md`](cli.md) | verify/use | stable |\n| How do I detect, register, audit, witness, or query KFD-3 product surfaces? | [`kfd-support.md`](kfd-support.md) + [`cli.md`](cli.md) | verify/use | stable |\n| How do I keep `@v2` floating refs while detecting Buildchain contract drift? | [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock) | verify/use | stable |\n| How do reusable workflows bind controller intent, source/runtime identity, outcomes, and receipt evidence? | [`controller-evidence.md`](controller-evidence.md) | verify/use | draft |\n| How do I propagate finalized upstream releases to downstream package/site PRs? | [`release-propagation.md`](release-propagation.md) | use | preview |\n| How do paper or report repositories publish PDFs, metadata, source bundles, site-consumable manifests, npm packages, and GitHub Releases? | [`publication-artifacts.md`](publication-artifacts.md) | use | stable |\n| How do I generate KFD / Release Passport badge bundles without hand-maintaining Markdown? | [`readme-badges.md`](readme-badges.md) + [`cli.md`](cli.md) | use | stable |\n| How do I generate and verify a Homebrew tap from release passport evidence? | [`homebrew.md`](homebrew.md) + [`cli.md`](cli.md) | use/verify | stable |\n| How do I prove a PR-stage reusable build is the artifact source promoted later? | [`release-candidate.md`](release-candidate.md) + [`reusable-build-surface.md`](reusable-build-surface.md) | verify | stable |\n| Why are binary release assets archived by platform, and where is the single bundle? | [`binary-distribution.md`](binary-distribution.md) | verify | stable |\n| How do I add timestamped logs inside build scripts? | [`toolkit-observability.md`](toolkit-observability.md) | use | stable |\n| What package-owned facts should buildchain.libkungfu.dev render? | [`site-bundle-contract.md`](site-bundle-contract.md) | use | stable |\n| How do I call the reusable build workflow? | [`reusable-build-surface.md`](reusable-build-surface.md) | use | stable |\n| How does Buildchain schedule and aggregate a project-owned Shifu Gate profile? | [`shifu-gate-profiles.md`](shifu-gate-profiles.md) | use/verify | draft |\n| How do I use one build job that follows alpha during development and stable for releases? | [`reusable-build-surface.md`](reusable-build-surface.md#automatic-channel-router) | use | preview |\n| How do self-hosted runners relay large artifacts through S3 before GitHub artifacts? | [`reusable-build-surface.md`](reusable-build-surface.md#artifact-transfer-relay) | use | stable |\n| How do self-hosted runners reuse local Git checkout caches without weakening source locks? | [`reusable-build-surface.md`](reusable-build-surface.md#locked-source-checkout-cache) | use | stable |\n| How do I validate an unreleased Buildchain runtime train while keeping `@v2`? | [`runtime-train-validation.md`](runtime-train-validation.md) | use | stable |\n| How do I automatically qualify alpha candidates and publish the newest non-revoked qualified candidate at a fixed window? | [`stable-candidate-patrol.md`](stable-candidate-patrol.md) | use | preview |\n| How do I deploy a site/app preview, staging, or production surface? | [`web-surface-deployments.md`](web-surface-deployments.md) | use | stable |\n| How do I publish observed infrastructure contracts for downstream consumers? | [`infra-contract.md`](infra-contract.md) | use | preview |\n| How do I use the active actions directly? | [`../actions/validate-config/README.md`](../actions/validate-config/README.md), [`../actions/run-lifecycle/README.md`](../actions/run-lifecycle/README.md), [`../actions/promote-buildchain-ref/README.md`](../actions/promote-buildchain-ref/README.md), [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |\n| How can a consumer workflow report a Buildchain-owned failure back to Buildchain? | [`consumer-issue-reporting.md`](consumer-issue-reporting.md) + [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |\n| What do the fixture repositories demonstrate? | [`../fixtures/libnode-shaped/README.md`](../fixtures/libnode-shaped/README.md), [`../fixtures/publish-transaction-shaped/README.md`](../fixtures/publish-transaction-shaped/README.md), [`../fixtures/web-surface-shaped/README.md`](../fixtures/web-surface-shaped/README.md), [`../fixtures/publication-artifact-shaped/README.md`](../fixtures/publication-artifact-shaped/README.md) | verify | stable |\n| What license and contribution terms apply? | [`../LICENSE`](../LICENSE) + [`../LICENSE-POLICY.md`](../LICENSE-POLICY.md) | use | stable |\n| What trademark, official-service, and provider-compliance boundaries apply? | [`../TRADEMARK.md`](../TRADEMARK.md) + [`../ACCEPTABLE_USE.md`](../ACCEPTABLE_USE.md) + [`../PROVIDER_COMPLIANCE.md`](../PROVIDER_COMPLIANCE.md) | use | stable |\n| How do I report a vulnerability? | [`../SECURITY.md`](../SECURITY.md) | use | stable |\n\n## Also asking about\n\n- **ABV / old workflows / old action repositories** -> [`release-governance.md`](release-governance.md)\n and [`migration-inventory.md`](migration-inventory.md).\n- **v2 / v2-alpha / v2.0 / v2.0-alpha / exact tags / floating tags** ->\n [`release-governance.md`](release-governance.md) and\n [`release-flow.md`](release-flow.md).\n- **Buildchain self-dogfood / released alpha canary / stable compatibility lane** ->\n [`release-governance.md`](release-governance.md#buildchain-alpha-self-dogfood).\n- **qualified alpha ledger / scheduled stable selection / hold and revoke** ->\n [`stable-candidate-patrol.md`](stable-candidate-patrol.md).\n- **v2.1 vs v2.2 / when to open a new minor line** ->\n [`versioning.md`](versioning.md).\n- **dry-run / what would happen if this channel PR merges** -> [`cli.md`](cli.md)\n and [`release-flow.md`](release-flow.md).\n- **protected dev branches / scheduled ready-PR merge / daily-weekly-monthly patrol** ->\n [`release-governance.md`](release-governance.md#protected-dev-branches) and\n [`release-governance.md`](release-governance.md#buildchain-patrol).\n- **pnpm / npm / yarn / package-manager adapters** ->\n [`lifecycle-protocol.md`](lifecycle-protocol.md).\n- **pip / Conan / CMake / custom commands** -> [`lifecycle-protocol.md`](lifecycle-protocol.md)\n and [`reusable-build-surface.md`](reusable-build-surface.md).\n- **libnode / native artifacts / self-hosted runner matrix** ->\n [`reusable-build-surface.md`](reusable-build-surface.md) and\n [`../fixtures/libnode-shaped/README.md`](../fixtures/libnode-shaped/README.md).\n- **S3 artifact relay / self-hosted runner artifact transfer** ->\n [`reusable-build-surface.md`](reusable-build-surface.md#artifact-transfer-relay).\n- **local Git checkout cache / self-hosted source transport** ->\n [`reusable-build-surface.md`](reusable-build-surface.md#locked-source-checkout-cache).\n- **runtime train validation / temporary `buildchain-ref` override** ->\n [`runtime-train-validation.md`](runtime-train-validation.md) and\n [`reusable-build-surface.md`](reusable-build-surface.md).\n- **consumer workflow feedback / automatic Buildchain GitHub issues** ->\n [`consumer-issue-reporting.md`](consumer-issue-reporting.md).\n- **PR-stage RC artifacts / promote-only release candidates** ->\n [`release-candidate.md`](release-candidate.md) and\n [`reusable-build-surface.md`](reusable-build-surface.md).\n- **infra contract / observed infrastructure outputs / downstream contract propagation** ->\n [`infra-contract.md`](infra-contract.md).\n- **standalone binary install / platform archives / GitHub Release bundle** ->\n [`install.md`](install.md), [`binary-distribution.md`](binary-distribution.md),\n and [`release-passport.md`](release-passport.md).\n- **Trusted Publishing / npm / publish evidence / recovery** ->\n [`cli.md`](cli.md) and [`publish-transaction.md`](publish-transaction.md).\n- **Git source digest / module build facts / product build facts / legacy\n Kungfu build info** -> [`build-facts.md`](build-facts.md) and [`cli.md`](cli.md).\n- **release chains / upstream package or publication artifact as source of truth / site synchronization** ->\n [`release-propagation.md`](release-propagation.md).\n- **paper repositories / PDFs / publication manifests / immutable archive registries / source bundles** ->\n [`publication-artifacts.md`](publication-artifacts.md).\n- **README status badges / KFD badge bundles / badge facts JSON** ->\n [`readme-badges.md`](readme-badges.md) and [`cli.md`](cli.md).\n- **Homebrew taps / distribution indexes / Formula drift checks** ->\n [`homebrew.md`](homebrew.md) and [`cli.md`](cli.md).\n- **KFD-1 contract worlds / byte-for-byte release gates** ->\n [`release-passport.md`](release-passport.md#kfd-1-contract-world-release-gate).\n- **KFD-2 public release trust claim audit** ->\n [`release-passport.md`](release-passport.md#kfd-2-release-trust-passport-audit).\n- **KFD-3 collaboration-interface / agent-facing control surface closure** ->\n [`release-passport.md`](release-passport.md#kfd-3-collaboration-interface-release-gate).\n- **floating `@v2` / contract lock / compatible drift issue** ->\n [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock).\n- **GitHub Release passport / binary assets / artifact evidence / agent release checks** ->\n [`release-passport.md`](release-passport.md),\n [`binary-distribution.md`](binary-distribution.md), and [`cli.md`](cli.md).\n- **Buildchain logging / timestamps / consumer build phase timing** ->\n [`toolkit-observability.md`](toolkit-observability.md) for JavaScript API\n imports, and [`cli.md`](cli.md) for workflow or shell command usage.\n- **buildchain.libkungfu.dev / package-owned site facts** ->\n [`site-bundle-contract.md`](site-bundle-contract.md).\n- **sites / web previews / staging / production gates** ->\n [`web-surface-deployments.md`](web-surface-deployments.md).\n- **trademark / fork / official service / provider compliance / release\n evidence boundary** -> [`../TRADEMARK.md`](../TRADEMARK.md),\n [`../ACCEPTABLE_USE.md`](../ACCEPTABLE_USE.md), and\n [`../PROVIDER_COMPLIANCE.md`](../PROVIDER_COMPLIANCE.md).\n\n## How this map is maintained\n\n- A document becomes a row here when it is a stable entrypoint for a user,\n contributor, or workflow consumer.\n- A row's status must never claim more than the artifact delivers.\n- `why` documents explain intent and design pressure; `verify` and `use`\n documents should state what is guaranteed, where to verify it, and the current\n maturity of that guarantee."
|
|
871
872
|
},
|
|
872
873
|
{
|
|
873
874
|
"id": "manual:migration-inventory",
|
|
@@ -1030,7 +1031,7 @@
|
|
|
1030
1031
|
],
|
|
1031
1032
|
"maturity": "stable",
|
|
1032
1033
|
"sourcePath": "docs/publication-artifacts.md",
|
|
1033
|
-
"digest": "sha256:
|
|
1034
|
+
"digest": "sha256:03a7f0b1dab5aa5e124b5ff2b740fffeaa56c10277543c8419ec7c414afcf2ce",
|
|
1034
1035
|
"headings": [
|
|
1035
1036
|
{
|
|
1036
1037
|
"level": 1,
|
|
@@ -1063,7 +1064,54 @@
|
|
|
1063
1064
|
"anchor": "site-consumption"
|
|
1064
1065
|
}
|
|
1065
1066
|
],
|
|
1066
|
-
"markdown": "# Publication Artifact Workflow\n\nBuildchain supports `project.type = \"publication-artifact\"` for repositories\nthat produce auditable papers, reports, specifications, or similar publication\npackages. These repositories are artifact producers. They should not be forced\nto become `web-surface` repositories just because a downstream site later\nrenders the paper.\n\nThe split is:\n\n```text\npaper repo = source, PDF, metadata, source bundle, publication manifest\npapers site = layout, navigation, public web surface, downstream rendering\n```\n\n## Configuration\n\nThe paper repository owns `.buildchain/buildchain.toml`:\n\n```toml\nschema = 1\n\n[project]\ntype = \"publication-artifact\"\nname = \"paper-observer-declared-timelines\"\n\n[publication]\nkind = \"paper\"\ntitle = \"Observer-Declared Timelines for Real-World Agent Work\"\nversion = \"0.1.0\"\nprimary_artifact = \"_build/main.pdf\"\nartifact_paths = [\"_build/main.pdf\"]\nmetadata_paths = [\"README.md\", \"docs/MAP.md\"]\nsource_paths = [\"paper\", \"README.md\", \"LICENSE\", \"Makefile\"]\nsite_consumers = [\"papers.libkungfu.dev\"]\nmanifest_path = \".buildchain/publication/publication-artifact.json\"\nsource_bundle_path = \".buildchain/publication/source.tar.gz\"\n\n[publication.archive]\nid = \"observer-declared-timelines\"\ncanonical_url = \"https://papers.libkungfu.dev/observer-declared-timelines/\"\nlatest_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/\"\nlatest_evidence_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/buildchain.release.json\"\nimmutable_base_url = \"https://papers.libkungfu.dev/archive\"\nregistry_path = \".buildchain/publication/publication-registry.json\"\n\n[publication.toolchain]\ntype = \"latex-docker\"\nimage = \"ghcr.io/kungfu-systems/build-images/latex-pdf-builder\"\ndigest = \"sha256:c20f3809e96836c1c78e97c76939d12f1de3fed0ea9b7c40c43332ec2ea480f8\"\ncommand = \"latexmk -pdf -outdir=_build paper/main.tex\"\n\n[publish]\nkind = \"npm-paper-package\"\npackage = \"@kungfu-tech/paper-observer-declared-timelines\"\nauth = \"trusted-publishing\"\n\n[lifecycle.build]\ncommand = \"make pdf\"\n\n[lifecycle.verify]\ncommand = \"make check\"\n```\n\n`primary_artifact` is the human-facing publication output, usually a PDF.\n`source_paths` are archived into a source bundle. `metadata_paths` are hashed\nand recorded so a site can consume the paper facts without scraping prose.\n\n`publication.archive` turns the publication into an append-only public archive\ncontract:\n\n- `canonical_url` is the stable human reader page.\n- `latest_url` and `latest_evidence_url` are movable aliases for the latest\n reader page and latest evidence.\n- `immutable_base_url` plus `id` and `publication.version` produce a versioned\n prefix such as\n `https://papers.libkungfu.dev/archive/observer-declared-timelines/v0.1.0/`.\n- `immutable_url_prefix` can be used instead when the repository already owns\n the full version prefix.\n- `registry_path` records every published version and its manifest, passport,\n source bundle, primary artifact, URLs, and SHA-256 digests.\n\nImmutable archive prefixes are append-only. Do not run site deployment commands\nwith `sync --delete` or equivalent deletion semantics over those prefixes. A\nsame-version republish is allowed only when the immutable digest is unchanged;\nif PDF, source bundle, route, metadata, or toolchain evidence changes for an\nexisting version, Buildchain fails before the registry is rewritten.\n\nThe Buildchain web-surface adapter consumes this boundary from a surface-local\n`manifest.json` whose `archivePolicy.contract` is\n`kungfu-buildchain-publication-archive-policy`. It excludes the derived archive\nroot from every owning or parent `sync --delete`, verifies existing object\ndigests, uploads only missing immutable files with `--no-overwrite`, and verifies\nthem again before mutable site content is synchronized. A current package set\ndoes not need to rebuild or enumerate every historical version: the protected\narchive root remains outside deletion even when older versions disappear from\nthe current artifact.\n\n`publication.toolchain` makes the source-to-PDF transformation part of the\nmachine-readable contract. `latex-docker` is the preferred LaTeX profile. The\nBuildchain paper scaffold and reusable workflow default to\n`ghcr.io/kungfu-systems/build-images/latex-pdf-builder:v1.2.0`, pinned by the\ndigest above. The workflow pulls the declared image by digest and runs the\ndeclared command in that pinned container. `custom-command` remains available\nfor compatibility, but the passport records it as lower trust because\nBuildchain can record the command boundary without proving the compiler or\nLaTeX distribution digest.\n\n`publish.kind = \"npm-paper-package\"` declares that Buildchain, not the consumer\nrepository, owns the standard paper npm package shape and release transaction\nmechanics. `publish.package` is the public npm package that contains the PDF,\npublication manifest, publication passport, optional archive registry, source\nbundle, and declared metadata files.\n\n## Reusable Workflow\n\nConsumer repositories that only need to build and upload paper evidence can\ncall the build-only wrapper directly:\n\n```yaml\njobs:\n publication:\n uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2\n with:\n toolchain-type: config\n verify-command: make check\n artifact-name: observer-declared-timelines\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe build-only workflow:\n\n- resolves the Buildchain runtime and checks the floating contract lock before\n any paper build runs;\n- resolves the declared publication toolchain from `[publication.toolchain]` or\n workflow inputs;\n- for `latex-docker`, pulls the pinned build-images LaTeX builder digest and\n runs the declared command in the container;\n- for `custom-command`, runs the declared command and records the lower-trust\n boundary in the passport;\n- runs the verify command;\n- creates a source bundle from `publication.source_paths`;\n- writes `.buildchain/publication/publication-artifact.json`;\n- writes `.buildchain/publication/publication-artifact-passport.json`;\n- when `[publication.archive]` is configured, writes\n `.buildchain/publication/publication-registry.json` and verifies same-version\n immutability;\n- uploads one GitHub artifact containing the PDF, manifest, passport, optional\n registry, and source bundle.\n\nIt does not publish npm packages, deploy web pages, or create GitHub Releases.\n\nThe paper release preset additionally hydrates every prior published package\nregistry from the npm registry before generating the current manifest. npm\npackage integrity authenticates each downloaded source; Buildchain verifies the\nregistry self-digest, merges immutable records, and fails if a cumulative\nregistry drops an accepted version or changes immutable route/artifact facts.\nThe synthesized package therefore carries complete history even on a clean\nrunner. Its cumulative registry and file SHA-256 values are bound into the paper\nrelease build summary and release passport evidence.\n\n## Paper Release Preset\n\nPaper repositories that publish a versioned npm package should use the\nBuildchain-managed release preset instead of copying npm transaction scripts or\npromotion YAML:\n\n```yaml\nname: Paper Release\n\non:\n push:\n branches:\n - alpha/v1/v1.0\n - release/v1/v1.0\n workflow_dispatch:\n inputs:\n buildchain-ref:\n description: \"Temporary Buildchain runtime ref\"\n required: false\n default: \"\"\n\njobs:\n paper-release:\n uses: kungfu-systems/buildchain/.github/workflows/paper-release.yml@v2\n permissions:\n checks: write\n contents: write\n id-token: write\n issues: write\n secrets:\n BUILDCHAIN_PROMOTION_TOKEN: ${{ secrets.RELEASE_AUTHORITY_TOKEN }}\n with:\n buildchain-ref: ${{ inputs.buildchain-ref || '' }}\n toolchain-type: config\n verify-command: make check\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\n`RELEASE_AUTHORITY_TOKEN` is a caller-chosen release authority secret name.\nMap whichever repository or organization secret owns protected release\nbookkeeping into the reusable workflow's `BUILDCHAIN_PROMOTION_TOKEN` contract;\nthe reusable workflow does not require that provider-side secret to use a\nspecific name. Before it builds the paper, the workflow uses that authority to\nread the target channel's branch protection and fails with a configuration\ndiagnostic if the protection is not readable. `github.token` remains a fallback\nfor repositories where its permissions are sufficient.\n\nThe preset:\n\n- resolves the same floating Buildchain runtime and contract lock as the build\n workflow;\n- verifies that the declared promotion authority can read the protected target\n channel before starting the publication build;\n- builds the PDF through the declared pinned LaTeX Docker toolchain or custom\n command;\n- verifies the paper repository;\n- writes the publication manifest, publication passport, optional archive\n registry, and source bundle;\n- synthesizes an npm package from `[publication]` and `[publish]` declarations\n under `.buildchain/publication/npm-package`;\n- computes npm-style `sha512` integrity from `npm pack --dry-run` and passes\n it as `publish-required-artifacts-json`;\n- creates a `publish-gate/<alpha|release>/.../<version>` source lock for the\n channel commit and requires `promote-buildchain-ref` to verify that lock\n before any publish side effect;\n- publishes the package through npm Trusted Publishing;\n- writes Buildchain release/passport evidence; and\n- creates or updates the exact-version GitHub Release by default.\n\nConsumers can opt out of the GitHub Release with `github-release: false`, but\nthe default is on so downstream release propagation can observe\n`release.published` without hand-written `gh release` steps.\n\nFor npm Trusted Publishing, register the consumer workflow file that calls this\npreset, for example `.github/workflows/paper-release.yml`, against the declared\npackage in npm. The trusted publisher is the consumer repository and workflow\nfile; the implementation still runs inside Buildchain's reusable workflow.\n\nStandard paper repositories should not carry local copies of\n`scripts/npm-publish-transaction.mjs`, package-generation scripts, or\npromotion/ref-lock YAML. If the default package shape is insufficient, extend\nBuildchain rather than forking the mechanics into each paper repository.\n\n## CLI And Node API\n\nGenerate the publication manifest locally or in CI:\n\n```sh\nbuildchain publication-artifact manifest --source-sha \"$(git rev-parse HEAD)\" --json\n```\n\nGenerate the npm package contents after the manifest exists:\n\n```sh\nbuildchain publication-artifact npm-package --json\n```\n\nNode API:\n\n```js\nimport {\n collectPublicationArtifact,\n writePublicationArtifact,\n} from \"@kungfu-tech/buildchain/publication-artifact\";\n\nimport {\n collectPublicationPackageFacts,\n preparePublicationNpmPackage,\n} from \"@kungfu-tech/buildchain/publication-package\";\n```\n\n`writePublicationArtifact()` is the single implementation used by the CLI and\nthe reusable workflow. The generated manifest records:\n\n- publication title, kind, authors, and primary artifact;\n- artifact paths, byte sizes, and SHA-256 digests;\n- metadata paths and SHA-256 digests;\n- source SHA, tree SHA, source files, and source bundle digest;\n- publication toolchain type, image, digest, command, invocation mode, and trust\n classification;\n- timestamp and reproducibility policy;\n- downstream site-consumption hints;\n- optional archive routes for canonical, latest, latest evidence, immutable\n version prefix, and public artifact URLs.\n\nThe companion publication artifact passport records the same source and\nartifact evidence plus an explicit responsibility split. Buildchain proves\ndeclared files and hashes; it does not peer-review paper claims.\n\nWhen archive config is present, the registry uses the\n`kungfu-buildchain-publication-artifact-registry` contract. A site repository\ncan render latest pages and historical version indexes from that registry\nwithout rebuilding old PDFs from the latest npm package or paper source.\n\n## Site Consumption\n\nA downstream papers site should treat the publication manifest as the single\nfact source for the artifact. The site owns rendering and navigation; it should\nnot reinterpret the paper repository as a web deployment source.\nFor registry-level routing, sites should first consume the package-owned\nBuildchain fact source:\n\n```text\nnode_modules/@kungfu-tech/buildchain/dist/site/publication-registry.json\n```\n\nor the equivalent package export:\n\n```js\nimport registry from \"@kungfu-tech/buildchain/site/publication-registry.json\" with { type: \"json\" };\n```\n\nThat registry uses the `kungfu-buildchain-publication-release-registry`\ncontract. It separates mutable canonical/latest reader routes from immutable\nversion prefixes, publication artifacts, source bundles, and passport evidence\nso site repositories can render `/papers/**` without maintaining a parallel\nfixture truth source.\n\nFor `paper-observer-declared-timelines`, the expected adoption path is:\n\n```text\npaper repo builds PDF + manifest + source bundle\npaper repo updates publication-registry.json\npapers site consumes publication-artifact.json\npapers site consumes publication-registry.json for history\nsite renders paper page and links the PDF/source bundle\n```\n\nThis mirrors web-surface governance without mixing producer and renderer\nresponsibilities."
|
|
1067
|
+
"markdown": "# Publication Artifact Workflow\n\nBuildchain supports `project.type = \"publication-artifact\"` for repositories\nthat produce auditable papers, reports, specifications, or similar publication\npackages. These repositories are artifact producers. They should not be forced\nto become `web-surface` repositories just because a downstream site later\nrenders the paper.\n\nThe split is:\n\n```text\npaper repo = source, PDF, metadata, source bundle, publication manifest\npapers site = layout, navigation, public web surface, downstream rendering\n```\n\n## Configuration\n\nThe paper repository owns `.buildchain/buildchain.toml`:\n\n```toml\nschema = 1\n\n[project]\ntype = \"publication-artifact\"\nname = \"paper-observer-declared-timelines\"\n\n[publication]\nkind = \"paper\"\ntitle = \"Observer-Declared Timelines for Real-World Agent Work\"\nversion = \"0.1.0\"\nprimary_artifact = \"_build/main.pdf\"\nartifact_paths = [\"_build/main.pdf\"]\nmetadata_paths = [\"README.md\", \"docs/MAP.md\"]\nsource_paths = [\"paper\", \"README.md\", \"LICENSE\", \"Makefile\"]\nsite_consumers = [\"papers.libkungfu.dev\"]\nmanifest_path = \".buildchain/publication/publication-artifact.json\"\nsource_bundle_path = \".buildchain/publication/source.tar.gz\"\n\n[publication.archive]\nid = \"observer-declared-timelines\"\ncanonical_url = \"https://papers.libkungfu.dev/observer-declared-timelines/\"\nlatest_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/\"\nlatest_evidence_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/buildchain.release.json\"\nimmutable_base_url = \"https://papers.libkungfu.dev/archive\"\nregistry_path = \".buildchain/publication/publication-registry.json\"\n\n[publication.toolchain]\ntype = \"latex-docker\"\nimage = \"ghcr.io/kungfu-systems/build-images/latex-pdf-builder\"\ndigest = \"sha256:c20f3809e96836c1c78e97c76939d12f1de3fed0ea9b7c40c43332ec2ea480f8\"\ncommand = \"latexmk -pdf -outdir=_build paper/main.tex\"\n\n[publish]\nkind = \"npm-paper-package\"\npackage = \"@kungfu-tech/paper-observer-declared-timelines\"\nauth = \"trusted-publishing\"\n\n[lifecycle.build]\ncommand = \"make pdf\"\n\n[lifecycle.verify]\ncommand = \"make check\"\n```\n\n`primary_artifact` is the human-facing publication output, usually a PDF.\n`source_paths` are archived into a source bundle. `metadata_paths` are hashed\nand recorded so a site can consume the paper facts without scraping prose.\n\n`publication.archive` turns the publication into an append-only public archive\ncontract:\n\n- `canonical_url` is the stable human reader page.\n- `latest_url` and `latest_evidence_url` are movable aliases for the latest\n reader page and latest evidence.\n- `immutable_base_url` plus `id` and `publication.version` produce a versioned\n prefix such as\n `https://papers.libkungfu.dev/archive/observer-declared-timelines/v0.1.0/`.\n- `immutable_url_prefix` can be used instead when the repository already owns\n the full version prefix.\n- `registry_path` records every published version and its manifest, passport,\n source bundle, primary artifact, URLs, and SHA-256 digests.\n\nImmutable archive prefixes are append-only. Do not run site deployment commands\nwith `sync --delete` or equivalent deletion semantics over those prefixes. A\nsame-version republish is allowed only when the immutable digest is unchanged;\nif PDF, source bundle, route, metadata, or toolchain evidence changes for an\nexisting version, Buildchain fails before the registry is rewritten.\n\nThe Buildchain web-surface adapter consumes this boundary from a surface-local\n`manifest.json` whose `archivePolicy.contract` is\n`kungfu-buildchain-publication-archive-policy`. It excludes the derived archive\nroot from every owning or parent `sync --delete`, verifies existing object\ndigests, uploads only missing immutable files with `--no-overwrite`, and verifies\nthem again before mutable site content is synchronized. A current package set\ndoes not need to rebuild or enumerate every historical version: the protected\narchive root remains outside deletion even when older versions disappear from\nthe current artifact.\n\n`publication.toolchain` makes the source-to-PDF transformation part of the\nmachine-readable contract. `latex-docker` is the preferred LaTeX profile. The\nBuildchain paper scaffold and reusable workflow default to\n`ghcr.io/kungfu-systems/build-images/latex-pdf-builder:v1.2.0`, pinned by the\ndigest above. The workflow pulls the declared image by digest and runs the\ndeclared command in that pinned container. `custom-command` remains available\nfor compatibility, but the passport records it as lower trust because\nBuildchain can record the command boundary without proving the compiler or\nLaTeX distribution digest.\n\n`publish.kind = \"npm-paper-package\"` declares that Buildchain, not the consumer\nrepository, owns the standard paper npm package shape and release transaction\nmechanics. `publish.package` is the public npm package that contains the PDF,\npublication manifest, publication passport, optional archive registry, source\nbundle, and declared metadata files.\n\n## Reusable Workflow\n\nConsumer repositories that only need to build and upload paper evidence can\ncall the build-only wrapper directly:\n\n```yaml\njobs:\n publication:\n uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2\n with:\n toolchain-type: config\n verify-command: make check\n artifact-name: observer-declared-timelines\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe build-only workflow:\n\n- resolves the Buildchain runtime and checks the floating contract lock before\n any paper build runs;\n- resolves the declared publication toolchain from `[publication.toolchain]` or\n workflow inputs;\n- for `latex-docker`, pulls the pinned build-images LaTeX builder digest and\n runs the declared command in the container;\n- for `custom-command`, runs the declared command and records the lower-trust\n boundary in the passport;\n- runs the verify command;\n- creates a source bundle from `publication.source_paths`;\n- writes `.buildchain/publication/publication-artifact.json`;\n- writes `.buildchain/publication/publication-artifact-passport.json`;\n- when `[publication.archive]` is configured, writes\n `.buildchain/publication/publication-registry.json` and verifies same-version\n immutability;\n- uploads one GitHub artifact containing the PDF, manifest, passport, optional\n registry, and source bundle.\n\nIt does not publish npm packages, deploy web pages, or create GitHub Releases.\n\nThe paper release preset additionally hydrates every prior published package\nregistry from the npm registry before generating the current manifest. npm\npackage integrity authenticates each downloaded source; Buildchain verifies the\nregistry self-digest, merges immutable records, and fails if a cumulative\nregistry drops an accepted version or changes immutable route/artifact facts.\nThe synthesized package therefore carries complete history even on a clean\nrunner. Its cumulative registry and file SHA-256 values are bound into the paper\nrelease build summary and release passport evidence.\n\n## Paper Release Preset\n\nPaper repositories that publish a versioned npm package should use the\nBuildchain-managed release preset instead of copying npm transaction scripts or\npromotion YAML:\n\n```yaml\nname: Paper Release\n\non:\n push:\n branches:\n - alpha/v1/v1.0\n - release/v1/v1.0\n workflow_dispatch:\n inputs:\n buildchain-ref:\n description: \"Temporary Buildchain runtime ref\"\n required: false\n default: \"\"\n\njobs:\n paper-release:\n uses: kungfu-systems/buildchain/.github/workflows/paper-release-sealed.yml@v2\n permissions:\n actions: read\n checks: write\n contents: write\n id-token: write\n issues: write\n with:\n buildchain-ref: ${{ inputs.buildchain-ref || '' }}\n publisher-workflow-path: .github/workflows/paper-release.yml\n toolchain-type: config\n verify-command: make check\n artifact-paths: _build/paper-name.pdf\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe sealed preset does not accept a long-lived promotion token. It builds and\npackages the paper in a read-only job, then a credential-free authority job\ndownloads that exact candidate, audits the external control plane, and seals a\ncapability over the source tree, Buildchain runtime, controller receipt, PDF,\nand npm package bytes. Only the final job receives write and OIDC permissions;\nit downloads the admitted candidate, recomputes the capability binding, and\npublishes without executing consumer build commands. npm binds the OIDC identity\nto the consumer workflow named by `publisher-workflow-path`.\n\nThe preset:\n\n- resolves the floating Buildchain runtime once and binds the exact SHA into the\n publication candidate and authority capability;\n- builds the PDF through the declared pinned LaTeX Docker toolchain or custom\n command in a read-only job;\n- verifies the paper repository;\n- writes the publication manifest, publication passport, optional archive\n registry, and source bundle;\n- synthesizes an npm package from `[publication]` and `[publish]` declarations\n under `.buildchain/publication/npm-package`;\n- computes npm-style `sha512` integrity from `npm pack --dry-run` and passes\n it as `publish-required-artifacts-json`;\n- creates a `publish-gate/<alpha|release>/.../<version>` source lock for the\n channel commit and requires `promote-buildchain-ref` to verify that lock\n before any publish side effect;\n- verifies the complete candidate again after authority and publishes the\n package through npm Trusted Publishing without rebuilding it;\n- writes Buildchain release/passport evidence; and\n- creates or updates the exact-version GitHub Release by default, uploading\n every file declared by `publication.primary_artifact` and\n `publication.artifact_paths` alongside the release evidence.\n\nConsumers can opt out of the GitHub Release with `github-release: false`, but\nthe default is on so downstream release propagation can observe\n`release.published` without hand-written `gh release` steps.\n\nDeclared publication artifacts are resolved from the generated publication\nmanifest rather than repeated in consumer workflow YAML. Publication fails\nbefore upload if a declared artifact is missing or if its basename would\ncollide with another GitHub Release asset.\n\nFor npm Trusted Publishing, register the consumer workflow file that calls this\npreset, for example `.github/workflows/paper-release.yml`, against the declared\npackage in npm. The trusted publisher is the consumer repository and workflow\nfile; the implementation still runs inside Buildchain's reusable workflow.\n\nStandard paper repositories should not carry local copies of\n`scripts/npm-publish-transaction.mjs`, package-generation scripts, or\npromotion/ref-lock YAML. If the default package shape is insufficient, extend\nBuildchain rather than forking the mechanics into each paper repository.\n\n## CLI And Node API\n\nGenerate the publication manifest locally or in CI:\n\n```sh\nbuildchain publication-artifact manifest --source-sha \"$(git rev-parse HEAD)\" --json\n```\n\nGenerate the npm package contents after the manifest exists:\n\n```sh\nbuildchain publication-artifact npm-package --json\n```\n\nNode API:\n\n```js\nimport {\n collectPublicationArtifact,\n writePublicationArtifact,\n} from \"@kungfu-tech/buildchain/publication-artifact\";\n\nimport {\n collectPublicationPackageFacts,\n preparePublicationNpmPackage,\n} from \"@kungfu-tech/buildchain/publication-package\";\n```\n\n`writePublicationArtifact()` is the single implementation used by the CLI and\nthe reusable workflow. The generated manifest records:\n\n- publication title, kind, authors, and primary artifact;\n- artifact paths, byte sizes, and SHA-256 digests;\n- metadata paths and SHA-256 digests;\n- source SHA, tree SHA, source files, and source bundle digest;\n- publication toolchain type, image, digest, command, invocation mode, and trust\n classification;\n- timestamp and reproducibility policy;\n- downstream site-consumption hints;\n- optional archive routes for canonical, latest, latest evidence, immutable\n version prefix, and public artifact URLs.\n\nThe companion publication artifact passport records the same source and\nartifact evidence plus an explicit responsibility split. Buildchain proves\ndeclared files and hashes; it does not peer-review paper claims.\n\nWhen archive config is present, the registry uses the\n`kungfu-buildchain-publication-artifact-registry` contract. A site repository\ncan render latest pages and historical version indexes from that registry\nwithout rebuilding old PDFs from the latest npm package or paper source.\n\n## Site Consumption\n\nA downstream papers site should treat the publication manifest as the single\nfact source for the artifact. The site owns rendering and navigation; it should\nnot reinterpret the paper repository as a web deployment source.\nFor registry-level routing, sites should first consume the package-owned\nBuildchain fact source:\n\n```text\nnode_modules/@kungfu-tech/buildchain/dist/site/publication-registry.json\n```\n\nor the equivalent package export:\n\n```js\nimport registry from \"@kungfu-tech/buildchain/site/publication-registry.json\" with { type: \"json\" };\n```\n\nThat registry uses the `kungfu-buildchain-publication-release-registry`\ncontract. It separates mutable canonical/latest reader routes from immutable\nversion prefixes, publication artifacts, source bundles, and passport evidence\nso site repositories can render `/papers/**` without maintaining a parallel\nfixture truth source.\n\nFor `paper-observer-declared-timelines`, the expected adoption path is:\n\n```text\npaper repo builds PDF + manifest + source bundle\npaper repo updates publication-registry.json\npapers site consumes publication-artifact.json\npapers site consumes publication-registry.json for history\nsite renders paper page and links the PDF/source bundle\n```\n\nThis mirrors web-surface governance without mixing producer and renderer\nresponsibilities."
|
|
1068
|
+
},
|
|
1069
|
+
{
|
|
1070
|
+
"id": "manual:publication-authority",
|
|
1071
|
+
"title": "Sealed Publication Authority",
|
|
1072
|
+
"route": "/docs/publication-authority",
|
|
1073
|
+
"category": "manual",
|
|
1074
|
+
"capabilityGroup": "release-passport-trust",
|
|
1075
|
+
"audience": [
|
|
1076
|
+
"release-operator",
|
|
1077
|
+
"agent"
|
|
1078
|
+
],
|
|
1079
|
+
"maturity": "preview",
|
|
1080
|
+
"sourcePath": "docs/publication-authority.md",
|
|
1081
|
+
"digest": "sha256:06ba05f9d8a2685a0896334b6013a97c45b7d71163cf6898e5a6274baf7f0296",
|
|
1082
|
+
"headings": [
|
|
1083
|
+
{
|
|
1084
|
+
"level": 1,
|
|
1085
|
+
"title": "Sealed Publication Authority",
|
|
1086
|
+
"anchor": "sealed-publication-authority"
|
|
1087
|
+
},
|
|
1088
|
+
{
|
|
1089
|
+
"level": 2,
|
|
1090
|
+
"title": "Evidence chain",
|
|
1091
|
+
"anchor": "evidence-chain"
|
|
1092
|
+
},
|
|
1093
|
+
{
|
|
1094
|
+
"level": 2,
|
|
1095
|
+
"title": "Runner and control-plane evidence",
|
|
1096
|
+
"anchor": "runner-and-control-plane-evidence"
|
|
1097
|
+
},
|
|
1098
|
+
{
|
|
1099
|
+
"level": 2,
|
|
1100
|
+
"title": "API and CLI",
|
|
1101
|
+
"anchor": "api-and-cli"
|
|
1102
|
+
},
|
|
1103
|
+
{
|
|
1104
|
+
"level": 1,
|
|
1105
|
+
"title": "Optional stronger external evidence; generate the JSON outside the workflow.",
|
|
1106
|
+
"anchor": "optional-stronger-external-evidence-generate-the-json-outside-the-workflow"
|
|
1107
|
+
},
|
|
1108
|
+
{
|
|
1109
|
+
"level": 2,
|
|
1110
|
+
"title": "Publication lanes",
|
|
1111
|
+
"anchor": "publication-lanes"
|
|
1112
|
+
}
|
|
1113
|
+
],
|
|
1114
|
+
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: sealed-publication-authority\ndoc_type: protocol\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-07-15\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-15\n limits: Live provider configuration must be re-audited; no credential values are represented.\n---\n\n# Sealed Publication Authority\n\nBuildchain publication authority is a closed-world, fail-closed protocol. It does\nnot mint registry or cloud credentials. It independently verifies whether an\nalready protected publication job is allowed to request a short-lived provider\ncredential for one exact product, target, version, channel, and artifact digest.\n\nThe machine-readable authority inventory is\n`dist/site/publication-authority-registry.json`. Any workflow with a write,\nenvironment, OIDC, cloud credential, registry publish, release, or Git push\nsignal must have an explicit descriptor. A new authority-bearing workflow that\nis absent from the inventory fails site generation. Unknown workflows and every\ndescriptor not marked `product-publication` are denied product publication.\n\n## Evidence chain\n\nA qualifying admission binds exact source and runtime SHAs; contract, consumer\npolicy, qualifying controller receipt, Shifu/Gate aggregate, artifact, runner,\nand control-plane digests; repository, authority workflow, provider publisher\nworkflow, Environment policy,\nproduct, target, version, and channel; plus a unique nonce and a lifetime of no\nmore than 15 minutes. Every expected binding is mandatory at verification time;\nan omitted expected field is not a wildcard.\n\nThe independent verifier recomputes every digest and ignores a producer's own\nallow/deny conclusion. It fetches the exact evidence run, validates the actual\nrelease-candidate passport and referenced qualifying controller receipt,\nrecomputes the Shifu Gate aggregate or explicit consumer-owned no-Gate policy,\nrecomputes the downloaded artifact manifests, and hashes every declared product\npayload file against those manifests. The `.buildchain/` diagnostics envelope is\nbound by the manifest digest but excluded from the product-byte set because it can\nbe finalized after the lifecycle scan. The verifier also compares the PR evidence tree to the\nadmitted post-merge source commit tree. It rejects an unknown\nworkflow, stale or replayed nonce, runner downgrade, control-plane drift,\nsource/runtime mismatch, and artifact substitution. A successful result is a\nscoped capability receipt, not a bearer credential.\n\n## Runner and control-plane evidence\n\nRunner evidence uses exactly four classes: `ephemeral`, `reimaged`,\n`persistent-measured`, and `unqualified`. Ephemeral runners also record their\njob-isolation boundary. Reimaged and persistent runners qualify only when a\nclean baseline is proven and baseline, toolchain, cache-contract, and task-\nisolation digests are all present. Otherwise they still emit diagnostic\nevidence with `qualificationStatus = unqualified`, but cannot receive a product\ncapability.\n\nThe external audit records digests and pass/fail status for repository Actions\ndefaults, classic branch protection or an active matching repository ruleset,\ndeclared protected Environment policy or an explicit no-Environment binding,\njob-scoped credentials,\nabsence of long-lived workflow publication credentials, provider authority,\nand authorized runner class. Provider modes are `npm-trusted-publisher`,\n`github-token`, and `oidc-role`. The OIDC-role mode consumes only a sanitized\nprovider audit containing a role digest and qualifying decision; raw IAM policy,\ntokens, or credentials are rejected. Package-owner, cloud-root, GitHub\nadministrator, and registry-root credentials remain outside Buildchain's trust\nboundary. Missing or unreadable facts fail closed.\n\nAn unauthenticated local npm CLI is not evidence that Trusted Publishing is\nmissing. `npm whoami` reports only the local CLI session and does not report the\nOIDC identity that npm creates during `npm publish`. The default read-only audit\ntherefore binds the exact provider, repository, caller workflow, optional\nEnvironment, job-scoped OIDC permission, and absence of long-lived credentials,\nthen records `provider-at-transaction`: npm makes the final authorization\ndecision when `npm publish` exchanges the job's OIDC token. A missing or drifted\ntrusted-publisher configuration consequently denies the transaction safely; it\nis not preflighted through an unrelated long-lived npm login.\n\nAn authenticated external auditor can add stronger point-in-time evidence by\nsupplying sanitized `npm trust list --json` output with `--npm-trust-json`. This\nchanges the publisher fact to `audited-control-plane`; the workflow never runs\n`npm trust list` itself and never receives that auditor's npm credential.\n\nThe credential-free collector proves effective Actions and runner scope from\nthe publication workflow fetched at `--workflow-ref`: explicit read-only\nworkflow defaults, job-scoped write/OIDC permissions, and an exact GitHub-hosted\nrunner label. It does not call repository Actions-default or self-hosted-runner\nadministration endpoints. Branch/ruleset and OIDC subject facts remain live\nread-only provider queries. When the detailed branch-protection endpoint is not\nreadable with the workflow token, `--source-sha` binds the provider's public\nprotected-branch summary to the exact merged PR, independent approval, required\nsuccessful check, same-repository lineage, and current branch head. This records\nprovider-enforced transaction evidence without treating an unavailable\nadministration endpoint as an unprotected branch. It avoids turning a\nrepository-admin token into a publication prerequisite.\n\nFor non-dry-run workflows, missing admission, runner, control-plane, Gate, or\nexpected-binding evidence is rejected before Buildchain downloads candidate\nartifacts. The denial explicitly records that npm Trusted Publishing and OIDC\nwere not evaluated, so downstream diagnostics cannot misclassify an admission\nassembly failure as an npm authentication failure.\n\nBuildchain's own `workflow_run` promotion lane may assemble those inputs only\nfor `kungfu-systems/buildchain`. It downloads the exact prior RC passport,\nsummary, referenced controller receipt, manifests, and product payloads; proves\nthe admitted channel commit has the same Git tree as the RC; performs the live\nread-only control-plane audit; records the GitHub-hosted job as ephemeral runner\nprovenance; and creates an explicit Buildchain-owned no-Gate decision. The\nindependent verifier then recomputes every receipt and payload digest exactly as\nit does for externally supplied admission. The self-assembly mode rejects other\nrepositories, unknown refs, non-exact source SHAs, and any caller other than\n`.github/workflows/buildchain-ref-promotion.yml`. Manual apply and external\nconsumer workflows still require their own explicit admission inputs.\n\nBefore authority verification, the reusable promotion controller runs the same\nrelease transaction selector in read-only mode. That plan supplies one exact\npublication version and tag to the admission verifier, the publish-gate source\nlock, and the real promotion action. The verifier rejects a capability for a\ndifferent version, and the promotion action rechecks the planned version before\nany publish transaction side effect. Release-candidate fixture versions are\nartifact evidence only; they never name Buildchain's own source-lock or\npublication capability.\n\nEvidence publication is a separate authority class and never grants product\npublication.\n\n## API and CLI\n\nUse `@kungfu-tech/buildchain/publication-authority` or run:\n\n```bash\nbuildchain verify publication-admission admission.json \\\n --registry-json publication-authority-registry.json \\\n --runner-json runner.json \\\n --control-plane-audit-json control-plane.json \\\n --publication-evidence-json publication-evidence.json \\\n --expected-json expected.json \\\n --used-nonce previous-run-nonce \\\n --json\n```\n\nThe read-only live collector defaults to npm trusted publishing. Other product\nproviders select an explicit adapter:\n\n```bash\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch dev/v2/v2.12 \\\n --source-sha <exact-merged-branch-sha> \\\n --workflow .github/workflows/release-candidate-promote.yml \\\n --workflow-ref <exact-buildchain-sha> \\\n --publisher-workflow .github/workflows/buildchain-ref-promotion.yml \\\n --job promote \\\n --environment none\n\n# Optional stronger external evidence; generate the JSON outside the workflow.\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch dev/v2/v2.12 \\\n --workflow .github/workflows/release-candidate-promote.yml \\\n --publisher-workflow .github/workflows/buildchain-ref-promotion.yml \\\n --job promote \\\n --environment none \\\n --npm-trust-json sanitized-npm-trust.json\n\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch release/v2/v2.12 \\\n --workflow .github/workflows/.binary-release-assets.yml \\\n --job publish \\\n --environment buildchain-release-assets \\\n --publisher-mode github-token\n\nbuildchain audit publication-control-plane \\\n --repository OWNER/CONSUMER \\\n --workflow-repository kungfu-systems/buildchain \\\n --branch main \\\n --workflow .github/workflows/.web-surface.yml \\\n --job production-apply \\\n --environment production \\\n --publisher-mode oidc-role \\\n --provider-audit-json sanitized-oidc-role-audit.json\n```\n\nThe authority workflow identifies the reusable implementation that performs the\npublication job. The publisher workflow identifies the caller filename bound by\nthe provider's trusted-publisher policy; these identities are deliberately\nseparate. `--environment none` is an explicit assertion that the job declares no\nGitHub Environment and the provider policy has no Environment restriction. A\nnamed Environment must exist, be protected, and be declared by the job. The\nBuildchain receipt alone is never sufficient authorization.\n\n## Publication lanes\n\n`Binary Distribution` is evidence-only. It builds platform archives and a\nrelease evidence bundle with read-only repository permissions. GitHub Release\nasset writes live in `Binary Release Assets`, which downloads an exact prior\nevidence run, verifies its bundle digest against the sealed capability, and is\nthe only binary job with `contents: write` in the protected\n`buildchain-release-assets` Environment.\n\nThe npm/promotion, paper, binary-release, and web-production lanes all depend on\nthe independent verifier. Preview, staging, build, source-check, controller,\nand failure-evidence lanes do not inherit product publication capability."
|
|
1067
1115
|
},
|
|
1068
1116
|
{
|
|
1069
1117
|
"id": "manual:publish-transaction",
|
|
@@ -1294,7 +1342,7 @@
|
|
|
1294
1342
|
],
|
|
1295
1343
|
"maturity": "stable",
|
|
1296
1344
|
"sourcePath": "docs/release-governance.md",
|
|
1297
|
-
"digest": "sha256:
|
|
1345
|
+
"digest": "sha256:cce9f80add3c746fe28d8ebf5afb809348694741cb75d19154ed3057a9374c0d",
|
|
1298
1346
|
"headings": [
|
|
1299
1347
|
{
|
|
1300
1348
|
"level": 1,
|
|
@@ -1382,7 +1430,7 @@
|
|
|
1382
1430
|
"anchor": "operational-reading-order"
|
|
1383
1431
|
}
|
|
1384
1432
|
],
|
|
1385
|
-
"markdown": "# Release Governance\n\nBuildchain v2 preserves the release semantics of the older ABV workflow while\nmoving the implementation into one modern repository.\n\nThe central idea is simple: a reviewed merge into a release channel is the\nrelease intent. Automation must then create the version-state commit, exact tag,\nfloating tag, and next alpha state that make that intent true in Git.\n\n## Design Problem\n\nKungfu release automation has to keep four facts aligned:\n\n1. The source tree that was reviewed.\n2. The package version recorded in manifests such as `package.json` or\n `lerna.json`.\n3. The exact immutable release or prerelease tag.\n4. The floating channel refs that consumers actually use.\n\nIf any one of these facts is updated by hand, the system can split:\n\n- a consumer can fetch `v2.0` and receive a tree whose package version still\n says the previous release;\n- a maintainer can move `v2` without producing an exact `v2.0.N` audit tag;\n- an alpha can be promoted to production even though the release tree is not the\n same tree that was tested;\n- a protected branch merge can succeed while the follow-up version commit is\n missing, or a flow-internal generated `dev`/`alpha`/`release` ref update can\n fail after publish because the automation identity was not declared in the\n branch-protection review bypass allowance.\n\nThe older ABV workflow addressed this by letting GitHub PRs drive release\nstate. Buildchain keeps that choice because it makes release intent reviewable,\nobservable, and recoverable from Git history.\n\n## What ABV Contributed\n\nThe old ABV model was not just \"bump a version number.\" It encoded a governance\nloop:\n\n- release branches are named as channels: `dev`, `alpha`, `release`, and the\n administrative `publish-gate/major`;\n- a PR from one channel to the next is the release request;\n- verify jobs check that the branch pair is valid before merge;\n- a maintainer review is required before the branch moves;\n- after merge, automation writes the version change and moves tags;\n- exact tags and floating refs are aligned with the resulting commit;\n- the next development channel is prepared automatically.\n\nABV also kept the version-state mutation in the repository. For JavaScript\nrepositories that usually meant changing `lerna.json` and/or `package.json`.\nThat commit is important because the tag alone is not enough evidence: the\nsource tree should also declare the version that the tag advertises.\n\nBuildchain v2 treats that as a hard semantic requirement for its own release\nline.\n\n## Buildchain Implementation\n\nBuildchain implements the same governance loop with:\n\n- `.github/workflows/release-verify.yml` for PR verification;\n- `.github/workflows/buildchain-ref-promotion.yml` for post-verify ref\n promotion; this workflow dogfoods the declarative\n `release-candidate-promote.yml` wrapper and does not hand-wire resolver,\n artifact download, publish-gate, or promote action steps;\n- Buildchain self promotion enables `release-passport-buildchain-self-kfd`, so\n the promote action generates KFD-1 witnesses, KFD-2 public claim JSON, and\n KFD-3 collaboration-interface witnesses from the final version-state workspace\n before release passport finalization. The witness hashes therefore bind to the\n exact published package and site facts from\n `packages/core/buildchain-kfd-claims.js` instead of relying on prose release\n notes;\n- `actions/promote-buildchain-ref` for branch, tag, version-state, and\n governance checks;\n- package-manager adapters that can update version state for pnpm, npm, and\n yarn style repositories;\n- `buildchain.toml` lifecycle configuration for repositories whose version\n state or verification commands are not Node package-manager defaults.\n\nThe implementation is intentionally stricter than a local release script:\n\n- manual workflow dispatch can only do dry-run promotion;\n- non-dry-run promotion must be driven by a completed `Verify` workflow;\n- target branch protection details must be readable, and branch protection must\n apply to administrators as well as regular contributors;\n- alpha promotion must come from a merged same-repository PR from\n `dev/vX/vX.Y` to `alpha/vX/vX.Y`;\n- release promotion must come from a merged same-repository PR from\n `alpha/vX/vX.Y` to `release/vX/vX.Y`;\n- major promotion must come from a merged same-repository PR from\n `release/vX/vX.Y` to `publish-gate/major`;\n- release promotion requires an existing same-patch alpha tag and checks the\n release source tree against that tested alpha tree;\n- generated version-state commits are verified before refs move.\n\nPromotion intents are serialized globally per caller repository with\n`cancel-in-progress: false`. A queued intent re-reads its protected target ref\nbefore checkout, dependency installation, release-candidate resolution, or any\npublish-gate/ref mutation. If the ref already points at a newer SHA, that older\nintent is no longer release authority: the workflow records the requested and\ncurrent SHAs, proves that the current target is ahead of the requested commit,\nand completes as a `target-ref-advanced` superseded no-op. Diverged or behind\ncomparisons are not superseded transactions and still fail closed.\nMissing refs, unreadable repository state, invalid channels, governance\nfailures, and artifact mismatches still fail closed. The promote action repeats\nthe target check at the mutation boundary, so a ref that advances after the\nworkflow preflight cannot receive a second set of publication side effects.\n\n## Version Lines\n\nKungfu uses Python-like version lines where a minor line can represent a\nlong-lived product train. A line such as `v2.0` can produce many production\npatch releases:\n\n```text\nv2.0.0\nv2.0.1\nv2.0.2\n...\nv2.0.1234\n```\n\nThis is why Buildchain maintains both exact and floating refs:\n\n- `v2.0.2` is immutable release evidence;\n- `v2.0` is the latest production release on the `2.0` line;\n- `v2` is the selected stable major-line entrypoint;\n- `v2.0.3-alpha.0` is immutable alpha evidence;\n- `v2.0-alpha` is the latest test channel for the `2.0` line.\n- `v2-alpha` is the latest test channel on the highest published alpha minor in major `2`.\n\nA release does not mean \"minor is complete.\" It means \"this patch on this minor\nline is now production.\"\n\nGitHub repository rules must preserve that distinction. Exact tags such as\n`v2.0.2` and `v2.0.3-alpha.0` should be immutable. Floating channel tags such as\n`v2`, `v2.0`, `v2.0-alpha`, and `v2-alpha` must remain movable by the Buildchain promotion\ntoken after governance checks and publish evidence pass. A tag ruleset that\nprotects every `refs/tags/v*` ref is too broad because it also locks the\nfloating channel tags that Buildchain is required to update. Prefer exact-tag\npatterns such as `refs/tags/v*.*.*` for immutable release evidence, while\nleaving floating channel tags under Buildchain automation control.\n\n## Alpha Semantics\n\nAn alpha merge is:\n\n```text\ndev/vX/vX.Y -> alpha/vX/vX.Y\n```\n\nBuildchain then:\n\n1. Computes the next prerelease for the minor line.\n2. Writes version state such as `vX.Y.Z-alpha.N`.\n3. Verifies the generated version-state tree.\n4. Creates or reuses the exact alpha tag.\n5. Moves `alpha/vX/vX.Y` to the generated alpha commit.\n6. Moves `dev/vX/vX.Y` to the same generated alpha commit when this is a\n fast-forward update.\n7. Moves `vX.Y-alpha` to the same generated alpha commit.\n8. Moves `vX-alpha` only when `X.Y` is the highest minor in major `X` with a published alpha; older minor alpha work records a skip and cannot move the major channel backwards.\n\nThis keeps the test channel self-describing. If a consumer checks out\n`v2.0-alpha` or `v2-alpha`, the manifests and exact alpha tag agree. The major\nalpha ref removes routine consumer edits when Buildchain opens a newer minor,\nwhile exact tags and SHAs remain the reproducible audit choice.\n\n### Buildchain Alpha Self-Dogfood\n\nBuildchain continuously consumes its own current major alpha through\n`.github/workflows/buildchain-alpha-self-dogfood.yml`. Both lanes call the\nreleased channel router at `build.yml@v2-alpha`. The auto lane must resolve\n`v2-alpha`; the explicit stable lane must resolve `v2`. Both execute the same\ndeclared install, build, and verify fixture, proving that a single consumer\nsurface routes to distinct released runtimes without duplicating lifecycle\nconfiguration in the consumer.\n\nThe reusable build trust gate reads `job.workflow_ref`, which identifies the\ncalled workflow and its selected ref. It does not infer the runtime from\n`github.workflow_ref`, because GitHub defines that context as the caller\nworkflow identity during a reusable call.\n\nThe router selects `.buildchain/alpha-contract-lock.json` for alpha and\n`.buildchain/contract-lock.json` for stable. The alpha lock records the exact\nreviewed alpha SHA and compatibility digest; it does not replace the stable\nconsumer lock. A later alpha with only compatible additive drift continues,\nwhile a changed breaking digest fails until the new alpha contract is reviewed.\n\nThe evidence job resolves `v2-alpha` and `v2` through the GitHub refs API,\ncompares those immutable SHAs with the reusable workflow outputs, verifies the\n`alpha` and `stable` classifications, and uploads a JSON evidence artifact.\nThe canary runs after successful Buildchain ref promotion, on a daily fallback\nschedule, and on manual dispatch. It shares the release-promotion concurrency\ngroup, so another promotion cannot move the floating refs between runtime\nresolution and evidence comparison.\n\nThis is a post-publication consumer canary, not a release bootstrap. Source\nverification still runs the current commit, and\n`buildchain-ref-promotion.yml` still passes the verified exact SHA into the\npromotion workflow. Patrol, dev-merge, repair, and promotion defaults remain on\nstable or exact refs so a broken alpha cannot prevent Buildchain from publishing\nits fix. When Buildchain opens a new major, inventory validation requires this\nworkflow's fixed GitHub `uses` refs to move from `vN`/`vN-alpha` to the new\nmajor; GitHub does not allow expressions in a reusable-workflow `uses` ref.\n\nIf `dev/vX/vX.Y` has already advanced before generated alpha version-state\nbookkeeping can sync back, Buildchain records `skipped-non-fast-forward` for the\ndev sync and still completes the exact and floating alpha tags for the reviewed\nalpha commit. Later dev changes must go through their own dev-to-alpha\npromotion instead of rewinding dev. The normal path is direct: after alpha\nmerges, Buildchain applies the generated version-state commit to alpha and then\nfast-forwards dev to the same commit without a human version-state PR.\n\nIf alpha finalization is resumed after generated version-state bookkeeping was\npartially applied, Buildchain accepts the current alpha head as the generated\ncommit, or as a historical merge commit that contains the recorded release\nmaterial. An already-created exact alpha tag may point at the transaction\nrelease/material SHA or at the finalized alpha head; missing floating alpha\ntags are retried before the transaction becomes `complete`.\n\n## Release Semantics\n\nA release merge is:\n\n```text\nalpha/vX/vX.Y -> release/vX/vX.Y\n```\n\nBuildchain then:\n\n1. Finds the same-patch alpha tag that was tested.\n2. Checks that the release source tree matches that alpha tag tree, excluding\n only generated version-state differences.\n3. Writes final release version state such as `vX.Y.Z`.\n4. Verifies the generated release tree.\n5. Creates or reuses the exact release tag `vX.Y.Z`.\n6. Moves `release/vX/vX.Y` to the exact release commit.\n7. Moves `vX.Y` to the exact release commit.\n8. Moves `vX` when this minor line should be the stable major entrypoint.\n9. Prepares the next alpha version-state commit, such as\n `vX.Y.(Z+1)-alpha.0`.\n10. Moves `alpha/vX/vX.Y`, `dev/vX/vX.Y`, and `vX.Y-alpha` to that next alpha\n commit.\n11. Moves `vX-alpha` to that next alpha only when this remains the highest published alpha minor.\n\nThe production channel and the test channel therefore intentionally diverge\nafter release: production stays on the release commit, while alpha/dev continue\nat the next prerelease commit.\n\n### Stable Release Throttle And Canary Gate\n\nBuildchain's own stable channel has an additional pre-publication gate. It is\nevaluated after the PR-stage release candidate has been resolved and before the\npublish-gate ref, package registry, exact stable tag, or floating stable refs\nare mutated. Train refs and alpha promotion do not execute this gate.\n\nAll alpha and release promotions first run a metadata-only release-candidate\npreflight after queued-intent revalidation. The preflight uses the same resolver\nand exact target SHA as the publication job, but does not download payloads or\ninstall the candidate repository dependencies. Missing channel PRs, stale\nworkflow runs, expired passport pairs, and insufficient payload artifact sets\ntherefore fail before the full promotion job starts. The publication job still\ndownloads and validates the exact evidence again at the trust boundary; the\npreflight moves failure earlier without weakening the final check.\n\nThe policy is versioned in `.buildchain/stable-release-policy.json`. A stable\ncandidate is allowed only when all of these facts are true:\n\n- the candidate resolves to an immutable exact alpha tag and its GitHub\n prerelease timestamp;\n- at least 24 hours have passed since the preceding stable patch on the same\n minor line;\n- the preceding stable-to-alpha comparison contains a product or public\n contract path, not only version, test, evidence, or retrospective changes;\n- the version-bound impact record has a non-empty summary and at least one\n surface impact;\n- the `Build Surface Fixture` release-candidate run succeeded;\n- `site-libkungfu-dev` completed its no-apply `Buildchain Stable Canary` and an allowed\n maintainer attested that successful run on the exact alpha SHA through the\n `buildchain-canary/site-libkungfu-dev` commit-status context;\n- the canary runtime input is exactly the candidate alpha tag or the 40-character\n commit SHA resolved from that tag; a successful status pointing at another\n workflow, repository, tag, floating ref, or SHA is rejected as mismatched;\n- at least one hour has elapsed after the last required canary completed.\n\nThe machine report is written to\n`.buildchain/release-passport/stable-release-gate.json`. A passing report is\nuploaded with the stable release passport. A blocked run writes the same report\nbefore failing, so the missing or stale condition is inspectable without\nopening a publication transaction.\n\nGitHub's Actions run REST object does not expose `workflow_dispatch` inputs.\nBuildchain therefore verifies the run's `workflow_id` against the authoritative\nworkflow metadata, then reads the exact runtime from the workflow-owned\n`<workflow name> / <runtime ref>` run-name when no input field is available.\nAn explicit API input, when present, remains authoritative and cannot be\noverridden by the display name.\n\nThe cooldown is a minimum interval, not an instruction to release every day.\nCompatible work should still be batched until a stable release has a concrete\nconsumer need. Changing the interval, canary set, attestors, product path\nboundary, or soak time is a reviewed policy change.\n\nRepositories that want a predictable scheduled stable window can use\n[`Stable Candidate Patrol`](stable-candidate-patrol.md). It persists each exact\nalpha independently, qualifies it after repository-declared checks and soak,\nand selects the newest qualified non-revoked candidate. A newer soaking alpha\ndoes not invalidate an older qualified candidate. The selected tree enters the\nexisting strict `publish-gate/release/<line>/<version> -> release/<line>` PR\npath, so scheduled selection changes release intent timing without weakening\nsource locks, review, verification, publish transactions, or passports.\n\nIf release finalization is resumed after generated version-state bookkeeping was\npartially applied, Buildchain applies the same recovery rule: the current\nrelease head may be the generated commit, or a historical merge commit that\ncontains the recorded release material, existing exact tags and alpha/dev refs\nare accepted when they match the transaction, and missing floating `vX.Y` or\n`vX` tags are retried idempotently before completion.\n\nOnce the durable release transaction is `complete` and the exact/floating\nstable refs have moved, next-alpha preparation is post-release bookkeeping. A\nfailure there records `deferred-post-release-bookkeeping` and\n`next-anchor-required` instead of retroactively reporting the stable release as\nfailed. Generated next-alpha merges use the current dev tree as their base and\noverlay only declared version-state paths, preserving concurrent dev changes.\n\n## Major Gate Semantics\n\nA major gate merge is:\n\n```text\nrelease/vX/vX.Y -> publish-gate/major\n```\n\n`publish-gate/major` is the explicit replacement for the older ABV `main`\nchannel. The name is intentionally operational: it is a gate for a rare\nadministrator decision, not the active trunk. Keeping this decision in the same\nPR UI as alpha and release promotion keeps the human workflow simple while\navoiding the misleading meaning of `main`. The older `major-gate` branch name is\na compatibility alias only.\n\nBuildchain then:\n\n1. Verifies the source is a merged same-repository PR from a protected release\n line into `publish-gate/major`.\n2. Writes the next major production version state, such as `v(X+1).0.0`.\n3. Creates or reuses the exact release tag `v(X+1).0.0`.\n4. Moves `publish-gate/major` and `release/v(X+1)/v(X+1).0` to that release commit.\n5. Moves `v(X+1).0` and `v(X+1)` to that release commit.\n6. Prepares the next alpha version-state commit, such as\n `v(X+1).0.1-alpha.0`.\n7. Moves `alpha/v(X+1)/v(X+1).0`, `dev/v(X+1)/v(X+1).0`, and\n `v(X+1).0-alpha` to that next alpha commit.\n\nChecking out `publish-gate/major` should therefore look like a frozen release\nstate, not like a branch where day-to-day source work continues. Day-to-day\nsource work continues on `dev/vX/vX.Y`.\n\n## Protected Dev Branches\n\n`dev/vX/vX.Y` is a protected development channel, not a scratch branch. Normal\nsource changes should be made on work branches such as `feature/*`, `fix/*`,\n`chore/*`, `docs/*`, `ci/*`, or `refactor/*`, then reviewed through a pull\nrequest into the target dev line.\n\nThis keeps the earliest development channel audit-friendly:\n\n- the version line being changed is visible in the PR base branch;\n- CI and required checks run before the channel moves;\n- branch protection can prevent direct pushes and stale merges;\n- later `dev -> alpha -> release` promotion inherits a reviewable source\n lineage instead of trying to reconstruct how the dev branch changed.\n\nBuildchain provides the reusable\n`.github/workflows/dev-pr-auto-merge.yml` workflow for repositories that want a\nscheduled or manual \"merge ready dev PRs\" pass. The consumer repository owns\nthe trigger schedule, but the merge decision is declared through workflow\ninputs: target dev branch, required status/check names, ready and block labels,\nallowed work-branch prefixes, review requirements, maximum merges per run,\nmerge method, and dry-run mode.\n\nThe workflow defaults are conservative. A PR is skipped unless it targets the\nconfigured dev line, is not a draft, has the ready label, has no block label,\ncomes from the same repository, uses an allowed work-branch prefix, has a\ncurrent approval, is mergeable, and has the configured required checks passing.\nAfter each merge, the next PR is re-evaluated before it can move the protected\ndev branch. This prevents one merge from silently making the next candidate\nstale or conflicting.\n\nThe canonical consumer required check context is `check / check`, matching the\nreusable workflow call plus its `check` job. Buildchain's own `Verify` workflow\nemits the repository-local context `check`, so Buildchain self-promotion,\nrelease-line bootstrap, and dogfood patrol wrappers pass `check` explicitly.\nRelease governance preserves the exact context emitted by the repository and\nrecords branch-protection policy before/after facts; it does not rewrite one\ncontext shape into the other. Consumer repositories can keep their context\nstable while changing the actual verification command declaratively in\n`buildchain.toml`:\n\n```toml\n[lifecycle.install]\ncommand = \"cargo fetch --locked\"\n\n[lifecycle.verify]\ncommand = \"cargo test --workspace --locked\"\n```\n\nConsumers that want Buildchain to own the check wrapper can call\n`.github/workflows/check.yml@v2`. The wrapper runs the declared\n`lifecycle.install` and `lifecycle.verify` stages and fails the `check` job when\neither declaration is missing or the command exits non-zero.\n\nDevelopment pull requests that need source acceptance without product build or\nartifact verification can opt into `mode: source`. That mode runs only\n`lifecycle.install` and `lifecycle.check` on GitHub-hosted `ubuntu-24.04` while\npreserving the stable `check / check` required-check context. Existing callers\nremain on `mode: verify` by default, and callers may set\n`upload-artifacts: false` without weakening the job conclusion.\n\nTypical consumer wrapper:\n\n```yaml\nname: Merge Ready Dev PRs\n\non:\n schedule:\n - cron: \"17 * * * *\"\n workflow_dispatch:\n inputs:\n dry-run:\n type: boolean\n default: true\n\njobs:\n merge-dev:\n uses: kungfu-systems/buildchain/.github/workflows/dev-pr-auto-merge.yml@v2\n permissions:\n contents: write\n pull-requests: write\n checks: read\n statuses: read\n with:\n target-branch: dev/v2/v2.6\n required-status-checks: check / check\n ready-label: ready\n block-labels: blocked,do-not-merge\n max-merges: 1\n dry-run: ${{ inputs.dry-run || false }}\n```\n\n## Buildchain Patrol\n\n`dev-pr-auto-merge.yml` remains the focused merge primitive. For repositories\nthat want a stable day-to-day operations contract, Buildchain also exposes a\npatrol workflow family:\n\n| Workflow | Intended cadence | Default intent |\n| --- | --- | --- |\n| `.github/workflows/patrol-daily.yml` | daily | lightweight inspection plus ready dev PR maintenance |\n| `.github/workflows/patrol-weekly.yml` | weekly | release-state, passport, gate, and stale-state health checks as they are added |\n| `.github/workflows/patrol-monthly.yml` | monthly | governance, permission, branch-protection, and workflow drift checks as they are added |\n| `.github/workflows/stable-candidate-patrol.yml` | repository-selected release window | qualify immutable alpha candidates and open the exact source-lock stable PR |\n\nThe cadence names describe patrol intensity, not release cadence:\n\n- daily patrol can run every day without implying a daily release;\n- weekly patrol is for medium-cost maintenance and audit checks;\n- monthly patrol is for structural drift checks that should not block ordinary\n development velocity.\n\nStable Candidate Patrol is separate from those maintenance cadences because its\ncaller-owned cron is a release-intent window. Its candidate ledger and selection\nremain generic; registry-specific side effects still run through the normal\nrepository `lifecycle.publish` transaction. See\n[`stable-candidate-patrol.md`](stable-candidate-patrol.md).\n\nConsumers should schedule thin callers and keep their YAML declarative. For\nexample:\n\n```yaml\nname: Buildchain Daily Patrol\n\non:\n schedule:\n - cron: \"17 2 * * *\"\n workflow_dispatch:\n\njobs:\n patrol:\n uses: kungfu-systems/buildchain/.github/workflows/patrol-daily.yml@v2\n with:\n dry-run: false\n max-actions: 1\n```\n\nWeekly and monthly callers use the matching wrapper:\n\n```yaml\njobs:\n patrol:\n uses: kungfu-systems/buildchain/.github/workflows/patrol-weekly.yml@v2\n with:\n dry-run: true\n```\n\nAll three wrappers default to the `v2` floating Buildchain runtime. When\n`target-branch` is omitted, the caller's current/default branch selects the\nactive semver dev line, so consumers do not pin patrol to a stale minor branch.\nThe separate workflow names keep consumer schedules readable and stable while\nBuildchain adds new checks behind the cadence wrappers.\n\n## Package-Manager Adapters\n\nOld ABV assumed JavaScript repositories with root version state and often\nLerna. Buildchain keeps the version-state contract but does not assume every\nrepository is yarn/Lerna.\n\nThe promotion action discovers and updates:\n\n- root `package.json`;\n- `lerna.json`;\n- package manifests from `package.json` workspaces;\n- package manifests from `lerna.json` packages;\n- package manifests from `pnpm-workspace.yaml`.\n\nIt then runs the repository's detected package manager semantics where needed:\n\n- pnpm repositories use pnpm-oriented workspace discovery;\n- npm repositories use npm/package-lock semantics where present;\n- yarn repositories use yarn-style metadata where present.\n\nFor Buildchain itself, version state is required. For a consumer repository that\nhas no package manifest, the same action can degrade to ref-only behavior only\nwhen that is explicitly allowed by the caller.\n\n## Lifecycle Configuration\n\n`buildchain.toml` is the v2 user configuration format. It lets a repository\ndeclare version-state files and lifecycle commands without pretending every\nproject is a Node workspace. Supported version files include JSON, TOML, and\nregex-based files such as `CMakeLists.txt` or `conanfile.py`.\n\nThe promotion action currently consumes `version.files` and `lifecycle.verify`.\nThe verify stage runs after generated version-state changes are applied locally\nand before any release refs move. If `verification-command` is passed directly\nto the action, that explicit command overrides `lifecycle.verify`.\n\nProtected release-line branches keep their normal human review gate. Managed\n`dev/vN/vN.M`, `alpha/vN/vN.M`, and `release/vN/vN.M` branches are configured\nwith one required approving review, strict GitHub Actions checks, administrator\nenforcement, conversation resolution, no force pushes, and no deletions. The\nreusable `release-candidate-promote.yml` wrapper defaults\n`branch-protection-bypass-apps` to `github-actions`, which lets the workflow's\nautomation identity apply generated version-state or post-publish channel\nbookkeeping after the reviewed channel PR has merged. Direct\n`promote-buildchain-ref` callers must opt into the same controlled bypass with\n`branch-protection-bypass-apps`, `branch-protection-bypass-users`, or\n`branch-protection-bypass-teams`; the action also adds the current promotion\ntoken's authenticated user or app to the managed bypass allowlist. Before\npatching a protected generated bookkeeping ref, the action creates the\nconfigured required check on the exact generated version-state commit, so strict\nstatus checks are satisfied by machine-verifiable Buildchain evidence rather\nthan a human PR. The protected ref PATCH itself uses the generated ref update\ntoken; the reusable wrapper defaults it to\n`secrets.BUILDCHAIN_PROMOTION_TOKEN || github.token`. If direct generated\nrelease finalization bookkeeping is still rejected, Buildchain creates or\nreuses a same-repository `buildchain/version-state/*` PR based on the current\ntarget channel head and records `finalization-needed=true` in the durable\ntransaction output. Strict alpha bookkeeping still fails with a\ntoken/protection diagnostic instead of creating a post-publish PR.\n\nFor a stable release, the wrapper also checks out the exact current development\nchannel into `.buildchain/reconciliation/dev`. When the prepared next-alpha\ncommit cannot fast-forward dev because reviewed work landed concurrently, the\npromotion action applies the next version to that checkout, regenerates every\ndeclared derived version-state file, reruns the verification lifecycle, and\nonly then creates the two-parent reconciliation commit. A checkout/current-ref\nSHA mismatch blocks reconciliation instead of committing stale projections.\nBuildchain's own promotion workflow reads `BUILDCHAIN_PROMOTION_BYPASS_APPS`,\n`BUILDCHAIN_PROMOTION_BYPASS_USERS`, and\n`BUILDCHAIN_PROMOTION_BYPASS_TEAMS` repository variables so the declared bypass\nidentity can match the actual `BUILDCHAIN_PROMOTION_TOKEN` actor, but consumers\ndo not need to duplicate that actor manually when the token identity is\ndiscoverable.\n\n## What This Guarantees\n\nWhen the loop succeeds, maintainers and consumers can rely on these facts:\n\n- every production release has an exact tag such as `v2.0.2`;\n- every production minor line has a floating tag such as `v2.0`;\n- every selected stable major has a floating tag such as `v2`;\n- every next-major release is driven by a reviewed `release -> publish-gate/major` PR,\n not a hidden manual button;\n- every test channel has an exact alpha tag such as `v2.0.3-alpha.0`;\n- every alpha minor line has a floating tag such as `v2.0-alpha`;\n- every major with a published alpha has a cross-minor floating tag such as `v2-alpha`, owned by its highest published alpha minor;\n- version manifests match the tag visible from the same commit;\n- production releases are derived from the alpha tree that was tested;\n- manual non-dry-run promotion cannot bypass PR review and verification;\n- flow-internal automation bypasses apply only to declared GitHub Apps, users,\n or teams on Buildchain-managed channel branch protection, while one-review\n protection remains enforced for humans;\n- admin users cannot make a channel promotion valid by temporarily bypassing\n branch protection.\n\nThis is the practical meaning of \"governance closed loop\" in Buildchain: the\ndecision, code, version state, and Git refs close over the same evidence chain.\n\n## What This Does Not Do\n\nBuildchain release promotion does not embed registry clients or product-specific\npublish logic. When publish transactions are enabled, `promote-buildchain-ref`\ncan run the consumer's `lifecycle.publish` command and own the transaction,\nevidence validation, durable recovery state, and ref finalization order. The\nconsumer repository still owns registry truth: npm, PyPI, OCI, S3, Conan, CMake\npackaging, download pages, dist-tags, and similar side effects must be\nimplemented by project lifecycle commands that emit Buildchain publish evidence.\n\nEvery Buildchain publish model that can run registry side effects must bind the\npublish entrypoint to an immutable `publish-gate/*` source lock. The reusable\n`release-candidate-promote.yml@v2` wrapper creates or updates that gate ref and\npasses `require-publish-source-lock`, `publish-source-ref`,\n`publish-source-sha`, and `publish-source-locked` to\n`promote-buildchain-ref`. Direct action callers must pass the same four inputs\nfrom the reusable build outputs. Workflows that only collect passports or run\ndry-run package checks do not move publish refs and are not publish-gate\npublication models.\n\nSemver GitHub Release publication is owned by `promote-buildchain-ref`, not by\nconsumer shell glue. Consumers normally use the `release-candidate-promote.yml`\nwrapper, where GitHub Release publication is enabled by default and can be\ndisabled with `github-release: false`; the wrapper passes that declaration to\nthe action. After the publish transaction reaches `complete`, Buildchain creates\nor updates the public GitHub Release and uploads the generated\n`buildchain.release.json`, release-passport assets, and publish evidence. Semver\nprerelease tags are marked `prerelease=true` and `make_latest=false`; stable\nsemver tags are marked latest. For anchored/manual package releases, the public\nrelease tag defaults to `v<publishedVersion>` while the internal exact\ntransaction tag remains in the release passport and release-state ref. This is\nthe supported path for downstream\n`release.published` propagation across semver, major, and promote-only release\ncandidate publication models.\n\nBuildchain also does not maintain bare exact tags such as `1.0.0`. The supported\nexact release and alpha refs are v-prefixed:\n\n```text\nv2.0.0\nv2.0.1-alpha.0\n```\n\n## Operational Reading Order\n\nWhen debugging or extending release behavior, read in this order:\n\n1. `docs/release-flow.md`\n2. `.github/workflows/release-verify.yml`\n3. `.github/workflows/buildchain-ref-promotion.yml`\n4. `.github/workflows/release-candidate-promote.yml`\n5. `actions/promote-buildchain-ref/README.md`\n6. `actions/promote-buildchain-ref/src/`\n7. `docs/migration-inventory.md`\n\nThat path gives the policy first, the workflow trigger second, and the action\nimplementation last."
|
|
1433
|
+
"markdown": "# Release Governance\n\nBuildchain v2 preserves the release semantics of the older ABV workflow while\nmoving the implementation into one modern repository.\n\nThe central idea is simple: a reviewed merge into a release channel is the\nrelease intent. Automation must then create the version-state commit, exact tag,\nfloating tag, and next alpha state that make that intent true in Git.\n\n## Design Problem\n\nKungfu release automation has to keep four facts aligned:\n\n1. The source tree that was reviewed.\n2. The package version recorded in manifests such as `package.json` or\n `lerna.json`.\n3. The exact immutable release or prerelease tag.\n4. The floating channel refs that consumers actually use.\n\nIf any one of these facts is updated by hand, the system can split:\n\n- a consumer can fetch `v2.0` and receive a tree whose package version still\n says the previous release;\n- a maintainer can move `v2` without producing an exact `v2.0.N` audit tag;\n- an alpha can be promoted to production even though the release tree is not the\n same tree that was tested;\n- a protected branch merge can succeed while the follow-up version commit is\n missing, or a flow-internal generated `dev`/`alpha`/`release` ref update can\n fail after publish because the automation identity was not declared in the\n branch-protection review bypass allowance.\n\nThe older ABV workflow addressed this by letting GitHub PRs drive release\nstate. Buildchain keeps that choice because it makes release intent reviewable,\nobservable, and recoverable from Git history.\n\n## What ABV Contributed\n\nThe old ABV model was not just \"bump a version number.\" It encoded a governance\nloop:\n\n- release branches are named as channels: `dev`, `alpha`, `release`, and the\n administrative `publish-gate/major`;\n- a PR from one channel to the next is the release request;\n- verify jobs check that the branch pair is valid before merge;\n- a maintainer review is required before the branch moves;\n- after merge, automation writes the version change and moves tags;\n- exact tags and floating refs are aligned with the resulting commit;\n- the next development channel is prepared automatically.\n\nABV also kept the version-state mutation in the repository. For JavaScript\nrepositories that usually meant changing `lerna.json` and/or `package.json`.\nThat commit is important because the tag alone is not enough evidence: the\nsource tree should also declare the version that the tag advertises.\n\nBuildchain v2 treats that as a hard semantic requirement for its own release\nline.\n\n## Buildchain Implementation\n\nBuildchain implements the same governance loop with:\n\n- `.github/workflows/release-verify.yml` for PR verification;\n- `.github/workflows/buildchain-ref-promotion.yml` for post-verify ref\n promotion; this workflow dogfoods the declarative\n `release-candidate-promote.yml` wrapper and does not hand-wire resolver,\n artifact download, publish-gate, or promote action steps;\n- Buildchain self promotion enables `release-passport-buildchain-self-kfd`, so\n the promote action generates KFD-1 witnesses, KFD-2 public claim JSON, and\n KFD-3 collaboration-interface witnesses from the final version-state workspace\n before release passport finalization. The witness hashes therefore bind to the\n exact published package and site facts from\n `packages/core/buildchain-kfd-claims.js` instead of relying on prose release\n notes;\n- `actions/promote-buildchain-ref` for branch, tag, version-state, and\n governance checks;\n- package-manager adapters that can update version state for pnpm, npm, and\n yarn style repositories;\n- `buildchain.toml` lifecycle configuration for repositories whose version\n state or verification commands are not Node package-manager defaults.\n\nThe implementation is intentionally stricter than a local release script:\n\n- manual workflow dispatch can only do dry-run promotion;\n- non-dry-run promotion must be driven by a completed `Verify` workflow;\n- target branch protection details must be readable, and branch protection must\n apply to administrators as well as regular contributors;\n- alpha promotion must come from a merged same-repository PR from\n `dev/vX/vX.Y` to `alpha/vX/vX.Y`;\n- release promotion must come from a merged same-repository PR from\n `alpha/vX/vX.Y` to `release/vX/vX.Y`;\n- major promotion must come from a merged same-repository PR from\n `release/vX/vX.Y` to `publish-gate/major`;\n- release promotion requires an existing same-patch alpha tag and checks the\n release source tree against that tested alpha tree;\n- generated version-state commits are verified before refs move.\n\nPromotion intents are serialized globally per caller repository with\n`cancel-in-progress: false`. A queued intent re-reads its protected target ref\nbefore checkout, dependency installation, release-candidate resolution, or any\npublish-gate/ref mutation. If the ref already points at a newer SHA, that older\nintent is no longer release authority: the workflow records the requested and\ncurrent SHAs, proves that the current target is ahead of the requested commit,\nand completes as a `target-ref-advanced` superseded no-op. Diverged or behind\ncomparisons are not superseded transactions and still fail closed.\nMissing refs, unreadable repository state, invalid channels, governance\nfailures, and artifact mismatches still fail closed. The promote action repeats\nthe target check at the mutation boundary, so a ref that advances after the\nworkflow preflight cannot receive a second set of publication side effects.\n\n## Version Lines\n\nKungfu uses Python-like version lines where a minor line can represent a\nlong-lived product train. A line such as `v2.0` can produce many production\npatch releases:\n\n```text\nv2.0.0\nv2.0.1\nv2.0.2\n...\nv2.0.1234\n```\n\nThis is why Buildchain maintains both exact and floating refs:\n\n- `v2.0.2` is immutable release evidence;\n- `v2.0` is the latest production release on the `2.0` line;\n- `v2` is the selected stable major-line entrypoint;\n- `v2.0.3-alpha.0` is immutable alpha evidence;\n- `v2.0-alpha` is the latest test channel for the `2.0` line.\n- `v2-alpha` is the latest test channel on the highest published alpha minor in major `2`.\n\nA release does not mean \"minor is complete.\" It means \"this patch on this minor\nline is now production.\"\n\nGitHub repository rules must preserve that distinction. Exact tags such as\n`v2.0.2` and `v2.0.3-alpha.0` should be immutable. Floating channel tags such as\n`v2`, `v2.0`, `v2.0-alpha`, and `v2-alpha` must remain movable by the Buildchain promotion\ntoken after governance checks and publish evidence pass. A tag ruleset that\nprotects every `refs/tags/v*` ref is too broad because it also locks the\nfloating channel tags that Buildchain is required to update. Prefer exact-tag\npatterns such as `refs/tags/v*.*.*` for immutable release evidence, while\nleaving floating channel tags under Buildchain automation control.\n\n## Alpha Semantics\n\nAn alpha merge is:\n\n```text\ndev/vX/vX.Y -> alpha/vX/vX.Y\n```\n\nBuildchain then:\n\n1. Computes the next prerelease for the minor line.\n2. Writes version state such as `vX.Y.Z-alpha.N`.\n3. Verifies the generated version-state tree.\n4. Creates or reuses the exact alpha tag.\n5. Moves `alpha/vX/vX.Y` to the generated alpha commit.\n6. Moves `dev/vX/vX.Y` to the same generated alpha commit when this is a\n fast-forward update.\n7. Moves `vX.Y-alpha` to the same generated alpha commit.\n8. Moves `vX-alpha` only when `X.Y` is the highest minor in major `X` with a published alpha; older minor alpha work records a skip and cannot move the major channel backwards.\n\nThis keeps the test channel self-describing. If a consumer checks out\n`v2.0-alpha` or `v2-alpha`, the manifests and exact alpha tag agree. The major\nalpha ref removes routine consumer edits when Buildchain opens a newer minor,\nwhile exact tags and SHAs remain the reproducible audit choice.\n\n### Buildchain Alpha Self-Dogfood\n\nBuildchain continuously consumes its own current major alpha through\n`.github/workflows/buildchain-alpha-self-dogfood.yml`. Both lanes call the\nreleased channel router at `build.yml@v2-alpha`. The auto lane must resolve\n`v2-alpha`; the explicit stable lane must resolve `v2`. Both execute the same\ndeclared install, build, and verify fixture, proving that a single consumer\nsurface routes to distinct released runtimes without duplicating lifecycle\nconfiguration in the consumer.\n\nThe reusable build trust gate reads `job.workflow_ref`, which identifies the\ncalled workflow and its selected ref. It does not infer the runtime from\n`github.workflow_ref`, because GitHub defines that context as the caller\nworkflow identity during a reusable call.\n\nThe router selects `.buildchain/alpha-contract-lock.json` for alpha and\n`.buildchain/contract-lock.json` for stable. The alpha lock records the exact\nreviewed alpha SHA and compatibility digest; it does not replace the stable\nconsumer lock. A later alpha with only compatible additive drift continues,\nwhile a changed breaking digest fails until the new alpha contract is reviewed.\n\nThe evidence job resolves `v2-alpha` and `v2` through the GitHub refs API,\ncompares those immutable SHAs with the reusable workflow outputs, verifies the\n`alpha` and `stable` classifications, and uploads a JSON evidence artifact.\nThe canary runs after successful Buildchain ref promotion, on a daily fallback\nschedule, and on manual dispatch. It shares the release-promotion concurrency\ngroup, so another promotion cannot move the floating refs between runtime\nresolution and evidence comparison.\n\nThis is a post-publication consumer canary, not a release bootstrap. Source\nverification still runs the current commit, and\n`buildchain-ref-promotion.yml` still passes the verified exact SHA into the\npromotion workflow. Patrol, dev-merge, repair, and promotion defaults remain on\nstable or exact refs so a broken alpha cannot prevent Buildchain from publishing\nits fix. When Buildchain opens a new major, inventory validation requires this\nworkflow's fixed GitHub `uses` refs to move from `vN`/`vN-alpha` to the new\nmajor; GitHub does not allow expressions in a reusable-workflow `uses` ref.\n\nIf `dev/vX/vX.Y` has already advanced before generated alpha version-state\nbookkeeping can sync back, Buildchain records `skipped-non-fast-forward` for the\ndev sync and still completes the exact and floating alpha tags for the reviewed\nalpha commit. Later dev changes must go through their own dev-to-alpha\npromotion instead of rewinding dev. The normal path is direct: after alpha\nmerges, Buildchain applies the generated version-state commit to alpha and then\nfast-forwards dev to the same commit without a human version-state PR.\n\nIf alpha finalization is resumed after generated version-state bookkeeping was\npartially applied, Buildchain accepts the current alpha head as the generated\ncommit, or as a historical merge commit that contains the recorded release\nmaterial. An already-created exact alpha tag may point at the transaction\nrelease/material SHA or at the finalized alpha head; missing floating alpha\ntags are retried before the transaction becomes `complete`.\n\n## Release Semantics\n\nA release merge is:\n\n```text\nalpha/vX/vX.Y -> release/vX/vX.Y\n```\n\nBuildchain then:\n\n1. Finds the same-patch alpha tag that was tested.\n2. Checks that the release source tree matches that alpha tag tree, excluding\n only generated version-state differences.\n3. Writes final release version state such as `vX.Y.Z`.\n4. Verifies the generated release tree.\n5. Creates or reuses the exact release tag `vX.Y.Z`.\n6. Moves `release/vX/vX.Y` to the exact release commit.\n7. Moves `vX.Y` to the exact release commit.\n8. Moves `vX` when this minor line should be the stable major entrypoint.\n9. Prepares the next alpha version-state commit, such as\n `vX.Y.(Z+1)-alpha.0`.\n10. Moves `alpha/vX/vX.Y`, `dev/vX/vX.Y`, and `vX.Y-alpha` to that next alpha\n commit.\n11. Moves `vX-alpha` to that next alpha only when this remains the highest published alpha minor.\n\nThe production channel and the test channel therefore intentionally diverge\nafter release: production stays on the release commit, while alpha/dev continue\nat the next prerelease commit.\n\n### Stable Release Throttle And Canary Gate\n\nBuildchain's own stable channel has an additional pre-publication gate. It is\nevaluated after the PR-stage release candidate has been resolved and before the\npublish-gate ref, package registry, exact stable tag, or floating stable refs\nare mutated. Train refs and alpha promotion do not execute this gate.\n\nAll alpha and release promotions first run a metadata-only release-candidate\npreflight after queued-intent revalidation. The preflight uses the same resolver\nand exact target SHA as the publication job, but does not download payloads or\ninstall the candidate repository dependencies. Missing channel PRs, stale\nworkflow runs, expired passport pairs, and insufficient payload artifact sets\ntherefore fail before the full promotion job starts. The publication job still\ndownloads and validates the exact evidence again at the trust boundary; the\npreflight moves failure earlier without weakening the final check.\n\nThe policy is versioned in `.buildchain/stable-release-policy.json`. A stable\ncandidate is allowed only when all of these facts are true:\n\n- the candidate resolves to an immutable exact alpha tag and its GitHub\n prerelease timestamp;\n- at least 24 hours have passed since the preceding stable patch on the same\n minor line;\n- the preceding stable-to-alpha comparison contains a product or public\n contract path, not only version, test, evidence, or retrospective changes;\n- the version-bound impact record has a non-empty summary and at least one\n surface impact;\n- the `Build Surface Fixture` release-candidate run succeeded;\n- `site-libkungfu-dev` completed its no-apply `Buildchain Stable Canary` and an allowed\n maintainer attested that successful run on the exact alpha SHA through the\n `buildchain-canary/site-libkungfu-dev` commit-status context;\n- the canary runtime input is exactly the candidate alpha tag or the 40-character\n commit SHA resolved from that tag; a successful status pointing at another\n workflow, repository, tag, floating ref, or SHA is rejected as mismatched;\n- at least one hour has elapsed after the last required canary completed.\n\nThe machine report is written to\n`.buildchain/release-passport/stable-release-gate.json`. A passing report is\nuploaded with the stable release passport. A blocked run writes the same report\nbefore failing, so the missing or stale condition is inspectable without\nopening a publication transaction.\n\nGitHub's Actions run REST object does not expose `workflow_dispatch` inputs.\nBuildchain therefore verifies the run's `workflow_id` against the authoritative\nworkflow metadata, then reads the exact runtime from the workflow-owned\n`<workflow name> / <runtime ref>` run-name when no input field is available.\nAn explicit API input, when present, remains authoritative and cannot be\noverridden by the display name.\n\nThe cooldown is a minimum interval, not an instruction to release every day.\nCompatible work should still be batched until a stable release has a concrete\nconsumer need. Changing the interval, canary set, attestors, product path\nboundary, or soak time is a reviewed policy change.\n\nRepositories that want a predictable scheduled stable window can use\n[`Stable Candidate Patrol`](stable-candidate-patrol.md). It persists each exact\nalpha independently, qualifies it after repository-declared checks and soak,\nand selects the newest qualified non-revoked candidate. A newer soaking alpha\ndoes not invalidate an older qualified candidate. The selected tree enters the\nexisting strict `publish-gate/release/<line>/<version> -> release/<line>` PR\npath, so scheduled selection changes release intent timing without weakening\nsource locks, review, verification, publish transactions, or passports.\n\nIf release finalization is resumed after generated version-state bookkeeping was\npartially applied, Buildchain applies the same recovery rule: the current\nrelease head may be the generated commit, or a historical merge commit that\ncontains the recorded release material, existing exact tags and alpha/dev refs\nare accepted when they match the transaction, and missing floating `vX.Y` or\n`vX` tags are retried idempotently before completion.\n\nOnce the durable release transaction is `complete` and the exact/floating\nstable refs have moved, next-alpha preparation is post-release bookkeeping. A\nfailure there records `deferred-post-release-bookkeeping` and\n`next-anchor-required` instead of retroactively reporting the stable release as\nfailed. Generated next-alpha merges use the current dev tree as their base and\noverlay only declared version-state paths, preserving concurrent dev changes.\n\n## Major Gate Semantics\n\nA major gate merge is:\n\n```text\nrelease/vX/vX.Y -> publish-gate/major\n```\n\n`publish-gate/major` is the explicit replacement for the older ABV `main`\nchannel. The name is intentionally operational: it is a gate for a rare\nadministrator decision, not the active trunk. Keeping this decision in the same\nPR UI as alpha and release promotion keeps the human workflow simple while\navoiding the misleading meaning of `main`. The older `major-gate` branch name is\na compatibility alias only.\n\nBuildchain then:\n\n1. Verifies the source is a merged same-repository PR from a protected release\n line into `publish-gate/major`.\n2. Writes the next major production version state, such as `v(X+1).0.0`.\n3. Creates or reuses the exact release tag `v(X+1).0.0`.\n4. Moves `publish-gate/major` and `release/v(X+1)/v(X+1).0` to that release commit.\n5. Moves `v(X+1).0` and `v(X+1)` to that release commit.\n6. Prepares the next alpha version-state commit, such as\n `v(X+1).0.1-alpha.0`.\n7. Moves `alpha/v(X+1)/v(X+1).0`, `dev/v(X+1)/v(X+1).0`, and\n `v(X+1).0-alpha` to that next alpha commit.\n\nChecking out `publish-gate/major` should therefore look like a frozen release\nstate, not like a branch where day-to-day source work continues. Day-to-day\nsource work continues on `dev/vX/vX.Y`.\n\n## Protected Dev Branches\n\n`dev/vX/vX.Y` is a protected development channel, not a scratch branch. Normal\nsource changes should be made on work branches such as `feature/*`, `fix/*`,\n`chore/*`, `docs/*`, `ci/*`, or `refactor/*`, then reviewed through a pull\nrequest into the target dev line.\n\nThis keeps the earliest development channel audit-friendly:\n\n- the version line being changed is visible in the PR base branch;\n- CI and required checks run before the channel moves;\n- branch protection can prevent direct pushes and stale merges;\n- later `dev -> alpha -> release` promotion inherits a reviewable source\n lineage instead of trying to reconstruct how the dev branch changed.\n\nBuildchain provides the reusable\n`.github/workflows/dev-pr-auto-merge.yml` workflow for repositories that want a\nscheduled or manual \"merge ready dev PRs\" pass. The consumer repository owns\nthe trigger schedule, but the merge decision is declared through workflow\ninputs: target dev branch, required status/check names, ready and block labels,\nallowed work-branch prefixes, review requirements, maximum merges per run,\nmerge method, and dry-run mode.\n\nThe workflow defaults are conservative. A PR is skipped unless it targets the\nconfigured dev line, is not a draft, has the ready label, has no block label,\ncomes from the same repository, uses an allowed work-branch prefix, has a\ncurrent approval, is mergeable, and has the configured required checks passing.\nAfter each merge, the next PR is re-evaluated before it can move the protected\ndev branch. This prevents one merge from silently making the next candidate\nstale or conflicting.\n\nThe canonical consumer required check context is `check / check`, matching the\nreusable workflow call plus its `check` job. Buildchain's own `Verify` workflow\nemits the repository-local context `check`, so Buildchain self-promotion,\nrelease-line bootstrap, and dogfood patrol wrappers pass `check` explicitly.\nRelease governance preserves the exact context emitted by the repository and\nrecords branch-protection policy before/after facts; it does not rewrite one\ncontext shape into the other. Consumer repositories can keep their context\nstable while changing the actual verification command declaratively in\n`buildchain.toml`:\n\n```toml\n[lifecycle.install]\ncommand = \"cargo fetch --locked\"\n\n[lifecycle.verify]\ncommand = \"cargo test --workspace --locked\"\n```\n\nConsumers that want Buildchain to own the check wrapper can call\n`.github/workflows/check.yml@v2`. The wrapper runs the declared\n`lifecycle.install` and `lifecycle.verify` stages and fails the `check` job when\neither declaration is missing or the command exits non-zero.\n\nDevelopment pull requests that need source acceptance without product build or\nartifact verification can opt into `mode: source`. That mode runs only\n`lifecycle.install` and `lifecycle.check` on GitHub-hosted `ubuntu-24.04` while\npreserving the stable `check / check` required-check context. Existing callers\nremain on `mode: verify` by default, and callers may set\n`upload-artifacts: false` without weakening the job conclusion.\n\nTypical consumer wrapper:\n\n```yaml\nname: Merge Ready Dev PRs\n\non:\n schedule:\n - cron: \"17 * * * *\"\n workflow_dispatch:\n inputs:\n dry-run:\n type: boolean\n default: true\n\njobs:\n merge-dev:\n uses: kungfu-systems/buildchain/.github/workflows/dev-pr-auto-merge.yml@v2\n permissions:\n contents: write\n pull-requests: write\n checks: read\n statuses: read\n with:\n target-branch: dev/v2/v2.6\n required-status-checks: check / check\n ready-label: ready\n block-labels: blocked,do-not-merge\n max-merges: 1\n dry-run: ${{ inputs.dry-run || false }}\n```\n\n## Buildchain Patrol\n\n`dev-pr-auto-merge.yml` remains the focused merge primitive. For repositories\nthat want a stable day-to-day operations contract, Buildchain also exposes a\npatrol workflow family:\n\n| Workflow | Intended cadence | Default intent |\n| --- | --- | --- |\n| `.github/workflows/patrol-daily.yml` | daily | lightweight inspection plus ready dev PR maintenance |\n| `.github/workflows/patrol-weekly.yml` | weekly | release-state, passport, gate, and stale-state health checks as they are added |\n| `.github/workflows/patrol-monthly.yml` | monthly | governance, permission, branch-protection, and workflow drift checks as they are added |\n| `.github/workflows/stable-candidate-patrol.yml` | repository-selected release window | qualify immutable alpha candidates and open the exact source-lock stable PR |\n\nThe cadence names describe patrol intensity, not release cadence:\n\n- daily patrol can run every day without implying a daily release;\n- weekly patrol is for medium-cost maintenance and audit checks;\n- monthly patrol is for structural drift checks that should not block ordinary\n development velocity.\n\nStable Candidate Patrol is separate from those maintenance cadences because its\ncaller-owned cron is a release-intent window. Its candidate ledger and selection\nremain generic; registry-specific side effects still run through the normal\nrepository `lifecycle.publish` transaction. See\n[`stable-candidate-patrol.md`](stable-candidate-patrol.md).\n\nConsumers should schedule thin callers and keep their YAML declarative. For\nexample:\n\n```yaml\nname: Buildchain Daily Patrol\n\non:\n schedule:\n - cron: \"17 2 * * *\"\n workflow_dispatch:\n\njobs:\n patrol:\n uses: kungfu-systems/buildchain/.github/workflows/patrol-daily.yml@v2\n with:\n dry-run: false\n max-actions: 1\n```\n\nWeekly and monthly callers use the matching wrapper:\n\n```yaml\njobs:\n patrol:\n uses: kungfu-systems/buildchain/.github/workflows/patrol-weekly.yml@v2\n with:\n dry-run: true\n```\n\nAll three wrappers default to the `v2` floating Buildchain runtime. When\n`target-branch` is omitted, the caller's current/default branch selects the\nactive semver dev line, so consumers do not pin patrol to a stale minor branch.\nThe separate workflow names keep consumer schedules readable and stable while\nBuildchain adds new checks behind the cadence wrappers.\n\n## Package-Manager Adapters\n\nOld ABV assumed JavaScript repositories with root version state and often\nLerna. Buildchain keeps the version-state contract but does not assume every\nrepository is yarn/Lerna.\n\nThe promotion action discovers and updates:\n\n- root `package.json`;\n- `lerna.json`;\n- package manifests from `package.json` workspaces;\n- package manifests from `lerna.json` packages;\n- package manifests from `pnpm-workspace.yaml`.\n\nIt then runs the repository's detected package manager semantics where needed:\n\n- pnpm repositories use pnpm-oriented workspace discovery;\n- npm repositories use npm/package-lock semantics where present;\n- yarn repositories use yarn-style metadata where present.\n\nFor Buildchain itself, version state is required. For a consumer repository that\nhas no package manifest, the same action can degrade to ref-only behavior only\nwhen that is explicitly allowed by the caller.\n\n## Lifecycle Configuration\n\n`buildchain.toml` is the v2 user configuration format. It lets a repository\ndeclare version-state files and lifecycle commands without pretending every\nproject is a Node workspace. Supported version files include JSON, TOML, and\nregex-based files such as `CMakeLists.txt` or `conanfile.py`.\n\nThe promotion action currently consumes `version.files` and `lifecycle.verify`.\nThe verify stage runs after generated version-state changes are applied locally\nand before any release refs move. If `verification-command` is passed directly\nto the action, that explicit command overrides `lifecycle.verify`.\n\nProtected release-line branches keep their normal human review gate. Managed\n`dev/vN/vN.M`, `alpha/vN/vN.M`, and `release/vN/vN.M` branches are configured\nwith one required approving review, strict GitHub Actions checks, administrator\nenforcement, conversation resolution, no force pushes, and no deletions. The\nreusable `release-candidate-promote.yml` wrapper defaults\n`branch-protection-bypass-apps` to `github-actions`, which lets the workflow's\nautomation identity apply generated version-state or post-publish channel\nbookkeeping after the reviewed channel PR has merged. Direct\n`promote-buildchain-ref` callers must opt into the same controlled bypass with\n`branch-protection-bypass-apps`, `branch-protection-bypass-users`, or\n`branch-protection-bypass-teams`; the action also adds the current promotion\ntoken's authenticated user or app to the managed bypass allowlist. Before\npatching a protected generated bookkeeping ref, the action creates the\nconfigured required check on the exact generated version-state commit, so strict\nstatus checks are satisfied by machine-verifiable Buildchain evidence rather\nthan a human PR. The protected ref PATCH itself uses the generated ref update\ntoken; the reusable wrapper defaults it to\n`secrets.BUILDCHAIN_PROMOTION_TOKEN || github.token`. If direct generated\nrelease finalization bookkeeping is still rejected, Buildchain creates or\nreuses a same-repository `buildchain/version-state/*` PR based on the current\ntarget channel head and records `finalization-needed=true` in the durable\ntransaction output. Strict alpha bookkeeping still fails with a\ntoken/protection diagnostic instead of creating a post-publish PR.\n\nFor a stable release, the wrapper also checks out the exact current development\nchannel into `.buildchain/reconciliation/dev`. When the prepared next-alpha\ncommit cannot fast-forward dev because reviewed work landed concurrently, the\npromotion action applies the next version to that checkout, regenerates every\ndeclared derived version-state file, reruns the verification lifecycle, and\nonly then creates the two-parent reconciliation commit. A checkout/current-ref\nSHA mismatch blocks reconciliation instead of committing stale projections.\nBuildchain's own promotion workflow reads `BUILDCHAIN_PROMOTION_BYPASS_APPS`,\n`BUILDCHAIN_PROMOTION_BYPASS_USERS`, and\n`BUILDCHAIN_PROMOTION_BYPASS_TEAMS` repository variables so the declared bypass\nidentity can match the actual `BUILDCHAIN_PROMOTION_TOKEN` actor, but consumers\ndo not need to duplicate that actor manually when the token identity is\ndiscoverable.\n\n## What This Guarantees\n\nWhen the loop succeeds, maintainers and consumers can rely on these facts:\n\n- every production release has an exact tag such as `v2.0.2`;\n- every production minor line has a floating tag such as `v2.0`;\n- every selected stable major has a floating tag such as `v2`;\n- every next-major release is driven by a reviewed `release -> publish-gate/major` PR,\n not a hidden manual button;\n- every test channel has an exact alpha tag such as `v2.0.3-alpha.0`;\n- every alpha minor line has a floating tag such as `v2.0-alpha`;\n- every major with a published alpha has a cross-minor floating tag such as `v2-alpha`, owned by its highest published alpha minor;\n- version manifests match the tag visible from the same commit;\n- production releases are derived from the alpha tree that was tested;\n- manual non-dry-run promotion cannot bypass PR review and verification;\n- flow-internal automation bypasses apply only to declared GitHub Apps, users,\n or teams on Buildchain-managed channel branch protection, while one-review\n protection remains enforced for humans;\n- admin users cannot make a channel promotion valid by temporarily bypassing\n branch protection.\n\nThis is the practical meaning of \"governance closed loop\" in Buildchain: the\ndecision, code, version state, and Git refs close over the same evidence chain.\n\n## What This Does Not Do\n\nBuildchain release promotion does not embed registry clients or product-specific\npublish logic. When publish transactions are enabled, `promote-buildchain-ref`\ncan run the consumer's `lifecycle.publish` command and own the transaction,\nevidence validation, durable recovery state, and ref finalization order. The\nconsumer repository still owns registry truth: npm, PyPI, OCI, S3, Conan, CMake\npackaging, download pages, dist-tags, and similar side effects must be\nimplemented by project lifecycle commands that emit Buildchain publish evidence.\n\nEvery Buildchain publish model that can run registry side effects must bind the\npublish entrypoint to an immutable `publish-gate/*` source lock. The reusable\n`release-candidate-promote.yml@v2` wrapper creates or updates that gate ref and\npasses `require-publish-source-lock`, `publish-source-ref`,\n`publish-source-sha`, and `publish-source-locked` to\n`promote-buildchain-ref`. Direct action callers must pass the same four inputs\nfrom the reusable build outputs. Workflows that only collect passports or run\ndry-run package checks do not move publish refs and are not publish-gate\npublication models. A dry-run of `release-candidate-promote.yml` computes and\nreports the exact `publish-gate/*` source lock that a real promotion would use,\nbut does not read, create, or move that ref.\n\nSemver GitHub Release publication is owned by `promote-buildchain-ref`, not by\nconsumer shell glue. Consumers normally use the `release-candidate-promote.yml`\nwrapper, where GitHub Release publication is enabled by default and can be\ndisabled with `github-release: false`; the wrapper passes that declaration to\nthe action. After the publish transaction reaches `complete`, Buildchain creates\nor updates the public GitHub Release and uploads the generated\n`buildchain.release.json`, release-passport assets, and publish evidence. Semver\nprerelease tags are marked `prerelease=true` and `make_latest=false`; stable\nsemver tags are marked latest. For anchored/manual package releases, the public\nrelease tag defaults to `v<publishedVersion>` while the internal exact\ntransaction tag remains in the release passport and release-state ref. This is\nthe supported path for downstream\n`release.published` propagation across semver, major, and promote-only release\ncandidate publication models.\n\nBuildchain also does not maintain bare exact tags such as `1.0.0`. The supported\nexact release and alpha refs are v-prefixed:\n\n```text\nv2.0.0\nv2.0.1-alpha.0\n```\n\n## Operational Reading Order\n\nWhen debugging or extending release behavior, read in this order:\n\n1. `docs/release-flow.md`\n2. `.github/workflows/release-verify.yml`\n3. `.github/workflows/buildchain-ref-promotion.yml`\n4. `.github/workflows/release-candidate-promote.yml`\n5. `actions/promote-buildchain-ref/README.md`\n6. `actions/promote-buildchain-ref/src/`\n7. `docs/migration-inventory.md`\n\nThat path gives the policy first, the workflow trigger second, and the action\nimplementation last."
|
|
1386
1434
|
},
|
|
1387
1435
|
{
|
|
1388
1436
|
"id": "manual:release-passport",
|
|
@@ -1663,7 +1711,7 @@
|
|
|
1663
1711
|
],
|
|
1664
1712
|
"maturity": "stable",
|
|
1665
1713
|
"sourcePath": "docs/shifu-gate-profiles.md",
|
|
1666
|
-
"digest": "sha256:
|
|
1714
|
+
"digest": "sha256:919c163a414df5ed562148e4da9e0e3a94718488e7477eb120073e2ee35b5288",
|
|
1667
1715
|
"headings": [
|
|
1668
1716
|
{
|
|
1669
1717
|
"level": 1,
|
|
@@ -1701,7 +1749,7 @@
|
|
|
1701
1749
|
"anchor": "validation-boundary"
|
|
1702
1750
|
}
|
|
1703
1751
|
],
|
|
1704
|
-
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: buildchain-shifu-gate-orchestration\ndoc_type: technical-manual\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: self-reviewed\nlast_reviewed: 2026-07-13\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-13\n invisible_context_boundary: No private runner configuration, credentials, or unpublished Shifu implementation state was used.\n---\n\n# Shifu Gate profile orchestration\n\nBuildchain can schedule and aggregate a project-owned Shifu Gate profile without\nowning that project's gate ids, commands, dependencies, or dev/alpha/release\npolicy. The reusable workflow is\n`.github/workflows/.gate-profile.yml`.\n\n## Ownership boundary\n\n| Concern | Owner | Enforced surface |\n| ----------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------- |\n| Gate schema, profile planning, execution, receipt qualification | Shifu | `shifu gate plan`, `shifu gate run --profile`, `shifu gate receipt validate` |\n| Concrete gate catalog and profile decisions | Consumer project | project Gate registry and detailed Gate docs |\n| Runner labels and declared capabilities | Consumer workflow / Buildchain preset | `runner-preset` or `platforms-json` |\n| Deterministic runner matrix, immutable checkout, receipt transport, aggregate check | Buildchain | `.gate-profile.yml` and `shifu-gate-profile.mjs` |\n| Whether a profile aggregate is required for dev, alpha, or release | Consumer project | protected-branch required-check policy and caller workflow |\n\nBuildchain treats the Shifu plan and receipt as versioned input contracts. It\ndoes not reimplement policy selection, execute raw shell strings, convert an\nexplicit diagnostic gate run into qualification, or mint missing evidence.\n\n## Runner matrix\n\nThe plan job asks the consumer's Shifu entrypoint for one plan per configured\nplatform. A platform is dispatchable only when:\n\n- the Shifu plan is qualifying;\n- every required selection is supported on that platform;\n- the runner declares every capability requested by the selected gates; and\n- all platform plans carry the same project id and registry digest.\n\nConfigured platforms are required by default. A required platform that cannot\nhost the profile fails before runner dispatch. A platform with\n`\"required\": false` may be omitted, but the omission and reasons remain in the\nmatrix and aggregate. Matrix entries retain the Shifu plan digest, ordered gate\ngroups, required/advisory modes, action ids, definition digests, skips, and\nunsupported selections.\n\n`github-hosted` declares only the inherent `node` capability. Projects that\nneed a native compiler, product artifacts, devices, or other facilities must\nuse a suitable preset or declare a custom matrix. Capabilities are scheduling\nclaims, not installation instructions.\n\n```json\n[\n {\n \"id\": \"linux-native\",\n \"name\": \"Linux native\",\n \"platform\": \"linux\",\n \"runner\": \"[\\\"self-hosted\\\",\\\"Linux\\\",\\\"X64\\\",\\\"product-build\\\"]\",\n \"capabilities\": [\"node\", \"native-toolchain\", \"product-artifacts\"]\n }\n]\n```\n\n## Execution and receipts\n\nEvery matrix job checks out the exact source SHA planned by Buildchain, invokes\n`shifu gate run --profile`, writes the receipt outside the source checkout, and\nthen invokes `shifu gate receipt validate`. Buildchain uploads the original\nreceipt and validation result even when the run fails.\n\nThe fixed `Gate profile / aggregate` job fails closed for missing receipts,\ninvalid or stale Shifu validation, dirty or mismatched source SHA, registry or\nplan drift, missing required results, required failures/skips, or gate action\nand definition digest drift. Advisory failures remain visible but do not turn a\nShifu-qualifying receipt into a required failure. Buildchain's aggregate is\n`buildchain.shifu-gate-aggregate/v1`; its digest covers the matrix, receipts,\nper-gate evidence pointers, omissions, and issues.\n\n## Consumer workflow\n\n```yaml\njobs:\n gates:\n uses: kungfu-systems/buildchain/.github/workflows/.gate-profile.yml@v2\n with:\n gate-profile: alpha-pr\n runner-preset: kungfu-v4-self-hosted\n include-advisory: true\n\n build:\n needs: gates\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v2\n with:\n release-candidate: true\n gate-profile-aggregate-json: ${{ needs.gates.outputs.gate-aggregate-json }}\n```\n\nThe command input is an argv map, not a shell string. The default supports the\nordinary Shifu launcher names on all three platforms. A project with a\ndifferent launcher can override it without teaching Buildchain project tasks:\n\n```yaml\ngate-command-json: >-\n {\"linux\":[\"./tools/shifu\"],\"macos\":[\"./tools/shifu\"],\"windows\":[\"./tools/shifu.cmd\"]}\n```\n\n`gate-command-json` is the execution command. If execution needs a cache,\ncontainer, or other project-owned wrapper that should not make the read-only\nplan depend on that service, pass a separate lightweight argv map through\n`gate-plan-command-json`. It defaults to the execution command for backward\ncompatibility; Buildchain still treats both inputs as argv and never evaluates\na shell string.\n\nProjects may also pass non-sensitive scalar environment through\n`gate-environment-json`; Buildchain validates the JSON shape and forwards it\nwithout interpreting names or values. Cache profile references use the same\nopaque `shifu-cache-profile-ref` and `shifu-cache-profile-digest` inputs as the\nreusable build. Do not place tokens, credentials, or other secrets in workflow\ninputs or Gate receipts.\n\nWhen a qualifying aggregate is passed to the build workflow, the\nrelease-candidate passport binds its profile, source SHA, registry digest,\nmatrix digest, aggregate digest, receipt count, and result count. A failed,\nnon-qualifying, or source-mismatched aggregate cannot produce a valid passport.\nPromote-only release validation preserves that same Gate evidence summary in\nthe final Release Passport release identity, so promotion cannot silently drop\nthe qualified profile provenance.\n\n## Failure diagnosis and rollback\n\nStart with the aggregate artifact, then the platform receipt named in its\nissues. Reproduce the exact project decision with Shifu, for example:\n\n```bash\n./shifu gate explain <gate-id> --profile <profile>\n./shifu gate plan <profile> --platform <platform> --json\n./shifu gate receipt validate <receipt.json> --json\n```\n\nThe existing reusable build workflow remains usable without Gate inputs. To\nroll back Gate orchestration, remove the caller's `gates` job and\n`gate-profile-aggregate-json` handoff; this does not alter the consumer's Shifu\nregistry or its direct diagnostic commands.\n\n## Validation boundary\n\nUnit fixtures prove deterministic matrix generation and required/advisory,\ncapability, unsupported, missing, stale, failure, and definition-drift\npropagation. Because a train ref changes runtime scripts but not the outer\nreusable workflow topology, an unreleased `.gate-profile.yml` must also be\nvalidated through a trusted `workflow_dispatch` canary that references the\ntemporary workflow ref or exact SHA. See\n[`runtime-train-validation.md`](runtime-train-validation.md)."
|
|
1752
|
+
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: buildchain-shifu-gate-orchestration\ndoc_type: technical-manual\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: self-reviewed\nlast_reviewed: 2026-07-13\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-13\n invisible_context_boundary: No private runner configuration, credentials, or unpublished Shifu implementation state was used.\n---\n\n# Shifu Gate profile orchestration\n\nBuildchain can schedule and aggregate a project-owned Shifu Gate profile without\nowning that project's gate ids, commands, dependencies, or dev/alpha/release\npolicy. The reusable workflow is\n`.github/workflows/.gate-profile.yml`.\n\n## Ownership boundary\n\n| Concern | Owner | Enforced surface |\n| ----------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------- |\n| Gate schema, profile planning, execution, receipt qualification | Shifu | `shifu gate plan`, `shifu gate run --profile`, `shifu gate receipt validate` |\n| Concrete gate catalog and profile decisions | Consumer project | project Gate registry and detailed Gate docs |\n| Runner labels and declared capabilities | Consumer workflow / Buildchain preset | `runner-preset` or `platforms-json` |\n| Deterministic runner matrix, immutable checkout, receipt transport, aggregate check | Buildchain | `.gate-profile.yml` and `shifu-gate-profile.mjs` |\n| Whether a profile aggregate is required for dev, alpha, or release | Consumer project | protected-branch required-check policy and caller workflow |\n\nBuildchain treats the Shifu plan and receipt as versioned input contracts. It\ndoes not reimplement policy selection, execute raw shell strings, convert an\nexplicit diagnostic gate run into qualification, or mint missing evidence.\n\n## Runner matrix\n\nThe plan job asks the consumer's Shifu entrypoint for one plan per configured\nplatform. A platform is dispatchable only when:\n\n- the Shifu plan is qualifying;\n- every required selection is supported on that platform;\n- the runner declares every capability requested by the selected gates; and\n- all platform plans carry the same project id and registry digest.\n\nConfigured platforms are required by default. A required platform that cannot\nhost the profile fails before runner dispatch. A platform with\n`\"required\": false` may be omitted, but the omission and reasons remain in the\nmatrix and aggregate. Matrix entries retain the Shifu plan digest, ordered gate\ngroups, required/advisory modes, action ids, definition digests, skips, and\nunsupported selections.\n\n`github-hosted` declares only the inherent `node` capability. Projects that\nneed a native compiler, product artifacts, devices, or other facilities must\nuse a suitable preset or declare a custom matrix. Capabilities are scheduling\nclaims, not installation instructions.\n\n```json\n[\n {\n \"id\": \"linux-native\",\n \"name\": \"Linux native\",\n \"platform\": \"linux\",\n \"runner\": \"[\\\"self-hosted\\\",\\\"Linux\\\",\\\"X64\\\",\\\"product-build\\\"]\",\n \"capabilities\": [\"node\", \"native-toolchain\", \"product-artifacts\"]\n }\n]\n```\n\n## Execution and receipts\n\nEvery matrix job checks out the exact source SHA planned by Buildchain, invokes\n`shifu gate run --profile`, writes the receipt outside the source checkout, and\nthen invokes `shifu gate receipt validate`. Buildchain uploads the original\nreceipt and validation result even when the run fails.\n\nBefore invoking the project-owned command, the workflow adds the runner\naccount's `~/.local/bin` directory to `PATH` on Windows, Linux, and macOS. This\nkeeps user-scoped tools such as `uv` available to strict Shifu cache profiles\nwithout assuming an administrator-managed system installation. The consumer or\nrunner owner remains responsible for provisioning the declared tools.\n\nThe fixed `Gate profile / aggregate` job fails closed for missing receipts,\ninvalid or stale Shifu validation, dirty or mismatched source SHA, registry or\nplan drift, missing required results, required failures/skips, or gate action\nand definition digest drift. Advisory failures remain visible but do not turn a\nShifu-qualifying receipt into a required failure. Buildchain's aggregate is\n`buildchain.shifu-gate-aggregate/v1`; its digest covers the matrix, receipts,\nper-gate evidence pointers, omissions, and issues.\n\n## Consumer workflow\n\n```yaml\njobs:\n gates:\n uses: kungfu-systems/buildchain/.github/workflows/.gate-profile.yml@v2\n with:\n gate-profile: alpha-pr\n runner-preset: kungfu-v4-self-hosted\n include-advisory: true\n\n build:\n needs: gates\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v2\n with:\n release-candidate: true\n gate-profile-aggregate-json: ${{ needs.gates.outputs.gate-aggregate-json }}\n```\n\nThe command input is an argv map, not a shell string. The default supports the\nordinary Shifu launcher names on all three platforms. A project with a\ndifferent launcher can override it without teaching Buildchain project tasks:\n\n```yaml\ngate-command-json: >-\n {\"linux\":[\"./tools/shifu\"],\"macos\":[\"./tools/shifu\"],\"windows\":[\"./tools/shifu.cmd\"]}\n```\n\n`gate-command-json` is the execution command. If execution needs a cache,\ncontainer, or other project-owned wrapper that should not make the read-only\nplan depend on that service, pass a separate lightweight argv map through\n`gate-plan-command-json`. It defaults to the execution command for backward\ncompatibility; Buildchain still treats both inputs as argv and never evaluates\na shell string.\n\nProjects may also pass non-sensitive scalar environment through\n`gate-environment-json`; Buildchain validates the JSON shape and forwards it\nwithout interpreting names or values. Cache profile references use the same\nopaque `shifu-cache-profile-ref` and `shifu-cache-profile-digest` inputs as the\nreusable build. Do not place tokens, credentials, or other secrets in workflow\ninputs or Gate receipts.\n\nWhen a qualifying aggregate is passed to the build workflow, the\nrelease-candidate passport binds its profile, source SHA, registry digest,\nmatrix digest, aggregate digest, receipt count, and result count. A failed,\nnon-qualifying, or source-mismatched aggregate cannot produce a valid passport.\nPromote-only release validation preserves that same Gate evidence summary in\nthe final Release Passport release identity, so promotion cannot silently drop\nthe qualified profile provenance.\n\n## Failure diagnosis and rollback\n\nStart with the aggregate artifact, then the platform receipt named in its\nissues. Reproduce the exact project decision with Shifu, for example:\n\n```bash\n./shifu gate explain <gate-id> --profile <profile>\n./shifu gate plan <profile> --platform <platform> --json\n./shifu gate receipt validate <receipt.json> --json\n```\n\nThe existing reusable build workflow remains usable without Gate inputs. To\nroll back Gate orchestration, remove the caller's `gates` job and\n`gate-profile-aggregate-json` handoff; this does not alter the consumer's Shifu\nregistry or its direct diagnostic commands.\n\n## Validation boundary\n\nUnit fixtures prove deterministic matrix generation and required/advisory,\ncapability, unsupported, missing, stale, failure, and definition-drift\npropagation. Because a train ref changes runtime scripts but not the outer\nreusable workflow topology, an unreleased `.gate-profile.yml` must also be\nvalidated through a trusted `workflow_dispatch` canary that references the\ntemporary workflow ref or exact SHA. See\n[`runtime-train-validation.md`](runtime-train-validation.md)."
|
|
1705
1753
|
},
|
|
1706
1754
|
{
|
|
1707
1755
|
"id": "manual:site-bundle-contract",
|
|
@@ -2274,7 +2322,7 @@
|
|
|
2274
2322
|
"pageRegistry": {
|
|
2275
2323
|
"path": "page-registry.json",
|
|
2276
2324
|
"contract": "kungfu-buildchain-site-page-registry",
|
|
2277
|
-
"pageCount":
|
|
2325
|
+
"pageCount": 49,
|
|
2278
2326
|
"categories": [
|
|
2279
2327
|
"action",
|
|
2280
2328
|
"api",
|
|
@@ -2394,7 +2442,7 @@
|
|
|
2394
2442
|
"path": "docs/MAP.md",
|
|
2395
2443
|
"plane": "use",
|
|
2396
2444
|
"exists": true,
|
|
2397
|
-
"digest": "sha256:
|
|
2445
|
+
"digest": "sha256:91dc800bafc31bc149680c86272827936c94e0f025d547bbabc10d58fe5f128e"
|
|
2398
2446
|
},
|
|
2399
2447
|
{
|
|
2400
2448
|
"id": "install",
|
|
@@ -2420,6 +2468,14 @@
|
|
|
2420
2468
|
"exists": true,
|
|
2421
2469
|
"digest": "sha256:442e1b72e3977af56a8ae5e081ffd89c2f3ebcd9cfd50f07af730344bdf9fb0e"
|
|
2422
2470
|
},
|
|
2471
|
+
{
|
|
2472
|
+
"id": "publication-authority",
|
|
2473
|
+
"title": "Sealed publication authority",
|
|
2474
|
+
"path": "docs/publication-authority.md",
|
|
2475
|
+
"plane": "verify",
|
|
2476
|
+
"exists": true,
|
|
2477
|
+
"digest": "sha256:06ba05f9d8a2685a0896334b6013a97c45b7d71163cf6898e5a6274baf7f0296"
|
|
2478
|
+
},
|
|
2423
2479
|
{
|
|
2424
2480
|
"id": "release-candidate",
|
|
2425
2481
|
"title": "Release Candidate Passport",
|
|
@@ -2570,7 +2626,7 @@
|
|
|
2570
2626
|
"path": "docs/release-governance.md",
|
|
2571
2627
|
"plane": "why",
|
|
2572
2628
|
"exists": true,
|
|
2573
|
-
"digest": "sha256:
|
|
2629
|
+
"digest": "sha256:cce9f80add3c746fe28d8ebf5afb809348694741cb75d19154ed3057a9374c0d"
|
|
2574
2630
|
},
|
|
2575
2631
|
{
|
|
2576
2632
|
"id": "release-flow",
|