@kungfu-tech/buildchain 2.14.12 → 2.14.13-alpha.1
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/dist/site/buildchain-contract.json +5 -5
- package/dist/site/buildchain-site.json +16 -16
- package/dist/site/kfd-claims.json +2 -2
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +4 -4
- package/dist/site/node-api-registry.json +1 -1
- package/dist/site/page-registry.json +8 -8
- package/dist/site/public-surface-audit.json +1 -1
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +8 -8
- package/docs/cli.md +6 -0
- package/docs/migration-inventory.md +1 -1
- package/docs/release-passport.md +6 -0
- package/docs/reusable-build-surface.md +1 -1
- package/package.json +1 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-site-bundle",
|
|
4
|
-
"generatedAt": "2026-07-21T19:
|
|
5
|
-
"publishedAt": "2026-07-21T19:
|
|
4
|
+
"generatedAt": "2026-07-21T19:58:22.693Z",
|
|
5
|
+
"publishedAt": "2026-07-21T19:58:22.693Z",
|
|
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": "98ee8b787cdd471b0ce60efa555f2abca7378927",
|
|
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.14.
|
|
40
|
+
"version": "2.14.13-alpha.1",
|
|
41
41
|
"versionSource": "package.json#version"
|
|
42
42
|
},
|
|
43
43
|
"source": {
|
|
@@ -440,7 +440,7 @@
|
|
|
440
440
|
],
|
|
441
441
|
"maturity": "stable",
|
|
442
442
|
"sourcePath": "docs/cli.md",
|
|
443
|
-
"digest": "sha256:
|
|
443
|
+
"digest": "sha256:758625143a51d0fe66871220c52273ceaf5c7a47fc1a99bda4608e3ad587ae81",
|
|
444
444
|
"headings": [
|
|
445
445
|
{
|
|
446
446
|
"level": 1,
|
|
@@ -468,7 +468,7 @@
|
|
|
468
468
|
"anchor": "npm-publish-gate"
|
|
469
469
|
}
|
|
470
470
|
],
|
|
471
|
-
"markdown": "# Buildchain CLI, npm Package, and Toolkit API\n\nBuildchain is published as the public npm package\n`@kungfu-tech/buildchain`. The package contains the `buildchain` command,\nthe importable ESM toolkit APIs, and the local scripts needed to initialize and\nvalidate repositories before they use the reusable GitHub workflow surface.\n\nThe npm package is not the release authority. Release authority still comes\nfrom the protected Buildchain branch and tag state machine. npm publishing is a\nside effect of an exact release tag that has already been produced by that\nstate machine.\n\n## Install and Run\n\nUse the published package directly:\n\n```bash\nnpx @kungfu-tech/buildchain --help\nnpx @kungfu-tech/buildchain init --type package\nnpx @kungfu-tech/buildchain validate --require-version-state\n```\n\nOr install it in a repository:\n\n```bash\npnpm add -D @kungfu-tech/buildchain\npnpm exec buildchain validate\n```\n\nConsumers should pin the exact Buildchain version that was validated in their\nrepository. When dogfooding a fresh Buildchain release immediately after it is\npublished, pnpm may block the install through a minimum release-age policy. In\nthat case, add a temporary package/version-specific `minimumReleaseAgeExclude`\nentry, such as `@kungfu-tech/buildchain@2.2.5`, and remove it once the package\nhas aged past the normal policy window. Do not replace that with a broad\nregistry or scope-wide exclude.\n\nUse the package API directly inside JavaScript build scripts:\n\n```js\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\n\nconst logger = createBuildchainLogger({ source: \"user\", component: \"build\" });\nawait logger.span(\"build.native\", { phase: \"build\" }, async () => {\n await buildNativeArtifacts();\n});\n```\n\nThe standalone binary and CLI are for workflow steps, shell scripts, and\nnon-JavaScript environments. JavaScript code that already depends on\n`@kungfu-tech/buildchain` should import the toolkit API instead of spawning\n`npx buildchain` or a downloaded binary.\n\n## Node API and Package Exports\n\nBuildchain's public Node API is the package `exports` surface, not arbitrary\ninternal file paths. The npm package also ships\n`dist/site/node-api-registry.json` and exports it as\n`@kungfu-tech/buildchain/site/node-api-registry.json` so agents can enumerate\nthe supported imports from the installed package.\nFor navigation, start with `dist/site/capability-registry.json`: it groups\nmanuals, CLI commands, workflow/action inputs, Node exports, site pages, and KFD\nclaim facts by product capability before an agent chooses a concrete command or\nmanual.\n\nCurrent public import families include:\n\n```js\nimport * as buildchain from \"@kungfu-tech/buildchain\";\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\nimport { collectModuleBuildFacts } from \"@kungfu-tech/buildchain/build-facts\";\nimport { checkHomebrewTap } from \"@kungfu-tech/buildchain/homebrew\";\nimport { verifyKfd1ReleaseGate } from \"@kungfu-tech/buildchain/kfd-gate\";\nimport { collectBadgeBundleFacts } from \"@kungfu-tech/buildchain/badges\";\nimport { collectReadmeBadgeFacts } from \"@kungfu-tech/buildchain/readme-badges\";\nimport { verifyReleasePassport } from \"@kungfu-tech/buildchain/release-passport\";\nimport { createReleasePropagationPlan } from \"@kungfu-tech/buildchain/release-propagation\";\nimport { planReleaseLineBootstrap } from \"@kungfu-tech/buildchain/release-line-bootstrap\";\nimport { collectPublicSurfaceReverseAudit } from \"@kungfu-tech/buildchain/public-surface-audit\";\nimport { createBuildchainLayoutDiscovery } from \"@kungfu-tech/buildchain/buildchain-layout\";\nimport { createPortableDevCachePlan } from \"@kungfu-tech/buildchain/portable-dev-cache\";\nimport contractWorld from \"@kungfu-tech/buildchain/site/buildchain-contract.json\" with { type: \"json\" };\nimport capabilityRegistry from \"@kungfu-tech/buildchain/site/capability-registry.json\" with { type: \"json\" };\nimport manualRegistry from \"@kungfu-tech/buildchain/site/manual-registry.json\" with { type: \"json\" };\nimport nodeApiRegistry from \"@kungfu-tech/buildchain/site/node-api-registry.json\" with { type: \"json\" };\nimport publicSurfaceAudit from \"@kungfu-tech/buildchain/site/public-surface-audit.json\" with { type: \"json\" };\n```\n\nUse `dist/site/manual-registry.json` to find the packaged operating manuals and\ntheir SHA-256 digests. Use `dist/site/buildchain-contract.json` to verify the\nfloating-ref contract world for a runtime such as `@v2`.\n\n## Commands\n\n`buildchain layout` is the stable machine question for repository layout. Tools\nsuch as Shifu should call it instead of copying `.buildchain/` path constants:\n\n```bash\nbuildchain layout --cwd /path/to/repository --json\n```\n\nThe result identifies the Buildchain version pin, repository root and config,\nthe canonical and currently resolved KFD-3 registry paths, and the KFD field\nused to declare Shifu jurisdiction. A repository is in Shifu's distribution\njurisdiction only when a KFD-3 surface explicitly declares\n`distribution.registrar=\"shifu\"`; the presence of Buildchain configuration is\nnot sufficient. The same contract is available through\n`createBuildchainLayoutDiscovery()` from\n`@kungfu-tech/buildchain/buildchain-layout`.\n\n`buildchain init` writes a starter `.buildchain/buildchain.toml` and a reusable workflow\ncaller at `.github/workflows/build.yml`.\n\n`buildchain portable-cache plan` turns a consumer-owned, secret-free manifest\ninto GitHub Actions cache inputs without letting each consumer invent key or\nrestore-prefix semantics. The exact key binds source SHA and the consumer plan\ndigest; the compatible restore prefix still requires the same provider schema,\nlayer, roots, runner image, platform/architecture, toolchain, dependency lock,\nand build profile.\n\n```bash\nbuildchain portable-cache plan \\\n --manifest .buildchain/portable-cache.json \\\n --output .buildchain/portable-cache-plan.json \\\n --github-output \"$GITHUB_OUTPUT\"\n```\n\nThe emitted `cache-key`, `restore-keys`, and `cache-paths` values are intended\nfor pinned `actions/cache/restore` and `actions/cache/save` actions. After\nrestore and a consumer validation probe, seal the provider result:\n\n```bash\nbuildchain portable-cache receipt \\\n --plan .buildchain/portable-cache-plan.json \\\n --matched-key \"$CACHE_MATCHED_KEY\" \\\n --cache-hit \"$CACHE_HIT\" \\\n --validation-status pass \\\n --cold-fallback-status passed \\\n --output .buildchain/portable-cache-receipt.json\n```\n\nThe receipt distinguishes `exact`, `compatible`, `miss`, and `corrupt`.\nUnknown or contradictory provider evidence fails closed. A miss or corruption\nrequires the consumer's audited cold path; a cache never substitutes for the\nconsumer's current build or tests. Roots must be workspace-relative or under\n`~/`, and manifests cannot carry credentials, absolute host paths, or escape\nsegments. `cold-fallback-status=passed` qualifies a miss only after the current\nsource has completed its normal build and test path.\n\nSupported presets:\n\n- `--type package` for Node package repositories with pnpm, npm, or yarn.\n- `--type native` for CMake-style native projects.\n- `--type web-surface` for preview/staging/production site or app deployments.\n- `--type infra-contract` for provider-agnostic infrastructure contract\n validation, observation, contract publication, and downstream propagation\n planning without default mutation. Provider adapters expose built-in command\n plans by default, and only configured `[infra.commands]` hooks can execute.\n- `--type publication-artifact` for papers, reports, specifications, and other\n publication repositories that produce PDFs, metadata, source bundles, and\n site-consumable manifests without becoming web-surface repositories. The\n scaffold uses Buildchain's pinned\n `ghcr.io/kungfu-systems/build-images/latex-pdf-builder:v1.2.0` toolchain for\n LaTeX PDF builds.\n- `--type distribution-index` for Homebrew taps and other index repositories\n whose files are projections of upstream release passport evidence.\n- `--type anchored-package` for packages whose version is anchored to an\n explicit upstream release manifest.\n\nThe native preset includes an opt-in `[diagnostics.native]` profile with common\ntool/cache/artifact probes. Consumers can keep it enabled, adjust the tool and\ndirectory lists, or disable it if a repository does not need native diagnostics.\n\n`buildchain validate` parses `.buildchain/buildchain.toml`, checks configured version-state\nfiles, and can require named lifecycle stages:\n\n```bash\nbuildchain validate \\\n --require-version-state \\\n --require-lifecycle-stages install,build,verify\n```\n\n`buildchain lifecycle run <stage>` executes a lifecycle stage and writes the\nsame deterministic artifact manifest contract used by the reusable workflow:\n\n```bash\nbuildchain lifecycle run build \\\n --artifact-path dist \\\n --artifact-name \"{repo}-{version}-{platform}\"\n```\n\n`buildchain dev merge-queue` plans a GitHub merge-queue policy for a protected\nBuildchain dev channel. Declare every workflow that emits a required check; the\ncommand fails closed unless each file handles both `pull_request` and\n`merge_group` without reading `github.event.pull_request` directly:\n\n```bash\nbuildchain dev merge-queue \\\n --repository kungfu-systems/example \\\n --branch dev/v4/v4.0 \\\n --workflow .github/workflows/source-acceptance.yml \\\n --workflow .github/workflows/affected-native-pr.yml\n```\n\nThe default output is a read-only plan. Add `--apply` only after reviewing it.\nApply creates the exact-branch merge-queue ruleset before changing classic\nrequired status checks from strict to loose, preserves the required check\nidentities, and is safe to repeat. `gh` must be authenticated with repository\nAdministration write permission for apply mode.\n\nRepositories can make that policy declarative in `buildchain.toml`:\n\n```toml\n[governance.dev.merge_queue]\nmode = \"enabled\" # enabled, inherit, or disabled\nrequired_workflows = [\".github/workflows/verify.yml\"]\ncheck_response_timeout_minutes = 120\nmax_entries_to_build = 1\nbypass_users = [\"release-owner\"]\n```\n\nUse `buildchain dev merge-queue --from-config` to resolve and reconcile the\ndeclaration. `enabled` requires an exact queue on the target dev branch;\n`disabled` suppresses automatic queue creation; `inherit` copies the active\ndefault dev branch's queue parameters and bypass actors. When the table is\nabsent, release-line bootstrap uses the backward-compatible `inherit` mode.\nEvery inherited or explicitly enabled queue still validates each declared\nrequired workflow before any mutation. For a legacy repository with no table,\nan already-active exact queue on the current default dev branch is accepted as\nthe inheritance evidence; new declarations should list the workflows so future\nchanges are revalidated from source.\nThe `Dev Merge Queue Governance` workflow runs this reconciliation after\ngovernance-relevant changes land on a dev branch; its manual dispatch remains\ndry-run by default.\n\n`buildchain release line open` plans or writes the first version-state commit\nfor a new semver minor line. It does not publish anything. The dry-run mode is\nthe default and returns the dev/alpha/release refs, protection contract, default\nbranch action, and initial version before any GitHub mutation happens:\n\n```bash\nbuildchain release line open \\\n --major 2 \\\n --minor 10 \\\n --source-ref release/v2/v2.9 \\\n --json\n```\n\nThe write mode only updates local version-state files. The repository workflow\n`Release Line Bootstrap` wraps this command and, when `apply=true`, commits the\ninitial version state, creates `dev/vX/vX.Y`, `alpha/vX/vX.Y`, and\n`release/vX/vX.Y`, applies one-review branch protection, reconciles declared or\ninherited merge-queue governance, switches the default branch only after that\nreconciliation succeeds, and opens the first dev-to-alpha channel PR:\n\n```bash\nbuildchain release line open \\\n --major 2 \\\n --minor 10 \\\n --source-ref release/v2/v2.9 \\\n --write \\\n --json\n```\n\n`buildchain` also publishes a public surface reverse audit as\n`dist/site/public-surface-audit.json`. The audit enumerates CLI commands from\n`bin/buildchain.mjs`, workflow inputs, action inputs, site pages, and docs\ncommand references, then compares them with the generated registries. Buildchain\nself-checks fail closed when an enumerable public surface is missing from the\nregistry:\n\n```js\nimport {\n collectPublicSurfaceReverseAudit,\n assertPublicSurfaceReverseAudit,\n} from \"@kungfu-tech/buildchain/public-surface-audit\";\n\nassertPublicSurfaceReverseAudit(collectPublicSurfaceReverseAudit({ root: process.cwd() }));\n```\n\n`buildchain kfd` is the product-facing KFD namespace. Schema commands expose the\nmachine-readable KFD standards shipped by `@kungfu-tech/kfd`, while versioned\nsubcommands host concrete product workflows. KFD-1, KFD-2, and KFD-3 are\nfirst-class Buildchain surfaces. KFD-4 is schema-only until Buildchain has a\nreal verification protocol for it.\n\n`status` reports implemented support and the active repo-owned file layout.\n`migrate-layout` moves legacy root files into `.buildchain/`:\n\n```bash\nbuildchain kfd status --json\nbuildchain kfd migrate-layout --write\n```\n\nKFD-1 commands generate and validate contract-world release evidence:\n\n```bash\nbuildchain kfd 1 schema --json\nbuildchain kfd 1 witness --json\nbuildchain kfd 1 gate --witness-json kfd-1-witness.json --json\nbuildchain kfd 1 verify --gate-json kfd-1-gate.json --json\n```\n\nKFD-2 commands validate trust taxonomy entries and generate Buildchain's public\nclaim evidence. Product repositories use the `product-claims` subcommand to\nvalidate and render their own declared KFD-2 release claims under the canonical\nBuildchain KFD layout:\n\n```bash\nbuildchain kfd 2 schema --json\nbuildchain kfd 2 taxonomy --entry-json residual-risk.json --kind residualRisk --json\nbuildchain kfd 2 claims --json\nbuildchain kfd 2 product-claims check --json\nbuildchain kfd 2 product-claims write --json\nbuildchain kfd 2 product-claims render --json\n```\n\nThe default source is `.buildchain/kfd/kfd-2/registry.json`; outputs are\n`.buildchain/kfd/kfd-2/release-claims.json`, per-claim release-passport inputs\nunder `claims/`, and `buildchain-claim-args.txt`. Use `--registry` or\n`--output-dir` only for an explicit product packaging projection. `check` never\nwrites and exits non-zero when outputs drift.\n\nKFD-3 commands are separate from Buildchain's self reverse audit: products can\ndetect standard public surfaces, register the accepted boundary, audit the\ncurrent source or artifact tree, generate a release-passport-compatible witness,\nand expose a capability map for agents:\n\n```bash\nbuildchain kfd schema list --json\nbuildchain kfd schema show kfd-3 --json\nbuildchain kfd 3 detect --kind node-api --kind cli --json\nbuildchain kfd 3 register node-api --product Buildchain\nbuildchain kfd 3 audit --json\nbuildchain kfd 3 witness --kind prebuild --output .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json\nbuildchain kfd 3 query buildchain --json\nbuildchain kfd 4 schema --json\n```\n\nThe public Node API is exported from `@kungfu-tech/buildchain/kfd`. See\n[`kfd-support.md`](kfd-support.md) for the detected / declared / enforced model\nand the agent query flow.\n\nLifecycle runs also write a Buildchain observability JSONL log at\n`.buildchain/logs/events.jsonl` by default. Framework events use\n`source=buildchain`; consumer lifecycle commands use `source=user`. This lets a\nmaintainer tell apart time spent inside Buildchain's artifact/manifest\nframework from time spent in the repository's own build, test, packaging, or\npublish commands. The artifact manifest and summary embed the observability\nsummary for that lifecycle run id, so uploaded artifacts preserve the timing\nfacts without mixing in older JSONL events.\n\n`buildchain log`, `buildchain mark`, and `buildchain span` expose the same event\nprotocol to repository scripts:\n\n```bash\nbuildchain mark --event configure.ready --phase configure --attribute target=release\nbuildchain span --event native.build --phase build -- cmake --build build\nbuildchain log warn --event cache.miss --component conan --attribute token=hidden\nbuildchain log summary --json\nbuildchain verify observability-log .buildchain/logs/events.jsonl --min-events 4 --require-phase build\nbuildchain diagnostics summary .buildchain/artifacts/*/diagnostics.json --json\nbuildchain sample process-tree --label native-build --interval-ms 15000 -- make -j20\n```\n\nDuring `buildchain lifecycle run`, child processes receive\n`BUILDCHAIN_LOG_PATH` and `BUILDCHAIN_LOG_RUN_ID`. A shell, Python, CMake, Conan,\nor JavaScript helper can call `buildchain mark` or `buildchain span` mid-build\nand have those events grouped into the same lifecycle summary.\n`buildchain verify observability-log` is a release gate: it fails when the log\nis missing, has too few events, contains error events, or does not include\nrequired phases, components, or event names.\n\nThe event protocol is JSONL and is also available from the SDK:\n\n```js\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\n\nconst logger = createBuildchainLogger({ source: \"user\", component: \"native-build\" });\nlogger.mark(\"configure.ready\", { phase: \"configure\" });\n```\n\nSecret-looking attribute keys such as `token`, `password`, `secret`,\n`authorization`, `cookie`, and `private-key` are redacted before they are written.\nFull command strings are not recorded by `span`; scripts should provide stable\nevent names and safe attributes instead.\n\n`buildchain diagnostics summary` reads one or more small diagnostics artifacts\nand emits the same cross-platform summary as the diagnostics SDK:\n\n```bash\nbuildchain diagnostics summary \\\n .buildchain/artifacts/linux-x64/diagnostics.json \\\n .buildchain/artifacts/macos-arm64/diagnostics.json \\\n --output .buildchain/artifacts/diagnostics-summary.json \\\n --json\n```\n\nThe JSON summary keeps per-platform lifecycle stage tables, adds lifecycle\ntotal durations, carries top slow spans, aggregates warning/error counts, and\nsorts the slowest platforms. Each platform row carries compact runner facts,\nchecked tool versions/missing tools, package manager/cache directory details,\ncompiler-cache availability, and a compact process sampler summary: requested\nparallelism, observed max active processes, the ratio between them, sample\ncount, process categories, and the top sampled command basenames. This lets\nmaintainers inspect matrix timing, runner, tool, cache, and concurrency context\nwithout downloading large platform binaries or process sidecars first.\nWhen a sibling `diagnostics-manifest.json` is available, the summary also records\nits file list and verifies the listed `diagnostics.json` byte count and sha256.\nMissing, unreadable, or mismatched sidecar manifests are reported through\n`diagnosticsManifestWarningCount` and the per-platform `diagnosticsManifest`\nfield without failing the timing rollup.\nThe summary also compares each `diagnostics.json` contract to\n`BUILDCHAIN_DIAGNOSTICS_CONTRACT`; mismatches are reported through\n`diagnosticsContractWarningCount` and the per-platform `diagnosticsContract`\nfield so reviewers can separate diagnostics schema drift from lifecycle\nwarnings or build failures.\n\nWithout `--json`, the command prints a compact lifecycle timing table with\ninstall/build/verify/publish, artifact scan/upload, total, warning, and error\ncolumns for each platform, plus `jobs` and `active` columns for requested and\nobserved process concurrency when sampler data is present.\n\n`buildchain facts` collects and verifies source/version/output facts for\nmodules and products:\n\n```bash\nbuildchain facts module \\\n --module native-core \\\n --output .buildchain/facts/native-core.json \\\n --legacy-kungfu-buildinfo framework/core/src/kungfu/yijinjing/kungfubuildinfo.json\n\nbuildchain facts aggregate \\\n --product kungfu \\\n --module-fact .buildchain/facts/native-core.json \\\n --artifact dist/kungfu.zip \\\n --output .buildchain/facts/kungfu.json\n\nbuildchain facts verify --fact .buildchain/facts/kungfu.json\n```\n\nThe same implementation is available from\n`@kungfu-tech/buildchain/build-facts`. Release passports can include these\nfacts with repeated `--build-facts-json` arguments to\n`buildchain collect github-release`. See\n[`build-facts.md`](build-facts.md) for the config schema and Node API.\n\n`buildchain sample process-tree` wraps a long-running command and periodically\nwrites process-tree snapshots:\n\n```bash\nbuildchain sample process-tree \\\n --label native-build \\\n --interval-ms 15000 \\\n --output .buildchain/diagnostics/process-samples.jsonl \\\n --summary-output .buildchain/diagnostics/process-summary.json \\\n -- \\\n make -j20\n```\n\nThe command returns the wrapped command's exit status. The JSONL file contains\nsmall timestamped samples; the summary JSON records requested parallelism,\nobserved concurrency, sampled CPU, command categories, and top command\nbasenames. Use it when a native build requests high parallelism but appears to\nspend long stretches in low-concurrency compile, archive, link, or cache steps.\n\n`buildchain doctor` checks repository readiness before remote side effects:\n\n```bash\nbuildchain doctor --json\n```\n\nIt validates `.buildchain/buildchain.toml`, package-manager detection, Git repository state,\nand the reusable workflow caller. For `version.strategy = \"anchored\"` with\n`version.next = \"manual\"`, it also embeds the anchored package release contract\ncheck: anchor manifest readability, configured version files, trusted\npublishing, package publish order, and required lifecycle stages. Add\n`--require-publish-source-lock` inside a publish job when the doctor report\nshould also fail unless the job is running from a resolved `publish-gate/*`\nsource lock.\n\nAnchored/manual package publish jobs can run the narrower source-lock gate\ndirectly:\n\n```bash\nbuildchain publish-source validate-anchored-release --json\n```\n\nThe command requires `BUILDCHAIN_PUBLISH_SOURCE_REF`,\n`BUILDCHAIN_PUBLISH_SOURCE_SHA`, and `BUILDCHAIN_PUBLISH_SOURCE_LOCKED` from the\nreusable build workflow outputs. It fails closed for direct `alpha/*` or\n`release/*` channel-branch publication, and checks the publish-gate consumer\nversion against configured version files and the anchor manifest. The JSON\nresult is shaped for future `buildchain.libkungfu.dev` fact ingestion.\n\n`buildchain release`, `buildchain web-surface`, `buildchain infra-contract`,\n`buildchain publication-artifact`, `buildchain publish-source`,\n`buildchain badges`, `buildchain homebrew`, and `buildchain build-contract`\nroute to the same implementation used by\nBuildchain's package APIs or GitHub Actions workflows. This keeps local\ninspection and CI behavior on the same implementation path.\n\nGenerate publication artifact metadata after building a paper or report:\n\n```bash\nbuildchain publication-artifact manifest \\\n --source-sha \"$(git rev-parse HEAD)\" \\\n --json\n```\n\nGenerate the Buildchain-owned npm paper package contents from declared\npublication facts:\n\n```bash\nbuildchain publication-artifact npm-package --json\n```\n\nThis command reads `project.type = \"publication-artifact\"`,\n`publication.version`, and `[publish] kind = \"npm-paper-package\"` plus\n`publish.package`; it writes `.buildchain/publication/npm-package` by default.\nThe `paper-release.yml@v2` reusable workflow uses the same command before\nrunning the standard npm publish transaction.\n\nThe command writes `.buildchain/publication/publication-artifact.json`,\n`.buildchain/publication/publication-artifact-passport.json`, a source bundle,\nand, when `[publication.archive]` is configured,\n`.buildchain/publication/publication-registry.json` by default. See\n[`publication-artifacts.md`](publication-artifacts.md) for the repository\ncontract, pinned LaTeX builder, and reusable workflow.\n\nGenerate, check, or update the managed README badge block:\n\n```bash\nbuildchain badges readme --json\nbuildchain badges readme --check\nbuildchain badges readme --write\nbuildchain badges bundle --json\nbuildchain badges bundle --check\nbuildchain badges bundle --write\nbuildchain badges bundle --claims kfd-1,release-passport --write\n```\n\nThe `--json` form emits the `kungfu-buildchain-readme-badge-facts` object.\n`--check` fails closed when the README marker block is missing or stale.\n`--write` inserts or replaces only the marked block. KFD passed badges come\nfrom the repository's own verified release passport; unreleased repositories\ndowngrade to explicit local declarations such as `declared`, `aligned`, or\n`planned`. `buildchain badges bundle` is the focused trust-badge entrypoint: it\nemits `kungfu-buildchain-badge-bundle-facts` and defaults to KFD-1, KFD-2,\nKFD-3, and Release Passport. See [`readme-badges.md`](readme-badges.md) for the\nmarker contract and `[badges]` / `[badges.bundle]` configuration.\n\nGenerate or check Homebrew tap projections from upstream release passports:\n\n```bash\nbuildchain homebrew update-formula \\\n --package buildchain \\\n --release-passport https://github.com/kungfu-systems/buildchain/releases/download/v2.8.15/buildchain.release.json \\\n --write\n\nbuildchain homebrew check --json\n```\n\n`update-formula` writes `Formula/buildchain.rb` and `tap-manifest.json` from\nupstream release passport evidence. `check` fails closed when the Formula,\nmanifest, artifact digests, or KFD status drift from the upstream passport. See\n[`homebrew.md`](homebrew.md) for the distribution-index project contract.\n\n`buildchain collect github-release` creates a release passport bundle from\nGitHub Release assets or a local asset directory:\n\n```bash\nbuildchain collect github-release \\\n --tag v2.2.0 \\\n --repository kungfu-systems/buildchain \\\n --assets-dir dist \\\n --output-dir .buildchain/release-passport\n```\n\nThe bundle includes `buildchain.release.json`, `artifact-evidence.json`,\n`impact.json`, `agent-index.json`, `product-mechanism.json`, `check-report.json`,\nand `llms.txt`. Production binary distribution defaults to GitHub-hosted\nrunners so other projects can reproduce the release lane; self-hosted runners\nremain compatibility fixtures and are recorded as runner facts when used.\n\nFor publish-transaction releases, pass the additional evidence inputs so\n`buildchain.release.json` becomes the unified passport instead of a binary-only\nasset summary:\n\n```bash\nbuildchain collect github-release \\\n --tag v2.3.2 \\\n --repository kungfu-systems/buildchain \\\n --assets-dir dist \\\n --publish-evidence-json .buildchain/release-evidence/v2.3.2/evidence.json \\\n --transaction-json .buildchain/release-state/v2.3.2/state.json \\\n --package-set-json package-set.json \\\n --impact-json impact.json \\\n --trusted-publishing-json trusted-publishing.json \\\n --anchor-manifest-json libnode.release.json \\\n --build-summary-json .buildchain/artifacts/build-summary.json \\\n --platform-manifest-json .buildchain/artifacts/linux-x64/manifest.json \\\n --platform-manifest-json .buildchain/artifacts/darwin-arm64/manifest.json \\\n --platform-manifest-json .buildchain/artifacts/win32-x64/manifest.json \\\n --dist-tag-evidence-json .buildchain/release-evidence/v2.3.2/dist-tag-evidence.json \\\n --kfd-1-witness-json .buildchain/kfd/kfd-1/contract-world.witness.json \\\n --kfd-2-claim-json .buildchain/kfd/kfd-2/release-claims.json \\\n --kfd-3-prebuild-witness-json .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json \\\n --kfd-3-artifact-verify-cmd \"kungfu agent verify --json\" \\\n --release-extra-json '{\"channel\":\"release\",\"targetRef\":\"release/v2/v2.3\"}' \\\n --output-dir .buildchain/release-passport\n```\n\nThe generated passport records the main and platform packages, npm dist-tags,\npublished versions, release source/ref state, anchor manifest digest, registry\nartifact digests, trusted publishing evidence, and Buildchain transaction\nresult. It also records `buildSummary`, `platformArtifactManifests`, and\n`distTagPromotion` when those JSON inputs are supplied. `packageSet` keeps the\nordered package set; `publish.packages[]` is the agent-readable npm publication\nsummary for each main/platform package. For Buildchain releases, verification\nexpects the supplied package set to include the main package plus the three\nplatform packages with version, dist-tag, and digest evidence. Verification\nfails closed if supplied sections are internally incomplete or point to\nartifacts without matching evidence.\n\n`--kfd-1-witness-json` attaches a KFD-1 contract-world release gate. The witness\nis structured JSON: consumers declare the contract world, canonical JSON policy,\nartifact paths, and expected SHA-256 digests. Buildchain imports KFD-owned\nmetadata from `@kungfu-tech/kfd`, freezes the witness before build publication,\nthen verifies the resulting artifact bytes itself and writes the evidence under\nthe KFD-provided top-level key currently named `kfd-1`. Consumers should not\nduplicate this by running repository-specific scripts or invoking the Kungfu\nSDK from their release workflow.\n\nFor the KFD repository, KFD-1 witnesses may be self-hosted standard-contract\nwitnesses: docs, schemas, standards metadata, package exports, and\nsite-consumption entrypoints are checked from source hashes to packaged artifact\nhashes, and the passport records schema IDs, self-hosting boundary, result, and\nresponsibility state.\n\n`--kfd-2-claim-json` attaches explicit public release claims to the KFD-2\nrelease trust passport audit. Buildchain also derives KFD-2 claims from KFD-1\nand KFD-3 gate evidence. Public claims must 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 and emit a\nwarning.\n\n`--kfd-3-prebuild-witness-json` attaches a KFD-3 collaboration-interface\nrelease gate. The product remains the source of truth: it emits a pre-build\nwitness that contains or points to its KFD-3 collaboration interface, declared\nparticipant-facing public surfaces, and registry digest. Buildchain freezes\nthat declaration before publication. The artifact side is supplied either by\n`--kfd-3-artifact-witness-json` or by a product-owned command such as\n`--kfd-3-artifact-verify-cmd \"kungfu agent verify --json\"`. Buildchain then\nchecks closure: every declared shipped public surface must be present in the\nartifact witness, and every artifact-exposed participant-facing public surface\nmust have been declared. The generated passport writes this evidence under the\nKFD-provided top-level key currently named `kfd-3`.\n\nThis gate is useful for agent-facing products because it turns KFD-3 from prose\ninto release evidence. A package cannot claim KFD-3 collaboration-interface\nsupport merely because the docs mention it; the release passport must show the\nfrozen declaration, the artifact-side witness digest, and a passing closure\ncomparison.\n\n`--invariant-passport-json` attaches a product-owned invariant Passport to the\nrelease gate and may be repeated. `--invariant-passport-cmd` runs a product\ncommand that emits one Passport JSON document. Buildchain verifies the\nPassport root, exact clean source identity, `verified` verdict, complete\nplatform coverage, and residual-risk shape; it does not redefine the product's\ninvariant semantics. Declared invariant Passport input is fail-closed.\nFor the KFD repository itself, the witness can declare docs, schemas, standards\nmetadata, package exports, and site-consumption contracts as grouped public\nsurfaces; the artifact witness must expose the same enumerable package/site\nsurfaces or verification fails closed.\n\n`--impact-json` supplies the surface-aware impact ledger. Production release\npassports (`release/*`) and major publish-gate passports require\n`surfaceImpacts[]`; alpha, local, and legacy passport contexts keep it\noptional. When `surfaceImpacts[]` is required or supplied, the verifier requires\neach entry to include an id, impact, and rationale, and requires\n`versionImpact.final` to match the highest declared surface impact. The\ncollector copies `versionImpact` plus `surfaceImpacts` into\n`buildchain.release.json`. This lets\n`buildchain explain release --for agent --json` state why a release is patch,\nminor, or major instead of relying on file-path memory.\n\nBuildchain dogfoods its observability toolkit in this lane. The standalone\nbuilder writes API-generated events, while the workflow uses `buildchain mark`,\n`buildchain span`, `buildchain verify observability-log`, and `buildchain log\nsummary`; the event logs and summaries are published as release passport assets.\n\nVerify and explain release passports:\n\n```bash\nbuildchain verify release-passport .buildchain/release-passport/buildchain.release.json\nbuildchain explain release --passport .buildchain/release-passport/buildchain.release.json --for agent --json\nbuildchain inspect release --passport .buildchain/release-passport/buildchain.release.json\n```\n\nThe verifier fails closed when required protocol files are absent, artifacts are\nnot covered by evidence, or digests disagree. The explanation output is shaped\nfor agents: trust, completeness, impact, recovery route, and next action.\n\nVerify a published artifact by subject:\n\n```bash\nbuildchain verify artifact ./Kungfu-2.8.0-windows-x64.exe\nbuildchain inspect artifact ./Kungfu-2.8.0-windows-x64.exe --json\nbuildchain explain artifact ./Kungfu-2.8.0-windows-x64.exe --for agent --json\nbuildchain verify artifact npm:@kungfu-tech/libnode@22.22.3-kf.3-alpha.18 \\\n --repository kungfu-systems/libnode \\\n --tag v22.22.3-kf.3-alpha.18 \\\n --json\n```\n\n`verify artifact` computes or obtains the subject digest, discovers the\ndetached release passport, verifies the passport, then requires that the\nsubject digest appears in the passport's release assets, package set, publish\nevidence, or artifact evidence. Outcomes are explicit: `pass`, `fail`, or\n`unverifiable`. A filename is only a hint; trust comes from digest equality.\nFor `npm:<name>@<version>` subjects, Buildchain resolves `dist.integrity` from\nthe npm registry before matching passport evidence. Use `--npm-registry <url>`\nto verify packages from a custom registry; otherwise Buildchain uses\n`npm_config_registry` or `https://registry.npmjs.org/`.\n\nDiscovery is fail-closed and ordered:\n\n1. `--passport <file-or-url>`.\n2. Sidecar pointer, such as `<artifact>.buildchain-passport.json`.\n3. Embedded/package pointer, such as `package.json` `buildchain.releasePassport`.\n4. Local config or org index, such as `.buildchain/artifact-passport-locators.json`.\n5. GitHub Release default discovery from `github-release:` subjects, GitHub\n Release asset URLs, or `--repository <owner/repo> --tag <tag>`.\n6. Custom `--locator-config <json-or-url>`.\n7. `unverifiable` with retry guidance.\n\nLocator files are policy, not protocol. They map subject fields such as\n`name`, `kind`, `version`, `digest`, `repository`, or `tag` to a detached\npassport location:\n\n```json\n{\n \"schemaVersion\": 1,\n \"contract\": \"kungfu-buildchain-artifact-passport-locator\",\n \"locators\": [\n {\n \"match\": {\n \"name\": \"Kungfu-2.8.0-windows-x64.exe\",\n \"digest\": \"sha256:...\"\n },\n \"passport\": \"../release-passport/buildchain.release.json\"\n }\n ]\n}\n```\n\nSupported subject shapes include local files and directories, URLs,\n`npm:<name>@<version>`, `oci:...`, `s3:...`,\n`github-release:<owner/repo>@<tag>/<asset>`, and deployment endpoints. Local\nfiles, directories, and URLs are digestable directly; remote package, OCI,\nobject storage, and deployment subjects should provide a digest or resolve to a\nlocator that records one.\n\nSeal an exact artifact verification with the Node API, then verify or project\nthe resulting KFX admission envelope without reconstructing its roots:\n\n```bash\nbuildchain verify artifact-envelope envelope.json \\\n --assessment-time 150 \\\n --expected-root sha256:... \\\n --expected-issuer buildchain.libkungfu.dev \\\n --expected-publisher kungfu-systems \\\n --expected-contract buildchain.release/v1 \\\n --json\n\nbuildchain project kfx-admission envelope.json \\\n --assessment-time 150 \\\n --json\n```\n\nBoth commands call the public artifact-verification-envelope verifier. The\nprojected `attestation`, `trustInputs`, and `kfdAssessment` are direct copies of\nthe sealed envelope, and `envelopeRoot` stays identical across Node and CLI.\nSee [`artifact-verification-envelope.md`](artifact-verification-envelope.md).\n\nVerify infra-contract lifecycle evidence bundles:\n\n```bash\nbuildchain infra-contract --mode ci --source-sha \"$GITHUB_SHA\"\nbuildchain verify infra-contract-evidence-bundle .buildchain/infra-contract-evidence-bundle.json\n```\n\nThe infra-contract `ci` mode is mutation-free. It writes validate, plan,\ncontract, propagation dry-run, evidence bundle, and verification JSON artifacts\nunder `.buildchain/`, giving reusable workflows one standard responsibility\nchain instead of hand-written command sequences.\n\nThe infra-contract verifier is read-only. It recomputes the bundle hash and\nchecks that desired, plan, approval, apply, observe, contract, and propagate\nevidence remain bound to the same contract artifact. It also recomputes the\nbundle validation summary, so stale or misleading summary booleans fail closed\neven when the bundle hash has been refreshed.\n\n`buildchain release --dry-run` explains the release-line state machine before a\nmaintainer opens or merges a channel PR:\n\n```bash\nbuildchain release --dry-run --target-ref alpha/v2/v2.2\nbuildchain release --dry-run --target-ref release/v2/v2.2 --sha <verified-sha>\nbuildchain release dry-run --target-ref publish-gate/major --source-ref release/v2/v2.2\nbuildchain release explain --target-ref alpha/v2/v2.1 --json\n```\n\nThis is a Buildchain-level dry-run, not an npm dry-run. It explains the legal\nsource branch, exact release or alpha tags, floating tags, channel branches,\nversion-state files, governance checks, and publish transaction behavior that\nwould apply if the corresponding PR merge were promoted. It does not move\nbranches, move tags, edit files, publish npm packages, or run lifecycle publish\ncommands. `release explain` is the same explanation surface with a clearer name.\nPass `--json` for a machine-readable plan.\n\n`buildchain transaction inspect` is the top-level recovery inspection command\nfor the publish transaction state:\n\n```bash\nbuildchain transaction inspect --version v2.1.0-alpha.0\n```\n\nIt reads or locally initializes the durable transaction record and validates\navailable publish evidence. Remote durable refs and public Git ref finalization\nremain owned by `actions/promote-buildchain-ref`; the CLI inspection surface is\nfor preflight and recovery reasoning before a maintainer reruns or resumes a\npromotion.\n\n`buildchain npm dry-run` verifies the package shape before a release tag exists:\n\n```bash\nbuildchain npm dry-run --json\n```\n\nThe command validates `package.json`, infers the exact release tag\n`v${package.json.version}`, chooses npm dist-tag `alpha` for prereleases and\n`latest` for stable releases, runs `npm pack --dry-run --json`, and then runs\n`npm publish --dry-run --access public --tag <alpha|latest>` unless\n`--skip-npm-publish-dry-run` is passed. It never performs a real publish.\n\n## npm Publish Gate\n\nBuildchain's own npm package is published from\n`.github/workflows/buildchain-ref-promotion.yml`, inside the same publish\ntransaction that promotes release refs:\n\n- `v2.0.13-alpha.0` publishes to npm with dist-tag `alpha`.\n- `v2.0.13` publishes to npm with dist-tag `latest`.\n- moving refs such as `v2`, `v2.0`, and `v2.0-alpha` do not match the publish\n workflow and do not publish.\n\nThe promotion workflow uses npm Trusted Publishing through GitHub Actions OIDC.\nIt runs on a GitHub-hosted runner with `id-token: write`, but it does not\nmanually run the release-candidate resolver or promote action. Buildchain's own\ndogfood path calls the declarative `release-candidate-promote.yml` wrapper with\nchannel, target ref/SHA, PR-stage workflow, artifact, status-check, and passport\ninputs. The wrapper generates the version-state commit, runs\n`lifecycle.verify`, runs `lifecycle.publish`, writes Buildchain publish\nevidence, validates that evidence, and only then moves exact tags and floating\nrefs.\n\n```bash\nnode scripts/npm-publish-transaction.mjs\n```\n\nBefore the first real release, configure npm Trusted Publishing for:\n\n- package: `@kungfu-tech/buildchain`\n- repository: `kungfu-systems/buildchain`\n- workflow: `.github/workflows/buildchain-ref-promotion.yml`\n\nNo npm package is published by manual dispatch or ordinary branch builds.\nManual dispatch on `.github/workflows/npm-publish.yml` remains dry-run only, so\nmaintainers can verify package contents and npm publish shape before opening or\nmerging the release PR."
|
|
471
|
+
"markdown": "# Buildchain CLI, npm Package, and Toolkit API\n\nBuildchain is published as the public npm package\n`@kungfu-tech/buildchain`. The package contains the `buildchain` command,\nthe importable ESM toolkit APIs, and the local scripts needed to initialize and\nvalidate repositories before they use the reusable GitHub workflow surface.\n\nThe npm package is not the release authority. Release authority still comes\nfrom the protected Buildchain branch and tag state machine. npm publishing is a\nside effect of an exact release tag that has already been produced by that\nstate machine.\n\n## Install and Run\n\nUse the published package directly:\n\n```bash\nnpx @kungfu-tech/buildchain --help\nnpx @kungfu-tech/buildchain init --type package\nnpx @kungfu-tech/buildchain validate --require-version-state\n```\n\nOr install it in a repository:\n\n```bash\npnpm add -D @kungfu-tech/buildchain\npnpm exec buildchain validate\n```\n\nConsumers should pin the exact Buildchain version that was validated in their\nrepository. When dogfooding a fresh Buildchain release immediately after it is\npublished, pnpm may block the install through a minimum release-age policy. In\nthat case, add a temporary package/version-specific `minimumReleaseAgeExclude`\nentry, such as `@kungfu-tech/buildchain@2.2.5`, and remove it once the package\nhas aged past the normal policy window. Do not replace that with a broad\nregistry or scope-wide exclude.\n\nUse the package API directly inside JavaScript build scripts:\n\n```js\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\n\nconst logger = createBuildchainLogger({ source: \"user\", component: \"build\" });\nawait logger.span(\"build.native\", { phase: \"build\" }, async () => {\n await buildNativeArtifacts();\n});\n```\n\nThe standalone binary and CLI are for workflow steps, shell scripts, and\nnon-JavaScript environments. JavaScript code that already depends on\n`@kungfu-tech/buildchain` should import the toolkit API instead of spawning\n`npx buildchain` or a downloaded binary.\n\n## Node API and Package Exports\n\nBuildchain's public Node API is the package `exports` surface, not arbitrary\ninternal file paths. The npm package also ships\n`dist/site/node-api-registry.json` and exports it as\n`@kungfu-tech/buildchain/site/node-api-registry.json` so agents can enumerate\nthe supported imports from the installed package.\nFor navigation, start with `dist/site/capability-registry.json`: it groups\nmanuals, CLI commands, workflow/action inputs, Node exports, site pages, and KFD\nclaim facts by product capability before an agent chooses a concrete command or\nmanual.\n\nCurrent public import families include:\n\n```js\nimport * as buildchain from \"@kungfu-tech/buildchain\";\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\nimport { collectModuleBuildFacts } from \"@kungfu-tech/buildchain/build-facts\";\nimport { checkHomebrewTap } from \"@kungfu-tech/buildchain/homebrew\";\nimport { verifyKfd1ReleaseGate } from \"@kungfu-tech/buildchain/kfd-gate\";\nimport { collectBadgeBundleFacts } from \"@kungfu-tech/buildchain/badges\";\nimport { collectReadmeBadgeFacts } from \"@kungfu-tech/buildchain/readme-badges\";\nimport { verifyReleasePassport } from \"@kungfu-tech/buildchain/release-passport\";\nimport { createReleasePropagationPlan } from \"@kungfu-tech/buildchain/release-propagation\";\nimport { planReleaseLineBootstrap } from \"@kungfu-tech/buildchain/release-line-bootstrap\";\nimport { collectPublicSurfaceReverseAudit } from \"@kungfu-tech/buildchain/public-surface-audit\";\nimport { createBuildchainLayoutDiscovery } from \"@kungfu-tech/buildchain/buildchain-layout\";\nimport { createPortableDevCachePlan } from \"@kungfu-tech/buildchain/portable-dev-cache\";\nimport contractWorld from \"@kungfu-tech/buildchain/site/buildchain-contract.json\" with { type: \"json\" };\nimport capabilityRegistry from \"@kungfu-tech/buildchain/site/capability-registry.json\" with { type: \"json\" };\nimport manualRegistry from \"@kungfu-tech/buildchain/site/manual-registry.json\" with { type: \"json\" };\nimport nodeApiRegistry from \"@kungfu-tech/buildchain/site/node-api-registry.json\" with { type: \"json\" };\nimport publicSurfaceAudit from \"@kungfu-tech/buildchain/site/public-surface-audit.json\" with { type: \"json\" };\n```\n\nUse `dist/site/manual-registry.json` to find the packaged operating manuals and\ntheir SHA-256 digests. Use `dist/site/buildchain-contract.json` to verify the\nfloating-ref contract world for a runtime such as `@v2`.\n\n## Commands\n\n`buildchain layout` is the stable machine question for repository layout. Tools\nsuch as Shifu should call it instead of copying `.buildchain/` path constants:\n\n```bash\nbuildchain layout --cwd /path/to/repository --json\n```\n\nThe result identifies the Buildchain version pin, repository root and config,\nthe canonical and currently resolved KFD-3 registry paths, and the KFD field\nused to declare Shifu jurisdiction. A repository is in Shifu's distribution\njurisdiction only when a KFD-3 surface explicitly declares\n`distribution.registrar=\"shifu\"`; the presence of Buildchain configuration is\nnot sufficient. The same contract is available through\n`createBuildchainLayoutDiscovery()` from\n`@kungfu-tech/buildchain/buildchain-layout`.\n\n`buildchain init` writes a starter `.buildchain/buildchain.toml` and a reusable workflow\ncaller at `.github/workflows/build.yml`.\n\n`buildchain portable-cache plan` turns a consumer-owned, secret-free manifest\ninto GitHub Actions cache inputs without letting each consumer invent key or\nrestore-prefix semantics. The exact key binds source SHA and the consumer plan\ndigest; the compatible restore prefix still requires the same provider schema,\nlayer, roots, runner image, platform/architecture, toolchain, dependency lock,\nand build profile.\n\n```bash\nbuildchain portable-cache plan \\\n --manifest .buildchain/portable-cache.json \\\n --output .buildchain/portable-cache-plan.json \\\n --github-output \"$GITHUB_OUTPUT\"\n```\n\nThe emitted `cache-key`, `restore-keys`, and `cache-paths` values are intended\nfor pinned `actions/cache/restore` and `actions/cache/save` actions. After\nrestore and a consumer validation probe, seal the provider result:\n\n```bash\nbuildchain portable-cache receipt \\\n --plan .buildchain/portable-cache-plan.json \\\n --matched-key \"$CACHE_MATCHED_KEY\" \\\n --cache-hit \"$CACHE_HIT\" \\\n --validation-status pass \\\n --cold-fallback-status passed \\\n --output .buildchain/portable-cache-receipt.json\n```\n\nThe receipt distinguishes `exact`, `compatible`, `miss`, and `corrupt`.\nUnknown or contradictory provider evidence fails closed. A miss or corruption\nrequires the consumer's audited cold path; a cache never substitutes for the\nconsumer's current build or tests. Roots must be workspace-relative or under\n`~/`, and manifests cannot carry credentials, absolute host paths, or escape\nsegments. `cold-fallback-status=passed` qualifies a miss only after the current\nsource has completed its normal build and test path.\n\nSupported presets:\n\n- `--type package` for Node package repositories with pnpm, npm, or yarn.\n- `--type native` for CMake-style native projects.\n- `--type web-surface` for preview/staging/production site or app deployments.\n- `--type infra-contract` for provider-agnostic infrastructure contract\n validation, observation, contract publication, and downstream propagation\n planning without default mutation. Provider adapters expose built-in command\n plans by default, and only configured `[infra.commands]` hooks can execute.\n- `--type publication-artifact` for papers, reports, specifications, and other\n publication repositories that produce PDFs, metadata, source bundles, and\n site-consumable manifests without becoming web-surface repositories. The\n scaffold uses Buildchain's pinned\n `ghcr.io/kungfu-systems/build-images/latex-pdf-builder:v1.2.0` toolchain for\n LaTeX PDF builds.\n- `--type distribution-index` for Homebrew taps and other index repositories\n whose files are projections of upstream release passport evidence.\n- `--type anchored-package` for packages whose version is anchored to an\n explicit upstream release manifest.\n\nThe native preset includes an opt-in `[diagnostics.native]` profile with common\ntool/cache/artifact probes. Consumers can keep it enabled, adjust the tool and\ndirectory lists, or disable it if a repository does not need native diagnostics.\n\n`buildchain validate` parses `.buildchain/buildchain.toml`, checks configured version-state\nfiles, and can require named lifecycle stages:\n\n```bash\nbuildchain validate \\\n --require-version-state \\\n --require-lifecycle-stages install,build,verify\n```\n\n`buildchain lifecycle run <stage>` executes a lifecycle stage and writes the\nsame deterministic artifact manifest contract used by the reusable workflow:\n\n```bash\nbuildchain lifecycle run build \\\n --artifact-path dist \\\n --artifact-name \"{repo}-{version}-{platform}\"\n```\n\n`buildchain dev merge-queue` plans a GitHub merge-queue policy for a protected\nBuildchain dev channel. Declare every workflow that emits a required check; the\ncommand fails closed unless each file handles both `pull_request` and\n`merge_group` without reading `github.event.pull_request` directly:\n\n```bash\nbuildchain dev merge-queue \\\n --repository kungfu-systems/example \\\n --branch dev/v4/v4.0 \\\n --workflow .github/workflows/source-acceptance.yml \\\n --workflow .github/workflows/affected-native-pr.yml\n```\n\nThe default output is a read-only plan. Add `--apply` only after reviewing it.\nApply creates the exact-branch merge-queue ruleset before changing classic\nrequired status checks from strict to loose, preserves the required check\nidentities, and is safe to repeat. `gh` must be authenticated with repository\nAdministration write permission for apply mode.\n\nRepositories can make that policy declarative in `buildchain.toml`:\n\n```toml\n[governance.dev.merge_queue]\nmode = \"enabled\" # enabled, inherit, or disabled\nrequired_workflows = [\".github/workflows/verify.yml\"]\ncheck_response_timeout_minutes = 120\nmax_entries_to_build = 1\nbypass_users = [\"release-owner\"]\n```\n\nUse `buildchain dev merge-queue --from-config` to resolve and reconcile the\ndeclaration. `enabled` requires an exact queue on the target dev branch;\n`disabled` suppresses automatic queue creation; `inherit` copies the active\ndefault dev branch's queue parameters and bypass actors. When the table is\nabsent, release-line bootstrap uses the backward-compatible `inherit` mode.\nEvery inherited or explicitly enabled queue still validates each declared\nrequired workflow before any mutation. For a legacy repository with no table,\nan already-active exact queue on the current default dev branch is accepted as\nthe inheritance evidence; new declarations should list the workflows so future\nchanges are revalidated from source.\nThe `Dev Merge Queue Governance` workflow runs this reconciliation after\ngovernance-relevant changes land on a dev branch; its manual dispatch remains\ndry-run by default.\n\n`buildchain release line open` plans or writes the first version-state commit\nfor a new semver minor line. It does not publish anything. The dry-run mode is\nthe default and returns the dev/alpha/release refs, protection contract, default\nbranch action, and initial version before any GitHub mutation happens:\n\n```bash\nbuildchain release line open \\\n --major 2 \\\n --minor 10 \\\n --source-ref release/v2/v2.9 \\\n --json\n```\n\nThe write mode only updates local version-state files. The repository workflow\n`Release Line Bootstrap` wraps this command and, when `apply=true`, commits the\ninitial version state, creates `dev/vX/vX.Y`, `alpha/vX/vX.Y`, and\n`release/vX/vX.Y`, applies one-review branch protection, reconciles declared or\ninherited merge-queue governance, switches the default branch only after that\nreconciliation succeeds, and opens the first dev-to-alpha channel PR:\n\n```bash\nbuildchain release line open \\\n --major 2 \\\n --minor 10 \\\n --source-ref release/v2/v2.9 \\\n --write \\\n --json\n```\n\n`buildchain` also publishes a public surface reverse audit as\n`dist/site/public-surface-audit.json`. The audit enumerates CLI commands from\n`bin/buildchain.mjs`, workflow inputs, action inputs, site pages, and docs\ncommand references, then compares them with the generated registries. Buildchain\nself-checks fail closed when an enumerable public surface is missing from the\nregistry:\n\n```js\nimport {\n collectPublicSurfaceReverseAudit,\n assertPublicSurfaceReverseAudit,\n} from \"@kungfu-tech/buildchain/public-surface-audit\";\n\nassertPublicSurfaceReverseAudit(collectPublicSurfaceReverseAudit({ root: process.cwd() }));\n```\n\n`buildchain kfd` is the product-facing KFD namespace. Schema commands expose the\nmachine-readable KFD standards shipped by `@kungfu-tech/kfd`, while versioned\nsubcommands host concrete product workflows. KFD-1, KFD-2, and KFD-3 are\nfirst-class Buildchain surfaces. KFD-4 is schema-only until Buildchain has a\nreal verification protocol for it.\n\n`status` reports implemented support and the active repo-owned file layout.\n`migrate-layout` moves legacy root files into `.buildchain/`:\n\n```bash\nbuildchain kfd status --json\nbuildchain kfd migrate-layout --write\n```\n\nKFD-1 commands generate and validate contract-world release evidence:\n\n```bash\nbuildchain kfd 1 schema --json\nbuildchain kfd 1 witness --json\nbuildchain kfd 1 gate --witness-json kfd-1-witness.json --json\nbuildchain kfd 1 verify --gate-json kfd-1-gate.json --json\n```\n\nKFD-2 commands validate trust taxonomy entries and generate Buildchain's public\nclaim evidence. Product repositories use the `product-claims` subcommand to\nvalidate and render their own declared KFD-2 release claims under the canonical\nBuildchain KFD layout:\n\n```bash\nbuildchain kfd 2 schema --json\nbuildchain kfd 2 taxonomy --entry-json residual-risk.json --kind residualRisk --json\nbuildchain kfd 2 claims --json\nbuildchain kfd 2 product-claims check --json\nbuildchain kfd 2 product-claims write --json\nbuildchain kfd 2 product-claims render --json\n```\n\nThe default source is `.buildchain/kfd/kfd-2/registry.json`; outputs are\n`.buildchain/kfd/kfd-2/release-claims.json`, per-claim release-passport inputs\nunder `claims/`, and `buildchain-claim-args.txt`. Use `--registry` or\n`--output-dir` only for an explicit product packaging projection. `check` never\nwrites and exits non-zero when outputs drift.\n\nKFD-3 commands are separate from Buildchain's self reverse audit: products can\ndetect standard public surfaces, register the accepted boundary, audit the\ncurrent source or artifact tree, generate a release-passport-compatible witness,\nand expose a capability map for agents:\n\n```bash\nbuildchain kfd schema list --json\nbuildchain kfd schema show kfd-3 --json\nbuildchain kfd 3 detect --kind node-api --kind cli --json\nbuildchain kfd 3 register node-api --product Buildchain\nbuildchain kfd 3 audit --json\nbuildchain kfd 3 witness --kind prebuild --output .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json\nbuildchain kfd 3 query buildchain --json\nbuildchain kfd 4 schema --json\n```\n\nThe public Node API is exported from `@kungfu-tech/buildchain/kfd`. See\n[`kfd-support.md`](kfd-support.md) for the detected / declared / enforced model\nand the agent query flow.\n\nLifecycle runs also write a Buildchain observability JSONL log at\n`.buildchain/logs/events.jsonl` by default. Framework events use\n`source=buildchain`; consumer lifecycle commands use `source=user`. This lets a\nmaintainer tell apart time spent inside Buildchain's artifact/manifest\nframework from time spent in the repository's own build, test, packaging, or\npublish commands. The artifact manifest and summary embed the observability\nsummary for that lifecycle run id, so uploaded artifacts preserve the timing\nfacts without mixing in older JSONL events.\n\n`buildchain log`, `buildchain mark`, and `buildchain span` expose the same event\nprotocol to repository scripts:\n\n```bash\nbuildchain mark --event configure.ready --phase configure --attribute target=release\nbuildchain span --event native.build --phase build -- cmake --build build\nbuildchain log warn --event cache.miss --component conan --attribute token=hidden\nbuildchain log summary --json\nbuildchain verify observability-log .buildchain/logs/events.jsonl --min-events 4 --require-phase build\nbuildchain diagnostics summary .buildchain/artifacts/*/diagnostics.json --json\nbuildchain sample process-tree --label native-build --interval-ms 15000 -- make -j20\n```\n\nDuring `buildchain lifecycle run`, child processes receive\n`BUILDCHAIN_LOG_PATH` and `BUILDCHAIN_LOG_RUN_ID`. A shell, Python, CMake, Conan,\nor JavaScript helper can call `buildchain mark` or `buildchain span` mid-build\nand have those events grouped into the same lifecycle summary.\n`buildchain verify observability-log` is a release gate: it fails when the log\nis missing, has too few events, contains error events, or does not include\nrequired phases, components, or event names.\n\nThe event protocol is JSONL and is also available from the SDK:\n\n```js\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\n\nconst logger = createBuildchainLogger({ source: \"user\", component: \"native-build\" });\nlogger.mark(\"configure.ready\", { phase: \"configure\" });\n```\n\nSecret-looking attribute keys such as `token`, `password`, `secret`,\n`authorization`, `cookie`, and `private-key` are redacted before they are written.\nFull command strings are not recorded by `span`; scripts should provide stable\nevent names and safe attributes instead.\n\n`buildchain diagnostics summary` reads one or more small diagnostics artifacts\nand emits the same cross-platform summary as the diagnostics SDK:\n\n```bash\nbuildchain diagnostics summary \\\n .buildchain/artifacts/linux-x64/diagnostics.json \\\n .buildchain/artifacts/macos-arm64/diagnostics.json \\\n --output .buildchain/artifacts/diagnostics-summary.json \\\n --json\n```\n\nThe JSON summary keeps per-platform lifecycle stage tables, adds lifecycle\ntotal durations, carries top slow spans, aggregates warning/error counts, and\nsorts the slowest platforms. Each platform row carries compact runner facts,\nchecked tool versions/missing tools, package manager/cache directory details,\ncompiler-cache availability, and a compact process sampler summary: requested\nparallelism, observed max active processes, the ratio between them, sample\ncount, process categories, and the top sampled command basenames. This lets\nmaintainers inspect matrix timing, runner, tool, cache, and concurrency context\nwithout downloading large platform binaries or process sidecars first.\nWhen a sibling `diagnostics-manifest.json` is available, the summary also records\nits file list and verifies the listed `diagnostics.json` byte count and sha256.\nMissing, unreadable, or mismatched sidecar manifests are reported through\n`diagnosticsManifestWarningCount` and the per-platform `diagnosticsManifest`\nfield without failing the timing rollup.\nThe summary also compares each `diagnostics.json` contract to\n`BUILDCHAIN_DIAGNOSTICS_CONTRACT`; mismatches are reported through\n`diagnosticsContractWarningCount` and the per-platform `diagnosticsContract`\nfield so reviewers can separate diagnostics schema drift from lifecycle\nwarnings or build failures.\n\nWithout `--json`, the command prints a compact lifecycle timing table with\ninstall/build/verify/publish, artifact scan/upload, total, warning, and error\ncolumns for each platform, plus `jobs` and `active` columns for requested and\nobserved process concurrency when sampler data is present.\n\n`buildchain facts` collects and verifies source/version/output facts for\nmodules and products:\n\n```bash\nbuildchain facts module \\\n --module native-core \\\n --output .buildchain/facts/native-core.json \\\n --legacy-kungfu-buildinfo framework/core/src/kungfu/yijinjing/kungfubuildinfo.json\n\nbuildchain facts aggregate \\\n --product kungfu \\\n --module-fact .buildchain/facts/native-core.json \\\n --artifact dist/kungfu.zip \\\n --output .buildchain/facts/kungfu.json\n\nbuildchain facts verify --fact .buildchain/facts/kungfu.json\n```\n\nThe same implementation is available from\n`@kungfu-tech/buildchain/build-facts`. Release passports can include these\nfacts with repeated `--build-facts-json` arguments to\n`buildchain collect github-release`. See\n[`build-facts.md`](build-facts.md) for the config schema and Node API.\n\n`buildchain sample process-tree` wraps a long-running command and periodically\nwrites process-tree snapshots:\n\n```bash\nbuildchain sample process-tree \\\n --label native-build \\\n --interval-ms 15000 \\\n --output .buildchain/diagnostics/process-samples.jsonl \\\n --summary-output .buildchain/diagnostics/process-summary.json \\\n -- \\\n make -j20\n```\n\nThe command returns the wrapped command's exit status. The JSONL file contains\nsmall timestamped samples; the summary JSON records requested parallelism,\nobserved concurrency, sampled CPU, command categories, and top command\nbasenames. Use it when a native build requests high parallelism but appears to\nspend long stretches in low-concurrency compile, archive, link, or cache steps.\n\n`buildchain doctor` checks repository readiness before remote side effects:\n\n```bash\nbuildchain doctor --json\n```\n\nIt validates `.buildchain/buildchain.toml`, package-manager detection, Git repository state,\nand the reusable workflow caller. For `version.strategy = \"anchored\"` with\n`version.next = \"manual\"`, it also embeds the anchored package release contract\ncheck: anchor manifest readability, configured version files, trusted\npublishing, package publish order, and required lifecycle stages. Add\n`--require-publish-source-lock` inside a publish job when the doctor report\nshould also fail unless the job is running from a resolved `publish-gate/*`\nsource lock.\n\nAnchored/manual package publish jobs can run the narrower source-lock gate\ndirectly:\n\n```bash\nbuildchain publish-source validate-anchored-release --json\n```\n\nThe command requires `BUILDCHAIN_PUBLISH_SOURCE_REF`,\n`BUILDCHAIN_PUBLISH_SOURCE_SHA`, and `BUILDCHAIN_PUBLISH_SOURCE_LOCKED` from the\nreusable build workflow outputs. It fails closed for direct `alpha/*` or\n`release/*` channel-branch publication, and checks the publish-gate consumer\nversion against configured version files and the anchor manifest. The JSON\nresult is shaped for future `buildchain.libkungfu.dev` fact ingestion.\n\n`buildchain release`, `buildchain web-surface`, `buildchain infra-contract`,\n`buildchain publication-artifact`, `buildchain publish-source`,\n`buildchain badges`, `buildchain homebrew`, and `buildchain build-contract`\nroute to the same implementation used by\nBuildchain's package APIs or GitHub Actions workflows. This keeps local\ninspection and CI behavior on the same implementation path.\n\nGenerate publication artifact metadata after building a paper or report:\n\n```bash\nbuildchain publication-artifact manifest \\\n --source-sha \"$(git rev-parse HEAD)\" \\\n --json\n```\n\nGenerate the Buildchain-owned npm paper package contents from declared\npublication facts:\n\n```bash\nbuildchain publication-artifact npm-package --json\n```\n\nThis command reads `project.type = \"publication-artifact\"`,\n`publication.version`, and `[publish] kind = \"npm-paper-package\"` plus\n`publish.package`; it writes `.buildchain/publication/npm-package` by default.\nThe `paper-release.yml@v2` reusable workflow uses the same command before\nrunning the standard npm publish transaction.\n\nThe command writes `.buildchain/publication/publication-artifact.json`,\n`.buildchain/publication/publication-artifact-passport.json`, a source bundle,\nand, when `[publication.archive]` is configured,\n`.buildchain/publication/publication-registry.json` by default. See\n[`publication-artifacts.md`](publication-artifacts.md) for the repository\ncontract, pinned LaTeX builder, and reusable workflow.\n\nGenerate, check, or update the managed README badge block:\n\n```bash\nbuildchain badges readme --json\nbuildchain badges readme --check\nbuildchain badges readme --write\nbuildchain badges bundle --json\nbuildchain badges bundle --check\nbuildchain badges bundle --write\nbuildchain badges bundle --claims kfd-1,release-passport --write\n```\n\nThe `--json` form emits the `kungfu-buildchain-readme-badge-facts` object.\n`--check` fails closed when the README marker block is missing or stale.\n`--write` inserts or replaces only the marked block. KFD passed badges come\nfrom the repository's own verified release passport; unreleased repositories\ndowngrade to explicit local declarations such as `declared`, `aligned`, or\n`planned`. `buildchain badges bundle` is the focused trust-badge entrypoint: it\nemits `kungfu-buildchain-badge-bundle-facts` and defaults to KFD-1, KFD-2,\nKFD-3, and Release Passport. See [`readme-badges.md`](readme-badges.md) for the\nmarker contract and `[badges]` / `[badges.bundle]` configuration.\n\nGenerate or check Homebrew tap projections from upstream release passports:\n\n```bash\nbuildchain homebrew update-formula \\\n --package buildchain \\\n --release-passport https://github.com/kungfu-systems/buildchain/releases/download/v2.8.15/buildchain.release.json \\\n --write\n\nbuildchain homebrew check --json\n```\n\n`update-formula` writes `Formula/buildchain.rb` and `tap-manifest.json` from\nupstream release passport evidence. `check` fails closed when the Formula,\nmanifest, artifact digests, or KFD status drift from the upstream passport. See\n[`homebrew.md`](homebrew.md) for the distribution-index project contract.\n\n`buildchain collect github-release` creates a release passport bundle from\nGitHub Release assets or a local asset directory:\n\n```bash\nbuildchain collect github-release \\\n --tag v2.2.0 \\\n --repository kungfu-systems/buildchain \\\n --assets-dir dist \\\n --output-dir .buildchain/release-passport\n```\n\nThe bundle includes `buildchain.release.json`, `artifact-evidence.json`,\n`impact.json`, `agent-index.json`, `product-mechanism.json`, `check-report.json`,\nand `llms.txt`. Production binary distribution defaults to GitHub-hosted\nrunners so other projects can reproduce the release lane; self-hosted runners\nremain compatibility fixtures and are recorded as runner facts when used.\n\nFor publish-transaction releases, pass the additional evidence inputs so\n`buildchain.release.json` becomes the unified passport instead of a binary-only\nasset summary:\n\n```bash\nbuildchain collect github-release \\\n --tag v2.3.2 \\\n --repository kungfu-systems/buildchain \\\n --assets-dir dist \\\n --publish-evidence-json .buildchain/release-evidence/v2.3.2/evidence.json \\\n --transaction-json .buildchain/release-state/v2.3.2/state.json \\\n --package-set-json package-set.json \\\n --impact-json impact.json \\\n --trusted-publishing-json trusted-publishing.json \\\n --anchor-manifest-json libnode.release.json \\\n --build-summary-json .buildchain/artifacts/build-summary.json \\\n --platform-manifest-json .buildchain/artifacts/linux-x64/manifest.json \\\n --platform-manifest-json .buildchain/artifacts/darwin-arm64/manifest.json \\\n --platform-manifest-json .buildchain/artifacts/win32-x64/manifest.json \\\n --dist-tag-evidence-json .buildchain/release-evidence/v2.3.2/dist-tag-evidence.json \\\n --kfd-1-witness-json .buildchain/kfd/kfd-1/contract-world.witness.json \\\n --kfd-2-claim-json .buildchain/kfd/kfd-2/release-claims.json \\\n --kfd-3-prebuild-witness-json .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json \\\n --kfd-3-artifact-verify-cmd \"kungfu agent verify --json\" \\\n --release-extra-json '{\"channel\":\"release\",\"targetRef\":\"release/v2/v2.3\"}' \\\n --output-dir .buildchain/release-passport\n```\n\nThe generated passport records the main and platform packages, npm dist-tags,\npublished versions, release source/ref state, anchor manifest digest, registry\nartifact digests, trusted publishing evidence, and Buildchain transaction\nresult. It also records `buildSummary`, `platformArtifactManifests`, and\n`distTagPromotion` when those JSON inputs are supplied. `packageSet` keeps the\nordered package set; `publish.packages[]` is the agent-readable npm publication\nsummary for each main/platform package. For Buildchain releases, verification\nexpects the supplied package set to include the main package plus the three\nplatform packages with version, dist-tag, and digest evidence. Verification\nfails closed if supplied sections are internally incomplete or point to\nartifacts without matching evidence.\n\n`--kfd-1-witness-json` attaches a KFD-1 contract-world release gate. The witness\nis structured JSON: consumers declare the contract world, canonical JSON policy,\nartifact paths, and expected SHA-256 digests. Buildchain imports KFD-owned\nmetadata from `@kungfu-tech/kfd`, freezes the witness before build publication,\nthen verifies the resulting artifact bytes itself and writes the evidence under\nthe KFD-provided top-level key currently named `kfd-1`. Consumers should not\nduplicate this by running repository-specific scripts or invoking the Kungfu\nSDK from their release workflow.\n\nFor the KFD repository, KFD-1 witnesses may be self-hosted standard-contract\nwitnesses: docs, schemas, standards metadata, package exports, and\nsite-consumption entrypoints are checked from source hashes to packaged artifact\nhashes, and the passport records schema IDs, self-hosting boundary, result, and\nresponsibility state.\n\n`--kfd-2-claim-json` attaches explicit public release claims to the KFD-2\nrelease trust passport audit. Buildchain also derives KFD-2 claims from KFD-1\nand KFD-3 gate evidence. Public claims must 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 and emit a\nwarning.\n\n`--kfd-3-prebuild-witness-json` attaches a KFD-3 collaboration-interface\nrelease gate. The product remains the source of truth: it emits a pre-build\nwitness that contains or points to its KFD-3 collaboration interface, declared\nparticipant-facing public surfaces, and registry digest. Buildchain freezes\nthat declaration before publication. The artifact side is supplied either by\n`--kfd-3-artifact-witness-json` or by a product-owned command such as\n`--kfd-3-artifact-verify-cmd \"kungfu agent verify --json\"`. Buildchain then\nchecks closure: every declared shipped public surface must be present in the\nartifact witness, and every artifact-exposed participant-facing public surface\nmust have been declared. The generated passport writes this evidence under the\nKFD-provided top-level key currently named `kfd-3`.\n\nThis gate is useful for agent-facing products because it turns KFD-3 from prose\ninto release evidence. A package cannot claim KFD-3 collaboration-interface\nsupport merely because the docs mention it; the release passport must show the\nfrozen declaration, the artifact-side witness digest, and a passing closure\ncomparison.\n\n`--invariant-passport-json` attaches a product-owned invariant Passport to the\nrelease gate and may be repeated. `--invariant-passport-cmd` runs a product\ncommand that emits one Passport JSON document. Buildchain verifies the\nPassport root, exact clean source identity, `verified` verdict, complete\nplatform coverage, and residual-risk shape; it does not redefine the product's\ninvariant semantics. Declared invariant Passport input is fail-closed.\nFor the KFD repository itself, the witness can declare docs, schemas, standards\nmetadata, package exports, and site-consumption contracts as grouped public\nsurfaces; the artifact witness must expose the same enumerable package/site\nsurfaces or verification fails closed.\n\n`--impact-json` supplies the surface-aware impact ledger. Production release\npassports (`release/*`) and major publish-gate passports require\n`surfaceImpacts[]`; alpha, local, and legacy passport contexts keep it\noptional. When `surfaceImpacts[]` is required or supplied, the verifier requires\neach entry to include an id, impact, and rationale, and requires\n`versionImpact.final` to match the highest declared surface impact. The\ncollector copies `versionImpact` plus `surfaceImpacts` into\n`buildchain.release.json`. This lets\n`buildchain explain release --for agent --json` state why a release is patch,\nminor, or major instead of relying on file-path memory.\n\nFor a promote-only stable transaction, Buildchain can derive a patch-level\nrelease-governance ledger when the PR-stage release-candidate passport proves\nthe stable source tree is exactly the previously qualified candidate tree.\nThis fallback is unavailable when candidate evidence is absent, stale, or not\ntree-equivalent.\n\nBuildchain dogfoods its observability toolkit in this lane. The standalone\nbuilder writes API-generated events, while the workflow uses `buildchain mark`,\n`buildchain span`, `buildchain verify observability-log`, and `buildchain log\nsummary`; the event logs and summaries are published as release passport assets.\n\nVerify and explain release passports:\n\n```bash\nbuildchain verify release-passport .buildchain/release-passport/buildchain.release.json\nbuildchain explain release --passport .buildchain/release-passport/buildchain.release.json --for agent --json\nbuildchain inspect release --passport .buildchain/release-passport/buildchain.release.json\n```\n\nThe verifier fails closed when required protocol files are absent, artifacts are\nnot covered by evidence, or digests disagree. The explanation output is shaped\nfor agents: trust, completeness, impact, recovery route, and next action.\n\nVerify a published artifact by subject:\n\n```bash\nbuildchain verify artifact ./Kungfu-2.8.0-windows-x64.exe\nbuildchain inspect artifact ./Kungfu-2.8.0-windows-x64.exe --json\nbuildchain explain artifact ./Kungfu-2.8.0-windows-x64.exe --for agent --json\nbuildchain verify artifact npm:@kungfu-tech/libnode@22.22.3-kf.3-alpha.18 \\\n --repository kungfu-systems/libnode \\\n --tag v22.22.3-kf.3-alpha.18 \\\n --json\n```\n\n`verify artifact` computes or obtains the subject digest, discovers the\ndetached release passport, verifies the passport, then requires that the\nsubject digest appears in the passport's release assets, package set, publish\nevidence, or artifact evidence. Outcomes are explicit: `pass`, `fail`, or\n`unverifiable`. A filename is only a hint; trust comes from digest equality.\nFor `npm:<name>@<version>` subjects, Buildchain resolves `dist.integrity` from\nthe npm registry before matching passport evidence. Use `--npm-registry <url>`\nto verify packages from a custom registry; otherwise Buildchain uses\n`npm_config_registry` or `https://registry.npmjs.org/`.\n\nDiscovery is fail-closed and ordered:\n\n1. `--passport <file-or-url>`.\n2. Sidecar pointer, such as `<artifact>.buildchain-passport.json`.\n3. Embedded/package pointer, such as `package.json` `buildchain.releasePassport`.\n4. Local config or org index, such as `.buildchain/artifact-passport-locators.json`.\n5. GitHub Release default discovery from `github-release:` subjects, GitHub\n Release asset URLs, or `--repository <owner/repo> --tag <tag>`.\n6. Custom `--locator-config <json-or-url>`.\n7. `unverifiable` with retry guidance.\n\nLocator files are policy, not protocol. They map subject fields such as\n`name`, `kind`, `version`, `digest`, `repository`, or `tag` to a detached\npassport location:\n\n```json\n{\n \"schemaVersion\": 1,\n \"contract\": \"kungfu-buildchain-artifact-passport-locator\",\n \"locators\": [\n {\n \"match\": {\n \"name\": \"Kungfu-2.8.0-windows-x64.exe\",\n \"digest\": \"sha256:...\"\n },\n \"passport\": \"../release-passport/buildchain.release.json\"\n }\n ]\n}\n```\n\nSupported subject shapes include local files and directories, URLs,\n`npm:<name>@<version>`, `oci:...`, `s3:...`,\n`github-release:<owner/repo>@<tag>/<asset>`, and deployment endpoints. Local\nfiles, directories, and URLs are digestable directly; remote package, OCI,\nobject storage, and deployment subjects should provide a digest or resolve to a\nlocator that records one.\n\nSeal an exact artifact verification with the Node API, then verify or project\nthe resulting KFX admission envelope without reconstructing its roots:\n\n```bash\nbuildchain verify artifact-envelope envelope.json \\\n --assessment-time 150 \\\n --expected-root sha256:... \\\n --expected-issuer buildchain.libkungfu.dev \\\n --expected-publisher kungfu-systems \\\n --expected-contract buildchain.release/v1 \\\n --json\n\nbuildchain project kfx-admission envelope.json \\\n --assessment-time 150 \\\n --json\n```\n\nBoth commands call the public artifact-verification-envelope verifier. The\nprojected `attestation`, `trustInputs`, and `kfdAssessment` are direct copies of\nthe sealed envelope, and `envelopeRoot` stays identical across Node and CLI.\nSee [`artifact-verification-envelope.md`](artifact-verification-envelope.md).\n\nVerify infra-contract lifecycle evidence bundles:\n\n```bash\nbuildchain infra-contract --mode ci --source-sha \"$GITHUB_SHA\"\nbuildchain verify infra-contract-evidence-bundle .buildchain/infra-contract-evidence-bundle.json\n```\n\nThe infra-contract `ci` mode is mutation-free. It writes validate, plan,\ncontract, propagation dry-run, evidence bundle, and verification JSON artifacts\nunder `.buildchain/`, giving reusable workflows one standard responsibility\nchain instead of hand-written command sequences.\n\nThe infra-contract verifier is read-only. It recomputes the bundle hash and\nchecks that desired, plan, approval, apply, observe, contract, and propagate\nevidence remain bound to the same contract artifact. It also recomputes the\nbundle validation summary, so stale or misleading summary booleans fail closed\neven when the bundle hash has been refreshed.\n\n`buildchain release --dry-run` explains the release-line state machine before a\nmaintainer opens or merges a channel PR:\n\n```bash\nbuildchain release --dry-run --target-ref alpha/v2/v2.2\nbuildchain release --dry-run --target-ref release/v2/v2.2 --sha <verified-sha>\nbuildchain release dry-run --target-ref publish-gate/major --source-ref release/v2/v2.2\nbuildchain release explain --target-ref alpha/v2/v2.1 --json\n```\n\nThis is a Buildchain-level dry-run, not an npm dry-run. It explains the legal\nsource branch, exact release or alpha tags, floating tags, channel branches,\nversion-state files, governance checks, and publish transaction behavior that\nwould apply if the corresponding PR merge were promoted. It does not move\nbranches, move tags, edit files, publish npm packages, or run lifecycle publish\ncommands. `release explain` is the same explanation surface with a clearer name.\nPass `--json` for a machine-readable plan.\n\n`buildchain transaction inspect` is the top-level recovery inspection command\nfor the publish transaction state:\n\n```bash\nbuildchain transaction inspect --version v2.1.0-alpha.0\n```\n\nIt reads or locally initializes the durable transaction record and validates\navailable publish evidence. Remote durable refs and public Git ref finalization\nremain owned by `actions/promote-buildchain-ref`; the CLI inspection surface is\nfor preflight and recovery reasoning before a maintainer reruns or resumes a\npromotion.\n\n`buildchain npm dry-run` verifies the package shape before a release tag exists:\n\n```bash\nbuildchain npm dry-run --json\n```\n\nThe command validates `package.json`, infers the exact release tag\n`v${package.json.version}`, chooses npm dist-tag `alpha` for prereleases and\n`latest` for stable releases, runs `npm pack --dry-run --json`, and then runs\n`npm publish --dry-run --access public --tag <alpha|latest>` unless\n`--skip-npm-publish-dry-run` is passed. It never performs a real publish.\n\n## npm Publish Gate\n\nBuildchain's own npm package is published from\n`.github/workflows/buildchain-ref-promotion.yml`, inside the same publish\ntransaction that promotes release refs:\n\n- `v2.0.13-alpha.0` publishes to npm with dist-tag `alpha`.\n- `v2.0.13` publishes to npm with dist-tag `latest`.\n- moving refs such as `v2`, `v2.0`, and `v2.0-alpha` do not match the publish\n workflow and do not publish.\n\nThe promotion workflow uses npm Trusted Publishing through GitHub Actions OIDC.\nIt runs on a GitHub-hosted runner with `id-token: write`, but it does not\nmanually run the release-candidate resolver or promote action. Buildchain's own\ndogfood path calls the declarative `release-candidate-promote.yml` wrapper with\nchannel, target ref/SHA, PR-stage workflow, artifact, status-check, and passport\ninputs. The wrapper generates the version-state commit, runs\n`lifecycle.verify`, runs `lifecycle.publish`, writes Buildchain publish\nevidence, validates that evidence, and only then moves exact tags and floating\nrefs.\n\n```bash\nnode scripts/npm-publish-transaction.mjs\n```\n\nBefore the first real release, configure npm Trusted Publishing for:\n\n- package: `@kungfu-tech/buildchain`\n- repository: `kungfu-systems/buildchain`\n- workflow: `.github/workflows/buildchain-ref-promotion.yml`\n\nNo npm package is published by manual dispatch or ordinary branch builds.\nManual dispatch on `.github/workflows/npm-publish.yml` remains dry-run only, so\nmaintainers can verify package contents and npm publish shape before opening or\nmerging the release PR."
|
|
472
472
|
},
|
|
473
473
|
{
|
|
474
474
|
"id": "manual:consumer-issue-reporting",
|
|
@@ -918,7 +918,7 @@
|
|
|
918
918
|
],
|
|
919
919
|
"maturity": "stable",
|
|
920
920
|
"sourcePath": "docs/migration-inventory.md",
|
|
921
|
-
"digest": "sha256:
|
|
921
|
+
"digest": "sha256:a5f7271a065544f7ac525dbddfe3d4b9f621b5284c730089f086dd9f961e883c",
|
|
922
922
|
"headings": [
|
|
923
923
|
{
|
|
924
924
|
"level": 1,
|
|
@@ -966,7 +966,7 @@
|
|
|
966
966
|
"anchor": "verification-gates"
|
|
967
967
|
}
|
|
968
968
|
],
|
|
969
|
-
"markdown": "# Buildchain v2 Migration Inventory\n\nThis inventory records the buildchain v2 action surface. Buildchain v2 is the\nmonorepo source of truth for active Kungfu repository workflows, the active\nreusable build workflow, and the three GitHub Actions that are still part of\nBuildchain's reusable contract.\nStandalone `workflows` and `action-*` repositories are historical rollback\nanchors, not active Buildchain migration targets.\n\n## Workflow Sources\n\n| Source repository | Previous branch | Buildchain v2 disposition |\n| --- | --- | --- |\n| `workflows` | `dev/v2/v2.0` | root `.github/workflows` sources migrated; reusable workflows linted by actionlint |\n\n## Reusable Workflow Boundaries\n\nThe active Buildchain-native reusable surface is:\n\n| Workflow | Disposition |\n| --- | --- |\n| `.github/workflows/.build.yml` | active reusable build contract: runner presets, trusted event gate, publish source lock, lifecycle commands, deterministic artifacts, aggregate summary, and release manifest outputs |\n\nHidden reusable workflow files from the old `workflows` repository are retained\nonly when they still have an active compatibility or migration boundary. Retired\nPR orchestration paths are not kept in `.github/workflows`; they remain listed\nin the inventory as excluded legacy surfaces. In particular,\n`.batch-pull-request.yml` is removed with the retired batch PR action family,\nand the legacy `.release-new-version.yml` path is not the modern publish\nsurface. New publish integrations should use `.build.yml`, `buildchain.toml`,\n`lifecycle.publish`, and publish transaction evidence.\n\nRelease templates that previously performed direct publishing or deployment are\nnow fail-closed when retained for compatibility discovery. They do not call\nlegacy publish actions, `npm publish`, or deploy providers directly. Callers must\nmigrate to `release-candidate-promote.yml@v2` or a project-owned\n`lifecycle.publish` command behind a publish-gate source lock, so floating\n`@v2` consumers cannot bypass source-lock drift protection.\n\nThe public promotion workflow is now a generated dual-channel router. Existing\ncallers remain source-compatible, while callers that want alpha workflow-shell\nfixes before stable promotion should add `buildchain-channel: auto` plus\n`buildchain-alpha-contract-lock-path` and\n`buildchain-stable-contract-lock-path`. Keep one common promotion declaration;\ndo not duplicate alpha and stable jobs or call\n`.release-candidate-promote.yml` directly.\n\nBuildchain also keeps the workflow-file layout transition declarative in\n`.buildchain/promotion-shell-routing.json`. Stable `v2.14.
|
|
969
|
+
"markdown": "# Buildchain v2 Migration Inventory\n\nThis inventory records the buildchain v2 action surface. Buildchain v2 is the\nmonorepo source of truth for active Kungfu repository workflows, the active\nreusable build workflow, and the three GitHub Actions that are still part of\nBuildchain's reusable contract.\nStandalone `workflows` and `action-*` repositories are historical rollback\nanchors, not active Buildchain migration targets.\n\n## Workflow Sources\n\n| Source repository | Previous branch | Buildchain v2 disposition |\n| --- | --- | --- |\n| `workflows` | `dev/v2/v2.0` | root `.github/workflows` sources migrated; reusable workflows linted by actionlint |\n\n## Reusable Workflow Boundaries\n\nThe active Buildchain-native reusable surface is:\n\n| Workflow | Disposition |\n| --- | --- |\n| `.github/workflows/.build.yml` | active reusable build contract: runner presets, trusted event gate, publish source lock, lifecycle commands, deterministic artifacts, aggregate summary, and release manifest outputs |\n\nHidden reusable workflow files from the old `workflows` repository are retained\nonly when they still have an active compatibility or migration boundary. Retired\nPR orchestration paths are not kept in `.github/workflows`; they remain listed\nin the inventory as excluded legacy surfaces. In particular,\n`.batch-pull-request.yml` is removed with the retired batch PR action family,\nand the legacy `.release-new-version.yml` path is not the modern publish\nsurface. New publish integrations should use `.build.yml`, `buildchain.toml`,\n`lifecycle.publish`, and publish transaction evidence.\n\nRelease templates that previously performed direct publishing or deployment are\nnow fail-closed when retained for compatibility discovery. They do not call\nlegacy publish actions, `npm publish`, or deploy providers directly. Callers must\nmigrate to `release-candidate-promote.yml@v2` or a project-owned\n`lifecycle.publish` command behind a publish-gate source lock, so floating\n`@v2` consumers cannot bypass source-lock drift protection.\n\nThe public promotion workflow is now a generated dual-channel router. Existing\ncallers remain source-compatible, while callers that want alpha workflow-shell\nfixes before stable promotion should add `buildchain-channel: auto` plus\n`buildchain-alpha-contract-lock-path` and\n`buildchain-stable-contract-lock-path`. Keep one common promotion declaration;\ndo not duplicate alpha and stable jobs or call\n`.release-candidate-promote.yml` directly.\n\nBuildchain also keeps the workflow-file layout transition declarative in\n`.buildchain/promotion-shell-routing.json`. Stable `v2.14.12` contains the hidden\nadvanced workflow, so the stable lane is pinned to that implementation's\nimmutable release SHA and forwards the full internal identity surface. This is\nprovider-owned compatibility state; consumers still keep the same single public\npromotion job.\n\n## Migrated Actions\n\nNo standalone `action-*` repository is shipped as a Buildchain action anymore.\nOld product, operations, PR-helper, page-generation, dependency-sync, and\nversion-bump actions have either been retired or absorbed into Buildchain's\nnative lifecycle, reusable workflow, and promotion scripts.\n\n## Retired Actions Excluded From v2\n\nThese legacy action repositories are intentionally not shipped as buildchain v2\nactions because the corresponding workflows now reject the retired mechanism or\nbecause the action is part of that retired path.\n\n| Previous repository | Reason |\n| --- | --- |\n| `action-approve` | retired GitHub issue/PR helper; use repository-native GitHub automation |\n| `action-batch-pull-request` | retired PR orchestration helper; not part of the Buildchain reusable contract |\n| `action-bump-version` | replaced by Buildchain release-line scripts and `actions/promote-buildchain-ref` |\n| `action-check-format` | replaced by project-owned `lifecycle.verify` commands |\n| `action-find-dependencies` | retired in workflows v2 or backed by retired Airtable/dependency/collaborator/purge mechanism |\n| `action-generate-download-page` | retired product page generator; model as project-owned lifecycle/deploy work if needed |\n| `action-generate-release-page` | retired product page generator; model as project-owned lifecycle/deploy work if needed |\n| `action-merge-close-issue` | retired GitHub issue/PR helper; use repository-native GitHub automation |\n| `action-package-dependency` | retired in workflows v2 or backed by retired Airtable/dependency/collaborator/purge mechanism |\n| `action-publish-prebuilt` | retired S3 prebuilt publisher; use lifecycle publish plus publish transaction evidence |\n| `action-purge-artifacts` | retired in workflows v2 or backed by retired Airtable/dependency/collaborator/purge mechanism |\n| `action-qa-automated` | retired external QA trigger; model as project-owned lifecycle or workflow logic |\n| `action-release-note` | retired in workflows v2 or backed by retired Airtable/dependency/collaborator/purge mechanism |\n| `action-rollback-release` | replaced by Buildchain publish transaction recover/finalize/repair semantics |\n| `action-set-collaborators` | retired in workflows v2 or backed by retired Airtable/dependency/collaborator/purge mechanism |\n| `action-sync-airtable` | retired in workflows v2 or backed by retired Airtable/dependency/collaborator/purge mechanism |\n| `action-sync-extensions-version` | retired in workflows v2 or backed by retired Airtable/dependency/collaborator/purge mechanism |\n| `action-sync-pr` | retired PR synchronization helper; not part of the Buildchain reusable contract |\n| `action-update-dependencies-version` | retired dependency-version helper; use package-manager adapters and lifecycle commands |\n\n## Retired Workflows Excluded From v2\n\nThese legacy workflow entrypoints are intentionally not shipped from the root\n`.github/workflows` directory.\n\n| Previous workflow | Reason |\n| --- | --- |\n| `.batch-pull-request.yml` | retired PR orchestration helper; v2.5 dev integration governance will use a new protected-dev PR protocol instead |\n| `.release-new-version.yml` | retained as a fail-closed compatibility stub; direct publish model replaced by source-locked release-candidate promotion |\n| `.release-elastic-beanstalk.yml` | retained as a fail-closed compatibility stub; deploy side effects must move behind project lifecycle publish and publish-gate source locks |\n| `.sam-release.yml` | retained as a fail-closed compatibility stub; deploy side effects must move behind project lifecycle publish and publish-gate source locks |\n| `.wheel-release.yml` | retained as a fail-closed compatibility stub; package publish side effects must move behind project lifecycle publish and publish-gate source locks |\n\n## Buildchain-Native Actions\n\nThese actions are new Buildchain v2 surfaces rather than migrations from an\nolder standalone action repository.\n\n| Buildchain path | Purpose |\n| --- | --- |\n| `actions/promote-buildchain-ref` | governance-closed Buildchain release ref promotion |\n| `actions/run-lifecycle` | lifecycle command execution and deterministic artifact manifest generation |\n| `actions/validate-config` | `buildchain.toml` version-state and lifecycle preflight without executing lifecycle commands |\n\n## Stable v2 Refs\n\n- Actions: `kungfu-systems/buildchain/actions/<name>@v2`\n- Reusable workflows: `kungfu-systems/buildchain/.github/workflows/<workflow>.yml@v2`\n\n## Verification Gates\n\n- `pnpm install --frozen-lockfile`\n- `pnpm run check`\n- GitHub-hosted `Verify` workflow\n- Manual `Self-hosted Runner Smoke` workflow for trusted self-hosted runner validation"
|
|
970
970
|
},
|
|
971
971
|
{
|
|
972
972
|
"id": "manual:observed-evidence-patrol",
|
|
@@ -1531,7 +1531,7 @@
|
|
|
1531
1531
|
],
|
|
1532
1532
|
"maturity": "stable",
|
|
1533
1533
|
"sourcePath": "docs/release-passport.md",
|
|
1534
|
-
"digest": "sha256:
|
|
1534
|
+
"digest": "sha256:f10d2f0f9cc694976b2a1d2a61195ed155c1bc24c964de1551475882e8197c92",
|
|
1535
1535
|
"headings": [
|
|
1536
1536
|
{
|
|
1537
1537
|
"level": 1,
|
|
@@ -1579,7 +1579,7 @@
|
|
|
1579
1579
|
"anchor": "binary-distribution"
|
|
1580
1580
|
}
|
|
1581
1581
|
],
|
|
1582
|
-
"markdown": "# Release Passport\n\nBuildchain Release Passport is the core product mechanism: a mature product\nrelease record for artifacts that users or agents depend on.\n\nThe protocol is GitHub-native because it uses protected refs, reviewed\npromotion PRs, exact tags, GitHub Releases, npm Trusted Publishing, and\nmachine-readable evidence. A project can keep its existing build system and use\nBuildchain to make the release record auditable.\n\nRelease-candidate and final passports may also include compact\n`controllerReceipts[]` references. These bind a real reusable-workflow receipt\nto its plan digest, consumer source SHA, and exact Buildchain runtime SHA; they\ndo not infer execution evidence from a green job. See\n[`controller-evidence.md`](controller-evidence.md).\n\n## Contract\n\nThe release passport surface is a welded contract. Additive fields are allowed;\nbreaking semantic changes require a new major line.\n\nIndependent verifiers can pin two package-owned, standalone files without\nscraping this implementation:\n\n- `dist/site/schemas/release-passport-v1.schema.json` is the self-contained\n JSON Schema for the Buildchain-owned envelope;\n- `dist/site/release-passport-check-manifest.json` names the normative checker,\n required and conditional sibling evidence, local-resolution rules,\n Buildchain aggregation fields, canonical KFD subsection schema authorities,\n and forward-compatibility policy.\n\nThe same files are exported as\n`@kungfu-tech/buildchain/site/schemas/release-passport-v1.schema.json` and\n`@kungfu-tech/buildchain/site/release-passport-check-manifest.json`. The schema\nchecks the envelope shape. `buildchain verify release-passport` remains the\nnormative semantic checker: it resolves sibling evidence relative to the\npassport and fails closed on missing evidence, digest drift, or inconsistent\nrelease facts. Buildchain owns envelope aggregation; KFD retains schema and\ncompatibility authority for the `kfd-1`, `kfd-2`, and `kfd-3` subsections.\n\nP0 protocol artifacts:\n\n- `product-mechanism.json`\n- `buildchain.release.json`\n- `artifact-evidence.json`\n- `impact.json`\n- `agent-index.json`\n- `check-report.json`\n- `llms.txt`\n- `buildchain-release-bundle.json`\n- `buildchain-release-bundle.tar.gz`\n\n`buildchain.release.json` is the first file an agent should read. It points to\nartifact evidence, impact, recovery, product mechanism, and agent index facts.\nIt is also the unified release responsibility summary: when publish\ntransactions are used, the same passport records the package set, npm dist-tags,\nrelease source refs, release-state ref, anchor manifest, registry artifact\ndigests, trusted publishing evidence, and transaction result.\n\nAdditive passport sections:\n\n- `release`: public release tag, internal transaction tag, line, channel,\n source SHA, target ref, release SHA, release material SHA, publish tooling\n SHA, and durable release-state ref. Anchored/manual package releases use the\n published package version for the public tag while preserving the internal\n exact transaction tag for Buildchain recovery.\n- `versionImpact`: final patch/minor/major classification, source, and\n rationale.\n- `surfaceImpacts`: per registered surface classification. The final impact is\n the highest entry in this list.\n- `packageSet`: main package, platform packages, package-set order, registry,\n versions, dist-tags, and package digests.\n- `anchorManifest`: anchored/manual version manifest path, digest, and fields.\n- `trustedPublishing`: provider, auth mode, workflow run evidence, and whether\n trusted publishing was enabled.\n- `transaction`: durable Buildchain release transaction id, state, exact tag,\n release SHA, state ref, and state SHA.\n- `surfaceTimestampPolicy`: the common Buildchain surface manifest timestamp\n policy. It records real CI/release generation and publication times,\n reproducibility inputs, source revision or source-date-epoch, and whether\n timestamp fields participate in the release artifact digest.\n- `buildFacts`: module/product build facts that bind Git source digests,\n version sources, lifecycle invocations, platforms, outputs, product\n artifacts, and verification results to the release.\n- `artifacts`: release assets and registry artifacts in one list, each pointing\n back to the evidence file that proves its digest. Registry artifacts retain\n optional built/reused action, content and current-release coordinates,\n platform/contract/parent metadata, and fail-closed verification evidence.\n- `invariantPassports`: product-owned invariant verification results admitted\n by Buildchain. Each entry binds the product contract and registry roots,\n semantic Passport root, exact clean source revision, complete platform\n coverage, verdict, and residual risk. Buildchain owns release admission, not\n the meaning of the product invariants.\n\nBuildchain's own binary lane also publishes observability artifacts generated by\nthe Buildchain logging API and CLI:\n\n- `buildchain-log-events-<platform>.jsonl`\n- `buildchain-log-summary-<platform>.json`\n- `buildchain-log-events-passport.jsonl`\n- `buildchain-log-summary-passport.json`\n\n`buildchain-release-bundle.tar.gz` is the single evidence bundle for consumers\nthat want one file for offline inspection, mirroring, or site ingestion.\n`buildchain-release-bundle.json` records its digest and the digest of every\nincluded file.\n\n## Runner Policy\n\nProduction binary distribution should use GitHub-hosted runners by default:\n\n- `ubuntu-24.04`\n- `macos-latest`\n- `windows-2022`\n\nThis keeps the public release path easy for other projects to reproduce.\nSelf-hosted runners remain compatibility fixtures: they prove that the protocol\ndoes not depend on GitHub-hosted images, but they are not the default public\ndistribution lane.\n\nThe protocol records runner facts in `artifact-evidence.json`; it does not\nrequire a specific runner class.\n\n## CLI\n\nGenerate a local release passport bundle from release assets:\n\n```bash\nbuildchain collect github-release \\\n --tag v2.2.0 \\\n --repository kungfu-systems/buildchain \\\n --assets-dir dist \\\n --publish-evidence-json .buildchain/release-evidence/v2.2.0/evidence.json \\\n --transaction-json .buildchain/release-state/v2.2.0/state.json \\\n --package-set-json package-set.json \\\n --anchor-manifest-json libnode.release.json \\\n --build-summary-json .buildchain/artifacts/build-summary.json \\\n --build-facts-json .buildchain/facts/native-core.json \\\n --build-facts-json .buildchain/facts/product.json \\\n --platform-manifest-json .buildchain/artifacts/linux-x64/manifest.json \\\n --platform-manifest-json .buildchain/artifacts/darwin-arm64/manifest.json \\\n --platform-manifest-json .buildchain/artifacts/win32-x64/manifest.json \\\n --dist-tag-evidence-json .buildchain/release-evidence/v2.2.0/dist-tag-evidence.json \\\n --kfd-1-witness-json .buildchain/kfd/kfd-1/contract-world.witness.json \\\n --kfd-2-claim-json .buildchain/kfd/kfd-2/release-claims.json \\\n --invariant-passport-json product/release/qualification/invariant-passport.json \\\n --output-dir .buildchain/release-passport\n```\n\nFor a promotion workflow, consumers can instead use\n`release-passport-invariant-passport-command`. The command must emit exactly one\ncanonical JSON object on stdout; for example:\n\n```yaml\nrelease-passport-invariant-passport-command: >-\n node scripts/kungfu-invariant.mjs --collect-evidence .\n --passport product/release/qualification/invariant-passport.json --json\n```\n\nSupplying the input makes the invariant gate mandatory. Command failure,\nmissing output, semantic-root drift, a non-`verified` verdict, incomplete\ncoverage, dirty source state, or a source revision unrelated to the release\nfails closed before release publication.\n\n`packageSet` records the ordered main-plus-platform package set.\n`publish.packages[]` summarizes each published npm package with its version,\ndist-tag, registry, role, platform, and digest, so agents do not need to stitch\nnpm facts back together from the lower-level evidence files.\n`buildSummary`, `platformArtifactManifests`, and `distTagPromotion` preserve the\nbuild and npm dist-tag evidence chain in the same passport. `buildFacts[]`\nrecords first-class module/product build facts, while\n`evidence.buildFacts[]` gives agents compact paths, SHA-256 hashes, contracts,\nids, and digests for quick audit traversal. See\n[`build-facts.md`](build-facts.md) for the fact collection and verification\ncontract.\n\n### KFD-1 contract-world release gate\n\nBuildchain can gate release artifacts with KFD-1 contract-world witnesses. This\nis a structured evidence protocol, not a request for consumers to shell out to\nthe Kungfu SDK. The authority chain is:\n\n1. KFD owns the standard metadata and schema ids in `@kungfu-tech/kfd`.\n2. Buildchain imports that metadata, owns the JSON formatting policy, freezes\n the pre-build witness, and independently verifies post-build artifact bytes.\n3. Consumers only pass declarative witness JSON plus the artifact payloads their\n build already produced.\n\nThis gives agents a concrete answer to \"what changed and can I trust it?\" A\nrelease can include both normal release passport evidence and KFD-1 evidence:\nthe passport proves the release transaction and artifacts are complete, while\nKFD-1 proves selected contract-world surfaces inside those artifacts are the\nbyte-for-byte surfaces the release intended to ship.\n\nThe witness JSON names the contract world, the canonical serialization policy,\nand the release surfaces that must be byte-for-byte verified:\n\n```json\n{\n \"id\": \"kungfu-config\",\n \"standard\": \"kfd-1\",\n \"source\": \"kfd\",\n \"contractWorld\": {\n \"id\": \"kungfu-config\",\n \"kind\": \"schema\",\n \"name\": \"Kungfu config schema\"\n },\n \"canonicalPolicy\": {\n \"format\": \"json\",\n \"encoding\": \"utf-8\",\n \"indent\": 2,\n \"trailingNewline\": true\n },\n \"surfaces\": [\n {\n \"id\": \"kungfu-config-schema\",\n \"artifactPath\": \"Contents/Resources/core/config.schema.json\",\n \"expectedSha256\": \"...\"\n }\n ]\n}\n```\n\n`collect github-release` writes the result under the KFD-provided top-level key\ncurrently named `kfd-1`. Each contract world records the frozen witness digest,\nthe KFD package version, KFD schema ids, the Buildchain formatting policy, and\nthe actual artifact digest observed after the build. Verification fails closed\nwhen the witness is missing required facts, an artifact cannot be found, or a\npost-build digest does not match the frozen witness.\n\nFor the KFD repository itself, the KFD-1 witness can be a self-hosted standard\ncontract witness. In that mode KFD owns the standard-contract facts and\nBuildchain verifies declared source standard metadata, schemas, package\nexports, and site-consumption entrypoints against the packaged artifact. The\npassport records source and artifact hash summaries, schema ids, the\nself-hosting boundary, result, residual risk, and responsibility state for\nsource ownership, artifact verification, and release-passport proof ownership.\n\nGood KFD-1 witnesses should point at release payload surfaces, not at private\nbuild-machine state. For Buildchain itself, the natural witness set is the\nrelease passport schema and implementation, KFD-1 gate implementation,\n`dist/site/buildchain-contract.json`, and the npm package payload files that\nexpose the public CLI, reusable workflow/action contracts, and site facts.\nThe final `buildchain.release.json` file should not be used as an ordinary\nbyte-for-byte KFD surface because it contains KFD evidence; instead, the\npassport is audited through release-state SHA, `check-report.json`, and the\ncontract files that generate and verify it.\n\n### KFD-2 release trust passport audit\n\nBuildchain can write a KFD-2 release trust passport audit under the top-level\n`kfd-2` section. The section is generated automatically from KFD-1 and KFD-3\nrelease-gate evidence, and callers may add explicit public release claims with\n`--kfd-2-claim-json`.\n\nEvery public claim must bind:\n\n- declared sources;\n- machine-readable evidence;\n- source/evidence/artifact hashes;\n- artifact coordinates;\n- verification results;\n- audit boundary;\n- responsibility state;\n- residual risk, even when the array is empty.\n\nUnbound public claims fail release passport verification. Claims that are\nmachine-bound but only supported by prose downgrade the KFD-2 audit and produce\na warning, so agents can distinguish \"verified\", \"needs review\", and \"not\nbound to evidence\" without reading release notes.\n\nFor Buildchain's own releases, public release claims are not authored in prose\ninside the workflow. The source registry is\n`packages/core/buildchain-kfd-claims.js`, published as\n`dist/site/kfd-claims.json` and exported as\n`@kungfu-tech/buildchain/buildchain-kfd-claims`. That registry is the\nversion-invariant source of public claims and collaboration surfaces: it does\nnot store the exact release version, promotion SHA, or exact runtime contract\ndigest. Those run-specific facts belong in the release passport and generated\nwitnesses. During Buildchain promotion,\n`scripts/generate-buildchain-kfd-witnesses.mjs` binds the source registry to the\ncurrent source/artifact hashes and generates:\n\n- a KFD-1 self contract-world witness for the packaged docs, schemas, workflows,\n actions, Node exports, and site-consumption facts;\n- one KFD-2 claim JSON per public Buildchain release claim;\n- KFD-3 pre-build and artifact witnesses for the same public collaboration\n surfaces.\n\nThe generated claim set covers Buildchain's KFD release passport support,\nagent-first single source of truth, floating `@v2` contract drift protection,\nsemver GitHub Release evidence publication, channel-preserving release\npropagation, and npm publish evidence/finalization. Buildchain self promotion\npasses those files into `promote-buildchain-ref`; `verifyReleasePassport()` then\nfails closed if any claim is missing source bindings, machine evidence, hashes,\nartifact coordinates, verification result, audit boundary, responsibility, or\nresidual risk.\n\n### KFD-3 collaboration-interface release gate\n\nKFD-3 asks a different release question than KFD-1. KFD-1 proves that named\npayload bytes match one contract world. KFD-3 proves that a product's shipped\nparticipant-facing collaboration/control surface is closed over its declared\ninterface.\n\nFor Buildchain itself, the declared interface starts in\n`packages/core/buildchain-kfd-claims.js`, not in this Markdown file. The\nregistry enumerates public human/agent surfaces across manuals, schema and\nstandard metadata, package exports, site-consumption contracts, workflows, and\nactions. `dist/site/kfd-claims.json` is the packaged machine-readable form used\nby downstream sites and by Buildchain's own release passport. Exact release\nversion/SHA binding is deliberately deferred to the promotion witness, so the\nsource registry can remain stable across semver version-state bumps.\n\nBuildchain also performs a reverse audit before that witness is used. The\ngenerated `dist/site/public-surface-audit.json` enumerates real CLI commands\nfrom `bin/buildchain.mjs`, workflow inputs, action inputs, site pages, and docs\ncommand references, then compares them with the generated registries. Buildchain\nself KFD witnesses include that audit result and classify the collaboration\ninterface as closed-world only when the reverse audit passes. If a public\ncommand, workflow input, action input, or site page is exposed without a\nregistry entry, `pnpm run check` fails before release promotion can produce a\npassport.\n\nThe product remains the fact source. Before build/publish, the product writes a\npre-build witness:\n\n```bash\nkungfu sdk collaboration-interface witness --json \\\n > .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json\n```\n\nThat witness must contain, or point to, the product-owned KFD-3 collaboration\ninterface, registry digest, participants, and declared public shipped surfaces.\nKFD repository self-verification can declare the same facts as grouped machine\nsurfaces: docs, schemas, standards metadata, package exports, and\nsite-consumption contracts.\nAfter the artifact is built, the product also provides artifact-side evidence,\neither as a JSON file or a command:\n\n```bash\nbuildchain collect github-release \\\n --kfd-3-prebuild-witness-json .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json \\\n --kfd-3-artifact-verify-cmd \"kungfu agent verify --json\"\n```\n\nBuildchain imports the KFD-3 metadata from `@kungfu-tech/kfd`, freezes the\npre-build witness digest, ingests the artifact witness, and compares the two\nsets:\n\n- every declared `shipped` public participant-facing surface must appear in the\n artifact witness;\n- every artifact-exposed public participant-facing surface must be declared by\n the pre-build witness;\n- if both witnesses record `collaborationInterface.digest`, the digests must\n match;\n- contradictory, missing, stale, or schema-incomplete evidence fails closed.\n\nThe generated release passport records the result under the KFD-provided\ntop-level key currently named `kfd-3`. The section includes the KFD package\nversion, schema ids/paths, pre-build witness digest, artifact witness digest,\ndeclared/exposed surface counts, missing declared shipped surfaces, and\nunclassified artifact public surfaces. Buildchain also projects the same\ncollaboration-interface evidence into the top-level `kfd-2` audit as a\nmachine-readable `trustProof` object on the generated `kfd-3:*` public claim.\nThat proof carries `releaseStatus`, witness file hashes and canonical hashes,\ndeclared capability verification, reverse audit result and boundary, residual\nrisk, and responsibility state.\n\nThe trust proof makes the strongest claim only when the witnesses justify it:\n`No unclassified reachable surface within the declared audit boundary.` If the\nproduct declares non-exhaustive surfaces, Buildchain keeps the passport\nverifiable but marks the interface `audited` instead of `enforced` and records\nthe residual risk explicitly. Draft or partial KFD-3 declarations are\ndowngraded; missing declared capabilities, undeclared public artifact surfaces,\nor stale collaboration-interface digests fail the proof.\n\nThis makes KFD-3 support usable by readers and agents immediately: they can\ninspect `buildchain.release.json` and know whether the released package\nactually exposes no more and no less than the declared collaboration interface,\ninstead of trusting docs or release notes.\n\n### Floating Buildchain contract lock\n\nKFD-1 protects release payload surfaces. Floating ref contract locks protect the\nconsumer's relationship to Buildchain itself. A consumer can keep\n`.buildchain/contract-lock.json` with the Buildchain floating ref it accepted,\nthe resolved SHA, the contract digest, and the compatibility policy. Each\nBuildchain run reads the actual contract from the checked-out Buildchain ref\nand compares it before heavy build or publish work begins.\n\nCompatible drift, such as optional inputs or extra diagnostics, continues and\ncreates a consumer-local issue for review. Breaking drift fails fast. This means\nconsumers can use `@v2` without silently accepting incompatible changes, while\nBuildchain maintainers can still ship compatible improvements under the same\nmajor floating tag.\n\n`impact.json` can be supplied with `--impact-json`. Production release\npassports (`release/*`) and major publish-gate passports require\n`surfaceImpacts[]`; alpha, local, and legacy passport contexts keep the field\noptional. When `surfaceImpacts[]` is required or supplied, verification fails\nclosed unless each entry has an id, impact, and rationale, and\n`versionImpact.final` matches the highest surface impact. For example, KFD-2\ncontent can remain patch while an additive `registry.kind` field on the\nmachine-consumed KFD registry schema records a minor `kfd-registry-schema`\nsurface impact.\n\nVerify a release passport:\n\n```bash\nbuildchain verify release-passport .buildchain/release-passport/buildchain.release.json\n```\n\nVerify a specific artifact by discovering its detached passport:\n\n```bash\nbuildchain verify artifact ./Kungfu-2.8.0-windows-x64.exe\n```\n\nArtifact verification is subject-centric. Buildchain identifies the subject,\ncomputes or obtains its digest, discovers a detached `buildchain.release.json`,\nverifies that release passport and its evidence, then proves the subject digest\nappears in the passport's artifacts, package set, publish evidence, or artifact\nevidence. The command returns `pass`, `fail`, or `unverifiable`; missing\npassports and digest mismatches fail closed.\n\nFor npm subjects, Buildchain treats the registry as the package digest source:\n`npm:<name>@<version>` resolves `dist.integrity` and matches it against\n`packageSet.main.digest`, `packageSet.platforms[].digest`, and publish evidence.\nUse `--npm-registry <url>` when the package comes from a non-default registry.\n\nDiscovery is ordered and auditable:\n\n1. explicit `--passport`;\n2. sidecar pointer;\n3. embedded/package pointer;\n4. local config or org index;\n5. GitHub Release default from artifact naming/repository/tag hints;\n6. custom locator;\n7. unverifiable with retry guidance.\n\nFor Buildchain-managed GitHub Release lanes, release passport files are\npublished as release assets by default when the upload backend is enabled, so a\nGitHub Release asset URL can discover the sibling `buildchain.release.json`\nwithout a consumer copying YAML resolver logic.\n\nExplain a release to an agent:\n\n```bash\nbuildchain explain release \\\n --passport .buildchain/release-passport/buildchain.release.json \\\n --for agent \\\n --json\n```\n\nThe verifier fails closed when a passport omits artifacts, omits evidence, has\ndigest mismatches, or misses required protocol files.\n\n## Binary Distribution\n\nInitial binary distribution stays lightweight:\n\n- GitHub Release assets.\n- `checksums.txt`.\n- release passport artifacts.\n- a single release evidence bundle.\n- install scripts and Homebrew tap fixtures after the passport path is reliable.\n\nBuildchain publishes platform-specific archives, not loose top-level\nexecutables:\n\n- `buildchain-x86_64-unknown-linux-gnu.tar.gz`\n- `buildchain-aarch64-apple-darwin.tar.gz`\n- `buildchain-x86_64-pc-windows-msvc.zip`\n\nThe executable name inside each archive stays natural for the platform\n(`buildchain` or `buildchain.exe`). Top-level loose executable assets are not\nuploaded, because Linux and macOS would otherwise collide when GitHub Actions\nmatrix artifacts are merged.\n\nHeavy package manager channels such as apt, yum, winget, choco, Scoop, mise, or\nasdf are out of the P0/P1 scope until there is real external demand.\n\nStandalone binaries are a distribution shape, not a second implementation. The\nsource of truth remains the Node/ESM CLI and core library.\n\nThe standalone binary builder imports `@kungfu-tech/buildchain/logging` directly\nand records setup, SEA blob generation, injection, signing, archiving, manifest,\nand evidence phases. The GitHub workflow wraps the same build and passport\nsteps with `buildchain mark`, `buildchain span`,\n`buildchain verify observability-log`, and `buildchain log summary`. Logging is\na hard release gate: missing events, error events, or missing required phases\nfail the job before assets are uploaded. The verified logs are release assets\nand are covered by the release passport digest checks.\n\nSee also [`binary-distribution.md`](binary-distribution.md) for asset naming and\nbundle details, and [`install.md`](install.md) for consumer commands."
|
|
1582
|
+
"markdown": "# Release Passport\n\nBuildchain Release Passport is the core product mechanism: a mature product\nrelease record for artifacts that users or agents depend on.\n\nThe protocol is GitHub-native because it uses protected refs, reviewed\npromotion PRs, exact tags, GitHub Releases, npm Trusted Publishing, and\nmachine-readable evidence. A project can keep its existing build system and use\nBuildchain to make the release record auditable.\n\nRelease-candidate and final passports may also include compact\n`controllerReceipts[]` references. These bind a real reusable-workflow receipt\nto its plan digest, consumer source SHA, and exact Buildchain runtime SHA; they\ndo not infer execution evidence from a green job. See\n[`controller-evidence.md`](controller-evidence.md).\n\n## Contract\n\nThe release passport surface is a welded contract. Additive fields are allowed;\nbreaking semantic changes require a new major line.\n\nIndependent verifiers can pin two package-owned, standalone files without\nscraping this implementation:\n\n- `dist/site/schemas/release-passport-v1.schema.json` is the self-contained\n JSON Schema for the Buildchain-owned envelope;\n- `dist/site/release-passport-check-manifest.json` names the normative checker,\n required and conditional sibling evidence, local-resolution rules,\n Buildchain aggregation fields, canonical KFD subsection schema authorities,\n and forward-compatibility policy.\n\nThe same files are exported as\n`@kungfu-tech/buildchain/site/schemas/release-passport-v1.schema.json` and\n`@kungfu-tech/buildchain/site/release-passport-check-manifest.json`. The schema\nchecks the envelope shape. `buildchain verify release-passport` remains the\nnormative semantic checker: it resolves sibling evidence relative to the\npassport and fails closed on missing evidence, digest drift, or inconsistent\nrelease facts. Buildchain owns envelope aggregation; KFD retains schema and\ncompatibility authority for the `kfd-1`, `kfd-2`, and `kfd-3` subsections.\n\nP0 protocol artifacts:\n\n- `product-mechanism.json`\n- `buildchain.release.json`\n- `artifact-evidence.json`\n- `impact.json`\n- `agent-index.json`\n- `check-report.json`\n- `llms.txt`\n- `buildchain-release-bundle.json`\n- `buildchain-release-bundle.tar.gz`\n\n`buildchain.release.json` is the first file an agent should read. It points to\nartifact evidence, impact, recovery, product mechanism, and agent index facts.\nIt is also the unified release responsibility summary: when publish\ntransactions are used, the same passport records the package set, npm dist-tags,\nrelease source refs, release-state ref, anchor manifest, registry artifact\ndigests, trusted publishing evidence, and transaction result.\n\nAdditive passport sections:\n\n- `release`: public release tag, internal transaction tag, line, channel,\n source SHA, target ref, release SHA, release material SHA, publish tooling\n SHA, and durable release-state ref. Anchored/manual package releases use the\n published package version for the public tag while preserving the internal\n exact transaction tag for Buildchain recovery.\n- `versionImpact`: final patch/minor/major classification, source, and\n rationale.\n- `surfaceImpacts`: per registered surface classification. The final impact is\n the highest entry in this list.\n- `packageSet`: main package, platform packages, package-set order, registry,\n versions, dist-tags, and package digests.\n- `anchorManifest`: anchored/manual version manifest path, digest, and fields.\n- `trustedPublishing`: provider, auth mode, workflow run evidence, and whether\n trusted publishing was enabled.\n- `transaction`: durable Buildchain release transaction id, state, exact tag,\n release SHA, state ref, and state SHA.\n- `surfaceTimestampPolicy`: the common Buildchain surface manifest timestamp\n policy. It records real CI/release generation and publication times,\n reproducibility inputs, source revision or source-date-epoch, and whether\n timestamp fields participate in the release artifact digest.\n- `buildFacts`: module/product build facts that bind Git source digests,\n version sources, lifecycle invocations, platforms, outputs, product\n artifacts, and verification results to the release.\n- `artifacts`: release assets and registry artifacts in one list, each pointing\n back to the evidence file that proves its digest. Registry artifacts retain\n optional built/reused action, content and current-release coordinates,\n platform/contract/parent metadata, and fail-closed verification evidence.\n- `invariantPassports`: product-owned invariant verification results admitted\n by Buildchain. Each entry binds the product contract and registry roots,\n semantic Passport root, exact clean source revision, complete platform\n coverage, verdict, and residual risk. Buildchain owns release admission, not\n the meaning of the product invariants.\n\nBuildchain's own binary lane also publishes observability artifacts generated by\nthe Buildchain logging API and CLI:\n\n- `buildchain-log-events-<platform>.jsonl`\n- `buildchain-log-summary-<platform>.json`\n- `buildchain-log-events-passport.jsonl`\n- `buildchain-log-summary-passport.json`\n\n`buildchain-release-bundle.tar.gz` is the single evidence bundle for consumers\nthat want one file for offline inspection, mirroring, or site ingestion.\n`buildchain-release-bundle.json` records its digest and the digest of every\nincluded file.\n\n## Runner Policy\n\nProduction binary distribution should use GitHub-hosted runners by default:\n\n- `ubuntu-24.04`\n- `macos-latest`\n- `windows-2022`\n\nThis keeps the public release path easy for other projects to reproduce.\nSelf-hosted runners remain compatibility fixtures: they prove that the protocol\ndoes not depend on GitHub-hosted images, but they are not the default public\ndistribution lane.\n\nThe protocol records runner facts in `artifact-evidence.json`; it does not\nrequire a specific runner class.\n\n## CLI\n\nGenerate a local release passport bundle from release assets:\n\n```bash\nbuildchain collect github-release \\\n --tag v2.2.0 \\\n --repository kungfu-systems/buildchain \\\n --assets-dir dist \\\n --publish-evidence-json .buildchain/release-evidence/v2.2.0/evidence.json \\\n --transaction-json .buildchain/release-state/v2.2.0/state.json \\\n --package-set-json package-set.json \\\n --anchor-manifest-json libnode.release.json \\\n --build-summary-json .buildchain/artifacts/build-summary.json \\\n --build-facts-json .buildchain/facts/native-core.json \\\n --build-facts-json .buildchain/facts/product.json \\\n --platform-manifest-json .buildchain/artifacts/linux-x64/manifest.json \\\n --platform-manifest-json .buildchain/artifacts/darwin-arm64/manifest.json \\\n --platform-manifest-json .buildchain/artifacts/win32-x64/manifest.json \\\n --dist-tag-evidence-json .buildchain/release-evidence/v2.2.0/dist-tag-evidence.json \\\n --kfd-1-witness-json .buildchain/kfd/kfd-1/contract-world.witness.json \\\n --kfd-2-claim-json .buildchain/kfd/kfd-2/release-claims.json \\\n --invariant-passport-json product/release/qualification/invariant-passport.json \\\n --output-dir .buildchain/release-passport\n```\n\nFor a promotion workflow, consumers can instead use\n`release-passport-invariant-passport-command`. The command must emit exactly one\ncanonical JSON object on stdout; for example:\n\n```yaml\nrelease-passport-invariant-passport-command: >-\n node scripts/kungfu-invariant.mjs --collect-evidence .\n --passport product/release/qualification/invariant-passport.json --json\n```\n\nSupplying the input makes the invariant gate mandatory. Command failure,\nmissing output, semantic-root drift, a non-`verified` verdict, incomplete\ncoverage, dirty source state, or a source revision unrelated to the release\nfails closed before release publication.\n\n`packageSet` records the ordered main-plus-platform package set.\n`publish.packages[]` summarizes each published npm package with its version,\ndist-tag, registry, role, platform, and digest, so agents do not need to stitch\nnpm facts back together from the lower-level evidence files.\n`buildSummary`, `platformArtifactManifests`, and `distTagPromotion` preserve the\nbuild and npm dist-tag evidence chain in the same passport. `buildFacts[]`\nrecords first-class module/product build facts, while\n`evidence.buildFacts[]` gives agents compact paths, SHA-256 hashes, contracts,\nids, and digests for quick audit traversal. See\n[`build-facts.md`](build-facts.md) for the fact collection and verification\ncontract.\n\n### KFD-1 contract-world release gate\n\nBuildchain can gate release artifacts with KFD-1 contract-world witnesses. This\nis a structured evidence protocol, not a request for consumers to shell out to\nthe Kungfu SDK. The authority chain is:\n\n1. KFD owns the standard metadata and schema ids in `@kungfu-tech/kfd`.\n2. Buildchain imports that metadata, owns the JSON formatting policy, freezes\n the pre-build witness, and independently verifies post-build artifact bytes.\n3. Consumers only pass declarative witness JSON plus the artifact payloads their\n build already produced.\n\nThis gives agents a concrete answer to \"what changed and can I trust it?\" A\nrelease can include both normal release passport evidence and KFD-1 evidence:\nthe passport proves the release transaction and artifacts are complete, while\nKFD-1 proves selected contract-world surfaces inside those artifacts are the\nbyte-for-byte surfaces the release intended to ship.\n\nThe witness JSON names the contract world, the canonical serialization policy,\nand the release surfaces that must be byte-for-byte verified:\n\n```json\n{\n \"id\": \"kungfu-config\",\n \"standard\": \"kfd-1\",\n \"source\": \"kfd\",\n \"contractWorld\": {\n \"id\": \"kungfu-config\",\n \"kind\": \"schema\",\n \"name\": \"Kungfu config schema\"\n },\n \"canonicalPolicy\": {\n \"format\": \"json\",\n \"encoding\": \"utf-8\",\n \"indent\": 2,\n \"trailingNewline\": true\n },\n \"surfaces\": [\n {\n \"id\": \"kungfu-config-schema\",\n \"artifactPath\": \"Contents/Resources/core/config.schema.json\",\n \"expectedSha256\": \"...\"\n }\n ]\n}\n```\n\n`collect github-release` writes the result under the KFD-provided top-level key\ncurrently named `kfd-1`. Each contract world records the frozen witness digest,\nthe KFD package version, KFD schema ids, the Buildchain formatting policy, and\nthe actual artifact digest observed after the build. Verification fails closed\nwhen the witness is missing required facts, an artifact cannot be found, or a\npost-build digest does not match the frozen witness.\n\nFor the KFD repository itself, the KFD-1 witness can be a self-hosted standard\ncontract witness. In that mode KFD owns the standard-contract facts and\nBuildchain verifies declared source standard metadata, schemas, package\nexports, and site-consumption entrypoints against the packaged artifact. The\npassport records source and artifact hash summaries, schema ids, the\nself-hosting boundary, result, residual risk, and responsibility state for\nsource ownership, artifact verification, and release-passport proof ownership.\n\nGood KFD-1 witnesses should point at release payload surfaces, not at private\nbuild-machine state. For Buildchain itself, the natural witness set is the\nrelease passport schema and implementation, KFD-1 gate implementation,\n`dist/site/buildchain-contract.json`, and the npm package payload files that\nexpose the public CLI, reusable workflow/action contracts, and site facts.\nThe final `buildchain.release.json` file should not be used as an ordinary\nbyte-for-byte KFD surface because it contains KFD evidence; instead, the\npassport is audited through release-state SHA, `check-report.json`, and the\ncontract files that generate and verify it.\n\n### KFD-2 release trust passport audit\n\nBuildchain can write a KFD-2 release trust passport audit under the top-level\n`kfd-2` section. The section is generated automatically from KFD-1 and KFD-3\nrelease-gate evidence, and callers may add explicit public release claims with\n`--kfd-2-claim-json`.\n\nEvery public claim must bind:\n\n- declared sources;\n- machine-readable evidence;\n- source/evidence/artifact hashes;\n- artifact coordinates;\n- verification results;\n- audit boundary;\n- responsibility state;\n- residual risk, even when the array is empty.\n\nUnbound public claims fail release passport verification. Claims that are\nmachine-bound but only supported by prose downgrade the KFD-2 audit and produce\na warning, so agents can distinguish \"verified\", \"needs review\", and \"not\nbound to evidence\" without reading release notes.\n\nFor Buildchain's own releases, public release claims are not authored in prose\ninside the workflow. The source registry is\n`packages/core/buildchain-kfd-claims.js`, published as\n`dist/site/kfd-claims.json` and exported as\n`@kungfu-tech/buildchain/buildchain-kfd-claims`. That registry is the\nversion-invariant source of public claims and collaboration surfaces: it does\nnot store the exact release version, promotion SHA, or exact runtime contract\ndigest. Those run-specific facts belong in the release passport and generated\nwitnesses. During Buildchain promotion,\n`scripts/generate-buildchain-kfd-witnesses.mjs` binds the source registry to the\ncurrent source/artifact hashes and generates:\n\n- a KFD-1 self contract-world witness for the packaged docs, schemas, workflows,\n actions, Node exports, and site-consumption facts;\n- one KFD-2 claim JSON per public Buildchain release claim;\n- KFD-3 pre-build and artifact witnesses for the same public collaboration\n surfaces.\n\nThe generated claim set covers Buildchain's KFD release passport support,\nagent-first single source of truth, floating `@v2` contract drift protection,\nsemver GitHub Release evidence publication, channel-preserving release\npropagation, and npm publish evidence/finalization. Buildchain self promotion\npasses those files into `promote-buildchain-ref`; `verifyReleasePassport()` then\nfails closed if any claim is missing source bindings, machine evidence, hashes,\nartifact coordinates, verification result, audit boundary, responsibility, or\nresidual risk.\n\n### KFD-3 collaboration-interface release gate\n\nKFD-3 asks a different release question than KFD-1. KFD-1 proves that named\npayload bytes match one contract world. KFD-3 proves that a product's shipped\nparticipant-facing collaboration/control surface is closed over its declared\ninterface.\n\nFor Buildchain itself, the declared interface starts in\n`packages/core/buildchain-kfd-claims.js`, not in this Markdown file. The\nregistry enumerates public human/agent surfaces across manuals, schema and\nstandard metadata, package exports, site-consumption contracts, workflows, and\nactions. `dist/site/kfd-claims.json` is the packaged machine-readable form used\nby downstream sites and by Buildchain's own release passport. Exact release\nversion/SHA binding is deliberately deferred to the promotion witness, so the\nsource registry can remain stable across semver version-state bumps.\n\nBuildchain also performs a reverse audit before that witness is used. The\ngenerated `dist/site/public-surface-audit.json` enumerates real CLI commands\nfrom `bin/buildchain.mjs`, workflow inputs, action inputs, site pages, and docs\ncommand references, then compares them with the generated registries. Buildchain\nself KFD witnesses include that audit result and classify the collaboration\ninterface as closed-world only when the reverse audit passes. If a public\ncommand, workflow input, action input, or site page is exposed without a\nregistry entry, `pnpm run check` fails before release promotion can produce a\npassport.\n\nThe product remains the fact source. Before build/publish, the product writes a\npre-build witness:\n\n```bash\nkungfu sdk collaboration-interface witness --json \\\n > .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json\n```\n\nThat witness must contain, or point to, the product-owned KFD-3 collaboration\ninterface, registry digest, participants, and declared public shipped surfaces.\nKFD repository self-verification can declare the same facts as grouped machine\nsurfaces: docs, schemas, standards metadata, package exports, and\nsite-consumption contracts.\nAfter the artifact is built, the product also provides artifact-side evidence,\neither as a JSON file or a command:\n\n```bash\nbuildchain collect github-release \\\n --kfd-3-prebuild-witness-json .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json \\\n --kfd-3-artifact-verify-cmd \"kungfu agent verify --json\"\n```\n\nBuildchain imports the KFD-3 metadata from `@kungfu-tech/kfd`, freezes the\npre-build witness digest, ingests the artifact witness, and compares the two\nsets:\n\n- every declared `shipped` public participant-facing surface must appear in the\n artifact witness;\n- every artifact-exposed public participant-facing surface must be declared by\n the pre-build witness;\n- if both witnesses record `collaborationInterface.digest`, the digests must\n match;\n- contradictory, missing, stale, or schema-incomplete evidence fails closed.\n\nThe generated release passport records the result under the KFD-provided\ntop-level key currently named `kfd-3`. The section includes the KFD package\nversion, schema ids/paths, pre-build witness digest, artifact witness digest,\ndeclared/exposed surface counts, missing declared shipped surfaces, and\nunclassified artifact public surfaces. Buildchain also projects the same\ncollaboration-interface evidence into the top-level `kfd-2` audit as a\nmachine-readable `trustProof` object on the generated `kfd-3:*` public claim.\nThat proof carries `releaseStatus`, witness file hashes and canonical hashes,\ndeclared capability verification, reverse audit result and boundary, residual\nrisk, and responsibility state.\n\nThe trust proof makes the strongest claim only when the witnesses justify it:\n`No unclassified reachable surface within the declared audit boundary.` If the\nproduct declares non-exhaustive surfaces, Buildchain keeps the passport\nverifiable but marks the interface `audited` instead of `enforced` and records\nthe residual risk explicitly. Draft or partial KFD-3 declarations are\ndowngraded; missing declared capabilities, undeclared public artifact surfaces,\nor stale collaboration-interface digests fail the proof.\n\nThis makes KFD-3 support usable by readers and agents immediately: they can\ninspect `buildchain.release.json` and know whether the released package\nactually exposes no more and no less than the declared collaboration interface,\ninstead of trusting docs or release notes.\n\n### Floating Buildchain contract lock\n\nKFD-1 protects release payload surfaces. Floating ref contract locks protect the\nconsumer's relationship to Buildchain itself. A consumer can keep\n`.buildchain/contract-lock.json` with the Buildchain floating ref it accepted,\nthe resolved SHA, the contract digest, and the compatibility policy. Each\nBuildchain run reads the actual contract from the checked-out Buildchain ref\nand compares it before heavy build or publish work begins.\n\nCompatible drift, such as optional inputs or extra diagnostics, continues and\ncreates a consumer-local issue for review. Breaking drift fails fast. This means\nconsumers can use `@v2` without silently accepting incompatible changes, while\nBuildchain maintainers can still ship compatible improvements under the same\nmajor floating tag.\n\n`impact.json` can be supplied with `--impact-json`. Production release\npassports (`release/*`) and major publish-gate passports require\n`surfaceImpacts[]`; alpha, local, and legacy passport contexts keep the field\noptional. When `surfaceImpacts[]` is required or supplied, verification fails\nclosed unless each entry has an id, impact, and rationale, and\n`versionImpact.final` matches the highest surface impact. For example, KFD-2\ncontent can remain patch while an additive `registry.kind` field on the\nmachine-consumed KFD registry schema records a minor `kfd-registry-schema`\nsurface impact.\n\nPromote-only stable publication may omit an explicit impact ledger only when\nthe downloaded PR-stage release-candidate passport proves exact tree\nequivalence. Buildchain then records a patch-level release-governance impact\nbound to that candidate. Missing, stale, or non-equivalent candidate evidence\ndoes not receive this fallback and remains fail-closed.\n\nVerify a release passport:\n\n```bash\nbuildchain verify release-passport .buildchain/release-passport/buildchain.release.json\n```\n\nVerify a specific artifact by discovering its detached passport:\n\n```bash\nbuildchain verify artifact ./Kungfu-2.8.0-windows-x64.exe\n```\n\nArtifact verification is subject-centric. Buildchain identifies the subject,\ncomputes or obtains its digest, discovers a detached `buildchain.release.json`,\nverifies that release passport and its evidence, then proves the subject digest\nappears in the passport's artifacts, package set, publish evidence, or artifact\nevidence. The command returns `pass`, `fail`, or `unverifiable`; missing\npassports and digest mismatches fail closed.\n\nFor npm subjects, Buildchain treats the registry as the package digest source:\n`npm:<name>@<version>` resolves `dist.integrity` and matches it against\n`packageSet.main.digest`, `packageSet.platforms[].digest`, and publish evidence.\nUse `--npm-registry <url>` when the package comes from a non-default registry.\n\nDiscovery is ordered and auditable:\n\n1. explicit `--passport`;\n2. sidecar pointer;\n3. embedded/package pointer;\n4. local config or org index;\n5. GitHub Release default from artifact naming/repository/tag hints;\n6. custom locator;\n7. unverifiable with retry guidance.\n\nFor Buildchain-managed GitHub Release lanes, release passport files are\npublished as release assets by default when the upload backend is enabled, so a\nGitHub Release asset URL can discover the sibling `buildchain.release.json`\nwithout a consumer copying YAML resolver logic.\n\nExplain a release to an agent:\n\n```bash\nbuildchain explain release \\\n --passport .buildchain/release-passport/buildchain.release.json \\\n --for agent \\\n --json\n```\n\nThe verifier fails closed when a passport omits artifacts, omits evidence, has\ndigest mismatches, or misses required protocol files.\n\n## Binary Distribution\n\nInitial binary distribution stays lightweight:\n\n- GitHub Release assets.\n- `checksums.txt`.\n- release passport artifacts.\n- a single release evidence bundle.\n- install scripts and Homebrew tap fixtures after the passport path is reliable.\n\nBuildchain publishes platform-specific archives, not loose top-level\nexecutables:\n\n- `buildchain-x86_64-unknown-linux-gnu.tar.gz`\n- `buildchain-aarch64-apple-darwin.tar.gz`\n- `buildchain-x86_64-pc-windows-msvc.zip`\n\nThe executable name inside each archive stays natural for the platform\n(`buildchain` or `buildchain.exe`). Top-level loose executable assets are not\nuploaded, because Linux and macOS would otherwise collide when GitHub Actions\nmatrix artifacts are merged.\n\nHeavy package manager channels such as apt, yum, winget, choco, Scoop, mise, or\nasdf are out of the P0/P1 scope until there is real external demand.\n\nStandalone binaries are a distribution shape, not a second implementation. The\nsource of truth remains the Node/ESM CLI and core library.\n\nThe standalone binary builder imports `@kungfu-tech/buildchain/logging` directly\nand records setup, SEA blob generation, injection, signing, archiving, manifest,\nand evidence phases. The GitHub workflow wraps the same build and passport\nsteps with `buildchain mark`, `buildchain span`,\n`buildchain verify observability-log`, and `buildchain log summary`. Logging is\na hard release gate: missing events, error events, or missing required phases\nfail the job before assets are uploaded. The verified logs are release assets\nand are covered by the release passport digest checks.\n\nSee also [`binary-distribution.md`](binary-distribution.md) for asset naming and\nbundle details, and [`install.md`](install.md) for consumer commands."
|
|
1583
1583
|
},
|
|
1584
1584
|
{
|
|
1585
1585
|
"id": "manual:release-propagation",
|
|
@@ -1640,7 +1640,7 @@
|
|
|
1640
1640
|
],
|
|
1641
1641
|
"maturity": "stable",
|
|
1642
1642
|
"sourcePath": "docs/reusable-build-surface.md",
|
|
1643
|
-
"digest": "sha256:
|
|
1643
|
+
"digest": "sha256:dea8ec2f1f2ea75e569a989988e9d6f76067e1d0ae496dadc34ef1dcfbfa35dd",
|
|
1644
1644
|
"headings": [
|
|
1645
1645
|
{
|
|
1646
1646
|
"level": 1,
|
|
@@ -1738,7 +1738,7 @@
|
|
|
1738
1738
|
"anchor": "fixture"
|
|
1739
1739
|
}
|
|
1740
1740
|
],
|
|
1741
|
-
"markdown": "# Reusable Build Surface\n\nBuildchain v2 provides a reusable build workflow for repositories that need\nBuildchain's release semantics but cannot be described as a simple Node package.\nThe first target shape is `libnode`: expensive native builds, multiple operating\nsystems, self-hosted runner labels, and release artifacts that must be auditable.\n\n## Automatic Channel Router\n\nThe preferred consumer surface is one reusable workflow call. After v2.12\nreaches the stable major ref, consumers keep this configuration for both alpha\ndevelopment and stable release work:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v2\n permissions:\n contents: read\n issues: write\n id-token: write\n with:\n working-directory: .\n artifact-name: libnode\n runner-preset: kungfu-v4-self-hosted\n publish-channel: none\n secrets: inherit\n```\n\n`buildchain-channel` defaults to `auto`. Selection uses this precedence:\n\n1. an explicit `buildchain-ref` train, SHA, or official channel;\n2. an explicit `buildchain-channel: alpha|stable`;\n3. `publish-channel: alpha|release|major`;\n4. GitHub release prerelease metadata;\n5. a canonical semver tag;\n6. non-release PR, push, dispatch, schedule, and workflow-run events default to\n alpha.\n\nThe resolved runtime is `vN-alpha` for development and prerelease intent and\n`vN` for stable release intent. Unknown custom publish channels, malformed\nrelease events, and non-semver release-like tags fail before the build matrix;\nthey never guess alpha for a stable release.\n\nThe router automatically selects `.buildchain/alpha-contract-lock.json` for\nalpha and `.buildchain/contract-lock.json` for stable. A repository can override\nthe common path with `buildchain-contract-lock-path`, or override one channel\nwith `buildchain-alpha-contract-lock-path` /\n`buildchain-stable-contract-lock-path`.\n\nOnly repositories changing the default policy need extra routing input:\n\n```yaml\nwith:\n buildchain-channel: stable\n```\n\nDuring the v2.12 prerelease evaluation window, canaries use\n`build.yml@v2-alpha`. The same router then selects `v2-alpha` or stable `v2` as\nthe runtime. Production consumers should adopt `build.yml@v2` after the router\nhas reached stable; this keeps the routing shell itself on a stable ref.\n\nThe router is generated from `.build.yml`'s input/output surface. Run\n`node scripts/generate-channel-build-workflow.mjs` after changing the advanced\nbuild workflow; inventory and unit tests reject a stale generated router.\n\n## Advanced Workflow\n\nConsumers that need direct workflow-shell or runtime control call the advanced\nsurface:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n working-directory: .\n artifact-name: libnode\n runner-preset: kungfu-v4-self-hosted\n linux-container-preset: kungfu-verify\n artifact-name-template: \"{artifact}-{platform}-{sha}\"\n artifact-paths: |\n dist\n build/stage\n expected-artifacts-json: >-\n {\"minFiles\":2,\"requiredPaths\":[\"dist/libnode.tar.gz\",\"dist/checksums.txt\"]}\n process-summary-path: .buildchain/diagnostics/process-summary.json\n release-candidate: true\n publish-channel: release\n publish-source-ref: publish-gate/release/v22/v22.22/22.22.3-kf.0\n```\n\n`runner-preset` is the stable first-class surface for known runner fleets:\n\n| Preset | Platforms |\n| ----------------------- | ------------------------------------------------------------------------ |\n| `github-hosted` | `ubuntu-24.04`, `macos-latest`, `windows-2022` |\n| `kungfu-v4-self-hosted` | Kungfu Linux x64, macOS ARM64, and Windows x64 self-hosted runner labels |\n| `custom` | Requires `platforms-json` |\n\nCallers can still provide a custom matrix with `platforms-json`. Each platform\nobject has:\n\n| Field | Meaning |\n| -------- | ------------------------------------------------- |\n| `id` | Stable artifact/platform key, such as `linux-x64` |\n| `name` | Human-readable job name |\n| `runner` | JSON string passed to `runs-on` after `fromJSON` |\n\nThe runner field is intentionally a JSON string so callers can pass either\nGitHub-hosted runners or multi-label self-hosted runners without Buildchain\nguessing the labels.\n\nOnly include platforms that should run. GitHub schedules matrix jobs before\nsteps execute, so a disabled entry with unavailable runner labels can still\nblock the workflow queue.\n\n## Linux Job Containers\n\nLinux build platforms can run inside a digest-pinned job container while macOS\nand Windows keep using native runners. This is the recommended way to remove\nmoving Linux runner prerequisites from Buildchain consumers: the Linux host only\nneeds a GitHub Actions runner, Docker, and network access; common verification\ntools come from the image contract.\n\nUse the Kungfu verification image for lifecycle stages that need Git, jq,\nPython, uv, and fnm, but do not need native compilation:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n runner-preset: kungfu-v4-self-hosted\n linux-container-preset: kungfu-verify\n```\n\n`kungfu-verify` resolves to:\n\n```text\nghcr.io/kungfu-systems/build-images/kungfu-verify@sha256:11f0ba64267ce88174a4f73a9bf833ff4e9c59cd16ec3d08a6432a06c2be6fb1\n```\n\nCallers that own a different Linux image can pass it explicitly:\n\n```yaml\nwith:\n linux-container-preset: custom\n linux-container-image: ghcr.io/example/project-build@sha256:<digest>\n```\n\n`linux-container-image` should be pinned by digest. A floating tag makes the\nrunner surface mutable and weakens Buildchain's release evidence.\n\nThe workflow splits the matrix into two build jobs:\n\n- Linux platforms go to `build-linux-container` when a Linux container is\n configured.\n- All other platforms go to `build-native`.\n\nArtifact names, manifest paths, expected artifact checks, publish-source locks,\nand aggregate summaries are the same in both jobs. The split is an execution\ndetail, not a different artifact contract.\n\n## Native Rust Toolchains\n\nNative lifecycle jobs can request an isolated Rust installation instead of\ndepending on a self-hosted runner user's PATH:\n\n```yaml\nwith:\n setup-rust: true\n rust-toolchain: \"1.96.0\"\n rustup-dist-server: \"https://rsproxy.cn\"\n rustup-update-root: \"https://rsproxy.cn/rustup\"\n cargo-registry-index: ${{ vars.BUILDCHAIN_CARGO_REGISTRY_INDEX }}\n```\n\n`setup-rust` defaults to `false`, so existing consumers are unchanged. When it\nis enabled, Buildchain installs `rust-toolchain` before the install, build, and\nverify lifecycle stages on every native matrix platform. Windows uses the\nofficial rustup bootstrap through `cmd.exe` and `curl.exe` into runner-temporary\nCargo and rustup homes, so it works under a restrictive PowerShell execution\npolicy and the service account does not depend on another user's PATH or mutate\nhost toolchain state. Pin an exact toolchain for release builds. Linux container jobs continue\nto obtain Rust from their digest-pinned image contract; Buildchain does not\nmutate that container surface.\n\nThe rustup server inputs are optional and default to Rust's official servers.\nConsumers behind a slow cross-border link may select a trusted transport mirror;\nrustup still verifies the selected toolchain's distribution metadata and\ncomponent checksums.\n\n`cargo-registry-index` is also optional. When set, Buildchain exposes it to\nCargo as `CARGO_REGISTRIES_CRATES_IO_INDEX` for every native lifecycle stage,\nso a self-hosted runner can use a repository or organization variable without\ncommitting private LAN topology to public workflow YAML. The endpoint must be a\ncrates.io-compatible index whose `config.json` download contract serves the\nmatching checksum-verified crate archives. An empty value preserves Cargo's\nnormal crates.io behavior.\n\nThe container image provides `fnm` but does not preinstall Node. Buildchain uses\n`fnm` inside the container to install the requested `node-version` before it\nruns Buildchain runtime scripts or lifecycle actions.\n\nDo not use `kungfu-verify` for stages that need CMake, Ninja, ccache, Conan, or\nDocker image publishing. Those should use a heavier native-build image or remain\non a host runner until their image contract is explicit.\n\n## Buildchain Runtime Override\n\nStable consumers should keep the reusable workflow pinned to stable refs such as\n`@v2`. The optional `buildchain-ref` input is empty by default; empty means\nBuildchain resolves and executes the stable runtime selected by the workflow\nshell. The full train validation protocol is documented in\n[`runtime-train-validation.md`](runtime-train-validation.md).\n\nFor one-off manual validation, a trusted maintainer can run the caller workflow\nwith a temporary runtime override:\n\n```yaml\non:\n workflow_dispatch:\n inputs:\n buildchain-ref:\n description: \"Temporary Buildchain runtime ref for trusted manual validation\"\n required: false\n default: \"\"\n\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n buildchain-ref: ${{ inputs.buildchain-ref || '' }}\n```\n\nAllowed override refs are deliberately narrow:\n\n| Ref form | Meaning |\n| --- | --- |\n| `train/v2/v2.3/<capability>` | Temporary capability train under the active minor line |\n| `refs/heads/train/v2/v2.3/<capability>` | Explicit branch ref for the same train |\n| `<40-character SHA>` | Exact immutable Buildchain runtime commit |\n\nOverride requests fail closed unless the event is `workflow_dispatch` and the\nactor has write, maintain, or admin permission on the caller repository.\nPull requests, including same-repository pull requests and fork-originated pull\nrequests, cannot use `buildchain-ref` override. This keeps automated PR builds on\nthe stable runtime surface.\n\nEvery run resolves the runtime ref to an immutable SHA before checkout. The job\nsummary and aggregate build summary record the workflow shell ref, requested\nruntime ref, resolved runtime ref, runtime SHA, stability class, trust decision,\nand rollback ref. Train refs are development validation refs: they do not move\n`v2`, `vX.Y`, `vX.Y-alpha`, npm dist-tags, or production release refs, and they\nmust not be pinned as long-term production dependencies.\n\nRuntime override validates Buildchain runtime scripts, CLI code, local actions,\nconfig parsing, and lifecycle behavior. It cannot validate changes that require\nthe outer reusable workflow YAML itself to change, such as new jobs,\npermissions, workflow outputs, or matrix topology. Those changes need a canary\nworkflow path or a temporary explicit workflow ref.\n\n## Floating Ref Contract Lock\n\nStable consumers should use floating major refs such as `@v2`, but a floating\nref is not blind trust. Each released Buildchain ref carries a package-owned\nruntime contract world in `dist/site/buildchain-contract.json`. Consumers may\nkeep a small lock file, `.buildchain/contract-lock.json`, recording the\nBuildchain ref, resolved SHA, contract digest, compatibility digest, accepted\nmajor line, and compatibility policy they reviewed.\n\nThe reusable build trust gate checks this lock before any heavy matrix job:\n\n1. resolve the Buildchain runtime ref, for example `v2`, to an immutable SHA;\n2. read `dist/site/buildchain-contract.json` from that checked-out Buildchain\n ref;\n3. read the consumer's `.buildchain/contract-lock.json`;\n4. compare the accepted contract with the current contract.\n\nSHA drift alone is not a failure. `v2` is expected to advance. Buildchain only\nfails fast when the accepted contract is no longer compatible, for example a\nrequired input is removed, a required output disappears, a protected behavior\npromise changes, or the major line changes. Additive changes such as optional\ninputs, optional outputs, diagnostics, or documentation updates continue under\nthe default `major-compatible` policy.\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n permissions:\n contents: read\n issues: write\n id-token: write\n with:\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n buildchain-contract-compatibility-policy: major-compatible\n buildchain-contract-drift-issue-mode: compatible-and-breaking\n```\n\nWhen compatible drift is detected, the build continues and Buildchain opens or\nupdates a low-priority issue in the consumer repository. The issue records the\nold SHA/digest, new SHA/digest, compatibility result, workflow run, and the next\naction: review the Buildchain release notes and update the lock. When breaking\ndrift is detected, the same issue path is used, but the trust gate fails before\nmatrix build or publish work starts. If the workflow token cannot write issues,\nBuildchain writes a copyable issue body into the job summary.\n\nThe lock is intentionally small. It does not copy the full contract. The full\ncontract remains in the Buildchain ref and package; the consumer records only\nwhat it accepted and the policy used to compare future floating-ref movement.\n\nAdvanced alpha-channel consumers select the matching workflow shell:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2-alpha\n with:\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe runtime follows the called workflow through `job.workflow_ref`. Callers may\nalso pass `buildchain-ref: v2-alpha` explicitly; official floating refs are\nordinary channel selections and are allowed on pull requests and pushes. Train\nrefs and exact SHAs remain trusted manual overrides.\n\n## Shifu Cache Profile Passthrough\n\nBuildchain can carry one trusted Shifu cache-profile reference and its exact\ndigest into lifecycle execution. Its contract is an opaque reference and digest\nonly. This surface is deliberately opaque:\nBuildchain does not fetch the profile, parse JSON, select cache services,\nrewrite bindings, decide fallback, or emit Shifu resolution evidence. Those\nsemantics remain owned by the consumer's pinned Shifu implementation.\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v2\n with:\n shifu-cache-profile-ref: ${{ vars.SHIFU_CACHE_PROFILE_REF }}\n shifu-cache-profile-digest: ${{ vars.SHIFU_CACHE_PROFILE_DIGEST }}\n```\n\nThe reusable workflow passes the pair as `SHIFU_CACHE_PROFILE_REF` and\n`SHIFU_CACHE_PROFILE_DIGEST` to install, build, and verify lifecycle commands.\nThe consumer must invoke its Shifu cache-aware execution surface. An empty pair\npreserves existing behavior; a consumer Shifu should fail closed when exactly\none value is present or the resolved bytes do not match the expected digest.\n\nUse trusted repository or organization variables rather than PR-controlled\nfiles for private/LAN references. The variables must remain secret-free; any\ncredentials use a separate provider-approved secret surface and must not be\nembedded in the profile reference. This passthrough is separate from\nBuildchain's locked source checkout cache below: Buildchain owns checkout\ntransport and source identity, while Shifu owns post-checkout execution cache\nbindings and receipts.\n\n## Locked Source Checkout Cache\n\nSelf-hosted runners that build large repositories can opt into a locked checkout\ncache for both the consumer source and the Buildchain runtime. This changes only\nthe Git object transport. Buildchain still resolves `publish-source-sha` and the\nruntime SHA before any build runner starts, checks out those exact commits, and\nverifies each final `HEAD` plus the resolved consumer source tree SHA before\nlifecycle commands run.\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n runner-preset: kungfu-v4-self-hosted\n checkout-cache-mode: auto\n checkout-cache-mirror-url-template: ${{ vars.BUILDCHAIN_CHECKOUT_CACHE_MIRROR_URL_TEMPLATE }}\n checkout-cache-reference-repository-template: ${{ vars.BUILDCHAIN_CHECKOUT_CACHE_REFERENCE_REPOSITORY_TEMPLATE }}\n checkout-cache-fallback: github\n checkout-cache-timeout-seconds: 60\n checkout-cache-github-timeout-seconds: 600\n checkout-cache-fetch-attempts: 3\n```\n\n`checkout-cache-mode` accepts:\n\n| Mode | Behavior |\n| --- | --- |\n| `off` | Default. Buildchain fetches the locked commit from GitHub. |\n| `auto` | Try the trusted cache first; on miss, record the miss and fall back according to `checkout-cache-fallback`. |\n| `require` | Require the cache to provide the locked commit and fail before lifecycle work if unavailable. |\n\nThe cache can be a local/LAN mirror URL template or a runner-local bare\nreference repository template. Templates support `{owner}`, `{repo}`,\n`{repository}`, `{repositorySlug}`, and `{sha}`. The workflow also reads\nrepository or organization variables named\n`BUILDCHAIN_CHECKOUT_CACHE_MIRROR_URL_TEMPLATE` and\n`BUILDCHAIN_CHECKOUT_CACHE_REFERENCE_REPOSITORY_TEMPLATE`, so consumers can keep\nprivate LAN topology out of repository YAML.\n\nThe GitHub-hosted trust gate resolves the reusable workflow shell to an exact\ncommit and uploads that shell's small checkout bootstrap script. Native and\nLinux-container build jobs download the bootstrap, then use the same cache\npolicy to obtain both the selected Buildchain runtime and consumer source at\ntheir already resolved immutable SHAs. Keeping the bootstrap owned by the\nworkflow shell is important when `@vN-alpha` routes a stable release to an older\n`vN` runtime: the stable runtime does not need to already contain the newest\ncheckout transport implementation. This also prevents a large direct\n`actions/checkout` runtime clone from becoming a separate timeout path on\nconstrained self-hosted uplinks. The bootstrap artifact does not contain the\nruntime repository and cannot move either selected ref.\n\nDo not read cache URLs or reference paths from PR-controlled files such as\n`.buildchain/buildchain.toml`. These values are trusted workflow inputs or repo/org\nvariables. Buildchain does not pass GitHub credentials to cache mirrors or\nreference repositories. If it must fall back to GitHub, the workflow token is\nused only for the GitHub fetch path. Cache attempts use\n`checkout-cache-timeout-seconds`; the potentially larger GitHub fallback uses\nthe independent `checkout-cache-github-timeout-seconds` budget (600 seconds by\ndefault). Buildchain fetches the advertised source ref before trying an exact\nSHA, so a cache hit or stale-cache seed can contribute objects and the fallback\ndoes not first waste a full timeout on an unadvertised SHA. Retryable timeout\nand transient network failures use the bounded `checkout-cache-fetch-attempts`\nbudget; permanent failures stop immediately. Diagnostics record both timeout\nbudgets and the actual GitHub fetch attempts before exact HEAD/tree\nverification.\n\nEach platform diagnostics artifact includes `source-checkout.json` and embeds a\ncompact `sourceCheckout` summary in `diagnostics.json`: mode, transport,\nhit/miss, fallback reason, duration, final HEAD verification, and tree\nverification. Remote URLs are sanitized and local reference paths are represented\nby a short display name plus fingerprint, not by secret-bearing credentials.\nRuntime checkout evidence is uploaded separately as `runtime-checkout.json`,\nincluding cache transport, fallback attempts, and exact runtime `HEAD`\nverification, even when a later lifecycle step fails.\n\nWhen a Buildchain maintainer asks for downstream validation, the expected\nrequest is:\n\n```text\nBuildchain train ready: buildchain-ref=train/v2/v2.3/<capability>.\nKeep uses: ...@v2; run workflow_dispatch with that buildchain-ref and report the runtime evidence summary.\n```\n\nAfter validation succeeds, the Buildchain change should continue through the\nnormal mainline and release path. Do not treat the train as a pending merge\nitem; it is only a temporary fast-use, diagnostic, and rollback channel. It may\nremain for a retention window after release, with old trains handled by a\nseparate periodic cleanup task.\n\n## Workflow Outputs\n\nThe reusable workflow exposes the resolved contract:\n\n| Output | Meaning |\n| --------------------------------- | ------------------------------------------------------------------------------- |\n| `runner-preset` | Resolved preset, or `custom` when `platforms-json` was provided |\n| `platforms-json` | Exact matrix JSON used by the build job |\n| `platform-count` | Number of matrix platforms |\n| `linux-container-enabled` | `true` when Linux platforms are routed through a job container |\n| `linux-container-image` | Resolved digest-pinned Linux job container image |\n| `build-summary-artifact` | Uploaded aggregate summary artifact name |\n| `build-diagnostics-summary-artifact` | Uploaded aggregate diagnostics summary artifact name |\n| `release-candidate-passport-artifact` | Uploaded PR-stage release-candidate passport artifact name when `release-candidate` is enabled |\n| `release-candidate-passport-json` | Compact release-candidate passport JSON when `release-candidate` is enabled |\n| `build-summary-json` | Compact aggregate JSON with platform count, file count, and byte total |\n| `build-diagnostics-summary-json` | Compact aggregate diagnostics JSON with platform, lifecycle warning/error, diagnostics contract warning, and sidecar manifest warning totals |\n| `trusted-event` | `true` when the event is trusted enough to reach build runners |\n| `buildchain-runtime-ref` | Runtime ref selected after applying the empty-default or override policy |\n| `buildchain-runtime-sha` | Immutable Buildchain runtime commit used by all runtime checkouts |\n| `buildchain-runtime-class` | `stable`, `alpha`, `train`, `exact-sha`, or `development` |\n| `buildchain-runtime-override` | `true` when a train or exact-SHA `buildchain-ref` override was accepted |\n| `buildchain-runtime-trust-decision` | Runtime override trust decision |\n| `buildchain-contract-lock-status` | `unchanged`, `compatible-drift`, `breaking-drift`, `missing-lock`, `non-floating-runtime`, or first-release `runtime-contract-unavailable` |\n| `buildchain-contract-lock-drift` | `true` when the floating runtime SHA or contract digest changed |\n| `buildchain-contract-digest` | Current Buildchain runtime contract digest |\n| `publish-channel` | Resolved publish channel requested by the caller |\n| `publish-allowed` | `true` only when this event/ref may publish after verification |\n| `publish-reason` | Human-readable reason for the publish gate decision |\n| `publish-source-ref` | Gate source ref that was resolved before checkout |\n| `publish-source-sha` | Exact source commit used by checkout, build, verify, and artifacts |\n| `publish-source-locked` | `true` when a `publish-gate/*` source ref was explicitly locked |\n| `publish-source-channel` | `alpha`, `release`, `anchor`, or `major` parsed from the source ref |\n| `publish-source-line` | Product line parsed from source refs such as `v22/v22.22` |\n| `publish-source-consumer-version` | Consumer package version parsed from source refs |\n| `release-manifest-json` | Resolved release manifest including source lock, version state, and anchor data |\n\nThe aggregate summaries are intentionally artifacts as well as outputs. GitHub\nActions matrix outputs are not a reliable place to carry every platform's full\nmanifest, so Buildchain uploads each platform manifest and then emits one\naggregate build summary artifact after the matrix completes. Buildchain uploads\n`diagnostics-summary.json` as a separate aggregate diagnostics summary artifact,\na compact rollup of each platform's small diagnostics upload. The rollup keeps\nper-platform runner facts, checked tool versions/missing tools, package\nmanager/cache directory details, compiler-cache availability, lifecycle timing,\nprocess sampler context, and links back to the exact platform artifacts. Each\nplatform diagnostics upload includes `diagnostics.json`,\n`diagnostics-manifest.json`, the lifecycle `events.jsonl`, and process sampler\nsidecars when enabled, so slow-build diagnosis does not require downloading the\nbinary platform artifact or the aggregate build summary. The sidecar manifest\nrecords the uploaded diagnostics files with bytes and sha256 hashes. Each\n`diagnostics.json` also records the related binary artifact name, manifest\nartifact name, diagnostics artifact name, diagnostics sidecar manifest path, and\nplatform id in `links`, so a reviewer can navigate from the small diagnostics\nartifact back to the exact platform outputs when deeper inspection is needed.\nThe workflow output `build-diagnostics-summary-json` includes\n`diagnosticsContractWarningCount` and `diagnosticsManifestWarningCount` so\nrelease jobs can detect drifting diagnostics JSON contracts and missing or\ndrifting diagnostics sidecar manifests without downloading the per-platform\ndiagnostics artifacts first.\n\n## Artifact Transfer Relay\n\nBy default, platform jobs upload payloads, manifests, and diagnostics directly\nto GitHub artifacts:\n\n```yaml\nwith:\n artifact-transfer-mode: github-artifacts\n```\n\nLarge self-hosted native builds can opt into the first-class S3 relay path:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n runner-preset: kungfu-v4-self-hosted\n artifact-transfer-mode: s3-to-github-artifacts\n artifact-relay-s3-bucket: ${{ vars.BUILDCHAIN_ARTIFACT_RELAY_S3_BUCKET }}\n artifact-relay-s3-region: ${{ vars.BUILDCHAIN_ARTIFACT_RELAY_S3_REGION }}\n artifact-relay-s3-prefix: ${{ vars.BUILDCHAIN_ARTIFACT_RELAY_S3_PREFIX }}\n```\n\nIn relay mode, each self-hosted platform job uploads the heavy payload files to\nS3 and uploads only a small `relay-manifest.json` to GitHub. A GitHub-hosted\n`relay-artifacts` job then assumes the configured download role, downloads the\npayloads from S3, verifies every file by SHA256, and re-uploads the normal\nGitHub artifacts under the same artifact names that direct mode uses. Downstream\nsummary, release-candidate, and promote-only workflows therefore continue to\nconsume GitHub artifacts and do not need custom S3 logic.\nThe relay implementation uses Node.js plus the standard AWS environment\ncredentials from GitHub OIDC; runner images and build containers do not need the\nAWS CLI installed.\n\nAfter the GitHub artifact uploads succeed, Buildchain deletes the S3 objects\nlisted in the relay manifest for that platform. If any download, verification,\nor GitHub artifact upload fails, cleanup is skipped so maintainers can inspect\nthe retained S3 payload. Configure a short bucket lifecycle expiration as a\ncost and cleanup backstop.\n\nThe relay configuration is intentionally generic. Buildchain does not hard-code\norganization buckets, regions, or role ARNs. Callers may pass explicit inputs,\nor set repository/organization variables and secrets using these names:\n\n| Variable or secret | Meaning |\n| --- | --- |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_BUCKET` | Relay bucket name |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_REGION` | Relay bucket region |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_PREFIX` | Relay object prefix; defaults to `buildchain-artifacts` |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_ROLE_ARN` | Shared OIDC role ARN for upload and download |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_UPLOAD_ROLE_ARN` | Upload OIDC role ARN for self-hosted build jobs |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_DOWNLOAD_ROLE_ARN` | Download OIDC role ARN for the GitHub-hosted relay job |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_OIDC_AUDIENCE` | Optional OIDC audience override |\n\nFor AWS China regions, Buildchain defaults the OIDC audience to\n`sts.amazonaws.com.cn`; other regions default to `sts.amazonaws.com`. The caller\nworkflow must allow `id-token: write`, and the target role trust policy should\nrestrict GitHub OIDC claims to the expected organization, repository, workflow,\nand branch/ref. The S3 permissions should be scoped to the relay bucket/prefix\nused by the repository.\nUpload roles need write/delete access under the relay prefix; download roles\nneed read access plus delete access for successful cleanup.\n\nRelay mode is opt-in and does not affect forks or open-source users that do not\nconfigure S3. Missing bucket, region, upload role, or download role values fail\nbefore the heavy build matrix is scheduled. Buildchain treats S3 as a transport\ncache, not as the final release evidence store; the final audit entry remains\nthe GitHub artifact set plus the Buildchain build summary and release-candidate\npassport.\n\nSet `release-candidate: true` when the successful reusable build is meant to be\nthe artifact source promoted later. Buildchain then uploads\n`release-candidate-passport.json` under the\n`<artifact-name>-release-candidate-<publish-source-sha>` artifact name. Promotion\njobs can pass that passport to `promote-buildchain-ref` with\n`promote-only-release-candidate: \"true\"` so source, channel, platforms, and the\naggregate build-summary hash are checked before publish-gate side effects. The\npassport records the locked commit's Git tree SHA, so a post-merge channel HEAD\ncan be accepted only when it is tree-equivalent to the PR-stage build evidence.\n\n## Publish Gate\n\nBuildchain separates \"may build/verify\" from \"may publish.\" A same-repository\npull request may be trusted enough to run the build matrix, but it still must\nnot publish packages, S3 objects, release pages, or preview aliases. Publishing\nis allowed only when the caller explicitly requests a channel and the current\nevent/ref matches that channel.\n\nUse `publish-channel` to request a channel:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n publish-channel: release\n\n publish:\n needs: build\n if: ${{ needs.build.outputs.publish-allowed == 'true' }}\n runs-on: ubuntu-24.04\n steps:\n - run: ./scripts/publish.sh\n```\n\nDefault channels are:\n\n| Channel | Allowed refs |\n| --------- | ---------------------------------------------------------------------------------------------------- |\n| `none` | Never publishes; this is the default |\n| `alpha` | `alpha/vN/vN.M` branches or exact `vN.M.P-alpha.K` tags |\n| `release` | `release/vN/vN.M` branches or release tags such as `vN.M.P`, `vN.M`, `vN` |\n| `major` | `publish-gate/major`, legacy `major-gate`, or next-major release tags such as `vN.0.0`, `vN.0`, `vN` |\n\nPull request events always produce `publish-allowed=false`, even when the PR is\nfrom the same repository. Untrusted fork events also produce\n`publish-allowed=false`; with the default `untrusted-policy: fail`, the workflow\nthen fails before any build runner starts.\n\nProjects with their own channel names can pass `publish-refs-json`:\n\n```yaml\nwith:\n publish-channel: nightly\n publish-refs-json: >-\n {\"nightly\":[\"^refs/heads/nightly/v\\\\d+$\"]}\n```\n\nThe aggregate build summary includes the same publish gate decision under\n`publishGate`, so a downloaded artifact summary explains both what was built and\nwhy it was or was not eligible to publish.\n\n## Publish Source Lock\n\n`publish-channel` answers \"may this event publish?\" Source lock answers \"which\nsource tree is the publish decision about?\" A caller can pass `publish-source-ref`\nto bind a publish run to a reviewed gate branch before any checkout happens:\n\n| Ref | Meaning |\n| ------------------------------------------------ | --------------------------------------------------------------------------- |\n| `publish-gate/alpha/<line>/<consumer-version>` | Build and publish an alpha candidate for a consumer line |\n| `publish-gate/release/<line>/<consumer-version>` | Build and publish a production candidate for a consumer line |\n| `publish-gate/anchor` | Resolve an explicit anchor request; it does not publish artifacts by itself |\n| `publish-gate/major` | Gate the next major source state |\n| `major-gate` | Legacy compatibility alias for the major gate |\n\nFor alpha and release refs, `<line>` is intentionally allowed to contain `/`, so\nKungfu-style lines such as `v22/v22.22` stay readable. The final path segment is\nthe consumer-visible version, for example `22.22.3-kf.0`.\n\nThe reusable workflow resolves the branch tip to `publish-source-sha`, checks out\nthat SHA in every build job, and uses the same SHA in artifact names, manifests,\nand aggregate summaries. Reruns therefore rebuild the same source tree even if a\ngate branch moves later.\n\nBefore any heavy build matrix is scheduled, the workflow also verifies that the\ntarget channel ref implied by the source lock already points at\n`publish-source-sha` and that the target channel HEAD came from the required\nmerged same-repository channel PR. `publish-gate/alpha/<line>/<version>` must\nmatch `alpha/<line>` and have PR lineage `dev/<line> -> alpha/<line>`;\n`publish-gate/release/<line>/<version>` must match `release/<line>` and have PR\nlineage `alpha/<line> -> release/<line>`. If either check fails, the run fails\nfast with a diagnostic telling maintainers to merge the source commit through\nthe channel PR first. This keeps verify from spending runner time on a source\ntree that cannot legally enter the requested publish channel.\n\nThe resolved release manifest is uploaded as an artifact and emitted as\n`release-manifest-json`. It records:\n\n- source ref, source SHA, channel, line, and consumer version;\n- configured version strategy and configured version-state files;\n- each version file's value, with release gates failing closed if the configured\n files do not equal the consumer version;\n- anchor manifest summary for anchored/manual projects;\n- explicit anchor request JSON for `publish-gate/anchor`;\n- publish registry, dist-tag, and gate visibility metadata.\n\nPublish side-effect jobs should verify the lock immediately before publishing:\n\n```yaml\n- name: Verify publish gate did not move\n run: node .buildchain/runtime/scripts/verify-publish-source-lock.mjs\n env:\n BUILDCHAIN_PUBLISH_SOURCE_REF: ${{ needs.build.outputs.publish-source-ref }}\n BUILDCHAIN_PUBLISH_SOURCE_SHA: ${{ needs.build.outputs.publish-source-sha }}\n BUILDCHAIN_SOURCE_REPOSITORY: ${{ github.repository }}\n GITHUB_TOKEN: ${{ github.token }}\n```\n\nIf the branch tip no longer matches the manifest SHA, the publish job must fail\nclosed. Moving a gate branch creates a new publish decision and should produce a\nnew build run.\n\n## Release Candidate Promote-Only\n\nFor native package sets, the PR build is the only heavy build. When a PR targets\n`alpha/<line>` or `release/<line>`, `.build.yml` uploads a release-candidate\nbundle next to the platform artifacts. The bundle contains:\n\n- `release-candidate.passport.json`;\n- the aggregate `build-summary.json`;\n- copied platform manifest evidence for the built platforms.\n\nThe passport records two separate source identities:\n\n- `builtSourceSha` / `builtSourceTreeSha`: the PR-stage source that produced the\n artifacts, usually the PR merge ref;\n- `promotionChannelSha` / `promotionChannelTreeSha`: the post-merge channel\n commit used for publish authority.\n\nThe reusable promote wrapper resolves the merged PR, finds exactly one matching\nPR-stage release-candidate artifact, downloads it with the build summary and\npayload artifacts from the same PR-stage run, validates the payload count,\ncompares the built tree with the promotion channel tree, locks\n`publish-gate/{alpha,release,major}` to the promotion channel commit, and then\ncalls `actions/promote-buildchain-ref` with\n`promote-only-release-candidate: \"true\"` and\n`require-publish-source-lock: \"true\"`. The wrapper passes the created\n`publish-gate/*` ref, target SHA, and `locked=true` into the promote action, so\nfloating `@v2` consumers receive publish-side source-lock drift protection by\ndefault. It also defaults `branch-protection-bypass-apps` to `github-actions`\nso the workflow automation can apply generated version-state and channel\nbookkeeping on protected `dev`/`alpha`/`release` branches after the reviewed\nchannel PR has merged; consumers using a different promotion identity can pass\n`branch-protection-bypass-users`, `branch-protection-bypass-teams`, or a\ndifferent app slug declaratively. The wrapper uses\n`secrets.BUILDCHAIN_PROMOTION_TOKEN || github.token` as the generated ref update\ntoken for protected bookkeeping PATCH calls, so a bypass-capable promotion token\ncan sync dev immediately after alpha/release publish without a post-publish PR.\nIt does not call `.build.yml`, does not create a matrix, and must fail before\npublish if the RC evidence, payload set, or source-lock ref is missing or\nambiguous.\n\nThe public `release-candidate-promote.yml` is a generated channel router. It\nderives the publication lane from `target-ref`, then selects the matching\nadvanced workflow shell, runtime, and consumer lock before the advanced\npromotion starts:\n\n- alpha targets use `.release-candidate-promote.yml@vN-alpha`, runtime\n `vN-alpha`, and `buildchain-alpha-contract-lock-path`;\n- release and major targets use `.release-candidate-promote.yml@vN`, runtime\n `vN`, and `buildchain-stable-contract-lock-path`.\n\nThe generated router also owns the stable-shell layout transition through\n`.buildchain/promotion-shell-routing.json`. Stable `v2.14.10` contains the hidden\nadvanced workflow, so the stable lane calls that workflow at the exact immutable\nSHA behind the released `v2` state and forwards the complete internal promotion\nidentity surface. The logical shell identity remains `vN`, and the router\nretains it in the public audit outputs. The internal advanced-shell call receives\nthe exact call ref selected by the routing configuration, so its called-workflow\nref check and checkout SHA both bind to the same immutable identity. Updating the\nrouting pin after a stable release does not require any consumer declaration\nchange.\n\nThe router resolves immutable SHAs and the selected lock digest before candidate\ndownload. The advanced shell verifies the same router, shell, runtime, lock,\nchannel, and target binding again. Train and exact-SHA runtime overrides remain\nrestricted to trusted `workflow_dispatch` actors with write, maintain, or admin\npermission. Promotion controller evidence, the promotion copy of the release\ncandidate passport, and the final release passport record these identities.\n\n```yaml\njobs:\n promote:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@v2\n secrets:\n buildchain-issue-app-id: ${{ secrets.BUILDCHAIN_ISSUE_APP_ID }}\n buildchain-issue-app-private-key: ${{ secrets.BUILDCHAIN_ISSUE_APP_PRIVATE_KEY }}\n with:\n buildchain-channel: auto\n buildchain-alpha-contract-lock-path: .buildchain/alpha-contract-lock.json\n buildchain-stable-contract-lock-path: .buildchain/contract-lock.json\n channel: alpha\n target-ref: alpha/v22/v22.22\n artifact-name: libnode\n # Defaults to build.yml / Build. Override only when the PR-stage build\n # workflow uses a different file or display name.\n release-candidate-workflow-file: build.yml\n release-candidate-workflow-name: Build\n package-manager: npm\n publish-target: npm\n runner-preset: github-hosted\n trusted-publishing: true\n github-release: true\n required-status-check: check / check\n required-artifact-count: 3\n publish-dist-tag: alpha\n publish-package-set-order: platforms-first-main-last\n publish-package-main: \"@kungfu-tech/libnode\"\n release-passport-product-name: Libnode\n buildchain-contract-drift-issue-mode: compatible-and-breaking\n```\n\nExisting callers may keep `buildchain-contract-lock-path`; a non-empty explicit\npath overrides channel-specific selection for compatibility. Migration only\nrequires adding the two channel lock inputs and may retain the remaining common\npromotion declaration unchanged. Consumers must not call the dot-prefixed\nadvanced workflow directly.\n\n`buildchain-issue-app-id` and `buildchain-issue-app-private-key` are optional\nbut recommended for cross-repository consumers. They should identify a GitHub\nApp installation with `issues: write` on `kungfu-systems/buildchain`; the\nwrapper mints the installation token before calling\n`actions/report-buildchain-issue`. Consumers can also pass a pre-minted\n`buildchain-issue-token`. If both are omitted, the wrapper falls back to\n`BUILDCHAIN_ISSUE_TOKEN`, `BUILDCHAIN_PROMOTION_TOKEN`, and then the consumer\nworkflow's `github.token`; the last fallback can only report issues when it has\nwrite access to the target Buildchain repository.\n\n`publish-required-artifacts-json` can still be passed explicitly for custom\npublish targets. Custom OCI requirements may omit pre-publish refs and digests;\nthe action resolves the exact version ref and validates final digests and any\nbuilt/reused provenance after `lifecycle.publish`. For the default\n`publish-artifact-kind: npm` path, consumers do\nnot download artifacts or run repository scripts to build publish evidence. The\nwrapper downloads the PR-stage payload artifacts, finds the downloaded `.tgz`\npackages, reads each tarball's `package/package.json` for the real scoped\npackage name and version, computes the npm `sha512-...` integrity from the\ntarball bytes, marks the package matching `publish-package-main` as `role:\nmain`, marks the rest as `role: platform`, and passes the generated\n`publish-required-artifacts-json` to `promote-buildchain-ref` before any publish\nside effect. Downloaded platform manifests are still passed into the release\npassport unless `release-passport-platform-manifest-paths` is set explicitly.\nThe same Buildchain contract lock check runs before release-candidate\nresolution and before publish. A compatible `v2` drift leaves an issue in the\nconsumer repository but does not trigger a second heavy build; an incompatible\ndrift fails before publish side effects.\n\nThe wrapper publishes the public release tag as a GitHub Release by default.\nAfter `promote-buildchain-ref` reports a complete release transaction, the\nwrapper creates or updates the public release, marks semver prerelease tags\nsuch as `v1.2.3-alpha.0`, `v1.2.3-rc.1`, or `v22.22.3-kf.3-alpha.7` as\n`prerelease=true` and `make_latest=false`, marks stable semver tags as latest,\nand uploads the publish evidence file plus every file in the generated release\npassport directory, including `buildchain.release.json` and `check-report.json`.\nFor anchored/manual package releases, the public release tag is derived from the\npublished package version and the internal exact transaction tag remains\navailable in the release passport.\nConsumers do not need to hand-write `gh release` logic to trigger\n`release.published` propagation. Set `github-release: false` only for\nrepositories that intentionally do not maintain GitHub Releases.\nIf the transaction still needs protected-ref finalization, the wrapper defers\nGitHub Release creation until the later run that reaches `state=complete`.\n\nCustom publish jobs can also repeat the channel-ref preflight:\n\n```yaml\n- name: Verify publish channel ref still matches\n run: node .buildchain/runtime/scripts/verify-publish-channel-ref.mjs\n env:\n BUILDCHAIN_PUBLISH_SOURCE_REF: ${{ needs.build.outputs.publish-source-ref }}\n BUILDCHAIN_PUBLISH_SOURCE_SHA: ${{ needs.build.outputs.publish-source-sha }}\n BUILDCHAIN_SOURCE_REPOSITORY: ${{ github.repository }}\n GITHUB_TOKEN: ${{ github.token }}\n```\n\nAnchored/manual package release jobs should also make the Buildchain promotion\naction validate that publication is entering through the same\n`publish-gate/{alpha,release,major}` source-lock contract before any package\npublish side effect:\n\n```yaml\n- name: Promote release ref and publish npm package set\n uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\n with:\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```\n\n`target-ref` stays the Buildchain channel promotion target, such as\n`alpha/v22/v22.22`, `release/v22/v22.22`, or `publish-gate/major`.\n`publish-source-ref` is the reviewed source-lock branch that authorized this\nspecific package publication. For alpha and release package publications, the\nsource-lock branch must point at the exact channel-line commit that promotion is\nvalidating; it is not a replacement for `target-ref`.\n\nThis keeps the version bump commit, publish authorization, and auditable publish\nentrypoint on the Buildchain source-lock protocol. The CLI form\n`buildchain publish-source validate-anchored-release --json` is still useful for\ncustom publish scripts, but the preferred GitHub Actions gate is the promotion\naction input above. A publish job that still runs directly from `alpha/*` or\n`release/*` channel branches fails this check because those refs are channel\nstate, not publish-gate decisions.\n\n## Package-Set Publish Plan\n\nProjects that publish multiple packages should treat package publication as a\npackage-set operation. Buildchain's package-set planner uses these rules:\n\n- platform packages publish first;\n- the main package publishes last;\n- the dist-tag move happens only after the full package set is present;\n- reruns accept already-published packages only when package name, version, and\n integrity match;\n- an existing package with different integrity is a hard failure.\n\nThis keeps a consumer from observing a floating dist-tag that points to a main\npackage before all platform artifacts for the same source SHA are available.\n\n## Command Sources\n\nThe workflow runs `.buildchain/buildchain.toml` lifecycle stages by default:\n\n```toml\n[lifecycle.install]\ncommand = \"corepack yarn install --immutable\"\n\n[lifecycle.build]\ncommands = [\n \"corepack yarn make\",\n \"corepack yarn build\",\n]\n\n[lifecycle.verify]\ncommand = \"corepack yarn test\"\n```\n\nCallers can override any stage for one invocation:\n\n```yaml\nwith:\n build-command: cmake --build build --config Release\n verify-command: ctest --test-dir build --output-on-failure\n```\n\nEvery native and container matrix job is bounded by\n`lifecycle-timeout-minutes`, which defaults to 120 minutes. The same input is\nthe fallback deadline for each install, build, and verify action, so a hung\ncommand fails with the lifecycle name and matrix platform before it can occupy\na self-hosted runner indefinitely. A stage-level `timeout_minutes` in\n`buildchain.toml` remains the more specific override for that stage.\n\n```yaml\nwith:\n lifecycle-timeout-minutes: 90\n```\n\nThe reusable build workflow samples the build lifecycle by default and carries\nthe generated summary into the final verify diagnostics. Callers can override\nthe sidecar path or disable sampling:\n\n```yaml\nwith:\n sample-process-tree: true\n process-summary-path: .buildchain/diagnostics/process-summary.json\n process-sample-interval-ms: 15000\n requested-parallelism: 20\n```\n\nWhen `sample-process-tree` is true, Buildchain wraps either `build-command` or\nthe configured `lifecycle.build` stage with `buildchain sample process-tree`.\nThe path is relative to the checked-out workspace and is read again during the\nfinal verify lifecycle. Custom workflows can still write their own sampler\nsummary and pass `process-summary-path`; Buildchain reads the file after the\nlifecycle command finishes, so it may be produced during the same invocation.\nWhen the build stage is optional, the reusable workflow treats the default\nsampler path as optional during verify; an explicitly supplied\n`process-summary-path` remains required.\n\nFor custom workflows, use the action directly:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/run-lifecycle@v2\n with:\n stage: build\n required: \"true\"\n timeout-minutes: \"90\"\n artifact-name: libnode-linux-x64-${{ github.sha }}\n artifact-paths: |\n dist\n build/stage\n```\n\n## Artifact Contract\n\nEach platform upload uses `artifact-name-template`. The default is:\n\n```text\n{artifact}-{platform}-{sha}\n```\n\nSupported placeholders are `{artifact}`, `{artifactName}`, `{platform}`,\n`{platformId}`, `{platformName}`, `{sha}`, `{shortSha}`, `{ref}`, `{runId}`,\nand `{runAttempt}`. Invalid GitHub artifact name characters are normalized to\n`-`, so `{ref}` remains deterministic even for refs such as\n`refs/heads/dev/v2/v2.0`.\n\nEach platform also writes and uploads:\n\n```text\n.buildchain/artifacts/<platform-id>/manifest.json\n.buildchain/artifacts/<platform-id>/summary.json\n```\n\nThe manifest schema is:\n\n```json\n{\n \"schemaVersion\": 1,\n \"contract\": \"kungfu-buildchain-artifact\",\n \"artifactName\": \"libnode-linux-x64-<sha>\",\n \"platform\": {\n \"id\": \"linux-x64\",\n \"name\": \"Linux x64\",\n \"os\": \"Linux\",\n \"arch\": \"X64\"\n },\n \"git\": {\n \"repository\": \"kungfu-systems/libnode\",\n \"sha\": \"<sha>\",\n \"ref\": \"<ref>\",\n \"runId\": \"<run id>\",\n \"runAttempt\": \"<attempt>\"\n },\n \"lifecycle\": {\n \"stage\": \"verify\",\n \"commandSource\": \"buildchain.toml\",\n \"executed\": true\n },\n \"summary\": {\n \"contract\": \"kungfu-buildchain-artifact-summary\",\n \"artifactName\": \"libnode-linux-x64-<sha>\",\n \"fileCount\": 1,\n \"totalBytes\": 1234,\n \"digest\": \"<hex>\"\n },\n \"expectedArtifacts\": {\n \"ok\": true,\n \"source\": \"expected-artifacts-json\",\n \"checks\": []\n },\n \"files\": [\n {\n \"path\": \"dist/example.zip\",\n \"size\": 1234,\n \"sha256\": \"<hex>\"\n }\n ]\n}\n```\n\nArtifact names do not include actor names, timestamps, or retry counters. Reruns\nproduce a new GitHub Actions run but keep the same source SHA/platform contract.\n\n`expected-artifacts-json` fails the build before upload when the artifact does\nnot match the caller's declared contract. Supported checks are:\n\n| Field | Meaning |\n| --------------- | ------------------------------------ |\n| `minFiles` | Minimum number of manifest files |\n| `maxFiles` | Maximum number of manifest files |\n| `minTotalBytes` | Minimum total byte count |\n| `requiredPaths` | Exact manifest paths that must exist |\n\n## Trusted Event Gate\n\nThe workflow has an explicit `trust-gate` job. By default, pull requests from\nforks fail before any build job can reach self-hosted runners, secrets,\npublishing credentials, or heavyweight build commands. Same-repository PRs,\nworkflow dispatches, and protected branch events can proceed.\n\nIf a repository wants fork PRs to skip rather than fail, it can set:\n\n```yaml\nwith:\n untrusted-policy: skip\n```\n\nDo not set `require-trusted-event: false` for workflows that use self-hosted\nrunners or secrets.\n\n`require-trusted-event` controls access to build runners. It does not override\nthe publish gate: pull requests remain non-publishing events.\n\n## Fixture\n\n`fixtures/libnode-shaped` is the contract fixture. It has:\n\n- `package.json` version state;\n- `.buildchain/buildchain.toml` with `install`, `build`, `verify`, and `publish`;\n- cross-platform Node scripts that create small `dist/` outputs;\n- `Build Surface Fixture` workflow coverage.\n\nThe fixture proves the reusable surface without running the real libnode native\nbuild."
|
|
1741
|
+
"markdown": "# Reusable Build Surface\n\nBuildchain v2 provides a reusable build workflow for repositories that need\nBuildchain's release semantics but cannot be described as a simple Node package.\nThe first target shape is `libnode`: expensive native builds, multiple operating\nsystems, self-hosted runner labels, and release artifacts that must be auditable.\n\n## Automatic Channel Router\n\nThe preferred consumer surface is one reusable workflow call. After v2.12\nreaches the stable major ref, consumers keep this configuration for both alpha\ndevelopment and stable release work:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v2\n permissions:\n contents: read\n issues: write\n id-token: write\n with:\n working-directory: .\n artifact-name: libnode\n runner-preset: kungfu-v4-self-hosted\n publish-channel: none\n secrets: inherit\n```\n\n`buildchain-channel` defaults to `auto`. Selection uses this precedence:\n\n1. an explicit `buildchain-ref` train, SHA, or official channel;\n2. an explicit `buildchain-channel: alpha|stable`;\n3. `publish-channel: alpha|release|major`;\n4. GitHub release prerelease metadata;\n5. a canonical semver tag;\n6. non-release PR, push, dispatch, schedule, and workflow-run events default to\n alpha.\n\nThe resolved runtime is `vN-alpha` for development and prerelease intent and\n`vN` for stable release intent. Unknown custom publish channels, malformed\nrelease events, and non-semver release-like tags fail before the build matrix;\nthey never guess alpha for a stable release.\n\nThe router automatically selects `.buildchain/alpha-contract-lock.json` for\nalpha and `.buildchain/contract-lock.json` for stable. A repository can override\nthe common path with `buildchain-contract-lock-path`, or override one channel\nwith `buildchain-alpha-contract-lock-path` /\n`buildchain-stable-contract-lock-path`.\n\nOnly repositories changing the default policy need extra routing input:\n\n```yaml\nwith:\n buildchain-channel: stable\n```\n\nDuring the v2.12 prerelease evaluation window, canaries use\n`build.yml@v2-alpha`. The same router then selects `v2-alpha` or stable `v2` as\nthe runtime. Production consumers should adopt `build.yml@v2` after the router\nhas reached stable; this keeps the routing shell itself on a stable ref.\n\nThe router is generated from `.build.yml`'s input/output surface. Run\n`node scripts/generate-channel-build-workflow.mjs` after changing the advanced\nbuild workflow; inventory and unit tests reject a stale generated router.\n\n## Advanced Workflow\n\nConsumers that need direct workflow-shell or runtime control call the advanced\nsurface:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n working-directory: .\n artifact-name: libnode\n runner-preset: kungfu-v4-self-hosted\n linux-container-preset: kungfu-verify\n artifact-name-template: \"{artifact}-{platform}-{sha}\"\n artifact-paths: |\n dist\n build/stage\n expected-artifacts-json: >-\n {\"minFiles\":2,\"requiredPaths\":[\"dist/libnode.tar.gz\",\"dist/checksums.txt\"]}\n process-summary-path: .buildchain/diagnostics/process-summary.json\n release-candidate: true\n publish-channel: release\n publish-source-ref: publish-gate/release/v22/v22.22/22.22.3-kf.0\n```\n\n`runner-preset` is the stable first-class surface for known runner fleets:\n\n| Preset | Platforms |\n| ----------------------- | ------------------------------------------------------------------------ |\n| `github-hosted` | `ubuntu-24.04`, `macos-latest`, `windows-2022` |\n| `kungfu-v4-self-hosted` | Kungfu Linux x64, macOS ARM64, and Windows x64 self-hosted runner labels |\n| `custom` | Requires `platforms-json` |\n\nCallers can still provide a custom matrix with `platforms-json`. Each platform\nobject has:\n\n| Field | Meaning |\n| -------- | ------------------------------------------------- |\n| `id` | Stable artifact/platform key, such as `linux-x64` |\n| `name` | Human-readable job name |\n| `runner` | JSON string passed to `runs-on` after `fromJSON` |\n\nThe runner field is intentionally a JSON string so callers can pass either\nGitHub-hosted runners or multi-label self-hosted runners without Buildchain\nguessing the labels.\n\nOnly include platforms that should run. GitHub schedules matrix jobs before\nsteps execute, so a disabled entry with unavailable runner labels can still\nblock the workflow queue.\n\n## Linux Job Containers\n\nLinux build platforms can run inside a digest-pinned job container while macOS\nand Windows keep using native runners. This is the recommended way to remove\nmoving Linux runner prerequisites from Buildchain consumers: the Linux host only\nneeds a GitHub Actions runner, Docker, and network access; common verification\ntools come from the image contract.\n\nUse the Kungfu verification image for lifecycle stages that need Git, jq,\nPython, uv, and fnm, but do not need native compilation:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n runner-preset: kungfu-v4-self-hosted\n linux-container-preset: kungfu-verify\n```\n\n`kungfu-verify` resolves to:\n\n```text\nghcr.io/kungfu-systems/build-images/kungfu-verify@sha256:11f0ba64267ce88174a4f73a9bf833ff4e9c59cd16ec3d08a6432a06c2be6fb1\n```\n\nCallers that own a different Linux image can pass it explicitly:\n\n```yaml\nwith:\n linux-container-preset: custom\n linux-container-image: ghcr.io/example/project-build@sha256:<digest>\n```\n\n`linux-container-image` should be pinned by digest. A floating tag makes the\nrunner surface mutable and weakens Buildchain's release evidence.\n\nThe workflow splits the matrix into two build jobs:\n\n- Linux platforms go to `build-linux-container` when a Linux container is\n configured.\n- All other platforms go to `build-native`.\n\nArtifact names, manifest paths, expected artifact checks, publish-source locks,\nand aggregate summaries are the same in both jobs. The split is an execution\ndetail, not a different artifact contract.\n\n## Native Rust Toolchains\n\nNative lifecycle jobs can request an isolated Rust installation instead of\ndepending on a self-hosted runner user's PATH:\n\n```yaml\nwith:\n setup-rust: true\n rust-toolchain: \"1.96.0\"\n rustup-dist-server: \"https://rsproxy.cn\"\n rustup-update-root: \"https://rsproxy.cn/rustup\"\n cargo-registry-index: ${{ vars.BUILDCHAIN_CARGO_REGISTRY_INDEX }}\n```\n\n`setup-rust` defaults to `false`, so existing consumers are unchanged. When it\nis enabled, Buildchain installs `rust-toolchain` before the install, build, and\nverify lifecycle stages on every native matrix platform. Windows uses the\nofficial rustup bootstrap through `cmd.exe` and `curl.exe` into runner-temporary\nCargo and rustup homes, so it works under a restrictive PowerShell execution\npolicy and the service account does not depend on another user's PATH or mutate\nhost toolchain state. Pin an exact toolchain for release builds. Linux container jobs continue\nto obtain Rust from their digest-pinned image contract; Buildchain does not\nmutate that container surface.\n\nThe rustup server inputs are optional and default to Rust's official servers.\nConsumers behind a slow cross-border link may select a trusted transport mirror;\nrustup still verifies the selected toolchain's distribution metadata and\ncomponent checksums.\n\n`cargo-registry-index` is also optional. When set, Buildchain exposes it to\nCargo as `CARGO_REGISTRIES_CRATES_IO_INDEX` for every native lifecycle stage,\nso a self-hosted runner can use a repository or organization variable without\ncommitting private LAN topology to public workflow YAML. The endpoint must be a\ncrates.io-compatible index whose `config.json` download contract serves the\nmatching checksum-verified crate archives. An empty value preserves Cargo's\nnormal crates.io behavior.\n\nThe container image provides `fnm` but does not preinstall Node. Buildchain uses\n`fnm` inside the container to install the requested `node-version` before it\nruns Buildchain runtime scripts or lifecycle actions.\n\nDo not use `kungfu-verify` for stages that need CMake, Ninja, ccache, Conan, or\nDocker image publishing. Those should use a heavier native-build image or remain\non a host runner until their image contract is explicit.\n\n## Buildchain Runtime Override\n\nStable consumers should keep the reusable workflow pinned to stable refs such as\n`@v2`. The optional `buildchain-ref` input is empty by default; empty means\nBuildchain resolves and executes the stable runtime selected by the workflow\nshell. The full train validation protocol is documented in\n[`runtime-train-validation.md`](runtime-train-validation.md).\n\nFor one-off manual validation, a trusted maintainer can run the caller workflow\nwith a temporary runtime override:\n\n```yaml\non:\n workflow_dispatch:\n inputs:\n buildchain-ref:\n description: \"Temporary Buildchain runtime ref for trusted manual validation\"\n required: false\n default: \"\"\n\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n buildchain-ref: ${{ inputs.buildchain-ref || '' }}\n```\n\nAllowed override refs are deliberately narrow:\n\n| Ref form | Meaning |\n| --- | --- |\n| `train/v2/v2.3/<capability>` | Temporary capability train under the active minor line |\n| `refs/heads/train/v2/v2.3/<capability>` | Explicit branch ref for the same train |\n| `<40-character SHA>` | Exact immutable Buildchain runtime commit |\n\nOverride requests fail closed unless the event is `workflow_dispatch` and the\nactor has write, maintain, or admin permission on the caller repository.\nPull requests, including same-repository pull requests and fork-originated pull\nrequests, cannot use `buildchain-ref` override. This keeps automated PR builds on\nthe stable runtime surface.\n\nEvery run resolves the runtime ref to an immutable SHA before checkout. The job\nsummary and aggregate build summary record the workflow shell ref, requested\nruntime ref, resolved runtime ref, runtime SHA, stability class, trust decision,\nand rollback ref. Train refs are development validation refs: they do not move\n`v2`, `vX.Y`, `vX.Y-alpha`, npm dist-tags, or production release refs, and they\nmust not be pinned as long-term production dependencies.\n\nRuntime override validates Buildchain runtime scripts, CLI code, local actions,\nconfig parsing, and lifecycle behavior. It cannot validate changes that require\nthe outer reusable workflow YAML itself to change, such as new jobs,\npermissions, workflow outputs, or matrix topology. Those changes need a canary\nworkflow path or a temporary explicit workflow ref.\n\n## Floating Ref Contract Lock\n\nStable consumers should use floating major refs such as `@v2`, but a floating\nref is not blind trust. Each released Buildchain ref carries a package-owned\nruntime contract world in `dist/site/buildchain-contract.json`. Consumers may\nkeep a small lock file, `.buildchain/contract-lock.json`, recording the\nBuildchain ref, resolved SHA, contract digest, compatibility digest, accepted\nmajor line, and compatibility policy they reviewed.\n\nThe reusable build trust gate checks this lock before any heavy matrix job:\n\n1. resolve the Buildchain runtime ref, for example `v2`, to an immutable SHA;\n2. read `dist/site/buildchain-contract.json` from that checked-out Buildchain\n ref;\n3. read the consumer's `.buildchain/contract-lock.json`;\n4. compare the accepted contract with the current contract.\n\nSHA drift alone is not a failure. `v2` is expected to advance. Buildchain only\nfails fast when the accepted contract is no longer compatible, for example a\nrequired input is removed, a required output disappears, a protected behavior\npromise changes, or the major line changes. Additive changes such as optional\ninputs, optional outputs, diagnostics, or documentation updates continue under\nthe default `major-compatible` policy.\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n permissions:\n contents: read\n issues: write\n id-token: write\n with:\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n buildchain-contract-compatibility-policy: major-compatible\n buildchain-contract-drift-issue-mode: compatible-and-breaking\n```\n\nWhen compatible drift is detected, the build continues and Buildchain opens or\nupdates a low-priority issue in the consumer repository. The issue records the\nold SHA/digest, new SHA/digest, compatibility result, workflow run, and the next\naction: review the Buildchain release notes and update the lock. When breaking\ndrift is detected, the same issue path is used, but the trust gate fails before\nmatrix build or publish work starts. If the workflow token cannot write issues,\nBuildchain writes a copyable issue body into the job summary.\n\nThe lock is intentionally small. It does not copy the full contract. The full\ncontract remains in the Buildchain ref and package; the consumer records only\nwhat it accepted and the policy used to compare future floating-ref movement.\n\nAdvanced alpha-channel consumers select the matching workflow shell:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2-alpha\n with:\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe runtime follows the called workflow through `job.workflow_ref`. Callers may\nalso pass `buildchain-ref: v2-alpha` explicitly; official floating refs are\nordinary channel selections and are allowed on pull requests and pushes. Train\nrefs and exact SHAs remain trusted manual overrides.\n\n## Shifu Cache Profile Passthrough\n\nBuildchain can carry one trusted Shifu cache-profile reference and its exact\ndigest into lifecycle execution. Its contract is an opaque reference and digest\nonly. This surface is deliberately opaque:\nBuildchain does not fetch the profile, parse JSON, select cache services,\nrewrite bindings, decide fallback, or emit Shifu resolution evidence. Those\nsemantics remain owned by the consumer's pinned Shifu implementation.\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v2\n with:\n shifu-cache-profile-ref: ${{ vars.SHIFU_CACHE_PROFILE_REF }}\n shifu-cache-profile-digest: ${{ vars.SHIFU_CACHE_PROFILE_DIGEST }}\n```\n\nThe reusable workflow passes the pair as `SHIFU_CACHE_PROFILE_REF` and\n`SHIFU_CACHE_PROFILE_DIGEST` to install, build, and verify lifecycle commands.\nThe consumer must invoke its Shifu cache-aware execution surface. An empty pair\npreserves existing behavior; a consumer Shifu should fail closed when exactly\none value is present or the resolved bytes do not match the expected digest.\n\nUse trusted repository or organization variables rather than PR-controlled\nfiles for private/LAN references. The variables must remain secret-free; any\ncredentials use a separate provider-approved secret surface and must not be\nembedded in the profile reference. This passthrough is separate from\nBuildchain's locked source checkout cache below: Buildchain owns checkout\ntransport and source identity, while Shifu owns post-checkout execution cache\nbindings and receipts.\n\n## Locked Source Checkout Cache\n\nSelf-hosted runners that build large repositories can opt into a locked checkout\ncache for both the consumer source and the Buildchain runtime. This changes only\nthe Git object transport. Buildchain still resolves `publish-source-sha` and the\nruntime SHA before any build runner starts, checks out those exact commits, and\nverifies each final `HEAD` plus the resolved consumer source tree SHA before\nlifecycle commands run.\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n runner-preset: kungfu-v4-self-hosted\n checkout-cache-mode: auto\n checkout-cache-mirror-url-template: ${{ vars.BUILDCHAIN_CHECKOUT_CACHE_MIRROR_URL_TEMPLATE }}\n checkout-cache-reference-repository-template: ${{ vars.BUILDCHAIN_CHECKOUT_CACHE_REFERENCE_REPOSITORY_TEMPLATE }}\n checkout-cache-fallback: github\n checkout-cache-timeout-seconds: 60\n checkout-cache-github-timeout-seconds: 600\n checkout-cache-fetch-attempts: 3\n```\n\n`checkout-cache-mode` accepts:\n\n| Mode | Behavior |\n| --- | --- |\n| `off` | Default. Buildchain fetches the locked commit from GitHub. |\n| `auto` | Try the trusted cache first; on miss, record the miss and fall back according to `checkout-cache-fallback`. |\n| `require` | Require the cache to provide the locked commit and fail before lifecycle work if unavailable. |\n\nThe cache can be a local/LAN mirror URL template or a runner-local bare\nreference repository template. Templates support `{owner}`, `{repo}`,\n`{repository}`, `{repositorySlug}`, and `{sha}`. The workflow also reads\nrepository or organization variables named\n`BUILDCHAIN_CHECKOUT_CACHE_MIRROR_URL_TEMPLATE` and\n`BUILDCHAIN_CHECKOUT_CACHE_REFERENCE_REPOSITORY_TEMPLATE`, so consumers can keep\nprivate LAN topology out of repository YAML.\n\nThe GitHub-hosted trust gate resolves the reusable workflow shell to an exact\ncommit and uploads that shell's small checkout bootstrap script. Native and\nLinux-container build jobs download the bootstrap, then use the same cache\npolicy to obtain both the selected Buildchain runtime and consumer source at\ntheir already resolved immutable SHAs. Keeping the bootstrap owned by the\nworkflow shell is important when `@vN-alpha` routes a stable release to an older\n`vN` runtime: the stable runtime does not need to already contain the newest\ncheckout transport implementation. This also prevents a large direct\n`actions/checkout` runtime clone from becoming a separate timeout path on\nconstrained self-hosted uplinks. The bootstrap artifact does not contain the\nruntime repository and cannot move either selected ref.\n\nDo not read cache URLs or reference paths from PR-controlled files such as\n`.buildchain/buildchain.toml`. These values are trusted workflow inputs or repo/org\nvariables. Buildchain does not pass GitHub credentials to cache mirrors or\nreference repositories. If it must fall back to GitHub, the workflow token is\nused only for the GitHub fetch path. Cache attempts use\n`checkout-cache-timeout-seconds`; the potentially larger GitHub fallback uses\nthe independent `checkout-cache-github-timeout-seconds` budget (600 seconds by\ndefault). Buildchain fetches the advertised source ref before trying an exact\nSHA, so a cache hit or stale-cache seed can contribute objects and the fallback\ndoes not first waste a full timeout on an unadvertised SHA. Retryable timeout\nand transient network failures use the bounded `checkout-cache-fetch-attempts`\nbudget; permanent failures stop immediately. Diagnostics record both timeout\nbudgets and the actual GitHub fetch attempts before exact HEAD/tree\nverification.\n\nEach platform diagnostics artifact includes `source-checkout.json` and embeds a\ncompact `sourceCheckout` summary in `diagnostics.json`: mode, transport,\nhit/miss, fallback reason, duration, final HEAD verification, and tree\nverification. Remote URLs are sanitized and local reference paths are represented\nby a short display name plus fingerprint, not by secret-bearing credentials.\nRuntime checkout evidence is uploaded separately as `runtime-checkout.json`,\nincluding cache transport, fallback attempts, and exact runtime `HEAD`\nverification, even when a later lifecycle step fails.\n\nWhen a Buildchain maintainer asks for downstream validation, the expected\nrequest is:\n\n```text\nBuildchain train ready: buildchain-ref=train/v2/v2.3/<capability>.\nKeep uses: ...@v2; run workflow_dispatch with that buildchain-ref and report the runtime evidence summary.\n```\n\nAfter validation succeeds, the Buildchain change should continue through the\nnormal mainline and release path. Do not treat the train as a pending merge\nitem; it is only a temporary fast-use, diagnostic, and rollback channel. It may\nremain for a retention window after release, with old trains handled by a\nseparate periodic cleanup task.\n\n## Workflow Outputs\n\nThe reusable workflow exposes the resolved contract:\n\n| Output | Meaning |\n| --------------------------------- | ------------------------------------------------------------------------------- |\n| `runner-preset` | Resolved preset, or `custom` when `platforms-json` was provided |\n| `platforms-json` | Exact matrix JSON used by the build job |\n| `platform-count` | Number of matrix platforms |\n| `linux-container-enabled` | `true` when Linux platforms are routed through a job container |\n| `linux-container-image` | Resolved digest-pinned Linux job container image |\n| `build-summary-artifact` | Uploaded aggregate summary artifact name |\n| `build-diagnostics-summary-artifact` | Uploaded aggregate diagnostics summary artifact name |\n| `release-candidate-passport-artifact` | Uploaded PR-stage release-candidate passport artifact name when `release-candidate` is enabled |\n| `release-candidate-passport-json` | Compact release-candidate passport JSON when `release-candidate` is enabled |\n| `build-summary-json` | Compact aggregate JSON with platform count, file count, and byte total |\n| `build-diagnostics-summary-json` | Compact aggregate diagnostics JSON with platform, lifecycle warning/error, diagnostics contract warning, and sidecar manifest warning totals |\n| `trusted-event` | `true` when the event is trusted enough to reach build runners |\n| `buildchain-runtime-ref` | Runtime ref selected after applying the empty-default or override policy |\n| `buildchain-runtime-sha` | Immutable Buildchain runtime commit used by all runtime checkouts |\n| `buildchain-runtime-class` | `stable`, `alpha`, `train`, `exact-sha`, or `development` |\n| `buildchain-runtime-override` | `true` when a train or exact-SHA `buildchain-ref` override was accepted |\n| `buildchain-runtime-trust-decision` | Runtime override trust decision |\n| `buildchain-contract-lock-status` | `unchanged`, `compatible-drift`, `breaking-drift`, `missing-lock`, `non-floating-runtime`, or first-release `runtime-contract-unavailable` |\n| `buildchain-contract-lock-drift` | `true` when the floating runtime SHA or contract digest changed |\n| `buildchain-contract-digest` | Current Buildchain runtime contract digest |\n| `publish-channel` | Resolved publish channel requested by the caller |\n| `publish-allowed` | `true` only when this event/ref may publish after verification |\n| `publish-reason` | Human-readable reason for the publish gate decision |\n| `publish-source-ref` | Gate source ref that was resolved before checkout |\n| `publish-source-sha` | Exact source commit used by checkout, build, verify, and artifacts |\n| `publish-source-locked` | `true` when a `publish-gate/*` source ref was explicitly locked |\n| `publish-source-channel` | `alpha`, `release`, `anchor`, or `major` parsed from the source ref |\n| `publish-source-line` | Product line parsed from source refs such as `v22/v22.22` |\n| `publish-source-consumer-version` | Consumer package version parsed from source refs |\n| `release-manifest-json` | Resolved release manifest including source lock, version state, and anchor data |\n\nThe aggregate summaries are intentionally artifacts as well as outputs. GitHub\nActions matrix outputs are not a reliable place to carry every platform's full\nmanifest, so Buildchain uploads each platform manifest and then emits one\naggregate build summary artifact after the matrix completes. Buildchain uploads\n`diagnostics-summary.json` as a separate aggregate diagnostics summary artifact,\na compact rollup of each platform's small diagnostics upload. The rollup keeps\nper-platform runner facts, checked tool versions/missing tools, package\nmanager/cache directory details, compiler-cache availability, lifecycle timing,\nprocess sampler context, and links back to the exact platform artifacts. Each\nplatform diagnostics upload includes `diagnostics.json`,\n`diagnostics-manifest.json`, the lifecycle `events.jsonl`, and process sampler\nsidecars when enabled, so slow-build diagnosis does not require downloading the\nbinary platform artifact or the aggregate build summary. The sidecar manifest\nrecords the uploaded diagnostics files with bytes and sha256 hashes. Each\n`diagnostics.json` also records the related binary artifact name, manifest\nartifact name, diagnostics artifact name, diagnostics sidecar manifest path, and\nplatform id in `links`, so a reviewer can navigate from the small diagnostics\nartifact back to the exact platform outputs when deeper inspection is needed.\nThe workflow output `build-diagnostics-summary-json` includes\n`diagnosticsContractWarningCount` and `diagnosticsManifestWarningCount` so\nrelease jobs can detect drifting diagnostics JSON contracts and missing or\ndrifting diagnostics sidecar manifests without downloading the per-platform\ndiagnostics artifacts first.\n\n## Artifact Transfer Relay\n\nBy default, platform jobs upload payloads, manifests, and diagnostics directly\nto GitHub artifacts:\n\n```yaml\nwith:\n artifact-transfer-mode: github-artifacts\n```\n\nLarge self-hosted native builds can opt into the first-class S3 relay path:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n runner-preset: kungfu-v4-self-hosted\n artifact-transfer-mode: s3-to-github-artifacts\n artifact-relay-s3-bucket: ${{ vars.BUILDCHAIN_ARTIFACT_RELAY_S3_BUCKET }}\n artifact-relay-s3-region: ${{ vars.BUILDCHAIN_ARTIFACT_RELAY_S3_REGION }}\n artifact-relay-s3-prefix: ${{ vars.BUILDCHAIN_ARTIFACT_RELAY_S3_PREFIX }}\n```\n\nIn relay mode, each self-hosted platform job uploads the heavy payload files to\nS3 and uploads only a small `relay-manifest.json` to GitHub. A GitHub-hosted\n`relay-artifacts` job then assumes the configured download role, downloads the\npayloads from S3, verifies every file by SHA256, and re-uploads the normal\nGitHub artifacts under the same artifact names that direct mode uses. Downstream\nsummary, release-candidate, and promote-only workflows therefore continue to\nconsume GitHub artifacts and do not need custom S3 logic.\nThe relay implementation uses Node.js plus the standard AWS environment\ncredentials from GitHub OIDC; runner images and build containers do not need the\nAWS CLI installed.\n\nAfter the GitHub artifact uploads succeed, Buildchain deletes the S3 objects\nlisted in the relay manifest for that platform. If any download, verification,\nor GitHub artifact upload fails, cleanup is skipped so maintainers can inspect\nthe retained S3 payload. Configure a short bucket lifecycle expiration as a\ncost and cleanup backstop.\n\nThe relay configuration is intentionally generic. Buildchain does not hard-code\norganization buckets, regions, or role ARNs. Callers may pass explicit inputs,\nor set repository/organization variables and secrets using these names:\n\n| Variable or secret | Meaning |\n| --- | --- |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_BUCKET` | Relay bucket name |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_REGION` | Relay bucket region |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_PREFIX` | Relay object prefix; defaults to `buildchain-artifacts` |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_ROLE_ARN` | Shared OIDC role ARN for upload and download |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_UPLOAD_ROLE_ARN` | Upload OIDC role ARN for self-hosted build jobs |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_DOWNLOAD_ROLE_ARN` | Download OIDC role ARN for the GitHub-hosted relay job |\n| `BUILDCHAIN_ARTIFACT_RELAY_S3_OIDC_AUDIENCE` | Optional OIDC audience override |\n\nFor AWS China regions, Buildchain defaults the OIDC audience to\n`sts.amazonaws.com.cn`; other regions default to `sts.amazonaws.com`. The caller\nworkflow must allow `id-token: write`, and the target role trust policy should\nrestrict GitHub OIDC claims to the expected organization, repository, workflow,\nand branch/ref. The S3 permissions should be scoped to the relay bucket/prefix\nused by the repository.\nUpload roles need write/delete access under the relay prefix; download roles\nneed read access plus delete access for successful cleanup.\n\nRelay mode is opt-in and does not affect forks or open-source users that do not\nconfigure S3. Missing bucket, region, upload role, or download role values fail\nbefore the heavy build matrix is scheduled. Buildchain treats S3 as a transport\ncache, not as the final release evidence store; the final audit entry remains\nthe GitHub artifact set plus the Buildchain build summary and release-candidate\npassport.\n\nSet `release-candidate: true` when the successful reusable build is meant to be\nthe artifact source promoted later. Buildchain then uploads\n`release-candidate-passport.json` under the\n`<artifact-name>-release-candidate-<publish-source-sha>` artifact name. Promotion\njobs can pass that passport to `promote-buildchain-ref` with\n`promote-only-release-candidate: \"true\"` so source, channel, platforms, and the\naggregate build-summary hash are checked before publish-gate side effects. The\npassport records the locked commit's Git tree SHA, so a post-merge channel HEAD\ncan be accepted only when it is tree-equivalent to the PR-stage build evidence.\n\n## Publish Gate\n\nBuildchain separates \"may build/verify\" from \"may publish.\" A same-repository\npull request may be trusted enough to run the build matrix, but it still must\nnot publish packages, S3 objects, release pages, or preview aliases. Publishing\nis allowed only when the caller explicitly requests a channel and the current\nevent/ref matches that channel.\n\nUse `publish-channel` to request a channel:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n publish-channel: release\n\n publish:\n needs: build\n if: ${{ needs.build.outputs.publish-allowed == 'true' }}\n runs-on: ubuntu-24.04\n steps:\n - run: ./scripts/publish.sh\n```\n\nDefault channels are:\n\n| Channel | Allowed refs |\n| --------- | ---------------------------------------------------------------------------------------------------- |\n| `none` | Never publishes; this is the default |\n| `alpha` | `alpha/vN/vN.M` branches or exact `vN.M.P-alpha.K` tags |\n| `release` | `release/vN/vN.M` branches or release tags such as `vN.M.P`, `vN.M`, `vN` |\n| `major` | `publish-gate/major`, legacy `major-gate`, or next-major release tags such as `vN.0.0`, `vN.0`, `vN` |\n\nPull request events always produce `publish-allowed=false`, even when the PR is\nfrom the same repository. Untrusted fork events also produce\n`publish-allowed=false`; with the default `untrusted-policy: fail`, the workflow\nthen fails before any build runner starts.\n\nProjects with their own channel names can pass `publish-refs-json`:\n\n```yaml\nwith:\n publish-channel: nightly\n publish-refs-json: >-\n {\"nightly\":[\"^refs/heads/nightly/v\\\\d+$\"]}\n```\n\nThe aggregate build summary includes the same publish gate decision under\n`publishGate`, so a downloaded artifact summary explains both what was built and\nwhy it was or was not eligible to publish.\n\n## Publish Source Lock\n\n`publish-channel` answers \"may this event publish?\" Source lock answers \"which\nsource tree is the publish decision about?\" A caller can pass `publish-source-ref`\nto bind a publish run to a reviewed gate branch before any checkout happens:\n\n| Ref | Meaning |\n| ------------------------------------------------ | --------------------------------------------------------------------------- |\n| `publish-gate/alpha/<line>/<consumer-version>` | Build and publish an alpha candidate for a consumer line |\n| `publish-gate/release/<line>/<consumer-version>` | Build and publish a production candidate for a consumer line |\n| `publish-gate/anchor` | Resolve an explicit anchor request; it does not publish artifacts by itself |\n| `publish-gate/major` | Gate the next major source state |\n| `major-gate` | Legacy compatibility alias for the major gate |\n\nFor alpha and release refs, `<line>` is intentionally allowed to contain `/`, so\nKungfu-style lines such as `v22/v22.22` stay readable. The final path segment is\nthe consumer-visible version, for example `22.22.3-kf.0`.\n\nThe reusable workflow resolves the branch tip to `publish-source-sha`, checks out\nthat SHA in every build job, and uses the same SHA in artifact names, manifests,\nand aggregate summaries. Reruns therefore rebuild the same source tree even if a\ngate branch moves later.\n\nBefore any heavy build matrix is scheduled, the workflow also verifies that the\ntarget channel ref implied by the source lock already points at\n`publish-source-sha` and that the target channel HEAD came from the required\nmerged same-repository channel PR. `publish-gate/alpha/<line>/<version>` must\nmatch `alpha/<line>` and have PR lineage `dev/<line> -> alpha/<line>`;\n`publish-gate/release/<line>/<version>` must match `release/<line>` and have PR\nlineage `alpha/<line> -> release/<line>`. If either check fails, the run fails\nfast with a diagnostic telling maintainers to merge the source commit through\nthe channel PR first. This keeps verify from spending runner time on a source\ntree that cannot legally enter the requested publish channel.\n\nThe resolved release manifest is uploaded as an artifact and emitted as\n`release-manifest-json`. It records:\n\n- source ref, source SHA, channel, line, and consumer version;\n- configured version strategy and configured version-state files;\n- each version file's value, with release gates failing closed if the configured\n files do not equal the consumer version;\n- anchor manifest summary for anchored/manual projects;\n- explicit anchor request JSON for `publish-gate/anchor`;\n- publish registry, dist-tag, and gate visibility metadata.\n\nPublish side-effect jobs should verify the lock immediately before publishing:\n\n```yaml\n- name: Verify publish gate did not move\n run: node .buildchain/runtime/scripts/verify-publish-source-lock.mjs\n env:\n BUILDCHAIN_PUBLISH_SOURCE_REF: ${{ needs.build.outputs.publish-source-ref }}\n BUILDCHAIN_PUBLISH_SOURCE_SHA: ${{ needs.build.outputs.publish-source-sha }}\n BUILDCHAIN_SOURCE_REPOSITORY: ${{ github.repository }}\n GITHUB_TOKEN: ${{ github.token }}\n```\n\nIf the branch tip no longer matches the manifest SHA, the publish job must fail\nclosed. Moving a gate branch creates a new publish decision and should produce a\nnew build run.\n\n## Release Candidate Promote-Only\n\nFor native package sets, the PR build is the only heavy build. When a PR targets\n`alpha/<line>` or `release/<line>`, `.build.yml` uploads a release-candidate\nbundle next to the platform artifacts. The bundle contains:\n\n- `release-candidate.passport.json`;\n- the aggregate `build-summary.json`;\n- copied platform manifest evidence for the built platforms.\n\nThe passport records two separate source identities:\n\n- `builtSourceSha` / `builtSourceTreeSha`: the PR-stage source that produced the\n artifacts, usually the PR merge ref;\n- `promotionChannelSha` / `promotionChannelTreeSha`: the post-merge channel\n commit used for publish authority.\n\nThe reusable promote wrapper resolves the merged PR, finds exactly one matching\nPR-stage release-candidate artifact, downloads it with the build summary and\npayload artifacts from the same PR-stage run, validates the payload count,\ncompares the built tree with the promotion channel tree, locks\n`publish-gate/{alpha,release,major}` to the promotion channel commit, and then\ncalls `actions/promote-buildchain-ref` with\n`promote-only-release-candidate: \"true\"` and\n`require-publish-source-lock: \"true\"`. The wrapper passes the created\n`publish-gate/*` ref, target SHA, and `locked=true` into the promote action, so\nfloating `@v2` consumers receive publish-side source-lock drift protection by\ndefault. It also defaults `branch-protection-bypass-apps` to `github-actions`\nso the workflow automation can apply generated version-state and channel\nbookkeeping on protected `dev`/`alpha`/`release` branches after the reviewed\nchannel PR has merged; consumers using a different promotion identity can pass\n`branch-protection-bypass-users`, `branch-protection-bypass-teams`, or a\ndifferent app slug declaratively. The wrapper uses\n`secrets.BUILDCHAIN_PROMOTION_TOKEN || github.token` as the generated ref update\ntoken for protected bookkeeping PATCH calls, so a bypass-capable promotion token\ncan sync dev immediately after alpha/release publish without a post-publish PR.\nIt does not call `.build.yml`, does not create a matrix, and must fail before\npublish if the RC evidence, payload set, or source-lock ref is missing or\nambiguous.\n\nThe public `release-candidate-promote.yml` is a generated channel router. It\nderives the publication lane from `target-ref`, then selects the matching\nadvanced workflow shell, runtime, and consumer lock before the advanced\npromotion starts:\n\n- alpha targets use `.release-candidate-promote.yml@vN-alpha`, runtime\n `vN-alpha`, and `buildchain-alpha-contract-lock-path`;\n- release and major targets use `.release-candidate-promote.yml@vN`, runtime\n `vN`, and `buildchain-stable-contract-lock-path`.\n\nThe generated router also owns the stable-shell layout transition through\n`.buildchain/promotion-shell-routing.json`. Stable `v2.14.12` contains the hidden\nadvanced workflow, so the stable lane calls that workflow at the exact immutable\nSHA behind the released `v2` state and forwards the complete internal promotion\nidentity surface. The logical shell identity remains `vN`, and the router\nretains it in the public audit outputs. The internal advanced-shell call receives\nthe exact call ref selected by the routing configuration, so its called-workflow\nref check and checkout SHA both bind to the same immutable identity. Updating the\nrouting pin after a stable release does not require any consumer declaration\nchange.\n\nThe router resolves immutable SHAs and the selected lock digest before candidate\ndownload. The advanced shell verifies the same router, shell, runtime, lock,\nchannel, and target binding again. Train and exact-SHA runtime overrides remain\nrestricted to trusted `workflow_dispatch` actors with write, maintain, or admin\npermission. Promotion controller evidence, the promotion copy of the release\ncandidate passport, and the final release passport record these identities.\n\n```yaml\njobs:\n promote:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@v2\n secrets:\n buildchain-issue-app-id: ${{ secrets.BUILDCHAIN_ISSUE_APP_ID }}\n buildchain-issue-app-private-key: ${{ secrets.BUILDCHAIN_ISSUE_APP_PRIVATE_KEY }}\n with:\n buildchain-channel: auto\n buildchain-alpha-contract-lock-path: .buildchain/alpha-contract-lock.json\n buildchain-stable-contract-lock-path: .buildchain/contract-lock.json\n channel: alpha\n target-ref: alpha/v22/v22.22\n artifact-name: libnode\n # Defaults to build.yml / Build. Override only when the PR-stage build\n # workflow uses a different file or display name.\n release-candidate-workflow-file: build.yml\n release-candidate-workflow-name: Build\n package-manager: npm\n publish-target: npm\n runner-preset: github-hosted\n trusted-publishing: true\n github-release: true\n required-status-check: check / check\n required-artifact-count: 3\n publish-dist-tag: alpha\n publish-package-set-order: platforms-first-main-last\n publish-package-main: \"@kungfu-tech/libnode\"\n release-passport-product-name: Libnode\n buildchain-contract-drift-issue-mode: compatible-and-breaking\n```\n\nExisting callers may keep `buildchain-contract-lock-path`; a non-empty explicit\npath overrides channel-specific selection for compatibility. Migration only\nrequires adding the two channel lock inputs and may retain the remaining common\npromotion declaration unchanged. Consumers must not call the dot-prefixed\nadvanced workflow directly.\n\n`buildchain-issue-app-id` and `buildchain-issue-app-private-key` are optional\nbut recommended for cross-repository consumers. They should identify a GitHub\nApp installation with `issues: write` on `kungfu-systems/buildchain`; the\nwrapper mints the installation token before calling\n`actions/report-buildchain-issue`. Consumers can also pass a pre-minted\n`buildchain-issue-token`. If both are omitted, the wrapper falls back to\n`BUILDCHAIN_ISSUE_TOKEN`, `BUILDCHAIN_PROMOTION_TOKEN`, and then the consumer\nworkflow's `github.token`; the last fallback can only report issues when it has\nwrite access to the target Buildchain repository.\n\n`publish-required-artifacts-json` can still be passed explicitly for custom\npublish targets. Custom OCI requirements may omit pre-publish refs and digests;\nthe action resolves the exact version ref and validates final digests and any\nbuilt/reused provenance after `lifecycle.publish`. For the default\n`publish-artifact-kind: npm` path, consumers do\nnot download artifacts or run repository scripts to build publish evidence. The\nwrapper downloads the PR-stage payload artifacts, finds the downloaded `.tgz`\npackages, reads each tarball's `package/package.json` for the real scoped\npackage name and version, computes the npm `sha512-...` integrity from the\ntarball bytes, marks the package matching `publish-package-main` as `role:\nmain`, marks the rest as `role: platform`, and passes the generated\n`publish-required-artifacts-json` to `promote-buildchain-ref` before any publish\nside effect. Downloaded platform manifests are still passed into the release\npassport unless `release-passport-platform-manifest-paths` is set explicitly.\nThe same Buildchain contract lock check runs before release-candidate\nresolution and before publish. A compatible `v2` drift leaves an issue in the\nconsumer repository but does not trigger a second heavy build; an incompatible\ndrift fails before publish side effects.\n\nThe wrapper publishes the public release tag as a GitHub Release by default.\nAfter `promote-buildchain-ref` reports a complete release transaction, the\nwrapper creates or updates the public release, marks semver prerelease tags\nsuch as `v1.2.3-alpha.0`, `v1.2.3-rc.1`, or `v22.22.3-kf.3-alpha.7` as\n`prerelease=true` and `make_latest=false`, marks stable semver tags as latest,\nand uploads the publish evidence file plus every file in the generated release\npassport directory, including `buildchain.release.json` and `check-report.json`.\nFor anchored/manual package releases, the public release tag is derived from the\npublished package version and the internal exact transaction tag remains\navailable in the release passport.\nConsumers do not need to hand-write `gh release` logic to trigger\n`release.published` propagation. Set `github-release: false` only for\nrepositories that intentionally do not maintain GitHub Releases.\nIf the transaction still needs protected-ref finalization, the wrapper defers\nGitHub Release creation until the later run that reaches `state=complete`.\n\nCustom publish jobs can also repeat the channel-ref preflight:\n\n```yaml\n- name: Verify publish channel ref still matches\n run: node .buildchain/runtime/scripts/verify-publish-channel-ref.mjs\n env:\n BUILDCHAIN_PUBLISH_SOURCE_REF: ${{ needs.build.outputs.publish-source-ref }}\n BUILDCHAIN_PUBLISH_SOURCE_SHA: ${{ needs.build.outputs.publish-source-sha }}\n BUILDCHAIN_SOURCE_REPOSITORY: ${{ github.repository }}\n GITHUB_TOKEN: ${{ github.token }}\n```\n\nAnchored/manual package release jobs should also make the Buildchain promotion\naction validate that publication is entering through the same\n`publish-gate/{alpha,release,major}` source-lock contract before any package\npublish side effect:\n\n```yaml\n- name: Promote release ref and publish npm package set\n uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\n with:\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```\n\n`target-ref` stays the Buildchain channel promotion target, such as\n`alpha/v22/v22.22`, `release/v22/v22.22`, or `publish-gate/major`.\n`publish-source-ref` is the reviewed source-lock branch that authorized this\nspecific package publication. For alpha and release package publications, the\nsource-lock branch must point at the exact channel-line commit that promotion is\nvalidating; it is not a replacement for `target-ref`.\n\nThis keeps the version bump commit, publish authorization, and auditable publish\nentrypoint on the Buildchain source-lock protocol. The CLI form\n`buildchain publish-source validate-anchored-release --json` is still useful for\ncustom publish scripts, but the preferred GitHub Actions gate is the promotion\naction input above. A publish job that still runs directly from `alpha/*` or\n`release/*` channel branches fails this check because those refs are channel\nstate, not publish-gate decisions.\n\n## Package-Set Publish Plan\n\nProjects that publish multiple packages should treat package publication as a\npackage-set operation. Buildchain's package-set planner uses these rules:\n\n- platform packages publish first;\n- the main package publishes last;\n- the dist-tag move happens only after the full package set is present;\n- reruns accept already-published packages only when package name, version, and\n integrity match;\n- an existing package with different integrity is a hard failure.\n\nThis keeps a consumer from observing a floating dist-tag that points to a main\npackage before all platform artifacts for the same source SHA are available.\n\n## Command Sources\n\nThe workflow runs `.buildchain/buildchain.toml` lifecycle stages by default:\n\n```toml\n[lifecycle.install]\ncommand = \"corepack yarn install --immutable\"\n\n[lifecycle.build]\ncommands = [\n \"corepack yarn make\",\n \"corepack yarn build\",\n]\n\n[lifecycle.verify]\ncommand = \"corepack yarn test\"\n```\n\nCallers can override any stage for one invocation:\n\n```yaml\nwith:\n build-command: cmake --build build --config Release\n verify-command: ctest --test-dir build --output-on-failure\n```\n\nEvery native and container matrix job is bounded by\n`lifecycle-timeout-minutes`, which defaults to 120 minutes. The same input is\nthe fallback deadline for each install, build, and verify action, so a hung\ncommand fails with the lifecycle name and matrix platform before it can occupy\na self-hosted runner indefinitely. A stage-level `timeout_minutes` in\n`buildchain.toml` remains the more specific override for that stage.\n\n```yaml\nwith:\n lifecycle-timeout-minutes: 90\n```\n\nThe reusable build workflow samples the build lifecycle by default and carries\nthe generated summary into the final verify diagnostics. Callers can override\nthe sidecar path or disable sampling:\n\n```yaml\nwith:\n sample-process-tree: true\n process-summary-path: .buildchain/diagnostics/process-summary.json\n process-sample-interval-ms: 15000\n requested-parallelism: 20\n```\n\nWhen `sample-process-tree` is true, Buildchain wraps either `build-command` or\nthe configured `lifecycle.build` stage with `buildchain sample process-tree`.\nThe path is relative to the checked-out workspace and is read again during the\nfinal verify lifecycle. Custom workflows can still write their own sampler\nsummary and pass `process-summary-path`; Buildchain reads the file after the\nlifecycle command finishes, so it may be produced during the same invocation.\nWhen the build stage is optional, the reusable workflow treats the default\nsampler path as optional during verify; an explicitly supplied\n`process-summary-path` remains required.\n\nFor custom workflows, use the action directly:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/run-lifecycle@v2\n with:\n stage: build\n required: \"true\"\n timeout-minutes: \"90\"\n artifact-name: libnode-linux-x64-${{ github.sha }}\n artifact-paths: |\n dist\n build/stage\n```\n\n## Artifact Contract\n\nEach platform upload uses `artifact-name-template`. The default is:\n\n```text\n{artifact}-{platform}-{sha}\n```\n\nSupported placeholders are `{artifact}`, `{artifactName}`, `{platform}`,\n`{platformId}`, `{platformName}`, `{sha}`, `{shortSha}`, `{ref}`, `{runId}`,\nand `{runAttempt}`. Invalid GitHub artifact name characters are normalized to\n`-`, so `{ref}` remains deterministic even for refs such as\n`refs/heads/dev/v2/v2.0`.\n\nEach platform also writes and uploads:\n\n```text\n.buildchain/artifacts/<platform-id>/manifest.json\n.buildchain/artifacts/<platform-id>/summary.json\n```\n\nThe manifest schema is:\n\n```json\n{\n \"schemaVersion\": 1,\n \"contract\": \"kungfu-buildchain-artifact\",\n \"artifactName\": \"libnode-linux-x64-<sha>\",\n \"platform\": {\n \"id\": \"linux-x64\",\n \"name\": \"Linux x64\",\n \"os\": \"Linux\",\n \"arch\": \"X64\"\n },\n \"git\": {\n \"repository\": \"kungfu-systems/libnode\",\n \"sha\": \"<sha>\",\n \"ref\": \"<ref>\",\n \"runId\": \"<run id>\",\n \"runAttempt\": \"<attempt>\"\n },\n \"lifecycle\": {\n \"stage\": \"verify\",\n \"commandSource\": \"buildchain.toml\",\n \"executed\": true\n },\n \"summary\": {\n \"contract\": \"kungfu-buildchain-artifact-summary\",\n \"artifactName\": \"libnode-linux-x64-<sha>\",\n \"fileCount\": 1,\n \"totalBytes\": 1234,\n \"digest\": \"<hex>\"\n },\n \"expectedArtifacts\": {\n \"ok\": true,\n \"source\": \"expected-artifacts-json\",\n \"checks\": []\n },\n \"files\": [\n {\n \"path\": \"dist/example.zip\",\n \"size\": 1234,\n \"sha256\": \"<hex>\"\n }\n ]\n}\n```\n\nArtifact names do not include actor names, timestamps, or retry counters. Reruns\nproduce a new GitHub Actions run but keep the same source SHA/platform contract.\n\n`expected-artifacts-json` fails the build before upload when the artifact does\nnot match the caller's declared contract. Supported checks are:\n\n| Field | Meaning |\n| --------------- | ------------------------------------ |\n| `minFiles` | Minimum number of manifest files |\n| `maxFiles` | Maximum number of manifest files |\n| `minTotalBytes` | Minimum total byte count |\n| `requiredPaths` | Exact manifest paths that must exist |\n\n## Trusted Event Gate\n\nThe workflow has an explicit `trust-gate` job. By default, pull requests from\nforks fail before any build job can reach self-hosted runners, secrets,\npublishing credentials, or heavyweight build commands. Same-repository PRs,\nworkflow dispatches, and protected branch events can proceed.\n\nIf a repository wants fork PRs to skip rather than fail, it can set:\n\n```yaml\nwith:\n untrusted-policy: skip\n```\n\nDo not set `require-trusted-event: false` for workflows that use self-hosted\nrunners or secrets.\n\n`require-trusted-event` controls access to build runners. It does not override\nthe publish gate: pull requests remain non-publishing events.\n\n## Fixture\n\n`fixtures/libnode-shaped` is the contract fixture. It has:\n\n- `package.json` version state;\n- `.buildchain/buildchain.toml` with `install`, `build`, `verify`, and `publish`;\n- cross-platform Node scripts that create small `dist/` outputs;\n- `Build Surface Fixture` workflow coverage.\n\nThe fixture proves the reusable surface without running the real libnode native\nbuild."
|
|
1742
1742
|
},
|
|
1743
1743
|
{
|
|
1744
1744
|
"id": "manual:runtime-train-validation",
|
|
@@ -2545,7 +2545,7 @@
|
|
|
2545
2545
|
"path": "docs/release-passport.md",
|
|
2546
2546
|
"plane": "verify",
|
|
2547
2547
|
"exists": true,
|
|
2548
|
-
"digest": "sha256:
|
|
2548
|
+
"digest": "sha256:f10d2f0f9cc694976b2a1d2a61195ed155c1bc24c964de1551475882e8197c92"
|
|
2549
2549
|
},
|
|
2550
2550
|
{
|
|
2551
2551
|
"id": "controller-evidence",
|
|
@@ -2641,7 +2641,7 @@
|
|
|
2641
2641
|
"path": "docs/migration-inventory.md",
|
|
2642
2642
|
"plane": "verify",
|
|
2643
2643
|
"exists": true,
|
|
2644
|
-
"digest": "sha256:
|
|
2644
|
+
"digest": "sha256:a5f7271a065544f7ac525dbddfe3d4b9f621b5284c730089f086dd9f961e883c"
|
|
2645
2645
|
},
|
|
2646
2646
|
{
|
|
2647
2647
|
"id": "ownership",
|
|
@@ -2665,7 +2665,7 @@
|
|
|
2665
2665
|
"path": "docs/cli.md",
|
|
2666
2666
|
"plane": "use",
|
|
2667
2667
|
"exists": true,
|
|
2668
|
-
"digest": "sha256:
|
|
2668
|
+
"digest": "sha256:758625143a51d0fe66871220c52273ceaf5c7a47fc1a99bda4608e3ad587ae81"
|
|
2669
2669
|
},
|
|
2670
2670
|
{
|
|
2671
2671
|
"id": "build-facts",
|
|
@@ -2697,7 +2697,7 @@
|
|
|
2697
2697
|
"path": "docs/reusable-build-surface.md",
|
|
2698
2698
|
"plane": "use",
|
|
2699
2699
|
"exists": true,
|
|
2700
|
-
"digest": "sha256:
|
|
2700
|
+
"digest": "sha256:dea8ec2f1f2ea75e569a989988e9d6f76067e1d0ae496dadc34ef1dcfbfa35dd"
|
|
2701
2701
|
},
|
|
2702
2702
|
{
|
|
2703
2703
|
"id": "publish-transaction",
|