@kungfu-tech/buildchain 2.8.7-alpha.1 → 2.8.7

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.
@@ -10,10 +10,24 @@
10
10
  "name": "@kungfu-tech/buildchain",
11
11
  "versionSource": "package.json#version"
12
12
  },
13
+ "source": {
14
+ "package": "@kungfu-tech/buildchain",
15
+ "homepageTextSource": "README.md",
16
+ "docsMap": "docs/MAP.md",
17
+ "manualRegistry": "manual-registry.json",
18
+ "siteFactsDir": "dist/site"
19
+ },
20
+ "routes": {
21
+ "home": "/",
22
+ "docsPattern": "/docs/{id}",
23
+ "llms": "/llms.txt",
24
+ "manifest": "/manifest.json"
25
+ },
13
26
  "sourceOfTruth": "npm package @kungfu-tech/buildchain/dist/site",
14
27
  "humanFirst": true,
15
28
  "agentFirst": true,
16
29
  "entrypoints": [
30
+ "page-registry.json",
17
31
  "cli-registry.json",
18
32
  "manual-registry.json",
19
33
  "node-api-registry.json",
@@ -26,7 +40,1547 @@
26
40
  "agent-index.json",
27
41
  "site-manifest.json"
28
42
  ],
43
+ "pages": [
44
+ {
45
+ "id": "overview:home",
46
+ "title": "Buildchain",
47
+ "route": "/",
48
+ "category": "overview",
49
+ "sourcePath": "README.md",
50
+ "digest": "sha256:99d7c49c026800f21837f58e5e0883be9f73544480fbbcf7a139179a70a81b07",
51
+ "headings": [
52
+ {
53
+ "level": 1,
54
+ "title": "Buildchain",
55
+ "anchor": "buildchain"
56
+ },
57
+ {
58
+ "level": 2,
59
+ "title": "Install and Verify",
60
+ "anchor": "install-and-verify"
61
+ },
62
+ {
63
+ "level": 1,
64
+ "title": "Example for Linux x64. Use the archive that matches your platform.",
65
+ "anchor": "example-for-linux-x64-use-the-archive-that-matches-your-platform"
66
+ },
67
+ {
68
+ "level": 2,
69
+ "title": "Project Governance",
70
+ "anchor": "project-governance"
71
+ },
72
+ {
73
+ "level": 2,
74
+ "title": "Use Buildchain",
75
+ "anchor": "use-buildchain"
76
+ },
77
+ {
78
+ "level": 2,
79
+ "title": "Release Model",
80
+ "anchor": "release-model"
81
+ },
82
+ {
83
+ "level": 2,
84
+ "title": "Toolkit Observability",
85
+ "anchor": "toolkit-observability"
86
+ },
87
+ {
88
+ "level": 2,
89
+ "title": "Site Fact Source",
90
+ "anchor": "site-fact-source"
91
+ },
92
+ {
93
+ "level": 2,
94
+ "title": "Homepage Content Contract",
95
+ "anchor": "homepage-content-contract"
96
+ },
97
+ {
98
+ "level": 2,
99
+ "title": "Local Verification",
100
+ "anchor": "local-verification"
101
+ },
102
+ {
103
+ "level": 2,
104
+ "title": "Read Next",
105
+ "anchor": "read-next"
106
+ }
107
+ ],
108
+ "markdown": "# Buildchain\n\nBuildchain Release Passport is a mature product release record for artifacts\nthat users or agents depend on.\n\nBuildchain by Kungfu uses GitHub as the execution and trust substrate: protected\nrefs, reviewed promotion PRs, exact tags, GitHub Releases, npm Trusted\nPublishing, and machine-readable evidence. Its job is to turn release intent\ninto an auditable product record, not to ask a repository to migrate away from\nits existing CI.\n\nThe same mechanism releases Buildchain itself.\n\n## Install and Verify\n\nFor standalone use, install a platform archive from a GitHub Release and verify\nthe release passport before trusting the binary:\n\n```bash\n# Example for Linux x64. Use the archive that matches your platform.\ncurl -LO https://github.com/kungfu-systems/buildchain/releases/download/v2.2.1/buildchain-x86_64-unknown-linux-gnu.tar.gz\ncurl -LO https://github.com/kungfu-systems/buildchain/releases/download/v2.2.1/buildchain.release.json\ncurl -LO https://github.com/kungfu-systems/buildchain/releases/download/v2.2.1/artifact-evidence.json\nnpx @kungfu-tech/buildchain verify release-passport buildchain.release.json\ntar -xzf buildchain-x86_64-unknown-linux-gnu.tar.gz\n./buildchain version\n```\n\nRelease pages publish platform archives, checksums, release passport files, and\na single evidence bundle:\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- `checksums.txt`\n- `buildchain.release.json`\n- `artifact-evidence.json`\n- `product-mechanism.json`\n- `impact.json`\n- `agent-index.json`\n- `check-report.json`\n- `llms.txt`\n- `buildchain-release-bundle.tar.gz`\n- `buildchain-release-bundle.json`\n\nLoose top-level `buildchain` and `buildchain.exe` assets are intentionally not\npublished. The executable lives inside each platform archive, which prevents\nLinux and macOS artifacts from overwriting each other in a merged release lane.\n\nFor npm consumers:\n\n```bash\nnpm install -D @kungfu-tech/buildchain\nnpx buildchain version\nnpx buildchain doctor --json\n```\n\nThe npm package is also the Buildchain toolkit. Use the command when a workflow\nor shell step needs an executable; use the ESM APIs directly from JavaScript\nbuild scripts. JavaScript callers should import the package instead of spawning\nthe CLI or unpacking the standalone binary:\n\n```js\nimport {\n createBuildchainLogger,\n verifyBuildchainLogEvents,\n} from \"@kungfu-tech/buildchain/logging\";\n\nconst logger = createBuildchainLogger({\n path: \".buildchain/logs/native-build.jsonl\",\n source: \"user\",\n component: \"native-build\",\n});\n\nawait logger.span(\"native.compile\", { phase: \"build\" }, async () => {\n await compileNativeTargets();\n});\n\nconst report = verifyBuildchainLogEvents({\n path: logger.path,\n requireEvents: [\"native.compile.start\", \"native.compile.end\"],\n});\n```\n\nThe package also ships `dist/site/` as the Buildchain-owned fact source for\n`buildchain.libkungfu.dev`.\n\n## Project Governance\n\n- [`LICENSE-POLICY.md`](LICENSE-POLICY.md) explains the Apache-2.0 project\n license, DCO-based contributions, and third-party notice boundary.\n- [`TRADEMARK.md`](TRADEMARK.md) explains official project marks and fork\n identity boundaries.\n- [`ACCEPTABLE_USE.md`](ACCEPTABLE_USE.md) explains acceptable use of official\n services and maintainer-operated infrastructure.\n- [`PROVIDER_COMPLIANCE.md`](PROVIDER_COMPLIANCE.md) explains the official\n posture for GitHub, npm, cloud, credential, release evidence, and other\n provider integrations.\n- [`SECURITY.md`](SECURITY.md) explains private vulnerability reporting.\n\nNative build consumers can import the diagnostics toolkit instead of copying\nrepository-local probes:\n\n```js\nimport {\n collectBuildchainDiagnostics,\n collectRunnerDiagnostics,\n writeDiagnosticsArtifact,\n} from \"@kungfu-tech/buildchain/diagnostics\";\n\nwriteDiagnosticsArtifact(\".buildchain/artifacts/diagnostics.json\", {\n contract: \"consumer-build-diagnostics\",\n buildchain: collectBuildchainDiagnostics({ cwd: process.cwd() }),\n runner: collectRunnerDiagnostics(),\n});\n```\n\n`buildchain lifecycle run` writes a small `diagnostics.json` next to the\nplatform manifest. It includes lifecycle-wide observability, runner/tool/cache\nsnapshots, Git state, and links to the larger manifest and artifact outputs.\n\nConsumers can report Buildchain-owned workflow failures directly to the\nBuildchain repository with a scoped issue-write token:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/report-buildchain-issue@v2\n if: failure()\n with:\n token: ${{ steps.buildchain-issue-token.outputs.token }}\n summary: \"Reusable build failed before artifact finalization\"\n failure-code: reusable-build-failed\n buildchain-ref: v2\n diagnostics-path: .buildchain/artifacts/diagnostics.json\n```\n\nThe action deduplicates by fingerprint, comments on existing open reports, and\nis fail-soft by default so issue reporting does not hide the original failure.\nUse `report-kind: workflow-friction` when Buildchain workflows should report\ntheir own repeated release friction back to the Buildchain issue tracker.\n\n## Use Buildchain\n\nBootstrap a repository:\n\n```bash\nnpx @kungfu-tech/buildchain init --type package --package-manager pnpm\nnpx @kungfu-tech/buildchain validate --require-version-state\nnpx @kungfu-tech/buildchain release --dry-run --target-ref alpha/v2/v2.2\n```\n\nBuildchain supports package and non-package projects through `buildchain.toml`.\nLifecycle commands can call pnpm, npm, yarn, pip, Conan, CMake, Make, custom\nscripts, or any other command that can run in the repository checkout.\n\nBuildchain's active GitHub Action surface is deliberately small:\n\n- `actions/validate-config`\n- `actions/run-lifecycle`\n- `actions/promote-buildchain-ref`\n- `actions/report-buildchain-issue`\n\nThe active reusable workflow surfaces are:\n\n- `.github/workflows/.build.yml` for deterministic multi-platform build and\n artifact contracts;\n- `.github/workflows/release-candidate-promote.yml` for post-merge\n promote-only publication from a PR-stage release candidate, without a second\n heavy build;\n- `.github/workflows/.web-surface.yml` for preview, staging, production, and\n cleanup plans for site/app repositories;\n- `.github/workflows/buildchain-ref-promotion.yml` for protected release\n promotion and version-state transactions;\n- `.github/workflows/binary-distribution.yml` for Buildchain's own release\n passport proof case.\n\nStable consumers should reference actions and workflows through floating major\nrefs after reviewing the exact release passport:\n\n```yaml\nuses: kungfu-systems/buildchain/actions/validate-config@v2\n```\n\n```yaml\nuses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n```\n\n```yaml\nuses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@v2\n```\n\n## Release Model\n\nBuildchain treats a reviewed branch merge as release intent:\n\n| Merge path | Meaning | Exact tag | Floating refs |\n| --- | --- | --- | --- |\n| `dev/vX/vX.Y -> alpha/vX/vX.Y` | publish the next testable alpha for a minor line | `vX.Y.Z-alpha.N` | `vX.Y-alpha`, `alpha/vX/vX.Y`, `dev/vX/vX.Y` |\n| `alpha/vX/vX.Y -> release/vX/vX.Y` | publish production for that minor line | `vX.Y.Z` | `vX.Y`, usually `vX`, `release/vX/vX.Y` |\n| `release/vX/vX.Y -> publish-gate/major` | publish the next major from a reviewed production line | `v(X+1).0.0` | `v(X+1)`, `v(X+1).0`, new dev/alpha/release branches |\n\nExact tags are immutable. Floating channel tags and branches are machine-updated\nby Buildchain and must remain writable by the release authority.\n\nAfter a production release, Buildchain prepares the next alpha source commit for\nthe same minor line. That keeps production consumers pinned to the production\npassport while development can continue on the next testable patch.\n\n`publish-gate/major` is not an active development trunk. It is a reviewed\npromotion gate used when maintainers decide that the next production release\nshould open a new major line.\n\n## Toolkit Observability\n\nBuildchain includes a logging toolkit for release and build steps. Inside\nJavaScript build code, prefer the package API:\n\n```js\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\n\nconst logger = createBuildchainLogger({ source: \"user\", component: \"conan\" });\nlogger.mark(\"conan.profile.ready\", { phase: \"configure\" });\nawait logger.span(\"conan.install\", { phase: \"dependencies\" }, runConanInstall);\n```\n\nIn workflows or shell scripts, use the equivalent CLI:\n\n```bash\nbuildchain mark --event native.configure --phase configure --component cmake\nbuildchain span --event native.build --phase build -- cmake --build build\nbuildchain log summary --json\nbuildchain verify observability-log .buildchain/logs/events.jsonl --min-events 4\n```\n\nEvery event records a timestamp. `span` records duration. The API form can be\nimported from repository scripts so heavy builds can mark phases from inside\ntheir own code.\n\n## Site Fact Source\n\n`@kungfu-tech/buildchain` publishes `dist/site/`:\n\n- `buildchain-site.json`\n- `site-manifest.json`\n- `page-registry.json`\n- `cli-registry.json`\n- `workflow-registry.json`\n- `release-model.json`\n- `artifact-schemas.json`\n- `product-mechanism.json`\n- `release-provenance.json`\n- `agent-index.json`\n\n`buildchain.libkungfu.dev` should render from these package-owned facts, then\nlayer presentation around them. The site should not hand-write Buildchain's\ncurrent release mechanics. `page-registry.json` is the complete markdown page\nsource for the public site: README homepage content, all packaged `docs/*.md`\nmanuals, action READMEs, the Node API package overview, and fixture guides.\n\n## Homepage Content Contract\n\nThis README is also the homepage text source for `buildchain.libkungfu.dev`.\nWhen a site repository consumes the `@kungfu-tech/buildchain` npm package, it\nshould use the generated `dist/site/buildchain-site.json` homepage fields\ninstead of parsing this README or maintaining separate homepage copy.\n\nThe first screen should be derived from:\n\n- Page identity: the top-level heading.\n- Lead: the opening paragraph that defines Buildchain Release Passport.\n- Trust signal: the start of `Install and Verify`, especially passport-first\n binary verification.\n- Use signal: the start of `Use Buildchain`, especially the reusable workflow\n and action surfaces.\n\nThe package-owned site bundle exposes ordered `homepage.sections`,\n`homepage.displayPlan`, `homepage.rendererContract`, and a complete\n`pages` collection mirrored from `page-registry.json`. A site renderer may adapt\nlayout, navigation, typography, examples, and visual assets, but it should not\nmaintain separate wording for Buildchain's release mechanics, workflow surface,\noperation manuals, Node API overview, fixture guides, or release-passport trust\nmodel. Renderer-contract text is machine/implementation metadata, not ordinary\nhomepage content.\n\n## Local Verification\n\n```bash\ncorepack enable pnpm\npnpm install --frozen-lockfile\npnpm run generate:site\npnpm run check\nnpm pack --dry-run --json --registry=https://registry.npmjs.org/\n```\n\n## Read Next\n\n- [Install and verify](docs/install.md)\n- [Documentation map](docs/MAP.md)\n- [Product mechanism](docs/product-mechanism.md)\n- [Release Passport and binary distribution](docs/release-passport.md)\n- [Binary distribution details](docs/binary-distribution.md)\n- [Toolkit observability](docs/toolkit-observability.md)\n- [Site bundle contract](docs/site-bundle-contract.md)\n- [Lifecycle protocol](docs/lifecycle-protocol.md)\n- [Reusable build surface](docs/reusable-build-surface.md)\n- [Release candidate passport](docs/release-candidate.md)\n- [Consumer issue reporting](docs/consumer-issue-reporting.md)\n- [Publish transaction](docs/publish-transaction.md)\n- [Release governance](docs/release-governance.md)",
109
+ "slug": "home"
110
+ },
111
+ {
112
+ "id": "action:promote-buildchain-ref",
113
+ "title": "promote-buildchain-ref",
114
+ "route": "/actions/promote-buildchain-ref",
115
+ "category": "action",
116
+ "sourcePath": "actions/promote-buildchain-ref/README.md",
117
+ "digest": "sha256:d826cb94712c1103ff46d05ea9f66d998bc93f6657ffca7309e120853f4e7437",
118
+ "headings": [
119
+ {
120
+ "level": 1,
121
+ "title": "promote-buildchain-ref",
122
+ "anchor": "promote-buildchain-ref"
123
+ },
124
+ {
125
+ "level": 2,
126
+ "title": "Dry Run",
127
+ "anchor": "dry-run"
128
+ },
129
+ {
130
+ "level": 2,
131
+ "title": "Publish Transactions",
132
+ "anchor": "publish-transactions"
133
+ }
134
+ ],
135
+ "markdown": "# promote-buildchain-ref\n\nInternal buildchain action for promoting verified buildchain release-line and\ncompatibility refs from buildchain release channels:\n\n- `alpha/v2/v2.0` creates or reuses the next exact prerelease tag such as\n `v2.0.1-alpha.0`, writes that version into package version state, points the\n alpha and dev channel branches at the version commit, then promotes\n `v2.0-alpha`;\n- `release/v2/v2.0` creates or reuses the next exact release tag such as\n `v2.0.0`, writes that version into package version state, points the release\n channel branch and release tags at the release commit, then prepares a second\n source commit for the next exact prerelease tag such as `v2.0.1-alpha.0` and\n points the alpha/dev channel branches plus `v2.0-alpha` at that prerelease\n commit;\n- `publish-gate/major` accepts a reviewed PR from a production release line such\n as `release/v2/v2.0`, writes the next major production version such as\n `v3.0.0`, points `publish-gate/major`, `release/v3/v3.0`, `v3.0`, and `v3`\n at that release commit, then prepares `v3.0.1-alpha.0` for\n `alpha/v3/v3.0`, `dev/v3/v3.0`, and `v3.0-alpha`. The older `major-gate`\n branch name is a compatibility alias only.\n\nThe release branch name defines the minor line. For example,\n`release/v2/v2.1` creates `v2.1.N`, promotes `v2.1`, and promotes `v2` only\nwhen the next minor tag such as `v2.2` does not already exist.\n\nThe action updates version state in `lerna.json`, root `package.json`, and\nworkspace package manifests discovered from package manager metadata\n(`package.json` workspaces, `lerna.json` packages, or `pnpm-workspace.yaml`).\nPackage manager detection is adaptive (`pnpm`, `npm`, or `yarn`) and is recorded\nin logs.\n\nRepositories can also provide `buildchain.toml` to declare version-state files\nand `lifecycle.verify`. TOML-configured version files take precedence over\npackage-manager discovery and can target JSON, TOML, or regex-based files. The\nversion commit itself is written through the GitHub Git Data API so the ref\ngraph is the durable source of truth. Repositories without any supported version\nstate degrade to ref-only promotion only when strict version state is disabled.\n\n## Dry Run\n\nUse `dry-run: \"true\"` or the CLI `buildchain release --dry-run` before merging a\nchannel PR when you need to understand what Buildchain would do. This dry-run is\nat the Buildchain release-line level. It explains:\n\n- the legal source branch for the target channel;\n- exact release or alpha tags that would be created or reused;\n- floating tags and channel branches that would move;\n- version-state files and verification lifecycle that would apply;\n- branch protection, PR lineage, and release-from-alpha checks;\n- publish transaction behavior when `lifecycle.publish` or\n `publish-transaction` is enabled.\n\nIt does not move refs, move tags, write package files, run publish commands, or\npublish npm packages. The GitHub action dry-run still calls GitHub APIs to\nresolve the current target SHA and concrete pending ref updates, but every\nwrite is reported as a dry-run update.\n\nRepositories whose package version is anchored to an explicitly selected\nupstream release can opt into manual next-anchor behavior:\n\n```toml\n[version]\nrequired = true\nstrategy = \"anchored\"\nnext = \"manual\"\nmanifest = \"libnode.release.json\"\n```\n\nIn this mode, the action validates the configured version files and anchor\nmanifest through the repository's verify lifecycle, but it does not rewrite the\npackage version to match the Buildchain release tag. After a production\nrelease, it sets `next-anchor-required=true` and does not auto-create the next\nalpha branch or tag. The repository must create the next upstream anchor line\nexplicitly, then run the normal channel promotion flow for that line.\n\nWhen branch protection requires pull requests, generated version-state commits\nare also routed through pull requests. The action creates an internal\n`buildchain/version-state/...` branch and PR, then stops before moving tags. Once\nthat PR is reviewed, checked, and merged, the next promotion run verifies that\nthe merge only changed declared version-state files from the legal source\nparent, then moves exact and floating refs.\n\n## Publish Transactions\n\nPromotion can also own external publish side effects. Enable this only from a\ntrusted channel workflow:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ github.sha }}\n target-ref: release/v2/v2.0\n publish-transaction: \"true\"\n publish-mode: publish-final-version\n publish-auth: trusted-publishing\n publish-required-artifacts-json: >-\n [\n {\"kind\":\"npm\",\"name\":\"@kungfu-tech/buildchain\",\"ref\":\"2.0.0\",\"digest\":\"sha256:...\"}\n ]\n```\n\nFor anchored/manual package repositories that build through the reusable\nworkflow, keep the publish entrypoint on the `publish-gate/*` source-lock\ncontract:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ needs.build.outputs.publish-source-sha }}\n target-ref: release/v22/v22.22\n require-publish-source-lock: \"true\"\n publish-source-ref: ${{ needs.build.outputs.publish-source-ref }}\n publish-source-sha: ${{ needs.build.outputs.publish-source-sha }}\n publish-source-locked: ${{ needs.build.outputs.publish-source-locked }}\n publish-transaction: \"true\"\n publish-mode: publish-final-version\n publish-auth: trusted-publishing\n```\n\n`target-ref` remains the channel promotion target that must point at `sha`.\n`publish-source-ref` is the reviewed source-lock branch that authorized this\nspecific package publication. Direct `alpha/*` or `release/*` channel refs are\nnot valid publish source locks when `require-publish-source-lock` is enabled,\nand a mismatched `publish-source-sha` fails before any promotion or publish side effects begin.\nThe reusable build workflow performs the cheaper channel-ref preflight earlier:\nafter source-lock resolution and before the build matrix, it requires the target\nchannel ref such as `alpha/v22/v22.22` or `release/v22/v22.22` to already point\nat the locked `publish-source-sha`. If not, maintainers should merge the source\ncommit through the channel PR first.\n\nFor promote-only release candidates, attach the PR-stage reusable build evidence\nand fail before publish-gate side effects if it no longer matches:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ needs.build.outputs.publish-source-sha }}\n target-ref: alpha/v22/v22.22\n promote-only-release-candidate: \"true\"\n release-candidate-passport-path: .buildchain/artifacts/release-candidate-passport.json\n release-candidate-build-summary-path: .buildchain/artifacts/build-summary.json\n```\n\nThe action validates repository, channel, source identity, platform matrix, and\nthe aggregate build-summary hash before it writes version state, opens\nrelease-state, runs publish transaction logic, or moves tags/branches. Source\nidentity accepts the exact source SHA, the PR merge ref SHA, or the promoted\nchannel HEAD's Git tree SHA matching the passport tree hash. If validation\nfails, run or attach the verified channel PR build first instead of promoting a\nstale or unproven artifact set.\n\nWhen enabled, the action creates or resumes a release transaction keyed by\nrepository, version, source SHA, and target ref. It persists that transaction to\na machine-managed branch under `buildchain/release-state/<version>`, with\n`state.json` and, once available, `evidence.json`. Fresh GitHub runners read\nthat durable ref before running publish, so reruns do not depend on a previous\nrunner's local `.buildchain` directory.\n\nThe action runs `lifecycle.publish` from `buildchain.toml` or the explicit\n`publish-command` input, then validates publish evidence before exact tags and\nfloating refs move. If durable state persistence fails, the action fails closed\nbefore publish or public ref finalization.\n\n`publish-mode` defaults to `publish-final-version`, the token-free path for\nnormal npm Trusted Publishing. Same-version alpha-to-latest recovery must be\ndeclared as `publish-mode: promote-existing-version` and\n`publish-auth: npm-token`; Buildchain runs `npm whoami` before it creates\nrelease-state or moves any `npm dist-tag`. The Trusted Publishing mode is not\nallowed to perform `npm dist-tag add`.\n\nBuildchain itself uses this path for npm. Its `lifecycle.publish` runs\n`node scripts/npm-publish-transaction.mjs`, which publishes\n`@kungfu-tech/buildchain` through npm Trusted Publishing and writes npm\nartifact evidence into the transaction before release refs move. The separate\n`.github/workflows/npm-publish.yml` workflow is dry-run only.\n\nPublish lifecycle environment:\n\n```text\nBUILDCHAIN_VERSION\nBUILDCHAIN_CHANNEL\nBUILDCHAIN_SOURCE_SHA\nBUILDCHAIN_TARGET_REF\nBUILDCHAIN_RELEASE_STATE\nBUILDCHAIN_EVIDENCE_DIR\nBUILDCHAIN_RELEASE_SHA\nBUILDCHAIN_RELEASE_MATERIAL_SHA\nBUILDCHAIN_PUBLISH_TOOLING_SHA\nBUILDCHAIN_PUBLISH_EVIDENCE\n```\n\nThe action outputs `transaction-id`, `transaction-state`,\n`transaction-exact-tag`, `transaction-release-sha`, `transaction-state-ref`,\n`transaction-state-sha`, `transaction-state-path`, `publish-evidence-path`, and\n`release-passport-path`, `release-passport-output-dir`,\n`release-passport-state-sha`, and `finalization-needed`.\n`transaction-state-ref` is the durable recovery location.\n`release-passport-state-sha` is the durable ref commit after the generated\n`release-passport/*` files have been uploaded into that recovery ref.\n`finalization-needed=true` means publish evidence is valid, but protected branch\nor ref finalization needs a later promotion run.\nSet `github-release: \"true\"` when the semver promotion should also publish the\nexact-tag GitHub Release. After the release transaction reaches `complete` and\n`finalization-needed` is false, the action creates or updates the GitHub Release\nfor `transaction-exact-tag`, applies deterministic semver metadata\n(`prerelease=true` and `make_latest=false` for prerelease tags, latest for stable\ntags), and uploads the publish evidence file plus generated release passport\nassets. If the transaction is not complete yet, the action defers GitHub Release\npublication to the next idempotent promotion run.\n\nAfter a publish transaction reaches `complete`, the action generates the unified\n`buildchain-release-passport` in `.buildchain/release-passport` by default and\npersists those files under `release-passport/` in the durable release-state ref.\nSet `release-passport-product-name` to record the consumer product name, for\nexample `Libnode`, instead of the default `Buildchain`.\nSet `release-passport-kfd-1-witness-jsons` to newline-separated KFD-1\ncontract-world witness JSON paths when released artifacts must prove\nbyte-for-byte KFD contract surfaces. Buildchain imports the KFD metadata from\n`@kungfu-tech/kfd`, freezes the witness, verifies artifact bytes, and writes the\nresult under the KFD-provided `kfd-1` passport section.\nSet `release-passport-kfd-2-claim-jsons` to newline-separated KFD-2 public\nrelease trust claim JSON paths when a release makes additional human/agent\nvisible claims. Buildchain requires each public claim to bind declared sources,\nmachine-readable evidence, hashes, artifact coordinates, verification results,\naudit boundary, responsibility state, and residual risk. Unbound claims fail\npassport verification; prose-only claims downgrade the KFD-2 audit.\nSet `release-passport-kfd-3-prebuild-witness-jsons` to newline-separated KFD-3\ncollaboration-interface pre-build witness paths, then provide artifact-side\nevidence with `release-passport-kfd-3-artifact-witness-jsons` or a\nproduct-owned `release-passport-kfd-3-artifact-verify-command` such as\n`kungfu agent verify --json`. Buildchain compares declared shipped public\nsurfaces with artifact-exposed public surfaces and writes the result under the\nKFD-provided `kfd-3` passport section.\nWhen present, the passport includes the aggregate build summary, platform\nartifact manifests, npm publish evidence, dist-tag promotion evidence, the\nrelease-state ref, trusted publishing metadata, and the Buildchain transaction\nresult. After the first passport upload, Buildchain backfills the durable\nrelease-state SHA into `buildchain.release.json` and persists the passport\nagain, so the consumer-side passport is a complete audit entrypoint. Set\n`release-passport: \"false\"` only for a controlled recovery run that must skip\npassport generation.\n\nFinalization recovery is anchored to the durable transaction, not to a single\nworkflow run SHA. After a generated version-state PR is merged, the current\nchannel head can be a merge commit that contains or corresponds to the recorded\n`release_material_sha`; it does not have to equal the original `source_sha` or\nthe transaction `release_sha`. Reruns accept exact tags that already point at\nthe transaction release/material SHA or the finalized channel head, and continue\nmoving any missing floating tags or dev/alpha refs before marking the\ntransaction `complete`.\n\nNormal reruns accept already-published artifacts only when evidence matches.\nMissing required artifacts can be published on the next run. Conflicting\nartifacts put the transaction into `repair_required`; `abandoned` and\n`failed_permanently` also fail closed unless `publish-transaction-override` is\nset for a controlled repair.\n\nIn strict buildchain promotion, ref movement is also gated by the old ABV\ngovernance semantics:\n\n- the target channel branch protection details must be readable, must enforce\n protection for administrators, and must require approving PR review plus the\n strict `check` job from the `Verify` workflow;\n- alpha promotion must come from a merged same-repository PR\n `dev/vN/vN.M -> alpha/vN/vN.M`;\n- release promotion must come from a merged same-repository PR\n `alpha/vN/vN.M -> release/vN/vN.M`;\n- major promotion must come from a merged same-repository PR\n `release/vN/vN.M -> publish-gate/major`;\n- release promotion must have an exact alpha tag for the same patch line, and\n the release source tree must match that alpha tag tree, so release does not\n introduce new code after alpha;\n- anchored/manual release promotion may differ from that alpha tree only in\n declared `version.files` and the configured anchor manifest, and only when the\n checked-out release material has passed `lifecycle.verify` or the explicit\n `verification-command`;\n- generated release and next-alpha version-state trees can be verified locally\n with either the `verification-command` input or `buildchain.toml`\n `lifecycle.verify` before any tags or channel refs move.\n\nThe promotion workflow should use `BUILDCHAIN_PROMOTION_TOKEN` for non-dry-run\npromotion. The token is the buildchain equivalent of the old ABV runner release\nauthority: protected branch review and check rules guard human channel merges,\nwhile the reusable build trust gate now checks the source-lock channel HEAD and\nmerged same-repository PR lineage before heavy build runners start. This action\nstill independently rechecks PR lineage, alpha/release tree equivalence, and\ngenerated version-state verification before moving channel refs and tags.\n\nThe tag names intentionally follow the old ABV release semantics:\nexact release tags are `vX.Y.Z`, exact alpha tags are `vX.Y.Z-alpha.N`, floating\nrelease tags are minor/major tags such as `v2.0` and `v2`, and floating alpha\ntags are minor-line tags such as `v2.0-alpha`. Bare tags such as `1.0.0` are not\nmaintained as buildchain release entrypoints.\n\nRepository rulesets should protect exact tags, not every `v*` tag. A ruleset\nsuch as `refs/tags/v*` also protects floating channel tags like `v2.0-alpha`,\nwhich Buildchain must update after exact tags and publish evidence are durable.\nUse an exact-tag rule such as `refs/tags/v*.*.*` for immutable evidence tags and\nleave floating channel tags mutable for the promotion token."
136
+ },
137
+ {
138
+ "id": "action:report-buildchain-issue",
139
+ "title": "report-buildchain-issue",
140
+ "route": "/actions/report-buildchain-issue",
141
+ "category": "action",
142
+ "sourcePath": "actions/report-buildchain-issue/README.md",
143
+ "digest": "sha256:8de128ccb5c617c14df22c5a963b98467942a2ffc74962928b3b55e7d9b3d4dc",
144
+ "headings": [
145
+ {
146
+ "level": 1,
147
+ "title": "report-buildchain-issue",
148
+ "anchor": "report-buildchain-issue"
149
+ }
150
+ ],
151
+ "markdown": "# report-buildchain-issue\n\nCreate or update a Buildchain repository issue from a consumer workflow or from\nBuildchain's own workflow-friction feedback loop.\n\nThis action is intended for consumer repositories that need to report\nBuildchain-owned failures with enough evidence for maintainers to act. It\nrequires a token that can write issues on the target Buildchain repository.\nFor cross-repository consumers, generate that token with a GitHub App\ninstallation token or another scoped credential owned by the consumer\norganization.\n\n```yaml\n- uses: actions/create-github-app-token@v2\n id: buildchain-issue-token\n with:\n app-id: ${{ secrets.BUILDCHAIN_ISSUE_APP_ID }}\n private-key: ${{ secrets.BUILDCHAIN_ISSUE_APP_PRIVATE_KEY }}\n owner: kungfu-systems\n repositories: buildchain\n\n- uses: kungfu-systems/buildchain/actions/report-buildchain-issue@v2\n if: failure()\n with:\n token: ${{ steps.buildchain-issue-token.outputs.token }}\n summary: \"Reusable build failed before artifact finalization\"\n failure-code: reusable-build-failed\n buildchain-ref: ${{ inputs.buildchain-ref || 'v2' }}\n diagnostics-path: .buildchain/artifacts/diagnostics.json\n```\n\nThe action computes a stable fingerprint from the consumer repository,\nworkflow, job, failure code, and Buildchain ref. When an open issue already\nexists for that fingerprint, it comments with the new run instead of opening a\nduplicate issue.\n\nBy default issue reporting is fail-soft:\n\n- `fail-on-error: \"false\"` prevents a reporting outage from hiding the original\n build failure.\n- transient GitHub API 429/5xx errors and connection failures are retried.\n- if a configured label is missing, issue creation is retried without labels.\n- if issue creation/commenting is still unavailable, the action writes the full\n copyable issue title, fingerprint, and body into the workflow summary.\n- common token, private-key, password, and authorization values are redacted\n before submission.\n\nUse `dry-run: \"true\"` to verify the computed fingerprint and body shape without\ncalling GitHub.\n\nFor Buildchain-owned workflow friction, use `report-kind: workflow-friction`.\nThis uses a separate marker and default labels so duplicate PRs, duplicate\nbuilds, transient API failures, stale release-state, or missing RC evidence can\nbe grouped without mixing with consumer failure reports:\n\n```yaml\npermissions:\n issues: write\n\nsteps:\n - uses: actions/create-github-app-token@v2\n id: buildchain-issue-token\n with:\n app-id: ${{ secrets.BUILDCHAIN_ISSUE_APP_ID }}\n private-key: ${{ secrets.BUILDCHAIN_ISSUE_APP_PRIVATE_KEY }}\n owner: kungfu-systems\n repositories: buildchain\n\n - uses: kungfu-systems/buildchain/actions/report-buildchain-issue@v2\n if: failure()\n with:\n token: ${{ steps.buildchain-issue-token.outputs.token || secrets.BUILDCHAIN_ISSUE_TOKEN || secrets.BUILDCHAIN_PROMOTION_TOKEN || github.token }}\n report-kind: workflow-friction\n target-repository: kungfu-systems/buildchain\n repository: ${{ github.repository }}\n workflow: ${{ github.workflow }}\n run-id: ${{ github.run_id }}\n run-attempt: ${{ github.run_attempt }}\n channel: alpha/v2/v2.4\n source-sha: ${{ github.sha }}\n friction-class: duplicate-build\n related-runs-json: ${{ steps.classify.outputs.related-runs-json }}\n heavy-builds-json: ${{ steps.classify.outputs.heavy-builds-json }}\n comment-cooldown-hours: \"24\"\n```\n\n`comment-cooldown-hours` is optional. When it is greater than zero, Buildchain\nstill deduplicates by fingerprint but skips adding another comment if the\nexisting issue already received a recent update."
152
+ },
153
+ {
154
+ "id": "action:run-lifecycle",
155
+ "title": "run-lifecycle",
156
+ "route": "/actions/run-lifecycle",
157
+ "category": "action",
158
+ "sourcePath": "actions/run-lifecycle/README.md",
159
+ "digest": "sha256:fa76b6a125b1e20b32fb12ebc59083dd7d3e1f5903a209543756c435d6448420",
160
+ "headings": [
161
+ {
162
+ "level": 1,
163
+ "title": "run-lifecycle",
164
+ "anchor": "run-lifecycle"
165
+ }
166
+ ],
167
+ "markdown": "# run-lifecycle\n\nRun a Buildchain lifecycle stage or an explicit command and write a deterministic\nartifact manifest.\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/run-lifecycle@v2\n with:\n stage: build\n required: \"true\"\n artifact-name: my-product-linux-x64-${{ github.sha }}\n artifact-paths: |\n dist\n build/stage\n```\n\nWhen `command` is provided, it overrides `buildchain.toml` for that invocation.\nWhen `command` is empty, the action loads `buildchain.toml` and runs the named\nstage.\n\nThe action writes both a full manifest and a compact summary. It also exposes\nthe summary as outputs for reusable workflow callers:\n\n| Output | Meaning |\n| --- | --- |\n| `manifest-path` | Full manifest path |\n| `summary-path` | Compact summary path |\n| `artifact-name` | Resolved artifact name |\n| `artifact-file-count` | Number of manifest files |\n| `artifact-total-bytes` | Total manifest bytes |\n| `artifact-summary-json` | One-line JSON summary |\n| `expected-artifacts-ok` | `true` when expectations passed |\n\n`expected-artifacts-json` can require exact paths, file count bounds, and a\nminimum byte total:\n\n```yaml\nwith:\n expected-artifacts-json: >-\n {\"minFiles\":2,\"requiredPaths\":[\"dist/app.tar.gz\",\"dist/checksums.txt\"]}\n```\n\nFor long native builds, set `sample-process-tree: \"true\"` and pass\n`process-summary-path`. The action wraps either the explicit `command` or the\nconfigured lifecycle stage with `buildchain sample process-tree`, then embeds\nthe produced summary in the lifecycle diagnostics artifact:\n\n```yaml\nwith:\n stage: build\n sample-process-tree: \"true\"\n process-summary-path: .buildchain/diagnostics/process-summary.json\n```\n\nCustom wrappers can still pass an existing sampler report or summary with\n`process-summary-path`; the action reads it after the lifecycle command\nfinishes, so commands may generate the file during the same invocation.\nSet `process-summary-required: \"false\"` when the summary is an optional sidecar,\nfor example when a reusable workflow may skip an optional build stage.\nThe diagnostics directory also includes `diagnostics-manifest.json`, a compact\ninventory of the diagnostics sidecars with byte counts and sha256 hashes."
168
+ },
169
+ {
170
+ "id": "action:validate-config",
171
+ "title": "validate-config",
172
+ "route": "/actions/validate-config",
173
+ "category": "action",
174
+ "sourcePath": "actions/validate-config/README.md",
175
+ "digest": "sha256:d94868373fe5d19dd00e1e956a7dfa9cb5dc2d0f83543d9d861643030644251e",
176
+ "headings": [
177
+ {
178
+ "level": 1,
179
+ "title": "validate-config",
180
+ "anchor": "validate-config"
181
+ },
182
+ {
183
+ "level": 2,
184
+ "title": "Usage",
185
+ "anchor": "usage"
186
+ }
187
+ ],
188
+ "markdown": "# validate-config\n\nBuildchain v2 action for validating `buildchain.toml` without running lifecycle\ncommands.\n\nUse this action during repository migration when a heavyweight project needs to\nprove that its Buildchain version state and lifecycle declaration are ready, but\nthe actual build should not run yet.\n\n## Usage\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/validate-config@v2\n with:\n require-version-state: \"true\"\n require-lifecycle-stages: \"install,build,verify\"\n```\n\nThe action checks:\n\n- `buildchain.toml` exists and uses schema `1`;\n- configured version-state files exist and expose a string version;\n- anchored/manual version strategy declarations and JSON/TOML anchor manifests\n are structurally valid when configured;\n- web-surface project, channel, deploy adapter, retention, and staging security\n declarations are structurally valid when configured;\n- required lifecycle stages are declared and structurally valid.\n\nIt does not execute `lifecycle.install`, `lifecycle.build`, `lifecycle.verify`,\nor any other lifecycle command.\n\nOutputs include `project-type`, `project-name`, `project-site`, `channels`, and\n`deploy-adapters-json`, so callers can route site workflows without reparsing\nTOML in every repository."
189
+ },
190
+ {
191
+ "id": "api:node-package",
192
+ "title": "Buildchain Core Package",
193
+ "route": "/api/node-package",
194
+ "category": "api",
195
+ "sourcePath": "packages/core/README.md",
196
+ "digest": "sha256:892fa941e4ba5647f83d5fbae501d5e023f885fc25ad3f6682a7bb4e6b482f8f",
197
+ "headings": [
198
+ {
199
+ "level": 1,
200
+ "title": "Buildchain Core Package",
201
+ "anchor": "buildchain-core-package"
202
+ },
203
+ {
204
+ "level": 2,
205
+ "title": "Toolkit Imports",
206
+ "anchor": "toolkit-imports"
207
+ }
208
+ ],
209
+ "markdown": "# Buildchain Core Package\n\nShared code lives here when workflow and action migration shows repeated logic\nthat is worth centralizing.\n\nCurrent shared surfaces:\n\n- `buildchain.toml` loading and normalization;\n- version-state file discovery and update helpers;\n- lifecycle stage normalization and execution;\n- config validation for release-package and `web-surface` projects.\n- toolkit observability logging through `@kungfu-tech/buildchain/logging`;\n- toolkit diagnostics and native profile collection through\n `@kungfu-tech/buildchain/diagnostics`;\n- release passport creation and verification through\n `@kungfu-tech/buildchain/release-passport`.\n\n## Toolkit Imports\n\nThe npm package exports ESM APIs. JavaScript build scripts should import these\nAPIs directly instead of spawning the `buildchain` CLI:\n\n```js\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\n\nconst logger = createBuildchainLogger({ source: \"user\", component: \"native\" });\nawait logger.span(\"native.package\", { phase: \"package\" }, packageArtifacts);\n```\n\nThe CLI remains the right surface for GitHub Actions steps, shell scripts, and\nnon-JavaScript build tools.\n\nDiagnostics consumers should import the published subpath and compare stable\ncontracts through the exported constants instead of hardcoding JSON contract\nnames:\n\n```js\nimport {\n BUILDCHAIN_DIAGNOSTICS_CONTRACT,\n BUILDCHAIN_DIAGNOSTICS_SUMMARY_CONTRACT,\n collectRunnerDiagnostics,\n summarizeDiagnosticsArtifacts,\n} from \"@kungfu-tech/buildchain/diagnostics\";\n```\n\nCommonJS scripts can use dynamic imports for the same package surfaces:\n\n```js\nconst { createBuildchainLogger } = await import(\"@kungfu-tech/buildchain/logging\");\nconst { collectRunnerDiagnostics } = await import(\"@kungfu-tech/buildchain/diagnostics\");\n```\n\nWeb-surface validation stays in core because both local scripts and GitHub\nActions need the same fail-closed interpretation of project, channel, deploy,\nretention, and staging security declarations.",
210
+ "slug": "node-package"
211
+ },
212
+ {
213
+ "id": "manual:binary-distribution",
214
+ "title": "Binary Distribution",
215
+ "route": "/docs/binary-distribution",
216
+ "category": "manual",
217
+ "sourcePath": "docs/binary-distribution.md",
218
+ "digest": "sha256:36899140a9b2e9ce1565ed41f3d64f73a8829fad3d59a04b9498d9479c85c4be",
219
+ "headings": [
220
+ {
221
+ "level": 1,
222
+ "title": "Binary Distribution",
223
+ "anchor": "binary-distribution"
224
+ },
225
+ {
226
+ "level": 2,
227
+ "title": "Asset Rules",
228
+ "anchor": "asset-rules"
229
+ },
230
+ {
231
+ "level": 2,
232
+ "title": "Runner Policy",
233
+ "anchor": "runner-policy"
234
+ },
235
+ {
236
+ "level": 2,
237
+ "title": "Evidence Bundle",
238
+ "anchor": "evidence-bundle"
239
+ },
240
+ {
241
+ "level": 2,
242
+ "title": "Local Smoke",
243
+ "anchor": "local-smoke"
244
+ }
245
+ ],
246
+ "markdown": "# Binary Distribution\n\nBuildchain's binary distribution is the first high-pressure proof case for the\nRelease Passport protocol. It is not the boundary of the product.\n\n## Asset Rules\n\nGitHub Release assets use platform-specific archives:\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 release lane does not upload loose top-level `buildchain` or\n`buildchain.exe` assets. Linux and macOS both name the executable `buildchain`\ninside their archives, so top-level loose assets would collide when matrix\nartifacts are merged.\n\nRelease asset upload is gated before the matrix starts. Manual\n`workflow_dispatch` runs are binary dry-runs only and must keep\n`upload-release=false`; real GitHub Release uploads must come from a true\n`v*` tag-triggered run so an invalid manual upload request cannot spend the\nthree-platform build matrix and then fail at `gh release upload`.\n\nGitHub Release metadata is deterministic and tag-derived. Exact alpha tags such\nas `v2.6.2-alpha.0` are created or updated with `prerelease=true` and\n`make_latest=false`; exact stable tags such as `v2.6.1` are created or updated\nwith `prerelease=false` and `make_latest=true`. The workflow uses\n`scripts/ensure-github-release.mjs` before asset upload instead of relying on\nGitHub's default latest-release heuristic.\n\nEach archive is accompanied by:\n\n- a platform manifest from the standalone binary builder;\n- platform observability event logs and summaries;\n- `checksums.txt`;\n- Release Passport evidence files;\n- `buildchain-release-bundle.tar.gz`;\n- `buildchain-release-bundle.json`.\n\n## Runner Policy\n\nProduction binary builds use GitHub-hosted runners:\n\n- `ubuntu-24.04`\n- `macos-latest`\n- `windows-2022`\n\nSelf-hosted runners are compatibility fixtures. They can prove that consumers\nwith private runner fleets can still use the protocol, but Buildchain's public\nbinary distribution should stay reproducible on GitHub-hosted runners.\n\n## Evidence Bundle\n\n`buildchain-release-bundle.tar.gz` groups release assets and passport evidence\nunder one archive:\n\n```text\nbuildchain-release-bundle/\n release-assets/\n release-passport/\n buildchain-release-bundle.index.json\n```\n\n`buildchain-release-bundle.json` records the bundle digest and every included\nfile digest. Consumers can download the bundle when they want one artifact for\noffline review, mirroring, or site ingestion.\n\n## Local Smoke\n\n```bash\nnode scripts/build-standalone-binary.mjs --version v0.0.0-local --output-dir dist/binary\nnode bin/buildchain.mjs collect github-release \\\n --tag v0.0.0-local \\\n --assets-dir dist/binary \\\n --output-dir .buildchain/release-passport\nnode scripts/create-release-bundle.mjs \\\n --assets-dir dist/binary \\\n --passport-dir .buildchain/release-passport \\\n --output-dir .buildchain/release-passport \\\n --tag v0.0.0-local\n```"
247
+ },
248
+ {
249
+ "id": "manual:cli",
250
+ "title": "Buildchain CLI, npm Package, and Toolkit API",
251
+ "route": "/docs/cli",
252
+ "category": "manual",
253
+ "sourcePath": "docs/cli.md",
254
+ "digest": "sha256:a8a348181d6419b746e863d1cacc9d6a91aa6ac5cc2b60819843d44487957c49",
255
+ "headings": [
256
+ {
257
+ "level": 1,
258
+ "title": "Buildchain CLI, npm Package, and Toolkit API",
259
+ "anchor": "buildchain-cli-npm-package-and-toolkit-api"
260
+ },
261
+ {
262
+ "level": 2,
263
+ "title": "Install and Run",
264
+ "anchor": "install-and-run"
265
+ },
266
+ {
267
+ "level": 2,
268
+ "title": "Node API and Package Exports",
269
+ "anchor": "node-api-and-package-exports"
270
+ },
271
+ {
272
+ "level": 2,
273
+ "title": "Commands",
274
+ "anchor": "commands"
275
+ },
276
+ {
277
+ "level": 2,
278
+ "title": "npm Publish Gate",
279
+ "anchor": "npm-publish-gate"
280
+ }
281
+ ],
282
+ "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.\n\nCurrent public import families include:\n\n```js\nimport * as buildchain from \"@kungfu-tech/buildchain\";\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\nimport { verifyKfd1ReleaseGate } from \"@kungfu-tech/buildchain/kfd-gate\";\nimport { verifyReleasePassport } from \"@kungfu-tech/buildchain/release-passport\";\nimport { createReleasePropagationPlan } from \"@kungfu-tech/buildchain/release-propagation\";\nimport contractWorld from \"@kungfu-tech/buildchain/site/buildchain-contract.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\" };\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 init` writes a starter `buildchain.toml` and a reusable workflow\ncaller at `.github/workflows/build.yml`.\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 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.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\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 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.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 publish-source`, and `buildchain build-contract` route to the same scripts used by Buildchain's\nGitHub Actions workflows. This keeps local inspection and CI behavior on the\nsame implementation path.\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-1/contract-world.witness.json \\\n --kfd-2-claim-json .buildchain/kfd-2/release-claims.json \\\n --kfd-3-prebuild-witness-json .buildchain/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.\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\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.\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\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."
283
+ },
284
+ {
285
+ "id": "manual:consumer-issue-reporting",
286
+ "title": "Consumer Issue Reporting",
287
+ "route": "/docs/consumer-issue-reporting",
288
+ "category": "manual",
289
+ "sourcePath": "docs/consumer-issue-reporting.md",
290
+ "digest": "sha256:8e2159312e47b42ab0bb644cb195362150acc8872e6ac0e7380ece0c5cf36955",
291
+ "headings": [
292
+ {
293
+ "level": 1,
294
+ "title": "Consumer Issue Reporting",
295
+ "anchor": "consumer-issue-reporting"
296
+ },
297
+ {
298
+ "level": 2,
299
+ "title": "Trust model",
300
+ "anchor": "trust-model"
301
+ },
302
+ {
303
+ "level": 2,
304
+ "title": "Behavior",
305
+ "anchor": "behavior"
306
+ },
307
+ {
308
+ "level": 2,
309
+ "title": "JavaScript API",
310
+ "anchor": "javascript-api"
311
+ }
312
+ ],
313
+ "markdown": "# Consumer Issue Reporting\n\nBuildchain ships a first-class issue reporting surface for consumer workflows.\nIt lets a repository open or update a Buildchain-owned GitHub issue when a\nBuildchain reusable workflow, action, or toolkit API produces a failure that\nneeds Buildchain maintainers.\n\n## Trust model\n\nThe consumer workflow must provide a token with issue-write access to the\ntarget repository. A repository's default `GITHUB_TOKEN` only writes to its own\nrepository, so cross-repository reports should use a GitHub App installation\ntoken scoped to:\n\n- the `kungfu-systems/buildchain` repository;\n- Issues: read and write;\n- no content write permission unless another workflow step needs it.\n\nThe recommended pattern is:\n\n```yaml\n- uses: actions/create-github-app-token@v2\n id: buildchain-issue-token\n with:\n app-id: ${{ secrets.BUILDCHAIN_ISSUE_APP_ID }}\n private-key: ${{ secrets.BUILDCHAIN_ISSUE_APP_PRIVATE_KEY }}\n owner: kungfu-systems\n repositories: buildchain\n\n- uses: kungfu-systems/buildchain/actions/report-buildchain-issue@v2\n if: failure()\n with:\n token: ${{ steps.buildchain-issue-token.outputs.token }}\n summary: \"Buildchain reusable build failed before artifact finalization\"\n failure-code: reusable-build-failed\n diagnostics-path: .buildchain/artifacts/diagnostics.json\n buildchain-ref: ${{ inputs.buildchain-ref || 'v2' }}\n```\n\n## Behavior\n\n`report-buildchain-issue` builds an issue body with consumer repository,\nworkflow, ref, SHA, Buildchain ref/version, diagnostics links, and optional\ndetails. It computes a stable fingerprint and embeds a hidden marker:\n\n```text\nbuildchain-consumer-issue:fingerprint=<sha256-prefix>\n```\n\nWhen an open issue with the same marker exists, the action comments on it with\nthe new run evidence. Otherwise it creates a new issue. Consumers may pass an\nexplicit `fingerprint` when they need a different dedupe boundary.\n\nThe action is fail-soft by default. It retries GitHub API 429/5xx responses and\nconnection failures, redacts common secret/token/private-key patterns, truncates\nlarge bodies, and retries issue creation without labels if the target\nrepository does not have the configured labels yet.\n\nSet `fail-on-error: \"true\"` only when the reporting step is part of a release\ngate and missing Buildchain feedback should stop the workflow.\n\n## JavaScript API\n\nConsumer scripts can import the same implementation:\n\n```js\nimport {\n buildConsumerIssueReport,\n reportBuildchainIssue,\n} from \"@kungfu-tech/buildchain/issue-reporting\";\n\nconst result = await reportBuildchainIssue({\n token: process.env.BUILDCHAIN_ISSUE_TOKEN,\n summary: \"Native artifact manifest is incomplete\",\n failureCode: \"native-manifest-incomplete\",\n buildchainRef: \"v2\",\n diagnosticsPath: \".buildchain/artifacts/diagnostics.json\",\n});\n```\n\nUse `buildConsumerIssueReport` for dry-run validation, previewing redaction, or\nunit tests without calling GitHub."
314
+ },
315
+ {
316
+ "id": "manual:infra-contract",
317
+ "title": "Infra Contract",
318
+ "route": "/docs/infra-contract",
319
+ "category": "manual",
320
+ "sourcePath": "docs/infra-contract.md",
321
+ "digest": "sha256:7826e8c70ac2d90ddd8d4e38bcdd1bcfa36eef5106431d7ad94b2fe9c8d3d5dc",
322
+ "headings": [
323
+ {
324
+ "level": 1,
325
+ "title": "Infra Contract",
326
+ "anchor": "infra-contract"
327
+ },
328
+ {
329
+ "level": 2,
330
+ "title": "Configuration",
331
+ "anchor": "configuration"
332
+ },
333
+ {
334
+ "level": 2,
335
+ "title": "CLI",
336
+ "anchor": "cli"
337
+ },
338
+ {
339
+ "level": 2,
340
+ "title": "Safety",
341
+ "anchor": "safety"
342
+ }
343
+ ],
344
+ "markdown": "# Infra Contract\n\n`project.type = \"infra-contract\"` models infrastructure release responsibility\nwithout binding Buildchain core to one infrastructure tool. The state machine is:\n\n```text\ndesired -> validate -> plan -> approval -> apply -> observe -> contract -> propagate\n```\n\nThe first supported surface is mutation-free: Buildchain validates declarations,\ncreates a normalized plan, reads reviewed or adapter-shaped observed outputs,\npublishes a deterministic contract artifact, and plans downstream consumer pull\nrequests. Propagation execution is also dry-run by default. Real infrastructure\nmutation and real consumer pull request creation are not PR or ordinary push side\neffects.\n\nAfter apply and propagation produce their own result JSON, Buildchain can also\nwrite a lifecycle evidence bundle. The bundle references the immutable contract\nartifact by `artifactHash`, verifies that any apply result matches the artifact's\n`sourceSha` and plan hash, verifies that propagation results target the same\nartifact, and then hashes the combined desired, plan, approval, apply, observe,\ncontract, and propagation evidence.\n\n## Configuration\n\n```toml\nschema = 1\n\n[project]\ntype = \"infra-contract\"\nname = \"infra-kungfu-sites\"\n\n[infra]\nadapter = \"manual-observed\"\nadoption_mode = \"manual-observed\"\napply = \"disabled\"\nenvironment = \"staging\"\ndesired = [\"desired/site-kungfu-tech.json\"]\ncontract = [\"outputs/site-kungfu-tech.json\"]\n\n[[consumers]]\nrepo = \"kungfu-systems/site-kungfu-tech\"\npath = \"infra/outputs.json\"\nsource = \"outputs/site-kungfu-tech.json\"\n```\n\nSupported adapters:\n\n```text\nmanual-observed\naws-cloudformation\nterraform\nopentofu\npulumi\naws-cdk\naws-cli\ncustom-command\n```\n\nBuildchain's safe fixture set covers the provider-neutral shape without live\nprovider calls:\n\n- `manual-observed` for existing reviewed resources;\n- `aws-cloudformation` for template plus stack output shapes;\n- `terraform` for plan/output JSON shapes;\n- `opentofu` for plan/output JSON shapes;\n- `pulumi` for preview/output JSON shapes;\n- `aws-cdk` for synthesized assembly plus stack output shapes;\n- `aws-cli` for generic desired request plus observed response shapes;\n- `custom-command` for user-defined validate, plan, observe, and approved apply\n hooks.\n\nFor built-in provider adapters, Buildchain records planned adapter command\nevidence for `validate`, `plan`, `apply`, and `observe` when a stage is\nsupported. These entries are command plans, not execution. They make the\nadapter handoff auditable before a repository opts in to concrete commands,\nand they stay `executed: false` even when `--execute-adapter-commands true` is\npassed.\n\nAny adapter can declare concrete command hooks under `[infra.commands]`.\nConfigured commands are the only executable provider surface. Buildchain records\nthem as planned adapter evidence by default. Passing\n`--execute-adapter-commands true` to `plan` or `contract` executes the\nnon-mutating `validate`, `plan`, or `observe` hooks and stores their exit\nstatus, stdout/stderr, and JSON stdout when present. The `apply` hook is only\navailable through the saved-plan apply path and is never executed by ordinary\nPR validation.\n\nSupported adoption modes:\n\n```text\nvalidate-only\nplan-only\nobserve-only\nmanual-observed\nimport-planned\nmanaged-apply\n```\n\n`apply = \"disabled\"` is the default. Non-disabled apply requires\n`adoption_mode = \"managed-apply\"`, a non-empty `environment`, a non-empty\n`identity_ref`, and an explicit approval id before mutation. `identity_ref` is a\nprovider-neutral reference to the runtime role, service account, or environment\ncredential name; it is not a secret value. Apply also requires a saved plan\nartifact whose `sourceSha`, `plannedAt`, and input hash still match the current\nrepository. Real apply execution requires a configured `[infra.commands].apply`\ncommand, `--dry-run false`, and `--execute-adapter-commands true`. Without a\nconfigured apply command, built-in provider adapters still fail closed before\nmutation execution.\n\nFor managed apply, bind the target and runtime identity explicitly:\n\n```toml\nadoption_mode = \"managed-apply\"\napply = \"manual-approval\"\nenvironment = \"preview\"\nidentity_ref = \"AWS_ROLE_ARN\"\n```\n\n## CLI\n\n```sh\nbuildchain infra-contract --mode validate\nbuildchain infra-contract --mode ci --source-sha \"$GITHUB_SHA\"\nbuildchain infra-contract --mode plan --source-sha \"$GITHUB_SHA\" \\\n --output .buildchain/infra-contract-plan.json\nbuildchain infra-contract --mode plan --source-sha \"$GITHUB_SHA\" \\\n --execute-adapter-commands true \\\n --output .buildchain/infra-contract-plan.json\nbuildchain infra-contract --mode contract \\\n --plan .buildchain/infra-contract-plan.json \\\n --source-sha \"$GITHUB_SHA\" \\\n --output .buildchain/buildchain.infra-contract.json\nbuildchain infra-contract --mode propagation-plan \\\n --artifact .buildchain/buildchain.infra-contract.json \\\n --output .buildchain/infra-contract-propagation.json\nbuildchain infra-contract --mode propagation-apply \\\n --propagation-plan .buildchain/infra-contract-propagation.json \\\n --dry-run true \\\n --output .buildchain/infra-contract-propagation-apply.json\nbuildchain infra-contract --mode apply \\\n --plan .buildchain/infra-contract-plan.json \\\n --source-sha \"$GITHUB_SHA\" \\\n --approval-id \"$APPROVAL_ID\" \\\n --dry-run true \\\n --output .buildchain/infra-contract-apply.json\nbuildchain infra-contract --mode apply \\\n --plan .buildchain/infra-contract-plan.json \\\n --source-sha \"$GITHUB_SHA\" \\\n --approval-id \"$APPROVAL_ID\" \\\n --dry-run false \\\n --execute-adapter-commands true \\\n --output .buildchain/infra-contract-apply.json\nbuildchain infra-contract --mode evidence-bundle \\\n --artifact .buildchain/buildchain.infra-contract.json \\\n --apply-result .buildchain/infra-contract-apply.json \\\n --propagation-result .buildchain/infra-contract-propagation-apply.json \\\n --output .buildchain/infra-contract-evidence-bundle.json\nbuildchain verify infra-contract-evidence-bundle \\\n .buildchain/infra-contract-evidence-bundle.json\n```\n\n`ci` is the default mutation-free lifecycle entrypoint for repositories created\nwith `buildchain init --type infra-contract`. It validates the project, writes a\nplan, writes an observed contract artifact, writes a propagation plan, runs\npropagation apply in dry-run mode, creates an evidence bundle, and verifies that\nbundle. It does not execute provider apply commands or open consumer PRs.\n\nFor projects where apply is disabled, omit `--apply-result`. For projects with\nno consumers, omit `--propagation-result`.\n\nThe evidence-bundle verifier is read-only. It recomputes the bundle hash,\nchecks the contract artifact hash, verifies that desired, plan, approval,\napply, observe, contract, and propagate evidence are all present, recomputes\nthe bundle validation summary, and fails closed when apply or propagation\nresults are not bound to the same artifact.\n\n## Safety\n\n- PR validation is mutation-free.\n- `buildchain infra-contract --mode ci` is mutation-free by default and produces\n auditable `.buildchain/infra-contract*.json` evidence for reusable workflow\n artifacts.\n- `manual-observed` and observe-only modes cannot apply.\n- Apply fails before mutation unless approval, target environment, identity\n reference, adapter capability, and ownership mode are explicit.\n- Apply rejects missing, stale, source-mismatched, or input-drifted plan\n artifacts before any adapter mutation can run.\n- Built-in provider adapter command evidence is planned-only unless the\n repository declares a concrete command for that stage under `[infra.commands]`.\n- Provider apply requires saved plan freshness, an approval id, target\n environment, identity reference, a configured apply command,\n `--dry-run false`, and `--execute-adapter-commands true`; nonzero adapter\n exits fail closed and are recorded as adapter evidence.\n- Terraform/OpenTofu state files and Pulumi state or secret JSON files are not\n accepted as contract inputs.\n- Consumers are represented as pull request plans. `propagation-apply` defaults\n to dry-run; real PR creation requires `--dry-run false`, `--approval-id`, and\n explicit `--consumer-workspace owner/repo=/path/to/checkout` mappings.\n- Buildchain never pushes mirrored contract files directly to consumer main\n branches. Real propagation creates reviewable branches and calls\n `gh pr create`.\n- Evidence bundles do not execute adapters, mutate infrastructure, or open PRs.\n They only verify and hash already saved contract, apply, and propagation\n outputs.\n- `buildchain verify infra-contract-evidence-bundle` is read-only and fails\n closed when the lifecycle evidence chain is incomplete, tampered, or carries\n a stale validation summary."
345
+ },
346
+ {
347
+ "id": "manual:install",
348
+ "title": "Install and Verify Buildchain",
349
+ "route": "/docs/install",
350
+ "category": "manual",
351
+ "sourcePath": "docs/install.md",
352
+ "digest": "sha256:34bc161a26595f95684694d341616e47bfd65b0c51a63225e68a575179636175",
353
+ "headings": [
354
+ {
355
+ "level": 1,
356
+ "title": "Install and Verify Buildchain",
357
+ "anchor": "install-and-verify-buildchain"
358
+ },
359
+ {
360
+ "level": 2,
361
+ "title": "Standalone Binary",
362
+ "anchor": "standalone-binary"
363
+ },
364
+ {
365
+ "level": 2,
366
+ "title": "npm Package",
367
+ "anchor": "npm-package"
368
+ },
369
+ {
370
+ "level": 2,
371
+ "title": "Repository Integration",
372
+ "anchor": "repository-integration"
373
+ },
374
+ {
375
+ "level": 2,
376
+ "title": "Verify a Release Passport",
377
+ "anchor": "verify-a-release-passport"
378
+ }
379
+ ],
380
+ "markdown": "# Install and Verify Buildchain\n\nBuildchain can be consumed as a standalone binary, an npm package, or a\nrepository workflow surface. In every case, verify the release record before\nadopting a new version.\n\n## Standalone Binary\n\nUse the archive that matches the platform:\n\n| Platform | Asset |\n| --- | --- |\n| Linux x64 | `buildchain-x86_64-unknown-linux-gnu.tar.gz` |\n| macOS arm64 | `buildchain-aarch64-apple-darwin.tar.gz` |\n| Windows x64 | `buildchain-x86_64-pc-windows-msvc.zip` |\n\nLinux example:\n\n```bash\ntag=v2.2.1\nbase=\"https://github.com/kungfu-systems/buildchain/releases/download/${tag}\"\ncurl -LO \"${base}/buildchain-x86_64-unknown-linux-gnu.tar.gz\"\ncurl -LO \"${base}/buildchain.release.json\"\ncurl -LO \"${base}/artifact-evidence.json\"\nnpx @kungfu-tech/buildchain verify release-passport buildchain.release.json\ntar -xzf buildchain-x86_64-unknown-linux-gnu.tar.gz\n./buildchain version\n```\n\nWindows example:\n\n```powershell\n$tag = \"v2.2.1\"\n$base = \"https://github.com/kungfu-systems/buildchain/releases/download/$tag\"\nInvoke-WebRequest \"$base/buildchain-x86_64-pc-windows-msvc.zip\" -OutFile buildchain.zip\nInvoke-WebRequest \"$base/buildchain.release.json\" -OutFile buildchain.release.json\nInvoke-WebRequest \"$base/artifact-evidence.json\" -OutFile artifact-evidence.json\nnpx @kungfu-tech/buildchain verify release-passport buildchain.release.json\nExpand-Archive buildchain.zip -DestinationPath .\n.\\buildchain.exe version\n```\n\nThe GitHub Release page does not publish loose top-level `buildchain` or\n`buildchain.exe` files. The executable is inside each platform archive.\n\n## npm Package\n\n```bash\nnpm install -D @kungfu-tech/buildchain\nnpx buildchain version\nnpx buildchain doctor --json\n```\n\nAlpha releases publish to the `alpha` npm dist-tag. Stable releases publish to\n`latest`. Both are created by the protected Buildchain promotion transaction.\n\nStable consumers should pin the exact Buildchain version they have validated,\nfor example:\n\n```bash\npnpm add -D @kungfu-tech/buildchain@2.2.5\n```\n\nIf a repository dogfoods a just-published Buildchain version and pnpm's release\nage policy blocks the install, use a temporary package/version-specific\n`minimumReleaseAgeExclude` entry instead of weakening the registry policy for\nall packages:\n\n```json\n{\n \"pnpm\": {\n \"minimumReleaseAgeExclude\": [\n \"@kungfu-tech/buildchain@2.2.5\"\n ]\n }\n}\n```\n\nRemove that entry after the package is old enough for the repository's normal\npolicy. Do not use a broad exclude such as `@kungfu-tech/*` for this case.\n\n## Repository Integration\n\n```bash\nnpx @kungfu-tech/buildchain init --type package --package-manager pnpm\nnpx @kungfu-tech/buildchain validate --require-version-state\nnpx @kungfu-tech/buildchain release --dry-run --target-ref alpha/v2/v2.2\n```\n\nUse `buildchain.toml` to declare lifecycle commands. The commands may use Node\npackage managers or non-Node tools such as pip, Conan, CMake, Make, or project\nscripts.\n\n## Verify a Release Passport\n\n```bash\nbuildchain verify release-passport buildchain.release.json\nbuildchain explain release --passport buildchain.release.json --for agent --json\n```\n\nThe verifier fails closed when the passport or its sibling evidence files are\nmissing required fields or mismatching artifact digests."
381
+ },
382
+ {
383
+ "id": "manual:lifecycle-protocol",
384
+ "title": "Lifecycle Protocol",
385
+ "route": "/docs/lifecycle-protocol",
386
+ "category": "manual",
387
+ "sourcePath": "docs/lifecycle-protocol.md",
388
+ "digest": "sha256:02e1be97935c0d9520ea22e8ef0dc61d9b860c347f07127074600cdca02713ce",
389
+ "headings": [
390
+ {
391
+ "level": 1,
392
+ "title": "Lifecycle Protocol",
393
+ "anchor": "lifecycle-protocol"
394
+ },
395
+ {
396
+ "level": 2,
397
+ "title": "Minimal File",
398
+ "anchor": "minimal-file"
399
+ },
400
+ {
401
+ "level": 2,
402
+ "title": "Version State",
403
+ "anchor": "version-state"
404
+ },
405
+ {
406
+ "level": 3,
407
+ "title": "Anchored Manual Versions",
408
+ "anchor": "anchored-manual-versions"
409
+ },
410
+ {
411
+ "level": 2,
412
+ "title": "Lifecycle Stages",
413
+ "anchor": "lifecycle-stages"
414
+ },
415
+ {
416
+ "level": 3,
417
+ "title": "Publish Stage",
418
+ "anchor": "publish-stage"
419
+ },
420
+ {
421
+ "level": 2,
422
+ "title": "Promotion Semantics",
423
+ "anchor": "promotion-semantics"
424
+ },
425
+ {
426
+ "level": 2,
427
+ "title": "Migration Preflight",
428
+ "anchor": "migration-preflight"
429
+ },
430
+ {
431
+ "level": 2,
432
+ "title": "Web-Surface Projects",
433
+ "anchor": "web-surface-projects"
434
+ },
435
+ {
436
+ "level": 2,
437
+ "title": "Infra-Contract Projects",
438
+ "anchor": "infra-contract-projects"
439
+ },
440
+ {
441
+ "level": 2,
442
+ "title": "Examples",
443
+ "anchor": "examples"
444
+ },
445
+ {
446
+ "level": 3,
447
+ "title": "Node Workspace",
448
+ "anchor": "node-workspace"
449
+ },
450
+ {
451
+ "level": 3,
452
+ "title": "Python Package",
453
+ "anchor": "python-package"
454
+ },
455
+ {
456
+ "level": 3,
457
+ "title": "CMake and Conan",
458
+ "anchor": "cmake-and-conan"
459
+ },
460
+ {
461
+ "level": 3,
462
+ "title": "Docker Image",
463
+ "anchor": "docker-image"
464
+ },
465
+ {
466
+ "level": 2,
467
+ "title": "Design Boundaries",
468
+ "anchor": "design-boundaries"
469
+ }
470
+ ],
471
+ "markdown": "# Lifecycle Protocol\n\nBuildchain uses `buildchain.toml` as the v2 repository configuration format.\nThe file is optional for simple JavaScript repositories, but it is the preferred\nway to describe release version state and lifecycle commands when a project is\nnot a plain pnpm, npm, or yarn workspace.\n\nOnly TOML is supported in v2. YAML, JSON, and JavaScript config files are not\nloaded.\n\n## Minimal File\n\n```toml\nschema = 1\n\n[version]\nrequired = true\n\n[[version.files]]\ntype = \"json\"\npath = \"package.json\"\nkey = \"version\"\n\n[lifecycle.verify]\ncommands = [\n \"pnpm run check\",\n]\n```\n\n`schema = 1` is required. Buildchain fails closed when the schema is missing or\nunknown.\n\n## Version State\n\nVersion state is the source file evidence that matches a release tag. During\npromotion, Buildchain writes the selected release or prerelease version into the\nconfigured files, verifies the resulting tree, creates a source version commit,\nthen moves exact and floating refs.\n\nSupported version file types:\n\n| Type | Use case | Required fields |\n| --- | --- | --- |\n| `json` | `package.json`, JSON manifests | `path`, `key` |\n| `toml` | `pyproject.toml`, other TOML manifests | `path`, `key` |\n| `regex` | `CMakeLists.txt`, `conanfile.py`, plain version files | `path`, `pattern`, `replacement` |\n\n`key` is a dotted key path:\n\n```toml\n[[version.files]]\ntype = \"toml\"\npath = \"pyproject.toml\"\nkey = \"project.version\"\n```\n\nRegex files must expose the current version through a named capture group called\n`version`:\n\n```toml\n[[version.files]]\ntype = \"regex\"\npath = \"CMakeLists.txt\"\npattern = 'project\\([^)]* VERSION (?<version>[^ )]+)'\nreplacement = '${version}'\n```\n\nIf `version.required = true`, promotion fails when no configured version files\nare available.\n\n### Anchored Manual Versions\n\nSome repositories do not derive their package version from the Buildchain\nrelease tag. `libnode` is the canonical example: the package version is anchored\nto an explicitly selected upstream Node.js release such as `22.22.3-kf.0`, while\nthe channel line may be `release/v22/v22.22`.\n\nThose repositories can opt into anchored manual semantics:\n\n```toml\n[version]\nrequired = true\nstrategy = \"anchored\"\nnext = \"manual\"\nmanifest = \"libnode.release.json\"\n\n[[version.files]]\ntype = \"json\"\npath = \"package.json\"\nkey = \"version\"\n```\n\nWith `strategy = \"anchored\"` and `next = \"manual\"`:\n\n- Buildchain validates the configured version files and anchor manifest, but it\n does not rewrite those files to the Buildchain release tag.\n- `lifecycle.verify` is the project-owned truth gate. It should compare the\n package version, anchor manifest, and upstream source/submodule state.\n- release promotion still creates the exact/floating production refs for the\n current line;\n- release promotion does not auto-create the next alpha branch or tag;\n- the action output `next-anchor-required` is `true`, signaling that the next\n upstream anchor line must be created explicitly by the repository.\n\nThe configured anchor manifest must be JSON or TOML. Buildchain does not\ninterpret project-specific field names; it only loads the manifest and exposes\nits top-level fields to validation summaries and lifecycle environment:\n\n```text\nBUILDCHAIN_VERSION_STRATEGY=anchored\nBUILDCHAIN_VERSION_NEXT=manual\nBUILDCHAIN_ANCHOR_MANIFEST=libnode.release.json\nBUILDCHAIN_ANCHOR_MANIFEST_JSON={\"nodeTag\":\"v22.22.3\",...}\n```\n\nThe upstream anchor decision remains outside Buildchain. A future line such as\n`dev/v24/v24.xx` should be created by an explicit repository workflow or human\ndecision after the upstream version has been selected and checked in.\n\n## Lifecycle Stages\n\nLifecycle stages are declarative shell commands. A stage can use exactly one of:\n\n- `command`: one shell command;\n- `commands`: multiple shell commands run in order;\n- `script`: a multiline shell script.\n\nAny command failure fails the stage. `timeout_minutes`, `retries`, `shell`, and\n`env` can be attached to a stage.\n\nDuring version-state verification, Buildchain also sets `BUILDCHAIN_VERSION` to\nthe release or prerelease version being verified.\n\n```toml\n[lifecycle.install]\ntimeout_minutes = 10\nretries = 3\ncommands = [\n \"pnpm install --frozen-lockfile\",\n]\n\n[lifecycle.build]\ncommands = [\n \"pnpm run build\",\n \"pnpm run package\",\n]\n\n[lifecycle.verify]\nshell = \"bash\"\nscript = \"\"\"\nset -euo pipefail\npnpm run check\ngit diff --check\n\"\"\"\n```\n\nShared environment variables can be declared once:\n\n```toml\n[lifecycle.env]\nPYTHONUNBUFFERED = \"1\"\n```\n\nStage-specific environment variables override shared lifecycle environment:\n\n```toml\n[lifecycle.test]\ncommand = \"pytest\"\n\n[lifecycle.test.env]\nPYTHONPATH = \"src\"\n```\n\n### Publish Stage\n\n`lifecycle.publish` is the project-owned side-effect stage. It may call npm,\nPyPI, Conan, CMake packaging scripts, Docker/OCI registries, S3 uploaders, or\nany other publisher. Buildchain does not assume the tool; it assumes the\nevidence contract.\n\n```toml\n[lifecycle.publish]\nscript = \"\"\"\nset -euo pipefail\npython scripts/publish_wheels.py\nnode scripts/publish-images.mjs\nnode scripts/write-publish-evidence.mjs\n\"\"\"\n```\n\nWhen `actions/promote-buildchain-ref` runs with `publish-transaction: \"true\"`,\nthe publish stage receives the transaction identity plus the resolved publish\ncontract:\n\n```text\nBUILDCHAIN_VERSION\nBUILDCHAIN_CHANNEL\nBUILDCHAIN_SOURCE_SHA\nBUILDCHAIN_TARGET_REF\nBUILDCHAIN_RELEASE_STATE\nBUILDCHAIN_EVIDENCE_DIR\nBUILDCHAIN_RELEASE_SHA\nBUILDCHAIN_RELEASE_MATERIAL_SHA\nBUILDCHAIN_PUBLISH_TOOLING_SHA\nBUILDCHAIN_PUBLISH_EVIDENCE\nBUILDCHAIN_PUBLISH_MODE\nBUILDCHAIN_PUBLISH_AUTH\nBUILDCHAIN_NPM_DIST_TAG\nBUILDCHAIN_PACKAGE_SET_ORDER\nBUILDCHAIN_PACKAGE_SET_MAIN_PACKAGE\n```\n\nThe stage must write publish evidence JSON. Buildchain validates that evidence\nbefore exact tags and floating refs move. In GitHub Actions, the promotion\naction also persists `state.json` and `evidence.json` to\n`refs/heads/buildchain/release-state/<version>` so fresh runners can recover\nwithout local workspace residue. See\n[`docs/publish-transaction.md`](publish-transaction.md) for the state machine,\nevidence schema, and recovery commands.\n\nFor npm packages, prefer:\n\n```toml\n[publish]\nmode = \"publish-final-version\"\nauth = \"trusted-publishing\"\ndist_tag = \"latest\"\n```\n\nUse `mode = \"promote-existing-version\"` only for explicit same-version\ndist-tag recovery, and pair it with `auth = \"npm-token\"`. Trusted Publishing\ndoes not authorize `npm dist-tag add`; Buildchain fails that combination before\nany publish transaction side effect.\n\n## Promotion Semantics\n\n`actions/promote-buildchain-ref` consumes `version.files`, `lifecycle.verify`,\nand optionally `lifecycle.publish`.\n\nThe verify stage runs after Buildchain has applied the generated version-state\nchanges to the local checkout, and before it creates release commits or moves\nrefs. After the command finishes, Buildchain checks that only declared\nversion-state files changed. This prevents verification from quietly adding\nextra source changes to the release commit.\n\nOn protected alpha and release branches, the generated version-state commit is\nmerged through a normal pull request. This keeps review requirements,\nconversation resolution, strict status checks, and admin enforcement intact.\nAfter that PR lands, Buildchain verifies that the version-state PR changed only\ndeclared version files from the legal channel-promotion parent before it moves\ntags.\n\nFor `version.strategy = \"anchored\"` with `version.next = \"manual\"`, release\npromotion does not generate a Buildchain-owned version-state commit. In that\nmode, a protected `alpha -> release` PR may carry the declared `version.files`\nfrom the tested alpha package version to the final package version, and may\ncarry the configured `version.manifest` with it. Buildchain only accepts that\nrelease tree difference when the PR is the valid channel-promotion PR, the\nchanged paths are limited to those declared version files plus the anchor\nmanifest, and `lifecycle.verify` or `verification-command` has validated the\nchecked-out release material. Any code or undeclared file change still fails the\nrelease tree gate.\n\nThe action input `verification-command` remains supported. When it is provided,\nit overrides `lifecycle.verify` for that invocation.\n\n## Migration Preflight\n\nHeavy repositories can validate their Buildchain declaration before they are\nready to run the real build. `actions/validate-config` checks that\n`buildchain.toml` parses, configured version-state files exist, configured\nversion keys are strings, and required lifecycle stage names are declared.\nFor web-surface repositories it also validates `project`, `channels`, `deploy`,\n`retention`, and `security` declarations.\n\nIt does not run lifecycle commands. This is useful for repositories such as\n`libnode`, where `lifecycle.build` represents an expensive multi-platform native\nbuild and the first migration milestone is to prove the release metadata and\nlifecycle protocol without consuming build runners.\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/validate-config@v2\n with:\n require-version-state: \"true\"\n require-lifecycle-stages: \"install,build,verify\"\n```\n\nWeb-surface repositories can use the same action without requiring version\nstate:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/validate-config@v2\n with:\n require-lifecycle-stages: \"build,verify\"\n```\n\nThe action exposes project and deploy metadata through outputs such as\n`project-type`, `project-site`, `channels`, and `deploy-adapters-json`.\n\n## Web-Surface Projects\n\n`project.type = \"web-surface\"` is for sites, docs, browser apps, and operator\nconsoles whose release object is a deployed surface, not a package version.\n\n```toml\nschema = 1\n\n[project]\ntype = \"web-surface\"\nname = \"site-libkungfu-dev\"\nsite = \"libkungfu-dev\"\n\n[channels.preview]\nurl_pattern = \"https://{alias}.preview.libkungfu.dev\"\nvisibility = \"ephemeral\"\nnoindex = true\n\n[channels.staging]\nurl = \"https://staging.libkungfu.dev\"\nvisibility = \"protected\"\naccess_control = \"managed-network\"\nedge_auth = \"none\"\nnoindex = true\npromotable = true\n\n[channels.production]\nurl = \"https://libkungfu.dev\"\nvisibility = \"public\"\ncanonical = true\nnoindex = false\n\n[surfaces.hub]\npath = \"/\"\nproduction_url = \"https://libkungfu.dev\"\nstaging_url = \"https://staging.libkungfu.dev\"\npreview_url_pattern = \"https://{alias}.preview.libkungfu.dev\"\n\n[surfaces.core]\npath = \"/core/\"\nproduction_url = \"https://core.libkungfu.dev\"\nstaging_url = \"https://core.staging.libkungfu.dev\"\npreview_url_pattern = \"https://core-{alias}.preview.libkungfu.dev\"\n\n[deploy.production]\nadapter = \"aws-s3-cloudfront\"\nbucket = \"libkungfu-dev-production\"\nartifact_path = \"dist\"\nsecret_refs = [\"AWS_ROLE_ARN\"]\n```\n\nSee [Web-surface deployments](web-surface-deployments.md) for named surface host\nmappings, the manifest, preview alias, retention, cleanup, and dry-run deploy\ncontract.\n\n## Infra-Contract Projects\n\n`project.type = \"infra-contract\"` is for infrastructure contract repositories\nthat need provider-neutral desired, plan, approval, apply, observe, contract,\nand propagation evidence. `buildchain init --type infra-contract` wires\n`lifecycle.verify` to `buildchain infra-contract --mode ci`, which writes\nmutation-free plan, contract, propagation dry-run, evidence bundle, and\nverification artifacts under `.buildchain/`. The surface supports\nmanual-observed, observe-only, and mocked adapter fixtures without reading\ncloud state files or executing live infrastructure mutation. See\n[Infra Contract](infra-contract.md).\n\n## Examples\n\n### Node Workspace\n\n```toml\nschema = 1\n\n[version]\nrequired = true\n\n[[version.files]]\ntype = \"json\"\npath = \"package.json\"\nkey = \"version\"\n\n[lifecycle.verify]\ncommands = [\n \"pnpm run check\",\n]\n```\n\n### Python Package\n\n```toml\nschema = 1\n\n[version]\nrequired = true\n\n[[version.files]]\ntype = \"toml\"\npath = \"pyproject.toml\"\nkey = \"project.version\"\n\n[lifecycle.install]\ncommand = \"python -m pip install -e .[test]\"\n\n[lifecycle.build]\ncommand = \"python -m build\"\n\n[lifecycle.verify]\ncommands = [\n \"python -m build\",\n \"pytest\",\n]\n```\n\n### CMake and Conan\n\n```toml\nschema = 1\n\n[[version.files]]\ntype = \"regex\"\npath = \"CMakeLists.txt\"\npattern = 'project\\([^)]* VERSION (?<version>[^ )]+)'\nreplacement = '${version}'\n\n[lifecycle.configure]\ncommands = [\n \"conan install . --build=missing\",\n \"cmake -S . -B build -DCMAKE_BUILD_TYPE=Release\",\n]\n\n[lifecycle.build]\ncommand = \"cmake --build build --config Release\"\n\n[lifecycle.verify]\ncommands = [\n \"cmake --build build --config Release\",\n \"ctest --test-dir build --output-on-failure\",\n]\n```\n\n### Docker Image\n\n```toml\nschema = 1\n\n[[version.files]]\ntype = \"json\"\npath = \"package.json\"\nkey = \"version\"\n\n[lifecycle.build]\ncommand = \"docker build -f Dockerfile -t kungfutrader/example:${BUILDCHAIN_VERSION} .\"\n\n[lifecycle.verify]\ncommand = \"docker build -f Dockerfile -t kungfutrader/example:verify .\"\n```\n\nDocker publishing is an external side effect and should be gated by a release\nworkflow after version-state promotion has been verified.\n\n## Design Boundaries\n\nThe lifecycle protocol is also the command source for the reusable build\nsurface. `.github/workflows/.build.yml` runs `lifecycle.install`,\n`lifecycle.build`, and `lifecycle.verify` by default, while allowing callers to\noverride each stage with explicit workflow inputs. The underlying\n`actions/run-lifecycle` action can be used directly by repositories that need a\ncustom workflow but still want Buildchain's lifecycle and deterministic manifest\ncontract.\n\nBuildchain lifecycle commands are data, not executable configuration files.\nThey make release behavior reviewable in pull requests and keep the release\nfact chain simple:\n\n1. choose the channel branch and release line;\n2. generate a source version commit from declared version files;\n3. verify that exact tree;\n4. move exact tags and floating refs only after verification succeeds;\n5. run publish or deployment side effects in separately gated workflows."
472
+ },
473
+ {
474
+ "id": "manual:map",
475
+ "title": "Documentation Map",
476
+ "route": "/docs/map",
477
+ "category": "manual",
478
+ "sourcePath": "docs/MAP.md",
479
+ "digest": "sha256:b5cfef531ba8ca655d8d66ffe0e530a0ca2c971daad5880943d2b824216ed043",
480
+ "headings": [
481
+ {
482
+ "level": 1,
483
+ "title": "Documentation Map",
484
+ "anchor": "documentation-map"
485
+ },
486
+ {
487
+ "level": 2,
488
+ "title": "Capability Coverage",
489
+ "anchor": "capability-coverage"
490
+ },
491
+ {
492
+ "level": 2,
493
+ "title": "Map",
494
+ "anchor": "map"
495
+ },
496
+ {
497
+ "level": 2,
498
+ "title": "Also asking about",
499
+ "anchor": "also-asking-about"
500
+ },
501
+ {
502
+ "level": 2,
503
+ "title": "How this map is maintained",
504
+ "anchor": "how-this-map-is-maintained"
505
+ }
506
+ ],
507
+ "markdown": "# Documentation Map\n\nStart here. Find the question you have; follow it to the document that answers\nit. This map is meant to be readable by both a person skimming for the right doc\nand an agent grounding a specific claim.\n\nEach row carries a **plane** - *why* (intent / rationale), *verify* (trust the\nrunning artifact), *use* (consume / extend) - and a **status**:\n\n- `stable` - current and holds.\n- `draft` - exists, rough or incomplete.\n- `to write` - planned; the material exists but is not yet a single doc.\n- `retired` - intentionally not part of the active Buildchain v2 surface.\n\n## Capability Coverage\n\nThis package should be usable by an agent from the npm artifact alone. The\nmachine-readable `dist/site/` bundle is the first fact source; the Markdown\nmanuals explain those facts and give operator examples.\n\n| Capability | Machine-readable entry | Manual entry |\n| --- | --- | --- |\n| KFD-1 / KFD-2 / KFD-3 release-passport gates | `dist/site/kfd-claims.json`, `dist/site/buildchain-contract.json`, `dist/site/artifact-schemas.json` | [`release-passport.md`](release-passport.md) |\n| Floating `@v2` drift detection and compatibility issues | `dist/site/buildchain-contract.json` | [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock) |\n| npm publish transactions, evidence, dist-tags, and recovery | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`publish-transaction.md`](publish-transaction.md) |\n| GitHub Release passport/evidence publication | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`release-governance.md`](release-governance.md), [`release-candidate.md`](release-candidate.md) |\n| release propagation for package/site chains | `dist/site/release-model.json` | [`release-propagation.md`](release-propagation.md) |\n| Buildchain CLI manual | `dist/site/cli-registry.json`, `dist/site/manual-registry.json` | [`cli.md`](cli.md) |\n| Node API / package exports | `dist/site/node-api-registry.json`, `dist/site/release-provenance.json` | [`cli.md`](cli.md#node-api-and-package-exports) |\n\n`dist/site/kfd-claims.json` is generated from\n`packages/core/buildchain-kfd-claims.js`. Treat that module and JSON file as the\nsource claim registry; this map and the manuals explain those claims but do not\nreplace them.\n\n## Map\n\n| Your question | Document | Plane | Status |\n| --- | --- | --- | --- |\n| What is Buildchain, in one idea? | [`../README.md`](../README.md) | - | stable |\n| Why is Buildchain a Release Passport mechanism rather than a generic workflow collection? | [`product-mechanism.md`](product-mechanism.md) | why | stable |\n| How do agents and contributors enter this repo? | [`../AGENTS.md`](../AGENTS.md) + [`../CONTRIBUTING.md`](../CONTRIBUTING.md) | use | stable |\n| How do I install a standalone binary or npm package? | [`install.md`](install.md) | use | stable |\n| How do I run the `buildchain` CLI? | [`cli.md`](cli.md) | use | stable |\n| How do I import Buildchain toolkit APIs from JavaScript build code? | [`toolkit-observability.md`](toolkit-observability.md) + [`../packages/core/README.md`](../packages/core/README.md) | use | stable |\n| How do I initialize a new repository? | [`cli.md`](cli.md) + [`lifecycle-protocol.md`](lifecycle-protocol.md) | use | stable |\n| Why does Buildchain use branch-driven release governance? | [`release-governance.md`](release-governance.md) | why | stable |\n| How do protected dev branches and scheduled ready-PR merging work? | [`release-governance.md`](release-governance.md#protected-dev-branches) | use | stable |\n| How do I run daily, weekly, or monthly repository patrols? | [`release-governance.md`](release-governance.md#buildchain-patrol) | use | stable |\n| How does Buildchain decide patch, minor, and major release lines? | [`versioning.md`](versioning.md) | why | stable |\n| What exact branch/tag state machine runs on alpha, release, and major gate? | [`release-flow.md`](release-flow.md) | verify | stable |\n| What did Buildchain migrate or retire from old action repositories? | [`migration-inventory.md`](migration-inventory.md) | verify | stable |\n| What is the active action and workflow source of truth? | [`ownership.md`](ownership.md) | verify | stable |\n| How do I declare version files and custom lifecycle commands? | [`lifecycle-protocol.md`](lifecycle-protocol.md) | use | stable |\n| How does publish evidence, recovery, and finalization work? | [`publish-transaction.md`](publish-transaction.md) | verify | stable |\n| How do I publish or verify release passport artifacts? | [`release-passport.md`](release-passport.md) | use | stable |\n| How do I gate release artifacts with KFD-1 contract-world witnesses? | [`release-passport.md`](release-passport.md#kfd-1-contract-world-release-gate) | verify/use | stable |\n| How do I audit public KFD-2 release trust claims? | [`release-passport.md`](release-passport.md#kfd-2-release-trust-passport-audit) + [`cli.md`](cli.md) | verify/use | stable |\n| How do I gate KFD-3 collaboration-interface releases? | [`release-passport.md`](release-passport.md#kfd-3-collaboration-interface-release-gate) + [`cli.md`](cli.md) | verify/use | stable |\n| How do I keep `@v2` floating refs while detecting Buildchain contract drift? | [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock) | verify/use | stable |\n| How do I propagate finalized upstream releases to downstream package/site PRs? | [`release-propagation.md`](release-propagation.md) | use | preview |\n| How do I prove a PR-stage reusable build is the artifact source promoted later? | [`release-candidate.md`](release-candidate.md) + [`reusable-build-surface.md`](reusable-build-surface.md) | verify | stable |\n| Why are binary release assets archived by platform, and where is the single bundle? | [`binary-distribution.md`](binary-distribution.md) | verify | stable |\n| How do I add timestamped logs inside build scripts? | [`toolkit-observability.md`](toolkit-observability.md) | use | stable |\n| What package-owned facts should buildchain.libkungfu.dev render? | [`site-bundle-contract.md`](site-bundle-contract.md) | use | stable |\n| How do I call the reusable build workflow? | [`reusable-build-surface.md`](reusable-build-surface.md) | use | stable |\n| How do self-hosted runners relay large artifacts through S3 before GitHub artifacts? | [`reusable-build-surface.md`](reusable-build-surface.md#artifact-transfer-relay) | use | stable |\n| How do I validate an unreleased Buildchain runtime train while keeping `@v2`? | [`runtime-train-validation.md`](runtime-train-validation.md) | use | stable |\n| How do I deploy a site/app preview, staging, or production surface? | [`web-surface-deployments.md`](web-surface-deployments.md) | use | stable |\n| How do I publish observed infrastructure contracts for downstream consumers? | [`infra-contract.md`](infra-contract.md) | use | preview |\n| How do I use the active actions directly? | [`../actions/validate-config/README.md`](../actions/validate-config/README.md), [`../actions/run-lifecycle/README.md`](../actions/run-lifecycle/README.md), [`../actions/promote-buildchain-ref/README.md`](../actions/promote-buildchain-ref/README.md), [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |\n| How can a consumer workflow report a Buildchain-owned failure back to Buildchain? | [`consumer-issue-reporting.md`](consumer-issue-reporting.md) + [`../actions/report-buildchain-issue/README.md`](../actions/report-buildchain-issue/README.md) | use | stable |\n| What do the fixture repositories demonstrate? | [`../fixtures/libnode-shaped/README.md`](../fixtures/libnode-shaped/README.md), [`../fixtures/publish-transaction-shaped/README.md`](../fixtures/publish-transaction-shaped/README.md), [`../fixtures/web-surface-shaped/README.md`](../fixtures/web-surface-shaped/README.md) | verify | stable |\n| What license and contribution terms apply? | [`../LICENSE`](../LICENSE) + [`../LICENSE-POLICY.md`](../LICENSE-POLICY.md) | use | stable |\n| What trademark, official-service, and provider-compliance boundaries apply? | [`../TRADEMARK.md`](../TRADEMARK.md) + [`../ACCEPTABLE_USE.md`](../ACCEPTABLE_USE.md) + [`../PROVIDER_COMPLIANCE.md`](../PROVIDER_COMPLIANCE.md) | use | stable |\n| How do I report a vulnerability? | [`../SECURITY.md`](../SECURITY.md) | use | stable |\n\n## Also asking about\n\n- **ABV / old workflows / old action repositories** -> [`release-governance.md`](release-governance.md)\n and [`migration-inventory.md`](migration-inventory.md).\n- **v2 / v2.0 / v2.0-alpha / exact tags / floating tags** ->\n [`release-governance.md`](release-governance.md) and\n [`release-flow.md`](release-flow.md).\n- **v2.1 vs v2.2 / when to open a new minor line** ->\n [`versioning.md`](versioning.md).\n- **dry-run / what would happen if this channel PR merges** -> [`cli.md`](cli.md)\n and [`release-flow.md`](release-flow.md).\n- **protected dev branches / scheduled ready-PR merge / daily-weekly-monthly patrol** ->\n [`release-governance.md`](release-governance.md#protected-dev-branches) and\n [`release-governance.md`](release-governance.md#buildchain-patrol).\n- **pnpm / npm / yarn / package-manager adapters** ->\n [`lifecycle-protocol.md`](lifecycle-protocol.md).\n- **pip / Conan / CMake / custom commands** -> [`lifecycle-protocol.md`](lifecycle-protocol.md)\n and [`reusable-build-surface.md`](reusable-build-surface.md).\n- **libnode / native artifacts / self-hosted runner matrix** ->\n [`reusable-build-surface.md`](reusable-build-surface.md) and\n [`../fixtures/libnode-shaped/README.md`](../fixtures/libnode-shaped/README.md).\n- **S3 artifact relay / self-hosted runner artifact transfer** ->\n [`reusable-build-surface.md`](reusable-build-surface.md#artifact-transfer-relay).\n- **runtime train validation / temporary `buildchain-ref` override** ->\n [`runtime-train-validation.md`](runtime-train-validation.md) and\n [`reusable-build-surface.md`](reusable-build-surface.md).\n- **consumer workflow feedback / automatic Buildchain GitHub issues** ->\n [`consumer-issue-reporting.md`](consumer-issue-reporting.md).\n- **PR-stage RC artifacts / promote-only release candidates** ->\n [`release-candidate.md`](release-candidate.md) and\n [`reusable-build-surface.md`](reusable-build-surface.md).\n- **infra contract / observed infrastructure outputs / downstream contract propagation** ->\n [`infra-contract.md`](infra-contract.md).\n- **standalone binary install / platform archives / GitHub Release bundle** ->\n [`install.md`](install.md), [`binary-distribution.md`](binary-distribution.md),\n and [`release-passport.md`](release-passport.md).\n- **Trusted Publishing / npm / publish evidence / recovery** ->\n [`cli.md`](cli.md) and [`publish-transaction.md`](publish-transaction.md).\n- **release chains / upstream package as source of truth / site synchronization** ->\n [`release-propagation.md`](release-propagation.md).\n- **KFD-1 contract worlds / byte-for-byte release gates** ->\n [`release-passport.md`](release-passport.md#kfd-1-contract-world-release-gate).\n- **KFD-2 public release trust claim audit** ->\n [`release-passport.md`](release-passport.md#kfd-2-release-trust-passport-audit).\n- **KFD-3 collaboration-interface / agent-facing control surface closure** ->\n [`release-passport.md`](release-passport.md#kfd-3-collaboration-interface-release-gate).\n- **floating `@v2` / contract lock / compatible drift issue** ->\n [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock).\n- **GitHub Release passport / binary assets / artifact evidence / agent release checks** ->\n [`release-passport.md`](release-passport.md),\n [`binary-distribution.md`](binary-distribution.md), and [`cli.md`](cli.md).\n- **Buildchain logging / timestamps / consumer build phase timing** ->\n [`toolkit-observability.md`](toolkit-observability.md) for JavaScript API\n imports, and [`cli.md`](cli.md) for workflow or shell command usage.\n- **buildchain.libkungfu.dev / package-owned site facts** ->\n [`site-bundle-contract.md`](site-bundle-contract.md).\n- **sites / web previews / staging / production gates** ->\n [`web-surface-deployments.md`](web-surface-deployments.md).\n- **trademark / fork / official service / provider compliance / release\n evidence boundary** -> [`../TRADEMARK.md`](../TRADEMARK.md),\n [`../ACCEPTABLE_USE.md`](../ACCEPTABLE_USE.md), and\n [`../PROVIDER_COMPLIANCE.md`](../PROVIDER_COMPLIANCE.md).\n\n## How this map is maintained\n\n- A document becomes a row here when it is a stable entrypoint for a user,\n contributor, or workflow consumer.\n- A row's status must never claim more than the artifact delivers.\n- `why` documents explain intent and design pressure; `verify` and `use`\n documents should state what is guaranteed, where to verify it, and the current\n maturity of that guarantee."
508
+ },
509
+ {
510
+ "id": "manual:migration-inventory",
511
+ "title": "Buildchain v2 Migration Inventory",
512
+ "route": "/docs/migration-inventory",
513
+ "category": "manual",
514
+ "sourcePath": "docs/migration-inventory.md",
515
+ "digest": "sha256:80018cf78785431e67bbc5278d82dda80d0baa320cdb5e4abda26a0b05e5c0bc",
516
+ "headings": [
517
+ {
518
+ "level": 1,
519
+ "title": "Buildchain v2 Migration Inventory",
520
+ "anchor": "buildchain-v2-migration-inventory"
521
+ },
522
+ {
523
+ "level": 2,
524
+ "title": "Workflow Sources",
525
+ "anchor": "workflow-sources"
526
+ },
527
+ {
528
+ "level": 2,
529
+ "title": "Reusable Workflow Boundaries",
530
+ "anchor": "reusable-workflow-boundaries"
531
+ },
532
+ {
533
+ "level": 2,
534
+ "title": "Migrated Actions",
535
+ "anchor": "migrated-actions"
536
+ },
537
+ {
538
+ "level": 2,
539
+ "title": "Retired Actions Excluded From v2",
540
+ "anchor": "retired-actions-excluded-from-v2"
541
+ },
542
+ {
543
+ "level": 2,
544
+ "title": "Retired Workflows Excluded From v2",
545
+ "anchor": "retired-workflows-excluded-from-v2"
546
+ },
547
+ {
548
+ "level": 2,
549
+ "title": "Buildchain-Native Actions",
550
+ "anchor": "buildchain-native-actions"
551
+ },
552
+ {
553
+ "level": 2,
554
+ "title": "Stable v2 Refs",
555
+ "anchor": "stable-v2-refs"
556
+ },
557
+ {
558
+ "level": 2,
559
+ "title": "Verification Gates",
560
+ "anchor": "verification-gates"
561
+ }
562
+ ],
563
+ "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\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"
564
+ },
565
+ {
566
+ "id": "manual:ownership",
567
+ "title": "Ownership And Migration Rules",
568
+ "route": "/docs/ownership",
569
+ "category": "manual",
570
+ "sourcePath": "docs/ownership.md",
571
+ "digest": "sha256:49074fb520c404d3c9f5b49b33562d4bdc4e3ed407cf22543fa8e19e312a6b8e",
572
+ "headings": [
573
+ {
574
+ "level": 1,
575
+ "title": "Ownership And Migration Rules",
576
+ "anchor": "ownership-and-migration-rules"
577
+ },
578
+ {
579
+ "level": 2,
580
+ "title": "Source Of Truth",
581
+ "anchor": "source-of-truth"
582
+ },
583
+ {
584
+ "level": 2,
585
+ "title": "Compatibility Rule",
586
+ "anchor": "compatibility-rule"
587
+ },
588
+ {
589
+ "level": 2,
590
+ "title": "Publishing Rule",
591
+ "anchor": "publishing-rule"
592
+ },
593
+ {
594
+ "level": 2,
595
+ "title": "Candidate Ref Rule",
596
+ "anchor": "candidate-ref-rule"
597
+ },
598
+ {
599
+ "level": 2,
600
+ "title": "Source-Locked Publish Rule",
601
+ "anchor": "source-locked-publish-rule"
602
+ }
603
+ ],
604
+ "markdown": "# Ownership And Migration Rules\n\n## Source Of Truth\n\nBuildchain v2 workflow and action design lands in this repository. Standalone\n`workflows` and `action-*` repositories are historical rollback anchors.\nBuildchain only ships the native action surface required for config validation,\nlifecycle execution, and release ref promotion.\n\n## Compatibility Rule\n\nDo not break existing stable reusable workflow refs during migration:\n\n- `kungfu-systems/workflows@v2`\n\nAny consumer migration must record:\n\n- old `uses:` refs;\n- new `uses:` refs;\n- workflow run ids;\n- rollback command or revert path.\n\nNew stable references should use:\n\n- `kungfu-systems/buildchain/actions/validate-config@v2`\n- `kungfu-systems/buildchain/actions/run-lifecycle@v2`\n- `kungfu-systems/buildchain/actions/promote-buildchain-ref@v2`\n- `kungfu-systems/buildchain/.github/workflows/<workflow>.yml@v2`\n\n## Publishing Rule\n\nPublishing paths stay disabled in buildchain's own verification workflows unless\nexplicitly enabled by a production release workflow. Any consumer cutover that\npublishes packages, S3 artifacts, release pages, or preview links must include\nrollback notes. Reusable workflow consumers should gate publish jobs with\n`needs.<build-job>.outputs.publish-allowed == 'true'` and record the requested\n`publish-channel`, rather than duplicating channel branch logic in every\nconsumer workflow.\n\n## Candidate Ref Rule\n\nCandidate refs are expected to resolve under `kungfu-systems/*`. Broader\nsources require an explicit trust decision before they can reach self-hosted\nrunners or secrets.\n\n## Source-Locked Publish Rule\n\nWhen a consumer uses `publish-gate/*` branches, publish jobs must use the\nresolved `publish-source-sha` and `release-manifest-json` emitted by the reusable\nbuild workflow. Before touching a package registry, S3 bucket, release page, or\nfloating alias, the publish job must verify that the gate branch still points at\nthe recorded SHA. A moved gate branch is a stale release decision, not a retry."
605
+ },
606
+ {
607
+ "id": "manual:product-mechanism",
608
+ "title": "Product Mechanism",
609
+ "route": "/docs/product-mechanism",
610
+ "category": "manual",
611
+ "sourcePath": "docs/product-mechanism.md",
612
+ "digest": "sha256:da50022f96f8876bb275a7832190cb1f6ab0fa6aab9d045dda924a7abddc3edf",
613
+ "headings": [
614
+ {
615
+ "level": 1,
616
+ "title": "Product Mechanism",
617
+ "anchor": "product-mechanism"
618
+ },
619
+ {
620
+ "level": 2,
621
+ "title": "Design Pressure",
622
+ "anchor": "design-pressure"
623
+ },
624
+ {
625
+ "level": 2,
626
+ "title": "What the Passport Solves",
627
+ "anchor": "what-the-passport-solves"
628
+ },
629
+ {
630
+ "level": 2,
631
+ "title": "Why Binary Distribution Matters",
632
+ "anchor": "why-binary-distribution-matters"
633
+ },
634
+ {
635
+ "level": 2,
636
+ "title": "Naming",
637
+ "anchor": "naming"
638
+ }
639
+ ],
640
+ "markdown": "# Product Mechanism\n\nBuildchain's product boundary is the Release Passport: a mature product release\nrecord for artifacts that users or agents depend on.\n\n## Design Pressure\n\nMany repositories can already compile, test, and upload artifacts. The hard\nproblem is proving what a release means after it has been promoted:\n\n- which reviewed source state was released;\n- which exact version-state commit and tag represent that release;\n- which artifacts were created;\n- which checks and publish steps were allowed to run;\n- which floating channel refs now point at that release;\n- how another human or agent can verify, explain, mirror, or roll back the\n release without asking the maintainer to reconstruct the story.\n\nBuildchain uses GitHub as the substrate for this proof. It does not require a\nproject to abandon its existing build system.\n\n## What the Passport Solves\n\nThe passport turns a release into a durable record:\n\n- exact tags are immutable release identities;\n- floating refs are explicitly machine-updated channel pointers;\n- version files are changed by version-state commits, not by unpublished local\n edits;\n- build and publish evidence is machine-readable;\n- release checks fail closed when evidence is incomplete;\n- site and documentation facts can be generated from the package instead of\n being copied by hand.\n\n## Why Binary Distribution Matters\n\nBinary artifacts are a strong proof case because users and agents may execute\nthem directly. That makes checksums, runner facts, package evidence, and\nrollback instructions more urgent.\n\nThe protocol is not binary-bound. The same release passport model applies to\nnpm packages, Python wheels, OCI images, native SDK archives, web-surface\ndeployments, and multi-artifact product releases.\n\n## Naming\n\nUse these names consistently:\n\n- Product name: `Buildchain`\n- Formal first mention: `Buildchain by Kungfu`\n- Category anchor: `Buildchain Release Passport`\n- Core release record: `buildchain.release.json`\n\nAvoid defining Buildchain as only a workflow collection, a binary distributor,\nor a replacement CI/CD platform."
641
+ },
642
+ {
643
+ "id": "manual:publish-transaction",
644
+ "title": "Publish Transaction",
645
+ "route": "/docs/publish-transaction",
646
+ "category": "manual",
647
+ "sourcePath": "docs/publish-transaction.md",
648
+ "digest": "sha256:dd45cf98f0847e3968f150a09bed84aa1f59cb2687ac988e9519f08dc9c91877",
649
+ "headings": [
650
+ {
651
+ "level": 1,
652
+ "title": "Publish Transaction",
653
+ "anchor": "publish-transaction"
654
+ },
655
+ {
656
+ "level": 2,
657
+ "title": "Why This Exists",
658
+ "anchor": "why-this-exists"
659
+ },
660
+ {
661
+ "level": 2,
662
+ "title": "Durable State",
663
+ "anchor": "durable-state"
664
+ },
665
+ {
666
+ "level": 2,
667
+ "title": "Lifecycle",
668
+ "anchor": "lifecycle"
669
+ },
670
+ {
671
+ "level": 2,
672
+ "title": "Release Modes And Auth",
673
+ "anchor": "release-modes-and-auth"
674
+ },
675
+ {
676
+ "level": 2,
677
+ "title": "Evidence",
678
+ "anchor": "evidence"
679
+ },
680
+ {
681
+ "level": 2,
682
+ "title": "Registry Truth Contract",
683
+ "anchor": "registry-truth-contract"
684
+ },
685
+ {
686
+ "level": 2,
687
+ "title": "States",
688
+ "anchor": "states"
689
+ },
690
+ {
691
+ "level": 2,
692
+ "title": "Ref Ordering",
693
+ "anchor": "ref-ordering"
694
+ },
695
+ {
696
+ "level": 2,
697
+ "title": "CLI Recovery",
698
+ "anchor": "cli-recovery"
699
+ },
700
+ {
701
+ "level": 2,
702
+ "title": "Build-Images Follow-Up",
703
+ "anchor": "build-images-follow-up"
704
+ }
705
+ ],
706
+ "markdown": "# Publish Transaction\n\nBuildchain release promotion is not just tag movement. A release can also publish\nexternal artifacts: npm packages, Python wheels, OCI images, binary archives,\nmetadata manifests, or site deployment records. Those side effects are harder\nthan Git refs because most registries are append-only: a failed rerun must know\nwhich artifacts already exist, which are still missing, and whether any existing\nartifact conflicts with the release material.\n\nBuildchain v2 models that work as a release transaction.\n\n## Why This Exists\n\nThe old ABV workflow made Git refs the visible release authority. That was\nenough when \"release\" meant \"create a version commit, move tags, and let\ndownstream jobs react.\" It is not enough when a single publish run must also\nupload packages and images.\n\nThe failure mode to avoid is:\n\n1. publish an external artifact;\n2. fail before moving the exact release tag or floating channel refs;\n3. rerun from a new job id with no memory of the artifact;\n4. either republish something different or move refs without proving the\n already-published artifact matches the release.\n\nThe transaction gives reruns a stable identity and a machine-readable state so\nBuildchain can resume safely. The identity is:\n\n```text\nrepository + version + source_sha + target_ref\n```\n\nIt is not the GitHub Actions run id.\n\n## Durable State\n\n`actions/promote-buildchain-ref` stores release transaction state in a\nmachine-managed Git branch:\n\n```text\nrefs/heads/buildchain/release-state/<version>\n```\n\nThe branch contains:\n\n```text\nstate.json\nevidence.json # present after publish evidence exists\n```\n\nThe local `.buildchain/release-state/...` and\n`.buildchain/release-evidence/...` files are working copies. They are useful for\nlocal inspection and lifecycle commands, but they are not the durable truth for\nGitHub-hosted reruns. On action startup, Buildchain reads the durable state ref\nfirst, restores the local working copies, and only then decides whether to\npublish, repair, or finalize.\n\nEvery meaningful state transition is written to the durable ref before public\nrelease refs move. Release-state GitHub API reads and writes use retry/backoff\nfor transient service failures such as HTTP 5xx responses, connection resets,\ntimeouts, and \"other side closed\" socket failures. If the durable write still\ncannot be persisted after retries, the action fails closed.\n\nDurable release-state refs reserve their exact version even when the public exact\ntag was never created. If a later machine run sees a failed or repair-required\nstate for `vX.Y.Z-alpha.N` and cannot resume it with the same transaction\nidentity, alpha version selection must advance to the next prerelease instead\nof reusing or overwriting that failed transaction slot.\n\n## Lifecycle\n\nRepositories declare publish work in `buildchain.toml`:\n\n```toml\n[publish]\nmode = \"publish-final-version\"\nauth = \"trusted-publishing\"\ndist_tag = \"latest\"\npackage_set_order = \"platforms-first-main-last\"\nmain_package = \"@kungfu-tech/libnode\"\n\n[lifecycle.publish]\ncommands = [\n \"python scripts/publish_wheels.py\",\n \"node scripts/publish-images.mjs\",\n \"node scripts/write-publish-evidence.mjs\",\n]\n```\n\n`actions/promote-buildchain-ref` runs `lifecycle.publish` only when\n`publish-transaction: \"true\"` is set or when a `publish-command` input is\nprovided. The action sets:\n\n```text\nBUILDCHAIN_VERSION\nBUILDCHAIN_CHANNEL\nBUILDCHAIN_SOURCE_SHA\nBUILDCHAIN_TARGET_REF\nBUILDCHAIN_RELEASE_STATE\nBUILDCHAIN_EVIDENCE_DIR\nBUILDCHAIN_RELEASE_SHA\nBUILDCHAIN_RELEASE_MATERIAL_SHA\nBUILDCHAIN_PUBLISH_TOOLING_SHA\nBUILDCHAIN_PUBLISH_EVIDENCE\nBUILDCHAIN_PUBLISH_MODE\nBUILDCHAIN_PUBLISH_AUTH\nBUILDCHAIN_NPM_DIST_TAG\nBUILDCHAIN_PACKAGE_SET_ORDER\nBUILDCHAIN_PACKAGE_SET_MAIN_PACKAGE\n```\n\nBuildchain itself uses this contract for npm publishing:\n\n```toml\n[lifecycle.publish]\ncommand = \"node scripts/npm-publish-transaction.mjs\"\n```\n\nThat script validates that `package.json` matches `BUILDCHAIN_VERSION`, runs\n`npm publish --access public --tag <BUILDCHAIN_NPM_DIST_TAG>` through npm Trusted\nPublishing, and writes npm artifact evidence before the promotion action moves\npublic refs.\n\n`BUILDCHAIN_RELEASE_MATERIAL_SHA` is the source material whose artifacts must\nmatch. `BUILDCHAIN_PUBLISH_TOOLING_SHA` identifies the publishing code. A repair\nrun may change tooling, but material drift fails closed.\n\n## Release Modes And Auth\n\nBuildchain distinguishes two npm release modes:\n\n| Mode | Use | Auth | npm operation |\n| --- | --- | --- | --- |\n| `publish-final-version` | normal alpha or stable publication | `trusted-publishing` | `npm publish --tag <alpha|latest>` |\n| `promote-existing-version` | same-version alpha-to-latest recovery | `npm-token` | `npm dist-tag add <pkg>@<version> latest` |\n\nThe normal libnode path is `publish-final-version`: publish an alpha package set\nsuch as `22.22.3-kf.3-alpha.0` with the `alpha` dist-tag, then publish a\ndistinct final package set such as `22.22.3-kf.3` with the `latest` dist-tag.\nGitHub-hosted npm Trusted Publishing can authorize those `npm publish` calls\nwhen the workflow grants `id-token: write`.\n\n`promote-existing-version` is deliberately separate. npm Trusted Publishing does\nnot authorize arbitrary registry-management operations such as `npm dist-tag\nadd`; it authorizes publish-time package provenance. Therefore same-version\npromotion must declare `auth = \"npm-token\"`. Buildchain runs an npm token\npreflight with `npm whoami` before it writes any release transaction state or\nmoves a dist-tag. Missing token auth fails early with a contract error instead\nof a late `E401` after publish evidence has started to move.\n\nFor package sets, `package_set_order = \"platforms-first-main-last\"` makes the\nmain package the visibility gate. Platform package side effects are planned or\nretried first, and the main package or main dist-tag move happens last.\n\nWhen the transaction reaches `complete`, `actions/promote-buildchain-ref`\ngenerates `.buildchain/release-passport/buildchain.release.json` and persists\nthe `release-passport/*` files into the durable `buildchain/release-state/...`\nref. The passport is the stable release artifact for agents and people: it\nlinks the package set, npm publish evidence, dist-tag evidence, build summary,\nplatform artifact manifests, trusted publishing metadata, release-state ref,\ndurable release-state SHA, and transaction result in one schema. Consumer\nrepositories can set `release-passport-product-name` so the passport names their\nproduct instead of the Buildchain default.\n\n## Evidence\n\nThe publish lifecycle must write JSON evidence. Buildchain validates common\nfields and required artifact identities before final refs move.\n\n```json\n{\n \"schema\": 1,\n \"version\": \"2.0.11\",\n \"channel\": \"release\",\n \"source_sha\": \"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa\",\n \"release_sha\": \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\n \"target_ref\": \"release/v2/v2.0\",\n \"release_material_sha\": \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\n \"publish_tooling_sha\": \"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb\",\n \"artifacts\": [\n {\n \"group\": \"node\",\n \"kind\": \"npm\",\n \"name\": \"@kungfu-systems/example\",\n \"ref\": \"2.0.11\",\n \"digest\": \"sha256:...\"\n },\n {\n \"group\": \"image\",\n \"kind\": \"oci\",\n \"name\": \"ghcr.io/kungfu-systems/example\",\n \"ref\": \"2.0.11\",\n \"digest\": \"sha256:...\"\n }\n ]\n}\n```\n\nThe generic contract is intentionally small:\n\n- `version`, `channel`, `source_sha`, `release_sha`, and `target_ref` must match\n the promotion run;\n- dist-tag promotion evidence is written beside the publish evidence as\n `dist-tag-evidence.json` and is referenced from the generated passport;\n- required artifacts must appear in evidence;\n- evidence used by a GitHub-hosted rerun must either be stored in the durable\n state ref or be reconstructed by a machine-verifiable consumer command;\n- existing artifacts with the same identity and digest are accepted on rerun;\n- missing artifacts can be published by the next run;\n- an existing artifact with a different digest puts the transaction into\n `repair_required`.\n\nArtifact identity is `group + kind + name + ref`. A required artifact that omits\n`group` matches any group with the same `kind + name + ref`.\n\n## Registry Truth Contract\n\nBuildchain owns transaction orchestration, finalization ordering, durable state,\nand generic evidence validation. It does not embed registry clients for npm,\nPyPI, GHCR/OCI, GitHub Releases, S3, Conan, CMake packaging, or project-specific\ndownload pages.\n\nConsumer `lifecycle.publish` commands own registry truth. A valid consumer stage\nmust be idempotent and machine-verifiable:\n\n- inspect the target registry before publishing;\n- accept an existing exact artifact only when version, identity, digest, and\n release-source binding match;\n- publish missing required artifacts;\n- reject conflicting existing artifacts and write evidence that lets Buildchain\n move the transaction to `repair_required`;\n- write `BUILDCHAIN_PUBLISH_EVIDENCE` after every successful inspect/publish\n cycle;\n- leave floating aliases such as npm dist-tags, PyPI stable markers, OCI\n floating tags, GitHub Release \"published\" status, or download-page stable\n links to a finalization step after Buildchain evidence validation.\n\nThe first-class adapter surface is command-based. Projects may wrap npm, PyPI,\nGHCR/OCI, GitHub Release assets, archives, SBOMs, provenance, or checksums\nhowever they need, as long as they emit the common evidence contract.\n\n## States\n\nThe state machine is:\n\n```text\nprepared -> publishing -> published -> finalizing -> complete\n | | |\n v v v\n publish_failed repair_required failed_permanently\n |\n v\n abandoned\n```\n\nSupported states:\n\n| State | Meaning |\n| --- | --- |\n| `prepared` | Transaction identity was created, but publish has not started. |\n| `publishing` | Publish lifecycle is running or may have been interrupted. |\n| `publish_failed` | Publish command failed before valid evidence was produced. |\n| `published` | Evidence is valid; refs have not necessarily finalized. |\n| `finalizing` | Buildchain is moving exact/floating refs or needs a later run to do it. |\n| `complete` | Required evidence is valid and refs have finalized. |\n| `repair_required` | Existing evidence or artifact state conflicts with expected release material. |\n| `abandoned` | A human or controlled process abandoned this transaction, usually because a newer version supersedes it. |\n| `failed_permanently` | Recovery should not continue without explicit override. |\n\n`repair_required`, `abandoned`, and `failed_permanently` fail closed unless the\noperator passes an explicit override. That override is for controlled repair\nruns, not normal retry behavior.\n\n## Ref Ordering\n\nWhen publish transactions are enabled, promotion order is:\n\n1. verify target source and governance;\n2. create or reuse the version-state release commit;\n3. acquire or resume the release transaction;\n4. run `lifecycle.publish` or accept already-valid evidence;\n5. validate evidence and required artifacts;\n6. move exact release/prerelease tag;\n7. move floating tags and channel refs;\n8. mark the transaction `complete`.\n\nIf protected branches require a generated version-state PR, the transaction can\nstop in `finalizing` and output `finalization-needed=true`. A later run can\nresume from the same transaction state and complete ref movement without\nrepublishing matching artifacts.\n\nIf finalization fails after an exact Git tag, a channel branch, or dev/alpha\nsync ref has already moved, the next run reads the durable `finalizing` state\nand continues from the recorded transaction. The current workflow SHA may be a\nversion-state merge commit that contains or corresponds to the transaction's\n`release_material_sha`; it does not have to equal the original `source_sha` or\nthe transaction `release_sha`. Exact tags are accepted when they already point\nat the transaction release/material SHA or the finalized channel head. Floating\nchannel tags and dev/alpha refs are then retried idempotently, and the\ntransaction is marked `complete` only after those public refs are consistent.\nWriting `complete` clears any stale `failure` value from earlier attempts, so\nthe durable `state.json` represents the successful final state instead of the\nlast transient error seen before a rerun.\nAn exact tag at an unrelated SHA is still a material conflict and blocks\nrecovery.\n\nIf finalization fails after an exact Git tag is created, the next run reads the\ndurable `finalizing` state, verifies the exact tag points at the recorded\nrelease SHA, and retries the remaining floating refs. An exact tag at a\ndifferent SHA is a material conflict and blocks recovery.\n\n## CLI Recovery\n\nLocal recovery commands operate on the same state/evidence files:\n\n```bash\nnode scripts/release-transaction.mjs inspect --version v2.0.11\nnode scripts/release-transaction.mjs recover --version v2.0.11\nnode scripts/release-transaction.mjs finalize --version v2.0.11\nnode scripts/release-transaction.mjs abort --version v2.0.11 --superseded-by v2.0.12\n```\n\nThe CLI is a diagnostic and local repair surface. It reports the durable\n`state_ref`, but remote durable-ref writes and public Git ref finalization are\nowned by `actions/promote-buildchain-ref`, because that action runs inside the\nsame governed GitHub permissions and branch-protection checks as release\npromotion. In other words, CLI `finalize` can mark the local transaction state\ncomplete after valid evidence; the machine-operated public finalization path is\nto rerun the promotion action.\n\nWhen no state file exists, creation commands also require:\n\n```bash\n--repository kungfu-systems/buildchain \\\n--source-sha <sha> \\\n--release-sha <sha> \\\n--target-ref release/v2/v2.0 \\\n--channel release\n```\n\n## Build-Images Follow-Up\n\n`build-images` should consume this contract rather than inventing a separate\nworkflow rule. The expected integration shape is:\n\n- image build writes OCI digests into publish evidence;\n- required image families are passed through `publish-required-artifacts-json`;\n- reruns check GHCR or the target registry and accept existing images only when\n tag and digest match;\n- preview or alpha image tags remain non-stable until the transaction evidence\n validates;\n- production image aliases move only after all required image artifacts are\n present and the Buildchain exact release tag has finalized."
707
+ },
708
+ {
709
+ "id": "manual:release-candidate",
710
+ "title": "Release Candidate Passport",
711
+ "route": "/docs/release-candidate",
712
+ "category": "manual",
713
+ "sourcePath": "docs/release-candidate.md",
714
+ "digest": "sha256:6b5107cded122925e8560a9b117ff1c96f5cf05d934caf83d7e4b2a4d777175e",
715
+ "headings": [
716
+ {
717
+ "level": 1,
718
+ "title": "Release Candidate Passport",
719
+ "anchor": "release-candidate-passport"
720
+ }
721
+ ],
722
+ "markdown": "# Release Candidate Passport\n\nThe release-candidate passport is the pre-promotion evidence contract produced\nafter a reusable build matrix succeeds and before any publish-gate side effects\nrun. It is different from the release passport:\n\n- `release-candidate-passport.json` proves which source SHA, channel, runtime,\n workflow run, and platform artifacts were verified before promotion.\n- `buildchain.release.json` is generated after publish finalization and remains\n the durable audit entrypoint for the published release.\n\nEnable it on the reusable build workflow:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n with:\n artifact-name: libnode\n release-candidate: true\n publish-channel: alpha\n publish-source-ref: publish-gate/alpha/v22/v22.22/22.22.3-kf.3-alpha.7\n```\n\nWhen the platform matrix and aggregate summaries complete, Buildchain uploads:\n\n```text\n<artifact-name>-release-candidate-<publish-source-sha>\n```\n\nThe passport contract is `kungfu-buildchain-release-candidate-passport`. It\ncontains:\n\n- repository and pull request context;\n- target channel, target ref, and product version or a non-publish\n `source-<shortSha>` candidate label;\n- source head SHA, merge ref SHA, and the Git `HEAD^{tree}` SHA for PR merge\n equivalence after the channel PR lands;\n- Buildchain runtime ref/SHA and workflow shell ref;\n- workflow run id/attempt/url;\n- normalized platform matrix and artifact summaries;\n- the hash of the aggregate `build-summary.json`.\n\nPromotion workflows that should not rebuild artifacts can enable:\n\n```yaml\n- uses: kungfu-systems/buildchain/actions/promote-buildchain-ref@v2\n with:\n token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n sha: ${{ needs.build.outputs.publish-source-sha }}\n target-ref: alpha/v22/v22.22\n promote-only-release-candidate: \"true\"\n release-candidate-passport-path: .buildchain/artifacts/release-candidate-passport.json\n release-candidate-build-summary-path: .buildchain/artifacts/build-summary.json\n```\n\nWith `promote-only-release-candidate: \"true\"`, promotion fails before\nversion-state, publish transaction, tag, or branch side effects when the\npassport does not match the repository, channel, source identity, platform\nmatrix, or build-summary hash. Source identity accepts the exact PR source SHA,\nthe PR merge ref SHA, or an exact Git tree match with the promoted channel HEAD;\nthis keeps post-merge channel commits strict without forcing a rebuild. The\nBuildchain-owned promotion workflow resolves the matching same-repository\nmerged channel PR and downloads its PR-stage RC passport automatically before\npromotion starts. The consumer wrapper defaults to a PR-stage workflow file\nnamed `build.yml` with display name `Build`, and filters the RC passport and\nbuild summary by the configured `artifact-name` before promotion. It also\ndownloads payload artifacts from the same PR-stage run, validates the required\npayload count, passes downloaded platform manifests into the release passport,\nand either forwards an explicit `publish-required-artifacts-json` value or\ngenerates one before calling `promote-buildchain-ref`. Before that call, the\nwrapper creates or updates `publish-gate/{alpha,release,major}` to the\npromotion channel commit and passes that ref, target SHA, and `locked=true` to\nthe promote action with `require-publish-source-lock: \"true\"`. Consumers using\nfloating `@v2` therefore get publish-side source-lock drift protection without\ncopying resolver or promote YAML. The default npm path\ngenerates that requirement list from the downloaded `.tgz` payloads themselves:\nBuildchain reads `package/package.json` inside each tarball for the real scoped\npackage name and version, computes npm-style `sha512-...` integrity over the\ntarball bytes, marks `publish-package-main` as `role: main`, and marks every\nother package as `role: platform`. Consumer workflows therefore stay\ndeclarative and do not need their own artifact download or publish-evidence\ngeneration scripts.\n\nBy default, the wrapper forwards GitHub Release publication to the underlying\n`promote-buildchain-ref` semver model. Once the release transaction is complete,\nthe action creates or updates the exact-tag GitHub Release, applies\nprerelease/latest metadata from the semver tag, and uploads the publish evidence\nfile together with the generated release passport assets. This keeps\nnpm/registry publication, Buildchain release passport persistence, and\n`release.published` propagation in one declarative reusable workflow. Consumers\nthat do not publish GitHub Releases can opt out with `github-release: false`.\n\nProducts that publish KFD release trust evidence can keep that path declarative\ntoo. Pass KFD-1 self contract witnesses, KFD-2 public claim files, and KFD-3\npre-build/artifact evidence into the wrapper:\n\n```yaml\njobs:\n promote:\n uses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@v2\n with:\n channel: alpha\n artifact-name: libnode\n release-passport-kfd-1-witness-jsons: .buildchain/kfd-1/standard-contract.witness.json\n release-passport-kfd-2-claim-jsons: .buildchain/kfd-2/release-claims.json\n release-passport-kfd-3-prebuild-witness-jsons: .buildchain/kfd-3/collaboration-interface.prebuild.json\n release-passport-kfd-3-artifact-verify-command: kungfu agent verify --json\n```\n\nBuildchain forwards those declarations into `promote-buildchain-ref`, verifies\nKFD-1 source/artifact contract surfaces, audits KFD-2 public release claims, and\ncompares KFD-3 declared shipped public surfaces with artifact-exposed public\nsurfaces. The release passport records the results under `kfd-1`, `kfd-2`, and\nthe KFD-provided `kfd-3` section."
723
+ },
724
+ {
725
+ "id": "manual:release-flow",
726
+ "title": "Release Flow Diagrams",
727
+ "route": "/docs/release-flow",
728
+ "category": "manual",
729
+ "sourcePath": "docs/release-flow.md",
730
+ "digest": "sha256:0a2f46501a64905067cc5872b45ac4824f9e632d59bfdfb2f6a794dfc5f959ea",
731
+ "headings": [
732
+ {
733
+ "level": 1,
734
+ "title": "Release Flow Diagrams",
735
+ "anchor": "release-flow-diagrams"
736
+ },
737
+ {
738
+ "level": 2,
739
+ "title": "Architecture",
740
+ "anchor": "architecture"
741
+ },
742
+ {
743
+ "level": 2,
744
+ "title": "Ref State",
745
+ "anchor": "ref-state"
746
+ },
747
+ {
748
+ "level": 2,
749
+ "title": "Ref Protection Contract",
750
+ "anchor": "ref-protection-contract"
751
+ },
752
+ {
753
+ "level": 2,
754
+ "title": "Alpha Promotion",
755
+ "anchor": "alpha-promotion"
756
+ },
757
+ {
758
+ "level": 2,
759
+ "title": "Release Promotion",
760
+ "anchor": "release-promotion"
761
+ },
762
+ {
763
+ "level": 2,
764
+ "title": "State Machine",
765
+ "anchor": "state-machine"
766
+ },
767
+ {
768
+ "level": 2,
769
+ "title": "Version Examples",
770
+ "anchor": "version-examples"
771
+ },
772
+ {
773
+ "level": 2,
774
+ "title": "Major Gate Promotion",
775
+ "anchor": "major-gate-promotion"
776
+ },
777
+ {
778
+ "level": 2,
779
+ "title": "Failure Boundaries",
780
+ "anchor": "failure-boundaries"
781
+ }
782
+ ],
783
+ "markdown": "# Release Flow Diagrams\n\nThis document describes the Buildchain v2 branch, tag, and version-state flow.\nSee [Release governance](release-governance.md) for the design rationale.\n\n## Architecture\n\n```mermaid\nflowchart TD\n Maintainer[\"Maintainer opens channel PR\"]\n Verify[\"Release - Verify\"]\n Review[\"Protected branch review\"]\n Merge[\"Merge PR into alpha or release\"]\n Promotion[\"Buildchain Ref Promotion\"]\n Action[\"promote-buildchain-ref action\"]\n VersionState[\"Version-state commit\"]\n ExactTag[\"Exact tag\"]\n FloatingRefs[\"Floating tags and channel branches\"]\n Consumers[\"Consumers pin stable or exact refs\"]\n\n Maintainer --> Verify\n Verify --> Review\n Review --> Merge\n Merge --> Promotion\n Promotion --> Action\n Action --> VersionState\n Action --> ExactTag\n Action --> FloatingRefs\n ExactTag --> Consumers\n FloatingRefs --> Consumers\n```\n\nBuildchain treats the PR merge as release intent and the promotion action as the\nonly component allowed to turn that intent into release refs.\n\n## Ref State\n\n| Ref kind | Example | Mutability | Purpose |\n| --- | --- | --- | --- |\n| Development branch | `dev/v2/v2.0` | moves | next source state for a minor line |\n| Alpha branch | `alpha/v2/v2.0` | moves | latest test state for a minor line |\n| Release branch | `release/v2/v2.0` | moves | latest production state for a minor line |\n| Major gate branch | `publish-gate/major` | moves | reviewed administrator gate for publishing the next major |\n| Exact alpha tag | `v2.0.3-alpha.0` | immutable | audit ref for one tested prerelease |\n| Exact release tag | `v2.0.2` | immutable | audit ref for one production release |\n| Floating alpha tag | `v2.0-alpha` | moves | latest test channel for a minor line |\n| Floating minor tag | `v2.0` | moves | latest production patch on a minor line |\n| Floating major tag | `v2` | moves | selected stable major entrypoint |\n\n## Ref Protection Contract\n\nRepository rulesets must distinguish immutable evidence refs from mutable\nchannel refs.\n\nProtect exact release and alpha tags as immutable evidence:\n\n```text\nrefs/tags/v*.*.*\n```\n\nDo not apply immutable-tag rulesets to every `refs/tags/v*` ref. Buildchain\nmust be able to update floating channel tags such as `v2`, `v2.0`, and\n`v2.0-alpha` after the exact tag and publish evidence are valid. A ruleset that\nmatches all `v*` tags also matches floating tags, so release finalization can\nfail with GitHub protected-ref errors even though the exact release tag and\npublished artifacts are already durable.\n\nThe intended governance split is:\n\n- exact tags such as `v2.0.14` and `v2.0.15-alpha.0` are immutable audit refs;\n- floating tags such as `v2`, `v2.0`, and `v2.0-alpha` are mutable channel refs\n owned by the Buildchain promotion token;\n- protected branches still require reviewed channel PRs before Buildchain can\n move any exact or floating release refs.\n\n## Alpha Promotion\n\n```mermaid\nsequenceDiagram\n participant Dev as dev/vX/vX.Y\n participant PR as PR dev -> alpha\n participant Verify as Release - Verify\n participant Alpha as alpha/vX/vX.Y\n participant Promote as Buildchain Ref Promotion\n participant Tags as Tags\n\n Dev->>PR: open channel PR\n PR->>Verify: run verification checks\n Verify-->>PR: check succeeds\n PR->>Alpha: reviewed merge\n Alpha->>Promote: Verify workflow_run completed\n Promote->>Promote: validate same-repo merged PR\n Promote->>Promote: compute next vX.Y.Z-alpha.N\n Promote->>Promote: write and verify version state\n Promote->>Tags: create or reuse vX.Y.Z-alpha.N\n Promote->>Tags: move vX.Y-alpha\n Promote->>Alpha: move alpha/vX/vX.Y\n Promote->>Dev: move dev/vX/vX.Y\n```\n\nResult:\n\n```text\nvX.Y.Z-alpha.N\nvX.Y-alpha\nalpha/vX/vX.Y\ndev/vX/vX.Y\n```\n\nall point at the generated alpha version-state commit.\n\n## Release Promotion\n\n```mermaid\nsequenceDiagram\n participant Alpha as alpha/vX/vX.Y\n participant PR as PR alpha -> release\n participant Verify as Release - Verify\n participant Release as release/vX/vX.Y\n participant Promote as Buildchain Ref Promotion\n participant Tags as Tags\n participant Dev as dev/vX/vX.Y\n\n Alpha->>PR: open channel PR\n PR->>Verify: run verification checks\n Verify-->>PR: check succeeds\n PR->>Release: reviewed merge\n Release->>Promote: Verify workflow_run completed\n Promote->>Promote: validate same-repo merged PR\n Promote->>Promote: find same-patch alpha tag\n Promote->>Promote: compare release tree with tested alpha tree\n Promote->>Promote: write final version state or verify anchored material\n Promote->>Tags: create or reuse vX.Y.Z\n Promote->>Tags: move vX.Y\n Promote->>Tags: move vX when eligible\n Promote->>Release: move release/vX/vX.Y\n Promote->>Promote: prepare vX.Y.(Z+1)-alpha.0\n Promote->>Tags: create or reuse vX.Y.(Z+1)-alpha.0\n Promote->>Tags: move vX.Y-alpha\n Promote->>Alpha: move alpha/vX/vX.Y\n Promote->>Dev: move dev/vX/vX.Y\n```\n\nResult:\n\n```text\nvX.Y.Z\nvX.Y\nvX\nrelease/vX/vX.Y\n```\n\npoint at the production version-state commit, while:\n\n```text\nvX.Y.(Z+1)-alpha.0\nvX.Y-alpha\nalpha/vX/vX.Y\ndev/vX/vX.Y\n```\n\npoint at the next alpha version-state commit.\n\n## State Machine\n\n```mermaid\nstateDiagram-v2\n [*] --> Development: work lands on dev/vX/vX.Y\n Development --> AlphaCandidate: PR dev -> alpha\n AlphaCandidate --> AlphaPublished: Verify + review + merge + promotion\n AlphaPublished --> ReleaseCandidate: PR alpha -> release\n ReleaseCandidate --> ProductionPublished: Verify + review + merge + promotion\n ProductionPublished --> NextAlphaPrepared: prepare vX.Y.(Z+1)-alpha.0\n NextAlphaPrepared --> Development: dev and alpha refs move to next alpha\n```\n\nThe same minor line can loop through this state machine many times.\n\n## Version Examples\n\nAssume `v2.0.2-alpha.1` has been tested and a maintainer merges\n`alpha/v2/v2.0 -> release/v2/v2.0`.\n\nBuildchain should produce:\n\n```text\nv2.0.2 exact production tag\nv2.0 floating minor tag\nv2 floating major tag when v2.0 is the selected major line\nrelease/v2/v2.0 production channel branch\n```\n\nIt should also prepare:\n\n```text\nv2.0.3-alpha.0 exact next alpha tag\nv2.0-alpha floating alpha tag\nalpha/v2/v2.0 alpha channel branch\ndev/v2/v2.0 development channel branch\n```\n\nThis is expected behavior. A production release closes one patch and opens the\nnext test patch on the same minor line.\n\n## Major Gate Promotion\n\n```mermaid\nsequenceDiagram\n participant Release as release/vX/vX.Y\n participant PR as PR release -> publish-gate/major\n participant Verify as Release - Verify\n participant Gate as publish-gate/major\n participant Promote as Buildchain Ref Promotion\n participant Tags as Tags\n participant Next as dev/alpha/release v(X+1).0\n\n Release->>PR: open administrator PR\n PR->>Verify: run verification checks\n Verify-->>PR: check succeeds\n PR->>Gate: reviewed merge\n Gate->>Promote: Verify workflow_run completed\n Promote->>Promote: validate same-repo release -> publish-gate/major PR\n Promote->>Promote: write v(X+1).0.0 version state\n Promote->>Tags: create v(X+1).0.0\n Promote->>Tags: move v(X+1).0 and v(X+1)\n Promote->>Gate: move publish-gate/major to v(X+1).0.0\n Promote->>Next: move release/v(X+1)/v(X+1).0 to v(X+1).0.0\n Promote->>Promote: prepare v(X+1).0.1-alpha.0\n Promote->>Next: move alpha/dev v(X+1).0 to next alpha\n```\n\n`publish-gate/major` is intentionally not an active source branch. It is the PR\ntarget for the administrator's \"publish the next major\" decision. The older\n`major-gate` name is a compatibility alias only.\n\n## Failure Boundaries\n\nPromotion should stop before moving refs when:\n\n- the run is a non-dry-run manual dispatch;\n- the expected same-repository PR cannot be found;\n- the PR was not merged;\n- the branch pair is not a valid channel path;\n- the required status check did not pass;\n- a release tree does not match the same-patch alpha tag tree, except for the\n declared anchored/manual version files and anchor manifest that\n `lifecycle.verify` or `verification-command` validates;\n- version-state verification fails;\n- a required exact tag already exists at a commit unrelated to the active\n transaction or finalized channel head.\n\nThese failures are intentional. They protect consumers from refs that look\nreleased but do not have a complete evidence chain.\n\nDuring transaction finalization recovery, the current channel head may be a\ngenerated version-state merge commit. Buildchain validates that the durable\ntransaction version, exact tag, evidence, and release material match, and that\nthe current target ref contains or corresponds to the recorded\n`release_material_sha`. It must then tolerate exact tags, dev refs, or alpha\nrefs that have already moved and continue filling any missing floating tags\nbefore writing the transaction state as `complete`."
784
+ },
785
+ {
786
+ "id": "manual:release-governance",
787
+ "title": "Release Governance",
788
+ "route": "/docs/release-governance",
789
+ "category": "manual",
790
+ "sourcePath": "docs/release-governance.md",
791
+ "digest": "sha256:c7348c64e83ea1d154955e2fc0f7318a1c5582a3dfa6bdc5728958ddb418e92d",
792
+ "headings": [
793
+ {
794
+ "level": 1,
795
+ "title": "Release Governance",
796
+ "anchor": "release-governance"
797
+ },
798
+ {
799
+ "level": 2,
800
+ "title": "Design Problem",
801
+ "anchor": "design-problem"
802
+ },
803
+ {
804
+ "level": 2,
805
+ "title": "What ABV Contributed",
806
+ "anchor": "what-abv-contributed"
807
+ },
808
+ {
809
+ "level": 2,
810
+ "title": "Buildchain Implementation",
811
+ "anchor": "buildchain-implementation"
812
+ },
813
+ {
814
+ "level": 2,
815
+ "title": "Version Lines",
816
+ "anchor": "version-lines"
817
+ },
818
+ {
819
+ "level": 2,
820
+ "title": "Alpha Semantics",
821
+ "anchor": "alpha-semantics"
822
+ },
823
+ {
824
+ "level": 2,
825
+ "title": "Release Semantics",
826
+ "anchor": "release-semantics"
827
+ },
828
+ {
829
+ "level": 2,
830
+ "title": "Major Gate Semantics",
831
+ "anchor": "major-gate-semantics"
832
+ },
833
+ {
834
+ "level": 2,
835
+ "title": "Protected Dev Branches",
836
+ "anchor": "protected-dev-branches"
837
+ },
838
+ {
839
+ "level": 2,
840
+ "title": "Buildchain Patrol",
841
+ "anchor": "buildchain-patrol"
842
+ },
843
+ {
844
+ "level": 2,
845
+ "title": "Package-Manager Adapters",
846
+ "anchor": "package-manager-adapters"
847
+ },
848
+ {
849
+ "level": 2,
850
+ "title": "Lifecycle Configuration",
851
+ "anchor": "lifecycle-configuration"
852
+ },
853
+ {
854
+ "level": 2,
855
+ "title": "What This Guarantees",
856
+ "anchor": "what-this-guarantees"
857
+ },
858
+ {
859
+ "level": 2,
860
+ "title": "What This Does Not Do",
861
+ "anchor": "what-this-does-not-do"
862
+ },
863
+ {
864
+ "level": 2,
865
+ "title": "Operational Reading Order",
866
+ "anchor": "operational-reading-order"
867
+ }
868
+ ],
869
+ "markdown": "# Release Governance\n\nBuildchain v2 preserves the release semantics of the older ABV workflow while\nmoving the implementation into one modern repository.\n\nThe central idea is simple: a reviewed merge into a release channel is the\nrelease intent. Automation must then create the version-state commit, exact tag,\nfloating tag, and next alpha state that make that intent true in Git.\n\n## Design Problem\n\nKungfu release automation has to keep four facts aligned:\n\n1. The source tree that was reviewed.\n2. The package version recorded in manifests such as `package.json` or\n `lerna.json`.\n3. The exact immutable release or prerelease tag.\n4. The floating channel refs that consumers actually use.\n\nIf any one of these facts is updated by hand, the system can split:\n\n- a consumer can fetch `v2.0` and receive a tree whose package version still\n says the previous release;\n- a maintainer can move `v2` without producing an exact `v2.0.N` audit tag;\n- an alpha can be promoted to production even though the release tree is not the\n same tree that was tested;\n- a protected branch merge can succeed while the follow-up version commit is\n missing.\n\nThe older ABV workflow addressed this by letting GitHub PRs drive release\nstate. Buildchain keeps that choice because it makes release intent reviewable,\nobservable, and recoverable from Git history.\n\n## What ABV Contributed\n\nThe old ABV model was not just \"bump a version number.\" It encoded a governance\nloop:\n\n- release branches are named as channels: `dev`, `alpha`, `release`, and the\n administrative `publish-gate/major`;\n- a PR from one channel to the next is the release request;\n- verify jobs check that the branch pair is valid before merge;\n- a maintainer review is required before the branch moves;\n- after merge, automation writes the version change and moves tags;\n- exact tags and floating refs are aligned with the resulting commit;\n- the next development channel is prepared automatically.\n\nABV also kept the version-state mutation in the repository. For JavaScript\nrepositories that usually meant changing `lerna.json` and/or `package.json`.\nThat commit is important because the tag alone is not enough evidence: the\nsource tree should also declare the version that the tag advertises.\n\nBuildchain v2 treats that as a hard semantic requirement for its own release\nline.\n\n## Buildchain Implementation\n\nBuildchain implements the same governance loop with:\n\n- `.github/workflows/release-verify.yml` for PR verification;\n- `.github/workflows/buildchain-ref-promotion.yml` for post-verify ref\n promotion; this workflow dogfoods the declarative\n `release-candidate-promote.yml` wrapper and does not hand-wire resolver,\n artifact download, publish-gate, or promote action steps;\n- Buildchain self promotion enables `release-passport-buildchain-self-kfd`, so\n the release passport consumes generated KFD-1 witnesses, KFD-2 public claim\n JSON, and KFD-3 collaboration-interface witnesses from\n `packages/core/buildchain-kfd-claims.js` instead of relying on prose release\n notes;\n- `actions/promote-buildchain-ref` for branch, tag, version-state, and\n governance checks;\n- package-manager adapters that can update version state for pnpm, npm, and\n yarn style repositories;\n- `buildchain.toml` lifecycle configuration for repositories whose version\n state or verification commands are not Node package-manager defaults.\n\nThe implementation is intentionally stricter than a local release script:\n\n- manual workflow dispatch can only do dry-run promotion;\n- non-dry-run promotion must be driven by a completed `Verify` workflow;\n- target branch protection details must be readable, and branch protection must\n apply to administrators as well as regular contributors;\n- alpha promotion must come from a merged same-repository PR from\n `dev/vX/vX.Y` to `alpha/vX/vX.Y`;\n- release promotion must come from a merged same-repository PR from\n `alpha/vX/vX.Y` to `release/vX/vX.Y`;\n- major promotion must come from a merged same-repository PR from\n `release/vX/vX.Y` to `publish-gate/major`;\n- release promotion requires an existing same-patch alpha tag and checks the\n release source tree against that tested alpha tree;\n- generated version-state commits are verified before refs move.\n\n## Version Lines\n\nKungfu uses Python-like version lines where a minor line can represent a\nlong-lived product train. A line such as `v2.0` can produce many production\npatch releases:\n\n```text\nv2.0.0\nv2.0.1\nv2.0.2\n...\nv2.0.1234\n```\n\nThis is why Buildchain maintains both exact and floating refs:\n\n- `v2.0.2` is immutable release evidence;\n- `v2.0` is the latest production release on the `2.0` line;\n- `v2` is the selected stable major-line entrypoint;\n- `v2.0.3-alpha.0` is immutable alpha evidence;\n- `v2.0-alpha` is the latest test channel for the `2.0` line.\n\nA release does not mean \"minor is complete.\" It means \"this patch on this minor\nline is now production.\"\n\nGitHub repository rules must preserve that distinction. Exact tags such as\n`v2.0.2` and `v2.0.3-alpha.0` should be immutable. Floating channel tags such as\n`v2`, `v2.0`, and `v2.0-alpha` must remain movable by the Buildchain promotion\ntoken after governance checks and publish evidence pass. A tag ruleset that\nprotects every `refs/tags/v*` ref is too broad because it also locks the\nfloating channel tags that Buildchain is required to update. Prefer exact-tag\npatterns such as `refs/tags/v*.*.*` for immutable release evidence, while\nleaving floating channel tags under Buildchain automation control.\n\n## Alpha Semantics\n\nAn alpha merge is:\n\n```text\ndev/vX/vX.Y -> alpha/vX/vX.Y\n```\n\nBuildchain then:\n\n1. Computes the next prerelease for the minor line.\n2. Writes version state such as `vX.Y.Z-alpha.N`.\n3. Verifies the generated version-state tree.\n4. Creates or reuses the exact alpha tag.\n5. Moves `alpha/vX/vX.Y` to the generated alpha commit.\n6. Moves `dev/vX/vX.Y` to the same generated alpha commit when this is a\n fast-forward update.\n7. Moves `vX.Y-alpha` to the same generated alpha commit.\n\nThis keeps the test channel self-describing. If a consumer checks out\n`v2.0-alpha`, the manifests and exact alpha tag agree.\n\nIf `dev/vX/vX.Y` has already advanced while the generated alpha version-state PR\nwas under review, Buildchain records `skipped-non-fast-forward` for the dev sync\nand still completes the exact and floating alpha tags for the reviewed alpha\ncommit. Later dev changes must go through their own dev-to-alpha promotion\ninstead of rewinding dev.\n\nIf alpha finalization is resumed after the version-state PR is merged,\nBuildchain accepts the current alpha head as a merge commit that contains the\nrecorded release material. An already-created exact alpha tag may point at the\ntransaction release/material SHA or at the finalized alpha head; missing\nfloating alpha tags are retried before the transaction becomes `complete`.\n\n## Release Semantics\n\nA release merge is:\n\n```text\nalpha/vX/vX.Y -> release/vX/vX.Y\n```\n\nBuildchain then:\n\n1. Finds the same-patch alpha tag that was tested.\n2. Checks that the release source tree matches that alpha tag tree, excluding\n only generated version-state differences.\n3. Writes final release version state such as `vX.Y.Z`.\n4. Verifies the generated release tree.\n5. Creates or reuses the exact release tag `vX.Y.Z`.\n6. Moves `release/vX/vX.Y` to the exact release commit.\n7. Moves `vX.Y` to the exact release commit.\n8. Moves `vX` when this minor line should be the stable major entrypoint.\n9. Prepares the next alpha version-state commit, such as\n `vX.Y.(Z+1)-alpha.0`.\n10. Moves `alpha/vX/vX.Y`, `dev/vX/vX.Y`, and `vX.Y-alpha` to that next alpha\n commit.\n\nThe production channel and the test channel therefore intentionally diverge\nafter release: production stays on the release commit, while alpha/dev continue\nat the next prerelease commit.\n\nIf release finalization is resumed after the version-state PR is merged,\nBuildchain applies the same recovery rule: the current release head may be a\nmerge commit that contains the recorded release material, existing exact tags\nand alpha/dev refs are accepted when they match the transaction, and missing\nfloating `vX.Y` or `vX` tags are retried idempotently before completion.\n\n## Major Gate Semantics\n\nA major gate merge is:\n\n```text\nrelease/vX/vX.Y -> publish-gate/major\n```\n\n`publish-gate/major` is the explicit replacement for the older ABV `main`\nchannel. The name is intentionally operational: it is a gate for a rare\nadministrator decision, not the active trunk. Keeping this decision in the same\nPR UI as alpha and release promotion keeps the human workflow simple while\navoiding the misleading meaning of `main`. The older `major-gate` branch name is\na compatibility alias only.\n\nBuildchain then:\n\n1. Verifies the source is a merged same-repository PR from a protected release\n line into `publish-gate/major`.\n2. Writes the next major production version state, such as `v(X+1).0.0`.\n3. Creates or reuses the exact release tag `v(X+1).0.0`.\n4. Moves `publish-gate/major` and `release/v(X+1)/v(X+1).0` to that release commit.\n5. Moves `v(X+1).0` and `v(X+1)` to that release commit.\n6. Prepares the next alpha version-state commit, such as\n `v(X+1).0.1-alpha.0`.\n7. Moves `alpha/v(X+1)/v(X+1).0`, `dev/v(X+1)/v(X+1).0`, and\n `v(X+1).0-alpha` to that next alpha commit.\n\nChecking out `publish-gate/major` should therefore look like a frozen release\nstate, not like a branch where day-to-day source work continues. Day-to-day\nsource work continues on `dev/vX/vX.Y`.\n\n## Protected Dev Branches\n\n`dev/vX/vX.Y` is a protected development channel, not a scratch branch. Normal\nsource changes should be made on work branches such as `feature/*`, `fix/*`,\n`chore/*`, `docs/*`, `ci/*`, or `refactor/*`, then reviewed through a pull\nrequest into the target dev line.\n\nThis keeps the earliest development channel audit-friendly:\n\n- the version line being changed is visible in the PR base branch;\n- CI and required checks run before the channel moves;\n- branch protection can prevent direct pushes and stale merges;\n- later `dev -> alpha -> release` promotion inherits a reviewable source\n lineage instead of trying to reconstruct how the dev branch changed.\n\nBuildchain provides the reusable\n`.github/workflows/dev-pr-auto-merge.yml` workflow for repositories that want a\nscheduled or manual \"merge ready dev PRs\" pass. The consumer repository owns\nthe trigger schedule, but the merge decision is declared through workflow\ninputs: target dev branch, required status/check names, ready and block labels,\nallowed work-branch prefixes, review requirements, maximum merges per run,\nmerge method, and dry-run mode.\n\nThe workflow defaults are conservative. A PR is skipped unless it targets the\nconfigured dev line, is not a draft, has the ready label, has no block label,\ncomes from the same repository, uses an allowed work-branch prefix, has a\ncurrent approval, is mergeable, and has the configured required checks passing.\nAfter each merge, the next PR is re-evaluated before it can move the protected\ndev branch. This prevents one merge from silently making the next candidate\nstale or conflicting.\n\nThe required check should be the `check` job. Repositories can keep that job\nname stable while changing the actual verification command declaratively in\n`buildchain.toml`:\n\n```toml\n[lifecycle.install]\ncommand = \"cargo fetch --locked\"\n\n[lifecycle.verify]\ncommand = \"cargo test --workspace --locked\"\n```\n\nConsumers that want Buildchain to own the check wrapper can call\n`.github/workflows/check.yml@v2`. The wrapper runs the declared\n`lifecycle.install` and `lifecycle.verify` stages and fails the `check` job when\neither declaration is missing or the command exits non-zero.\n\nTypical consumer wrapper:\n\n```yaml\nname: Merge Ready Dev PRs\n\non:\n schedule:\n - cron: \"17 * * * *\"\n workflow_dispatch:\n inputs:\n dry-run:\n type: boolean\n default: true\n\njobs:\n merge-dev:\n uses: kungfu-systems/buildchain/.github/workflows/dev-pr-auto-merge.yml@v2\n permissions:\n contents: write\n pull-requests: write\n checks: read\n statuses: read\n with:\n target-branch: dev/v2/v2.6\n required-status-checks: check\n ready-label: ready\n block-labels: blocked,do-not-merge\n max-merges: 1\n dry-run: ${{ inputs.dry-run || false }}\n```\n\n## Buildchain Patrol\n\n`dev-pr-auto-merge.yml` remains the focused merge primitive. For repositories\nthat want a stable day-to-day operations contract, Buildchain also exposes a\npatrol workflow family:\n\n| Workflow | Intended cadence | Default intent |\n| --- | --- | --- |\n| `.github/workflows/patrol-daily.yml` | daily | lightweight inspection plus ready dev PR maintenance |\n| `.github/workflows/patrol-weekly.yml` | weekly | release-state, passport, gate, and stale-state health checks as they are added |\n| `.github/workflows/patrol-monthly.yml` | monthly | governance, permission, branch-protection, and workflow drift checks as they are added |\n\nThe cadence names describe patrol intensity, not release cadence:\n\n- daily patrol can run every day without implying a daily release;\n- weekly patrol is for medium-cost maintenance and audit checks;\n- monthly patrol is for structural drift checks that should not block ordinary\n development velocity.\n\nConsumers should schedule thin callers and keep their YAML declarative. For\nexample:\n\n```yaml\nname: Buildchain Daily Patrol\n\non:\n schedule:\n - cron: \"17 2 * * *\"\n workflow_dispatch:\n\njobs:\n patrol:\n uses: kungfu-systems/buildchain/.github/workflows/patrol-daily.yml@v2\n with:\n dry-run: false\n max-actions: 1\n```\n\nWeekly and monthly callers use the matching wrapper:\n\n```yaml\njobs:\n patrol:\n uses: kungfu-systems/buildchain/.github/workflows/patrol-weekly.yml@v2\n with:\n dry-run: true\n```\n\nAll three wrappers default to the `v2` floating Buildchain runtime. When\n`target-branch` is omitted, the caller's current/default branch selects the\nactive semver dev line, so consumers do not pin patrol to a stale minor branch.\nThe separate workflow names keep consumer schedules readable and stable while\nBuildchain adds new checks behind the cadence wrappers.\n\n## Package-Manager Adapters\n\nOld ABV assumed JavaScript repositories with root version state and often\nLerna. Buildchain keeps the version-state contract but does not assume every\nrepository is yarn/Lerna.\n\nThe promotion action discovers and updates:\n\n- root `package.json`;\n- `lerna.json`;\n- package manifests from `package.json` workspaces;\n- package manifests from `lerna.json` packages;\n- package manifests from `pnpm-workspace.yaml`.\n\nIt then runs the repository's detected package manager semantics where needed:\n\n- pnpm repositories use pnpm-oriented workspace discovery;\n- npm repositories use npm/package-lock semantics where present;\n- yarn repositories use yarn-style metadata where present.\n\nFor Buildchain itself, version state is required. For a consumer repository that\nhas no package manifest, the same action can degrade to ref-only behavior only\nwhen that is explicitly allowed by the caller.\n\n## Lifecycle Configuration\n\n`buildchain.toml` is the v2 user configuration format. It lets a repository\ndeclare version-state files and lifecycle commands without pretending every\nproject is a Node workspace. Supported version files include JSON, TOML, and\nregex-based files such as `CMakeLists.txt` or `conanfile.py`.\n\nThe promotion action currently consumes `version.files` and `lifecycle.verify`.\nThe verify stage runs after generated version-state changes are applied locally\nand before any release refs move. If `verification-command` is passed directly\nto the action, that explicit command overrides `lifecycle.verify`.\n\nProtected release-line branches keep their normal review gate. When generated\nversion state would move a protected alpha or release branch, Buildchain creates\na version-state PR instead of bypassing branch protection. After that PR is\nreviewed, checked, and merged, the next promotion run verifies that only\ndeclared version-state files changed from the legally merged source parent, then\nmoves the exact and floating tags.\n\n## What This Guarantees\n\nWhen the loop succeeds, maintainers and consumers can rely on these facts:\n\n- every production release has an exact tag such as `v2.0.2`;\n- every production minor line has a floating tag such as `v2.0`;\n- every selected stable major has a floating tag such as `v2`;\n- every next-major release is driven by a reviewed `release -> publish-gate/major` PR,\n not a hidden manual button;\n- every test channel has an exact alpha tag such as `v2.0.3-alpha.0`;\n- every alpha minor line has a floating tag such as `v2.0-alpha`;\n- version manifests match the tag visible from the same commit;\n- production releases are derived from the alpha tree that was tested;\n- manual non-dry-run promotion cannot bypass PR review and verification;\n- admin users cannot make a channel promotion valid by temporarily bypassing\n branch protection.\n\nThis is the practical meaning of \"governance closed loop\" in Buildchain: the\ndecision, code, version state, and Git refs close over the same evidence chain.\n\n## What This Does Not Do\n\nBuildchain release promotion does not embed registry clients or product-specific\npublish logic. When publish transactions are enabled, `promote-buildchain-ref`\ncan run the consumer's `lifecycle.publish` command and own the transaction,\nevidence validation, durable recovery state, and ref finalization order. The\nconsumer repository still owns registry truth: npm, PyPI, OCI, S3, Conan, CMake\npackaging, download pages, dist-tags, and similar side effects must be\nimplemented by project lifecycle commands that emit Buildchain publish evidence.\n\nEvery Buildchain publish model that can run registry side effects must bind the\npublish entrypoint to an immutable `publish-gate/*` source lock. The reusable\n`release-candidate-promote.yml@v2` wrapper creates or updates that gate ref and\npasses `require-publish-source-lock`, `publish-source-ref`,\n`publish-source-sha`, and `publish-source-locked` to\n`promote-buildchain-ref`. Direct action callers must pass the same four inputs\nfrom the reusable build outputs. Workflows that only collect passports or run\ndry-run package checks do not move publish refs and are not publish-gate\npublication models.\n\nSemver GitHub Release publication is owned by `promote-buildchain-ref`, not by\nconsumer shell glue. Consumers normally use the `release-candidate-promote.yml`\nwrapper, where GitHub Release publication is enabled by default and can be\ndisabled with `github-release: false`; the wrapper passes that declaration to\nthe action. After the publish transaction reaches `complete`, Buildchain creates\nor updates the exact-tag GitHub Release and uploads the generated\n`buildchain.release.json`, release-passport assets, and publish evidence. Semver\nprerelease tags are marked `prerelease=true` and `make_latest=false`; stable\nsemver tags are marked latest. This is the supported path for downstream\n`release.published` propagation across semver, major, and promote-only release\ncandidate publication models.\n\nBuildchain also does not maintain bare exact tags such as `1.0.0`. The supported\nexact release and alpha refs are v-prefixed:\n\n```text\nv2.0.0\nv2.0.1-alpha.0\n```\n\n## Operational Reading Order\n\nWhen debugging or extending release behavior, read in this order:\n\n1. `docs/release-flow.md`\n2. `.github/workflows/release-verify.yml`\n3. `.github/workflows/buildchain-ref-promotion.yml`\n4. `.github/workflows/release-candidate-promote.yml`\n5. `actions/promote-buildchain-ref/README.md`\n6. `actions/promote-buildchain-ref/src/`\n7. `docs/migration-inventory.md`\n\nThat path gives the policy first, the workflow trigger second, and the action\nimplementation last."
870
+ },
871
+ {
872
+ "id": "manual:release-passport",
873
+ "title": "Release Passport",
874
+ "route": "/docs/release-passport",
875
+ "category": "manual",
876
+ "sourcePath": "docs/release-passport.md",
877
+ "digest": "sha256:4d69798646adb84c6d193b1f32e7dc50e389db8932e63e9cb71489b6015e0333",
878
+ "headings": [
879
+ {
880
+ "level": 1,
881
+ "title": "Release Passport",
882
+ "anchor": "release-passport"
883
+ },
884
+ {
885
+ "level": 2,
886
+ "title": "Contract",
887
+ "anchor": "contract"
888
+ },
889
+ {
890
+ "level": 2,
891
+ "title": "Runner Policy",
892
+ "anchor": "runner-policy"
893
+ },
894
+ {
895
+ "level": 2,
896
+ "title": "CLI",
897
+ "anchor": "cli"
898
+ },
899
+ {
900
+ "level": 3,
901
+ "title": "KFD-1 contract-world release gate",
902
+ "anchor": "kfd-1-contract-world-release-gate"
903
+ },
904
+ {
905
+ "level": 3,
906
+ "title": "KFD-2 release trust passport audit",
907
+ "anchor": "kfd-2-release-trust-passport-audit"
908
+ },
909
+ {
910
+ "level": 3,
911
+ "title": "KFD-3 collaboration-interface release gate",
912
+ "anchor": "kfd-3-collaboration-interface-release-gate"
913
+ },
914
+ {
915
+ "level": 3,
916
+ "title": "Floating Buildchain contract lock",
917
+ "anchor": "floating-buildchain-contract-lock"
918
+ },
919
+ {
920
+ "level": 2,
921
+ "title": "Binary Distribution",
922
+ "anchor": "binary-distribution"
923
+ }
924
+ ],
925
+ "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\n## Contract\n\nThe release passport surface is a welded contract. Additive fields are allowed;\nbreaking semantic changes require a new major line.\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`: exact tag, line, channel, source SHA, target ref, release SHA,\n release material SHA, publish tooling SHA, and durable release-state ref.\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- `artifacts`: release assets and registry artifacts in one list, each pointing\n back to the evidence file that proves its digest.\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 --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-1/contract-world.witness.json \\\n --kfd-2-claim-json .buildchain/kfd-2/release-claims.json \\\n --output-dir .buildchain/release-passport\n```\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.\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\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-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-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\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."
926
+ },
927
+ {
928
+ "id": "manual:release-propagation",
929
+ "title": "Release Propagation",
930
+ "route": "/docs/release-propagation",
931
+ "category": "manual",
932
+ "sourcePath": "docs/release-propagation.md",
933
+ "digest": "sha256:190e3537075f37cf8a7e52bf8254606e1d9450d87c5a81dc11df8b56a7d03065",
934
+ "headings": [
935
+ {
936
+ "level": 1,
937
+ "title": "Release Propagation",
938
+ "anchor": "release-propagation"
939
+ },
940
+ {
941
+ "level": 2,
942
+ "title": "Contract",
943
+ "anchor": "contract"
944
+ },
945
+ {
946
+ "level": 2,
947
+ "title": "Upstream Release Envelope",
948
+ "anchor": "upstream-release-envelope"
949
+ },
950
+ {
951
+ "level": 2,
952
+ "title": "CLI",
953
+ "anchor": "cli"
954
+ },
955
+ {
956
+ "level": 2,
957
+ "title": "Reusable Workflow",
958
+ "anchor": "reusable-workflow"
959
+ },
960
+ {
961
+ "level": 2,
962
+ "title": "kfd to site-libkungfu-dev",
963
+ "anchor": "kfd-to-site-libkungfu-dev"
964
+ }
965
+ ],
966
+ "markdown": "# Release Propagation\n\nRelease propagation lets a finalized upstream release open a downstream update\nPR using the upstream release passport as the audit source. It is for product\nchains such as:\n\n```text\nkfd -> site-libkungfu-dev\nA -> B -> C\n```\n\nThe downstream repository receives an exact lock, not a floating dist-tag. A\nsite or app can then consume the upstream package, site bundle, or release\npassport as its single source of truth without hand-copying release facts.\n\n## Contract\n\nThe propagation graph is declarative JSON:\n\n```json\n{\n \"schemaVersion\": 1,\n \"contract\": \"kungfu-buildchain-release-propagation-graph\",\n \"nodes\": [\n {\n \"id\": \"kfd\",\n \"repository\": \"kungfu-systems/kfd\",\n \"package\": \"@kungfu-tech/kfd\"\n },\n {\n \"id\": \"site-libkungfu-dev\",\n \"repository\": \"kungfu-systems/site-libkungfu-dev\",\n \"lockPath\": \"buildchain.upstreams/kfd.release.json\",\n \"baseRef\": \"dev/v2/v2.7\"\n }\n ],\n \"edges\": [\n {\n \"id\": \"kfd-to-site\",\n \"from\": \"kfd\",\n \"to\": \"site-libkungfu-dev\",\n \"channelPolicy\": \"preserve\"\n }\n ]\n}\n```\n\n`channelPolicy: \"preserve\"` is the default and maps:\n\n```text\nalpha -> alpha\nrelease -> release\n```\n\nCross-channel mapping is allowed only when an edge declares\n`channelPolicy: \"explicit\"` and a `channelMap`. Buildchain rejects cycles so a\nchain can fan out or continue as `A -> B -> C`, but cannot loop back into an\nalready visited release line.\n\n## Upstream Release Envelope\n\nThe upstream release envelope is the post-finalization fact set:\n\n```json\n{\n \"repository\": \"kungfu-systems/kfd\",\n \"channel\": \"alpha\",\n \"tag\": \"v1.4.0-alpha.3\",\n \"sourceSha\": \"1111111111111111111111111111111111111111\",\n \"package\": {\n \"name\": \"@kungfu-tech/kfd\",\n \"version\": \"1.4.0-alpha.3\",\n \"integrity\": \"sha512-...\"\n },\n \"releasePassport\": {\n \"url\": \"https://github.com/kungfu-systems/kfd/releases/download/v1.4.0-alpha.3/buildchain.release.json\",\n \"sha256\": \"2222222222222222222222222222222222222222222222222222222222222222\"\n },\n \"siteBundle\": {\n \"manifestSha256\": \"3333333333333333333333333333333333333333333333333333333333333333\"\n }\n}\n```\n\nThe package version and integrity must be exact. Downstream build logic should\ninstall that version directly, not resolve `alpha` or `latest` again.\n\n## CLI\n\nGenerate a propagation plan:\n\n```bash\nbuildchain release-propagation plan \\\n --graph buildchain.release-propagation.json \\\n --upstream-release .buildchain/upstream-release.json \\\n --output .buildchain/release-propagation-plan.json \\\n --json\n```\n\nWrite the downstream lock:\n\n```bash\nbuildchain release-propagation write-lock \\\n --plan .buildchain/release-propagation-plan.json \\\n --target site-libkungfu-dev \\\n --cwd downstream-checkout \\\n --json\n```\n\nThe written lock has contract\n`kungfu-buildchain-release-propagation-lock` and records:\n\n- upstream repository, channel, exact tag, source SHA;\n- npm package name, exact version, and sha512 integrity;\n- release passport URL and SHA-256;\n- optional site bundle manifest SHA-256;\n- downstream repository, channel, base ref, lock path;\n- edge id and channel policy.\n\n## Reusable Workflow\n\nUpstream repositories can call\n`.github/workflows/release-propagation.yml@v2` after release finalization:\n\n```yaml\njobs:\n propagate-site:\n uses: kungfu-systems/buildchain/.github/workflows/release-propagation.yml@v2\n with:\n buildchain-ref: v2\n graph-json: ${{ needs.release.outputs.propagation-graph-json }}\n upstream-release-json: ${{ needs.release.outputs.upstream-release-json }}\n downstream-target: site-libkungfu-dev\n downstream-repository: kungfu-systems/site-libkungfu-dev\n downstream-base-ref: dev/v2/v2.7\n dry-run: false\n secrets:\n propagation-token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}\n```\n\nThe workflow checks out the Buildchain runtime selected by\n`buildchain-repository` and `buildchain-ref` into `.buildchain/runtime`, invokes\nthat runtime for the propagation plan and lock write, then checks out the\ndownstream repository, writes the exact lock, and opens or updates a PR. It does\nnot publish the downstream release directly. The downstream repository keeps its\nnormal Buildchain governance: the PR updates source-of-truth facts, then\ndownstream alpha or release publication runs through its own protected channel.\nFor unreleased runtime validation, keep the caller's reusable workflow reference\non `@v2` and pass a temporary train ref through `buildchain-ref`.\n\n## kfd to site-libkungfu-dev\n\nFor `kfd -> site-libkungfu-dev`, the graph should preserve channels:\n\n- a `kfd` alpha release produces a downstream alpha lock and downstream alpha\n publication consumes the exact `@kungfu-tech/kfd@...-alpha.N` package;\n- a `kfd` stable release produces a downstream release lock and downstream\n stable publication consumes the exact stable package.\n\nThis keeps the site synchronized to the package truth without allowing the site\nto drift onto a floating npm dist-tag."
967
+ },
968
+ {
969
+ "id": "manual:reusable-build-surface",
970
+ "title": "Reusable Build Surface",
971
+ "route": "/docs/reusable-build-surface",
972
+ "category": "manual",
973
+ "sourcePath": "docs/reusable-build-surface.md",
974
+ "digest": "sha256:8c3e7a5e099c8eb0715bb6f58af90d261f8cb83d384f3281b8763f340277582b",
975
+ "headings": [
976
+ {
977
+ "level": 1,
978
+ "title": "Reusable Build Surface",
979
+ "anchor": "reusable-build-surface"
980
+ },
981
+ {
982
+ "level": 2,
983
+ "title": "Workflow",
984
+ "anchor": "workflow"
985
+ },
986
+ {
987
+ "level": 2,
988
+ "title": "Linux Job Containers",
989
+ "anchor": "linux-job-containers"
990
+ },
991
+ {
992
+ "level": 2,
993
+ "title": "Buildchain Runtime Override",
994
+ "anchor": "buildchain-runtime-override"
995
+ },
996
+ {
997
+ "level": 2,
998
+ "title": "Floating Ref Contract Lock",
999
+ "anchor": "floating-ref-contract-lock"
1000
+ },
1001
+ {
1002
+ "level": 2,
1003
+ "title": "Workflow Outputs",
1004
+ "anchor": "workflow-outputs"
1005
+ },
1006
+ {
1007
+ "level": 2,
1008
+ "title": "Artifact Transfer Relay",
1009
+ "anchor": "artifact-transfer-relay"
1010
+ },
1011
+ {
1012
+ "level": 2,
1013
+ "title": "Publish Gate",
1014
+ "anchor": "publish-gate"
1015
+ },
1016
+ {
1017
+ "level": 2,
1018
+ "title": "Publish Source Lock",
1019
+ "anchor": "publish-source-lock"
1020
+ },
1021
+ {
1022
+ "level": 2,
1023
+ "title": "Release Candidate Promote-Only",
1024
+ "anchor": "release-candidate-promote-only"
1025
+ },
1026
+ {
1027
+ "level": 2,
1028
+ "title": "Package-Set Publish Plan",
1029
+ "anchor": "package-set-publish-plan"
1030
+ },
1031
+ {
1032
+ "level": 2,
1033
+ "title": "Command Sources",
1034
+ "anchor": "command-sources"
1035
+ },
1036
+ {
1037
+ "level": 2,
1038
+ "title": "Artifact Contract",
1039
+ "anchor": "artifact-contract"
1040
+ },
1041
+ {
1042
+ "level": 2,
1043
+ "title": "Trusted Event Gate",
1044
+ "anchor": "trusted-event-gate"
1045
+ },
1046
+ {
1047
+ "level": 2,
1048
+ "title": "Fixture",
1049
+ "anchor": "fixture"
1050
+ }
1051
+ ],
1052
+ "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## Workflow\n\nStable consumers call:\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\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\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 non-empty `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 does not call `.build.yml`, does not create a matrix, and must fail\nbefore publish if the RC evidence, payload set, or source-lock ref is missing or\nambiguous.\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 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\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-lock-path: buildchain.contract-lock.json\n buildchain-contract-drift-issue-mode: compatible-and-breaking\n```\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. For the default `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 promoted exact tag as a GitHub Release by default.\nAfter `promote-buildchain-ref` reports a complete release transaction, the\nwrapper creates or updates the exact-tag 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`.\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.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\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 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.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."
1053
+ },
1054
+ {
1055
+ "id": "manual:runtime-train-validation",
1056
+ "title": "Runtime Train Validation",
1057
+ "route": "/docs/runtime-train-validation",
1058
+ "category": "manual",
1059
+ "sourcePath": "docs/runtime-train-validation.md",
1060
+ "digest": "sha256:bb053594407bd0f78aa43352a249a2ffa19825374147cc712cd56ca6ad50dfa3",
1061
+ "headings": [
1062
+ {
1063
+ "level": 1,
1064
+ "title": "Runtime Train Validation",
1065
+ "anchor": "runtime-train-validation"
1066
+ },
1067
+ {
1068
+ "level": 2,
1069
+ "title": "Train refs",
1070
+ "anchor": "train-refs"
1071
+ },
1072
+ {
1073
+ "level": 2,
1074
+ "title": "Buildchain contributor requirement",
1075
+ "anchor": "buildchain-contributor-requirement"
1076
+ },
1077
+ {
1078
+ "level": 2,
1079
+ "title": "Consumer workflow requirement",
1080
+ "anchor": "consumer-workflow-requirement"
1081
+ },
1082
+ {
1083
+ "level": 2,
1084
+ "title": "Validation request",
1085
+ "anchor": "validation-request"
1086
+ },
1087
+ {
1088
+ "level": 2,
1089
+ "title": "Trust and limitation",
1090
+ "anchor": "trust-and-limitation"
1091
+ }
1092
+ ],
1093
+ "markdown": "# Runtime Train Validation\n\nBuildchain consumers should keep stable workflow refs such as `@v2` in\ncommitted workflow YAML. Runtime trains provide a temporary validation pointer\nfor Buildchain changes that are ready for downstream testing but not yet\npromoted through the normal `dev -> alpha -> release` chain.\n\n## Train refs\n\nA train ref is a branch in the Buildchain repository:\n\n```text\ntrain/v2/v2.3/<capability>\n```\n\nIt is a validation pointer, not a release channel:\n\n- it does not move `v2`, `vX.Y`, `vX.Y-alpha`, exact tags, npm dist-tags, or\n production refs;\n- it must not be pinned as a long-term production dependency;\n- it should point at the Buildchain commit that downstream maintainers are\n expected to validate;\n- it is not a pending merge target or a delivery state;\n- the final durable path is still a pull request into the active `dev/*`\n channel, followed by the requested alpha or release promotion.\n- it may remain for a retention window after release so initiating repositories\n have a stable fast-use and rollback channel while stable refs, caches, or\n rollout windows settle.\n\n## Buildchain contributor requirement\n\nWhen a Buildchain change needs downstream validation before stable refs move,\npublish a train ref before asking consumers to test it:\n\n```sh\ngit push origin HEAD:refs/heads/train/v2/v2.3/<capability>\n```\n\nUse a capability slug that names the behavior being validated, for example:\n\n```text\ntrain/v2/v2.3/runtime-loader\ntrain/v2/v2.3/toolkit-diagnostics\ntrain/v2/v2.3/site-source-of-truth\n```\n\nThe pull request or validation request should include the train ref, the exact\ncommit SHA it points to, and the downstream evidence expected from consumers.\nIf the train is refreshed, state the new SHA in the validation thread.\n\nAfter downstream validation succeeds, close out through the normal release\npath. Merge the Buildchain pull request into the active `dev/*` mainline, run\nthe requested alpha or release promotion, and record the final mainline commit\nplus release ref or tag in the delivery thread. Do not leave the train as the\nitem that still needs to be merged; it is only a temporary fast-use,\ndiagnostic, and rollback channel for initiating repositories. Retained trains\nare cleaned up by a separate periodic Buildchain cleanup task.\n\n## Consumer workflow requirement\n\nConsumers keep their reusable workflow pinned to the stable shell:\n\n```yaml\njobs:\n build:\n uses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n```\n\nTo validate a train without committing temporary workflow refs, expose a\ntrusted manual pass-through once:\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\nBuildchain initializes new package workflows with this pass-through. Existing\nconsumers that do not have it should add it once before validating a train.\n\n## Validation request\n\nUse this short request when a train is ready:\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\nThe consumer should run a trusted `workflow_dispatch`, paste the train ref into\n`buildchain-ref`, and report the workflow summary or aggregate Buildchain\nsummary. The evidence should include:\n\n- workflow shell ref;\n- requested runtime ref;\n- resolved runtime ref;\n- resolved runtime SHA;\n- stability class;\n- trust decision;\n- rollback ref.\n\n## Trust and limitation\n\nRuntime overrides fail closed unless the event is `workflow_dispatch` and the\nactor has write, maintain, or admin permission on the caller repository.\nPull requests, including fork-originated pull requests, cannot use a non-empty\n`buildchain-ref`.\n\nRuntime train validation covers Buildchain runtime scripts, CLI code, local\nactions, configuration parsing, and lifecycle behavior. It cannot validate\nchanges that require the outer reusable workflow YAML itself to change, such as\nnew jobs, permissions, workflow outputs, or matrix topology. Those changes need\na canary workflow path or a temporary explicit workflow ref."
1094
+ },
1095
+ {
1096
+ "id": "manual:site-bundle-contract",
1097
+ "title": "Site Bundle Contract",
1098
+ "route": "/docs/site-bundle-contract",
1099
+ "category": "manual",
1100
+ "sourcePath": "docs/site-bundle-contract.md",
1101
+ "digest": "sha256:1977091fc18b816208e7af50a177fd15e114498bfa49041573812405b46585aa",
1102
+ "headings": [
1103
+ {
1104
+ "level": 1,
1105
+ "title": "Site Bundle Contract",
1106
+ "anchor": "site-bundle-contract"
1107
+ },
1108
+ {
1109
+ "level": 2,
1110
+ "title": "Files",
1111
+ "anchor": "files"
1112
+ },
1113
+ {
1114
+ "level": 2,
1115
+ "title": "npm Consumption",
1116
+ "anchor": "npm-consumption"
1117
+ },
1118
+ {
1119
+ "level": 2,
1120
+ "title": "Generation",
1121
+ "anchor": "generation"
1122
+ },
1123
+ {
1124
+ "level": 2,
1125
+ "title": "Scope",
1126
+ "anchor": "scope"
1127
+ },
1128
+ {
1129
+ "level": 2,
1130
+ "title": "Rendering Boundary",
1131
+ "anchor": "rendering-boundary"
1132
+ }
1133
+ ],
1134
+ "markdown": "# Site Bundle Contract\n\n`@kungfu-tech/buildchain` publishes `dist/site/` as the package-owned fact\nsource for `buildchain.libkungfu.dev` and other documentation surfaces.\n\nThe website may design navigation, visual hierarchy, examples, and explanatory\ncopy around these facts. It should not hand-write the current Buildchain\nrelease mechanics, command registry, workflow registry, or artifact schema.\n\n## Files\n\n```text\ndist/site/\n buildchain-site.json\n site-manifest.json\n cli-registry.json\n manual-registry.json\n node-api-registry.json\n workflow-registry.json\n release-model.json\n artifact-schemas.json\n buildchain-contract.json\n kfd-claims.json\n product-mechanism.json\n release-provenance.json\n agent-index.json\n```\n\n`buildchain-site.json` is the top-level bundle entrypoint.\nIt includes a `homepage` object generated from `README.md`, including\n`homepage.sections`, `homepage.displayPlan`, and a\n`homepage.rendererContract` that is implementation metadata rather than\nordinary homepage copy. Site repositories should consume those fields instead\nof parsing `README.md` themselves.\nIt also includes a `pages` collection that mirrors `page-registry.json`, so a\nsite repository can build the full Buildchain public documentation surface from\nthe npm package without scanning the source checkout.\n`page-registry.json` is the complete page fact source: README homepage content,\nall packaged `docs/*.md` manuals, action README files, the Node API package\noverview, and fixture guides.\n`buildchain-contract.json` is the machine-readable Buildchain runtime contract\nworld used by floating-ref contract locks. It records public workflow/action/CLI\nsurfaces, compatibility digests, and audit digests for the files that implement\nthose surfaces.\n`manual-registry.json` enumerates the packaged Markdown manuals with source\ndigests so an agent can find complete operating documentation from the npm\nartifact. `node-api-registry.json` enumerates public Node import surfaces from\n`package.json#exports`, so agents do not have to infer supported APIs from\ninternal paths.\n`kfd-claims.json` is the Buildchain-owned KFD claim registry. It is generated\nfrom `packages/core/buildchain-kfd-claims.js` and enumerates the public release\nclaims plus the KFD-3 collaboration surfaces that Buildchain self-verifies\nduring release promotion.\n\n## npm Consumption\n\n```bash\nnpm install @kungfu-tech/buildchain\n```\n\nThen read files from:\n\n```text\nnode_modules/@kungfu-tech/buildchain/dist/site/\n```\n\nPackage exports are also provided for direct JSON-aware consumers:\n\n```js\nimport siteManifest from \"@kungfu-tech/buildchain/site/site-manifest.json\" with { type: \"json\" };\n```\n\n## Generation\n\n```bash\npnpm run generate:site\npnpm run check:site\n```\n\n`check:site` fails when generated files are stale. `pnpm run check` includes\nthis gate, so release candidates cannot publish an out-of-date site bundle.\n\n## Scope\n\nThe P0 bundle includes:\n\n- README-derived homepage fields and display plan;\n- complete markdown page registry for public Buildchain docs, action manuals,\n Node API overview, and fixtures;\n- site manifest;\n- CLI command registry;\n- manual registry for packaged agent-facing documentation;\n- Node API registry for public package exports;\n- workflow/action registry;\n- release model facts;\n- artifact and evidence schema index;\n- Buildchain runtime contract world for `@v2` floating-ref compatibility checks,\n KFD-1/KFD-2/KFD-3 release gates, GitHub Release evidence publication, and\n site-consumption contracts;\n- Buildchain KFD claim registry for release-passport self verification and\n agent-first public claim discovery;\n- product mechanism manifest;\n- release provenance;\n- agent read order.\n\nFuture minor lines can add examples, recipes, fixture indexes, and richer\nschema metadata without breaking existing consumers.\n\n`release-propagation.md` describes the package-to-package or package-to-site\nrelease chain model. The site bundle exposes that document and the\n`release-propagation` CLI entry so downstream sites can render the current\nBuildchain-owned propagation contract instead of hand-writing it.\n\n## Rendering Boundary\n\nBuildchain owns the homepage wording, section ordering intent, complete\nmarkdown page registry, release model facts, workflow/action registry, CLI\nregistry, manual registry, Node API registry, KFD claim registry, and\nrelease-passport evidence vocabulary. The site owns HTML, CSS, responsive\nlayout, navigation, visual assets, decorative media, markdown-to-HTML rendering,\nand progressive disclosure within the Buildchain-provided\n`homepage.displayPlan` and page metadata.\n\nThe page registry is also part of Buildchain's KFD-3 collaboration-interface\nsurface. Releases declare it as a site-consumption contract, and Buildchain's\nKFD-3 witness generation includes the underlying markdown sources as public\ndocumentation surfaces. If a page is public enough for the site to render, it\nmust be declared and hash-bound in the package-owned site bundle."
1135
+ },
1136
+ {
1137
+ "id": "manual:toolkit-observability",
1138
+ "title": "Toolkit Observability",
1139
+ "route": "/docs/toolkit-observability",
1140
+ "category": "manual",
1141
+ "sourcePath": "docs/toolkit-observability.md",
1142
+ "digest": "sha256:239949a75ca81b6002a2e148f7028402dbd98c00e246acd8d0955855781206a1",
1143
+ "headings": [
1144
+ {
1145
+ "level": 1,
1146
+ "title": "Toolkit Observability",
1147
+ "anchor": "toolkit-observability"
1148
+ },
1149
+ {
1150
+ "level": 2,
1151
+ "title": "Choose API or CLI",
1152
+ "anchor": "choose-api-or-cli"
1153
+ },
1154
+ {
1155
+ "level": 2,
1156
+ "title": "Library API",
1157
+ "anchor": "library-api"
1158
+ },
1159
+ {
1160
+ "level": 2,
1161
+ "title": "Diagnostics API",
1162
+ "anchor": "diagnostics-api"
1163
+ },
1164
+ {
1165
+ "level": 2,
1166
+ "title": "CLI Logging",
1167
+ "anchor": "cli-logging"
1168
+ },
1169
+ {
1170
+ "level": 2,
1171
+ "title": "Release Gate",
1172
+ "anchor": "release-gate"
1173
+ }
1174
+ ],
1175
+ "markdown": "# Toolkit Observability\n\nBuildchain ships a small logging toolkit for repository workflows and project\nscripts. The goal is to separate time spent in Buildchain's framework from time\nspent in the consumer's own build, test, packaging, and publish steps.\n\n## Choose API or CLI\n\n`@kungfu-tech/buildchain` is not only a CLI package. It exports ESM toolkit APIs\nthat project scripts can import directly:\n\n```js\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\n```\n\nUse the API inside JavaScript or TypeScript build code. Do not spawn\n`buildchain`, download the standalone binary, or shell out through `npx` from\ncode that can import the package. The CLI is for GitHub Actions steps, shell\nscripts, and non-JavaScript tools.\n\nWhen a script runs inside `buildchain lifecycle run`, the lifecycle runner sets\n`BUILDCHAIN_LOG_PATH` and `BUILDCHAIN_LOG_RUN_ID`. Imported loggers pick up those\nenvironment variables automatically, so events emitted deep inside the build are\ngrouped into the same lifecycle summary.\n\nOutside a Buildchain lifecycle or GitHub Actions run, the logger defaults to\nconsole output unless a path is provided. Pass `path` when local scripts should\nwrite a reusable JSONL log:\n\n```js\nconst logger = createBuildchainLogger({\n path: \".buildchain/logs/native-build.jsonl\",\n source: \"user\",\n component: \"native-build\",\n});\n```\n\n## Library API\n\n```js\nimport {\n createBuildchainLogger,\n verifyBuildchainLogEvents,\n} from \"@kungfu-tech/buildchain/logging\";\n\nconst logger = createBuildchainLogger({\n source: \"user\",\n component: \"native-build\",\n});\n\nlogger.mark(\"configure.ready\", {\n phase: \"configure\",\n attributes: { preset: \"release\" },\n});\n\nawait logger.span(\"native.compile\", {\n phase: \"build\",\n attributes: { target: \"release\" },\n}, async () => {\n await compile();\n});\n\nlogger.spanSync(\"native.archive\", {\n phase: \"build\",\n attributes: { tool: \"libtool\" },\n}, () => {\n archiveStaticLibraries();\n});\n\nlogger.spawnSync(\"native.build\", \"make\", [\"-j20\"], {\n stdio: \"inherit\",\n}, {\n phase: \"build\",\n attributes: { requestedJobs: 20 },\n});\n\nconst report = verifyBuildchainLogEvents({\n path: logger.path,\n minEvents: 3,\n requirePhases: [\"configure\", \"build\"],\n requireEvents: [\n \"configure.ready\",\n \"native.compile.start\",\n \"native.compile.end\",\n ],\n});\n\nif (!report.ok) {\n throw new Error(\"Buildchain observability verification failed\");\n}\n```\n\nUse the API when a build script has internal stages that are invisible to the\nouter workflow. Keep secret values out of attributes; known sensitive keys are\nredacted, but callers should still avoid logging private material.\n\nCommonJS scripts should import Buildchain's ESM surfaces dynamically:\n\n```js\nconst { createBuildchainLogger } = await import(\"@kungfu-tech/buildchain/logging\");\nconst { collectRunnerDiagnostics } = await import(\"@kungfu-tech/buildchain/diagnostics\");\n```\n\n## Diagnostics API\n\nThe diagnostics surface collects local, non-telemetry build facts that are\nuseful when a native build is slow or flaky:\n\n```js\nimport {\n collectBuildchainDiagnostics,\n collectCacheDiagnostics,\n collectCompilerCacheDiagnostics,\n collectRunnerDiagnostics,\n collectToolDiagnostics,\n detectRequestedParallelism,\n startProcessSampler,\n summarizeDiagnosticsArtifacts,\n summarizeLifecycleObservability,\n summarizeProcessSamples,\n validateAnchoredPackageRelease,\n writeDiagnosticsArtifact,\n} from \"@kungfu-tech/buildchain/diagnostics\";\n\nconst lifecycleObservability = summarizeLifecycleObservability({\n logPath: \".buildchain/logs/events.jsonl\",\n});\nconst buildCommand = \"make\";\nconst buildArgs = [\"-j20\"];\nconst requestedParallelism = detectRequestedParallelism({\n command: buildCommand,\n args: buildArgs,\n});\nconst processSampler = startProcessSampler({\n intervalMs: 15000,\n label: \"native-build\",\n command: buildCommand,\n args: buildArgs,\n});\n// Run the long native build while the sampler is active.\nconst processSummary = summarizeProcessSamples({\n requestedParallelism: requestedParallelism.value,\n samples: processSampler.stop(),\n});\nconst cacheDiagnostics = collectCacheDiagnostics({ cwd: process.cwd() });\n\nwriteDiagnosticsArtifact(\".buildchain/artifacts/diagnostics.json\", {\n contract: \"consumer-build-diagnostics\",\n buildchain: collectBuildchainDiagnostics({ cwd: process.cwd() }),\n runner: collectRunnerDiagnostics(),\n tools: collectToolDiagnostics({ cwd: process.cwd() }),\n cache: cacheDiagnostics,\n lifecycleObservability,\n process: processSummary,\n});\n```\n\n`collectCacheDiagnostics()` includes package-manager/workspace context, selected\ncache directory stats, and compiler-cache stats from `ccache --show-stats\n--json` plus `sccache --show-stats --stats-format json` when those tools are\npresent. If a ccache build does not support JSON stats, Buildchain falls back to\nplain `ccache --show-stats` and parses the text counters. Missing cache tools\nare recorded as unavailable instead of failing the diagnostics artifact. Call\n`collectCompilerCacheDiagnostics()` directly when a consumer script only needs\ncompiler cache data. Native diagnostics also expose `compilerCaches` and\n`nativeCacheDirs` as top-level fields in each diagnostics artifact and aggregate\nsummary, so reviewers do not have to dig through nested cache sections first.\n\nProcess samples are intentionally summarized before they become long-lived\nartifacts. The summary records requested parallelism, the source of that value\n(`command`, `process-tree`, `env:MAKEFLAGS`,\n`env:CMAKE_BUILD_PARALLEL_LEVEL`, or `explicit`), observed active process\nconcurrency, elapsed sample time, total sampled CPU, and conservative command\ncategories such as `compiler`, `archive`, `linker`, `build-tool`, and `cache`.\nThe sampler detects common `make -j N`, `ninja -j N`, CMake/MSBuild/Xcode job\nflags, and MAKEFLAGS. This lets native projects distinguish \"we asked for\n`make -j20`\" from \"the build graph only kept two active compiler or archive\nchildren busy during the sampled window\" without storing environment dumps.\n\nNative repositories can opt into a reusable diagnostics profile in\n`buildchain.toml`:\n\n```toml\n[diagnostics.native]\nenabled = true\nsample_process_tree = true\ncompiler_cache = \"auto\"\nexpected_tools = [\"ccache\", \"sccache\", \"clang\", \"cl\", \"cmake\", \"ninja\"]\nartifact_dirs = [\"build\", \"dist\", \"build/Release\"]\ncache_dirs = [\".ccache\", \".sccache\"]\n```\n\nWhen enabled, diagnostics artifacts include the normalized profile, selected\ntool versions, compiler-cache stats, and configured artifact/cache directory\nstats. The profile is data-driven: Buildchain does not assume a specific\nproject such as libnode. The reusable build workflow also exposes\n`sample-process-tree`, which wraps the build lifecycle with the process sampler\nand carries the generated summary into the final diagnostics artifact. Custom\nworkflows can call `buildchain sample process-tree` directly when they need a\ndifferent command boundary.\n\nAnchored/manual package projects can also run one higher-level release-shape\ncheck instead of assembling lower-level config calls:\n\n```js\nconst anchoredReport = validateAnchoredPackageRelease({\n cwd: process.cwd(),\n requireManifest: true,\n requirePackageSetOrder: \"platforms-first-main-last\",\n requireTrustedPublishing: true,\n});\n\nif (!anchoredReport.ok) {\n throw new Error(\"Anchored package release contract failed\");\n}\n```\n\nIn an actual publish job, make that check source-lock aware:\n\n```js\nconst publishReady = validateAnchoredPackageRelease({\n cwd: process.cwd(),\n requirePublishGateSourceLock: true,\n});\n```\n\nThe source-lock inputs are read from `BUILDCHAIN_PUBLISH_SOURCE_REF`,\n`BUILDCHAIN_PUBLISH_SOURCE_SHA`, and `BUILDCHAIN_PUBLISH_SOURCE_LOCKED`, which\nthe reusable build workflow emits after resolving `publish-source-ref`. That\nturns direct channel-branch publication from `alpha/*` or `release/*` into a\nhard failure, while `publish-gate/alpha/<line>/<version>` and\n`publish-gate/release/<line>/<version>` also validate the requested consumer\nversion against configured version files and the anchor manifest.\n\n`buildchain lifecycle run` writes this small diagnostics artifact next to the\nplatform manifest by default. The per-platform diagnostics upload includes the\ncompact `diagnostics.json`, `diagnostics-manifest.json`, lifecycle\n`events.jsonl`, and, when process sampling is enabled, copied\n`process-summary.json` and `process-samples.jsonl` sidecars. The sidecar\nmanifest records each uploaded diagnostics file with its relative path, byte\ncount, and sha256 hash. It is intended to stay small enough to download without\nfetching large binary packages, and it should not include full environment dumps\nor secret-looking values.\n\nUse `summarizeDiagnosticsArtifacts()` when a matrix build uploads one\ndiagnostics artifact per platform. The summary keeps each platform's lifecycle\nstage table, adds a lifecycle total duration, carries the top slow spans, and\naggregates warning/error counts plus the slowest platforms. Per-platform rows\nalso include compact runner facts, checked tool versions/missing tools, package\nmanager/cache directory details, compiler cache availability, and a compact\nprocess sampler view with requested parallelism, observed max active processes,\nthe ratio between them, sample count, process categories, and top sampled\ncommand basenames. That gives release reviewers a small cross-platform timing,\nrunner, tool, cache, and concurrency view without downloading full build outputs\nor process sidecars.\n\nThe reusable build workflow writes that rollup as `diagnostics-summary.json` and\nuploads it in a separate aggregate diagnostics summary artifact. Consumers can\nread the `build-diagnostics-summary-artifact` output when they need only timing,\nwarning/error, runner, cache, and process-sampler context instead of the build\nsummary or binary artifacts. Per-platform rows keep the diagnostics `links`\nobject, including the binary artifact name, manifest artifact name, diagnostics\nartifact name, platform id, diagnostics sidecar manifest path, manifest path,\nsummary path, and process sidecar paths when present. They also keep compact\nrunner/tool/cache summaries so reviewers can tell whether a slow row ran on the\nexpected runner, missed an expected tool, or lacked useful compiler-cache stats.\nWhen the downloaded platform diagnostics include a sibling\n`diagnostics-manifest.json`, `summarizeDiagnosticsArtifacts()` carries a compact\n`diagnosticsManifest` section for that platform and verifies the manifest's\n`diagnostics.json` byte count and sha256. Missing or mismatched sidecar manifests\nincrement `diagnosticsManifestWarningCount`, so reviewers can distinguish\ndiagnostics sidecar drift from lifecycle warnings or build failures.\nThe same summary carries `diagnosticsContract` per platform and aggregates\n`diagnosticsContractWarningCount` when a downloaded `diagnostics.json` does not\nmatch `BUILDCHAIN_DIAGNOSTICS_CONTRACT`.\n\nThe diagnostics SDK also exports stable contract constants such as\n`BUILDCHAIN_DIAGNOSTICS_SUMMARY_CONTRACT`,\n`BUILDCHAIN_DIAGNOSTICS_MANIFEST_CONTRACT`,\n`BUILDCHAIN_PROCESS_SAMPLE_REPORT_CONTRACT`,\n`BUILDCHAIN_PROCESS_SAMPLE_SUMMARY_CONTRACT`, and\n`BUILDCHAIN_ANCHORED_PACKAGE_RELEASE_VALIDATION_CONTRACT` from\n`@kungfu-tech/buildchain/diagnostics`; consumers should compare against those\nconstants instead of hardcoding contract strings.\n\nThe CLI exposes the same aggregation for shell and workflow steps:\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\nOmit `--json` when the workflow log should show a compact platform table with\nlifecycle stages, artifact scan/upload time, total time, requested jobs,\nobserved active processes, warnings, and errors.\n\nFor long native build commands, the CLI can also sample the child process tree\nwhile preserving the wrapped command's exit code:\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 JSONL sample file stores timestamped process-tree snapshots with full\nredacted command lines, command basenames, CPU percentages when available,\nelapsed time, and requested parallelism context. Unix and macOS snapshots read\nthe full `ps args` field instead of truncated `comm` names. Windows snapshots\nread `Win32_Process` command lines through PowerShell so the sampler no longer\nreturns an empty process set on Windows runners. The summary file records\nobserved concurrency, total sampled CPU, command categories, and top command\nbasenames. This is intended for diagnosing low-utilization tails such as\narchive/link phases without logging full environment dumps.\n\nThe lifecycle observability summary is stage-wide, not just final-step timing:\nwhen install and build write to the same Buildchain log, the final platform\nmanifest can show both stages and the slowest spans.\n\n## CLI Logging\n\n```bash\nbuildchain mark \\\n --event native.configure \\\n --phase configure \\\n --component cmake \\\n --attribute preset=release\n\nbuildchain span \\\n --event native.build \\\n --phase build \\\n --component cmake \\\n -- cmake --build build --config Release\n\nbuildchain log summary --json\nbuildchain verify observability-log .buildchain/logs/events.jsonl --min-events 4\n```\n\nEvery event records a timestamp. `span` records duration and preserves the\nwrapped command's exit code.\n\n## Release Gate\n\nBuildchain's own binary distribution lane verifies required log events before\nuploading release assets. Consumers can apply the same pattern:\n\n```bash\nbuildchain verify observability-log .buildchain/logs/events.jsonl \\\n --require-phase build \\\n --require-phase package \\\n --require-component workflow \\\n --require-event native.build.start \\\n --require-event native.build.end\n```\n\nThis makes missing instrumentation a release failure instead of a dashboard\nafterthought."
1176
+ },
1177
+ {
1178
+ "id": "manual:versioning",
1179
+ "title": "Buildchain Versioning",
1180
+ "route": "/docs/versioning",
1181
+ "category": "manual",
1182
+ "sourcePath": "docs/versioning.md",
1183
+ "digest": "sha256:77b92fc979cc100beab3f8a13cd791dea992737b986ace505104edff4810a296",
1184
+ "headings": [
1185
+ {
1186
+ "level": 1,
1187
+ "title": "Buildchain Versioning",
1188
+ "anchor": "buildchain-versioning"
1189
+ },
1190
+ {
1191
+ "level": 2,
1192
+ "title": "Lines",
1193
+ "anchor": "lines"
1194
+ },
1195
+ {
1196
+ "level": 2,
1197
+ "title": "Welded Surfaces",
1198
+ "anchor": "welded-surfaces"
1199
+ },
1200
+ {
1201
+ "level": 2,
1202
+ "title": "Decision Log",
1203
+ "anchor": "decision-log"
1204
+ },
1205
+ {
1206
+ "level": 2,
1207
+ "title": "Runner Policy",
1208
+ "anchor": "runner-policy"
1209
+ }
1210
+ ],
1211
+ "markdown": "# Buildchain Versioning\n\nBuildchain uses semantic version lines to describe public contracts, not only\ncode size. A release can be small in diff size and still open a new minor line\nwhen it adds a durable surface that consumers, workflows, or agents can depend\non.\n\n## Lines\n\n| Line | Meaning |\n| --- | --- |\n| Patch | Compatible fix, hardening, documentation correction, or implementation repair inside an existing surface. |\n| Minor | New compatible welded surface: reusable workflow output, CLI command family, config protocol, published subpath, evidence file, runner contract, or agent-readable artifact. |\n| Major | Breaking semantic change, removed stable surface, changed branch/tag governance, or incompatible protocol rewrite. |\n\nKungfu minor lines are long-lived trains. `v2.0`, `v2.1`, and `v2.2` can each\nreceive many patch releases. The major ref, such as `v2`, points at the\nselected stable major entrypoint; the minor ref, such as `v2.2`, points at the\nlatest stable production patch for that minor line.\n\n## Welded Surfaces\n\nThese surfaces are classified independently; the final release impact is the\nhighest impact across the affected registered surfaces:\n\n- reusable workflow inputs, outputs, and artifact contracts;\n- public CLI command families and their machine-readable JSON shapes;\n- public npm exports such as `@kungfu-tech/buildchain/logging`;\n- config protocols such as `buildchain.toml`;\n- release governance state machines and protected ref semantics;\n- release evidence contracts such as passport, artifact evidence, impact\n ledger, and agent index files;\n- binary distribution shapes that users can install or automate against.\n\nFor each surface:\n\n- content, documentation, or implementation-only work that does not touch a\n registered surface is patch;\n- additive fields, new commands, new exports, new evidence sections, or new\n registered surfaces are minor;\n- removals, incompatible renames, changed meanings, newly required fields,\n weakened trust gates, or changed ref flow are major.\n\nThe release passport records this as `surfaceImpacts[]` plus\n`versionImpact.final`. The final impact must equal the highest surface impact,\nso an agent cannot silently label a release patch when one machine surface needs\nminor review.\n\n`surfaceImpacts[]` is mandatory for production release passports (`release/*`)\nand major publish-gate passports. Alpha, local, and legacy passport contexts\nkeep the field optional so temporary validation can proceed without pretending\nto be a production release decision.\n\nExample: a KFD document such as KFD-2 is content and remains patch, but adding a\n`kind` field to the machine-consumed KFD `registry.json` is an additive change\nto the `kfd-registry-schema` surface and therefore requires minor-impact\nreview. This avoids both false shortcuts: \"new KFD means minor\" and \"all KFD\nrepository changes are patch\".\n\n## Decision Log\n\n| Date | Action | Line | Faces | Class | Rationale | PR |\n| --- | --- | --- | --- | --- | --- | --- |\n| 2026-07-06 | open-minor | `v2.8` | kfd-1-contract-world-release-gate, kfd-2-release-trust-passport-audit, kfd-3-collaboration-interface-trust-proof, publish-source-lock-enforcement, required-check-protection | additive | KFD release gates add KFD-1 self contract verification, KFD-2 public release trust claim audit, KFD-3 collaboration-interface trust proofs, publish-side source-lock enforcement for promote-only wrappers, and protected channel required checks repaired to bind GitHub Actions check runs instead of legacy commit status contexts. | |\n| 2026-07-04 | open-minor | `v2.5` | scheduled-integration-governance | additive | Scheduled integration governance adds scheduled feature-branch discovery, conflict-free integration, reporting, and agent-visible governance automation for dev-line maintenance. | |\n| 2026-07-03 | open-minor | `v2.4` | infra-contract-lifecycle | additive | Infra contract lifecycle adds the provider-neutral `infra-contract` CLI command family, project type, adapter capability contract, lifecycle evidence bundle, propagation evidence, CI evidence mode, and consumer-facing contract artifacts. | |\n| 2026-07-02 | open-minor | `v2.3` | web-surface-host-mapping | additive | Web surface host mapping adds first-class multi-host surface bindings, reusable workflow URL outputs, per-surface deployment overrides, and an agent-readable fixture contract. | |\n| 2026-07-02 | open-minor | `v2.2` | release-passport, binary-distribution | additive | Release passport and binary distribution add agent-readable release passport files, artifact evidence, impact ledger, agent index, GitHub Release collection and verification commands, and standalone binary assets. | |\n| 2026-07-02 | open-minor | `v2.1` | logging-sdk, cli-observability, package-subpaths | additive | Buildchain toolkit observability adds the public logging SDK, CLI observability commands, and package subpaths that consumers can import. | |\n\n## Runner Policy\n\nThe `v2.2` binary distribution lane uses GitHub-hosted runners for production\nassets because that is the easiest release path for external users to reproduce:\n\n- `ubuntu-24.04`\n- `macos-latest`\n- `windows-2022`\n\nSelf-hosted runners remain compatibility fixtures. They prove Buildchain's\nprotocol does not depend on GitHub-hosted images, but they do not define the\npublic binary distribution path."
1212
+ },
1213
+ {
1214
+ "id": "manual:web-surface-deployments",
1215
+ "title": "Web-Surface Deployment Contract",
1216
+ "route": "/docs/web-surface-deployments",
1217
+ "category": "manual",
1218
+ "sourcePath": "docs/web-surface-deployments.md",
1219
+ "digest": "sha256:61891635707e9ed27b8754b83713db61cf9a7a6bdf65beb6a9ac8aa39356e168",
1220
+ "headings": [
1221
+ {
1222
+ "level": 1,
1223
+ "title": "Web-Surface Deployment Contract",
1224
+ "anchor": "web-surface-deployment-contract"
1225
+ },
1226
+ {
1227
+ "level": 2,
1228
+ "title": "Configuration",
1229
+ "anchor": "configuration"
1230
+ },
1231
+ {
1232
+ "level": 3,
1233
+ "title": "Multi-Surface Host Mapping",
1234
+ "anchor": "multi-surface-host-mapping"
1235
+ },
1236
+ {
1237
+ "level": 2,
1238
+ "title": "Preview Aliases",
1239
+ "anchor": "preview-aliases"
1240
+ },
1241
+ {
1242
+ "level": 2,
1243
+ "title": "Deployment Manifest",
1244
+ "anchor": "deployment-manifest"
1245
+ },
1246
+ {
1247
+ "level": 2,
1248
+ "title": "Deploy Plans",
1249
+ "anchor": "deploy-plans"
1250
+ },
1251
+ {
1252
+ "level": 2,
1253
+ "title": "Explicit Apply",
1254
+ "anchor": "explicit-apply"
1255
+ },
1256
+ {
1257
+ "level": 2,
1258
+ "title": "Production Preflight And Health",
1259
+ "anchor": "production-preflight-and-health"
1260
+ },
1261
+ {
1262
+ "level": 2,
1263
+ "title": "Cleanup Plans",
1264
+ "anchor": "cleanup-plans"
1265
+ },
1266
+ {
1267
+ "level": 2,
1268
+ "title": "Reusable Workflow Shape",
1269
+ "anchor": "reusable-workflow-shape"
1270
+ },
1271
+ {
1272
+ "level": 2,
1273
+ "title": "Site Repository Shape",
1274
+ "anchor": "site-repository-shape"
1275
+ },
1276
+ {
1277
+ "level": 2,
1278
+ "title": "Boundaries",
1279
+ "anchor": "boundaries"
1280
+ }
1281
+ ],
1282
+ "markdown": "# Web-Surface Deployment Contract\n\nBuildchain supports `project.type = \"web-surface\"` for repositories that publish\nsites, docs, product pages, operator consoles, or browser apps. These projects\nneed auditable deployment semantics, but they are not package release lines and\nshould not be forced into `dev/alpha/release` version-state automation.\n\nThe release object for a web surface is:\n\n```text\nsource commit + build artifact + deploy target + channel + deployment manifest\n```\n\nThis keeps the evidence chain clear:\n\n- the source SHA explains what code was built;\n- the artifact hash explains exactly what was deployed;\n- the channel explains who can see it and whether it is promotable;\n- the deploy target and adapter explain where it would be published;\n- the deployment manifest records retention, rollback, security, and secret\n reference metadata.\n\n## Configuration\n\n`buildchain.toml` is the source of truth. Web-surface projects must declare\npreview, staging, and production channels plus a deploy adapter for each.\n\n```toml\nschema = 1\n\n[project]\ntype = \"web-surface\"\nname = \"site-kungfu-tech\"\nsite = \"kungfu-tech\"\n\n[channels.preview]\nurl_pattern = \"https://{alias}.preview.kungfu.tech\"\nvisibility = \"ephemeral\"\nrequires_auth = false\nnoindex = true\n\n[channels.staging]\nurl = \"https://staging.kungfu.tech\"\nvisibility = \"protected\"\naccess_control = \"managed-network\"\nedge_auth = \"none\"\nnoindex = true\npromotable = true\n\n[channels.production]\nurl = \"https://kungfu.tech\"\nvisibility = \"public\"\ncanonical = true\nnoindex = false\n\n[deploy.preview]\nadapter = \"aws-s3-cloudfront\"\nbucket = \"kungfu-tech-preview\"\ncloudfront_distribution = \"E-PREVIEW\"\nartifact_path = \"dist\"\nsecret_refs = [\"AWS_ROLE_ARN\"]\n```\n\n### Multi-Surface Host Mapping\n\nSome site repositories publish more than one first-class web surface from the\nsame artifact. For example, `site-libkungfu-dev` has a hub plus separate\nhostnames for core, Buildchain, and Kung Fu Decisions. These are not just\nnavigation paths; staging, production preflight, and post-deploy health checks\nmust verify host-level behavior for each surface.\n\nDeclare named surfaces with per-channel URLs:\n\n```toml\n[surfaces.hub]\npath = \"/\"\nproduction_url = \"https://libkungfu.dev\"\nstaging_url = \"https://staging.libkungfu.dev\"\npreview_url_pattern = \"https://{alias}.preview.libkungfu.dev\"\n\n[surfaces.core]\npath = \"/core/\"\nproduction_url = \"https://core.libkungfu.dev\"\nstaging_url = \"https://core.staging.libkungfu.dev\"\npreview_url_pattern = \"https://core-{alias}.preview.libkungfu.dev\"\n\n[surfaces.buildchain]\npath = \"/buildchain/\"\nproduction_url = \"https://buildchain.libkungfu.dev\"\nstaging_url = \"https://buildchain.staging.libkungfu.dev\"\npreview_url_pattern = \"https://buildchain-{alias}.preview.libkungfu.dev\"\n\n[surfaces.kfd]\npath = \"/kfd/\"\nproduction_url = \"https://kfd.libkungfu.dev\"\nstaging_url = \"https://kfd.staging.libkungfu.dev\"\npreview_url_pattern = \"https://kfd-{alias}.preview.libkungfu.dev\"\n```\n\nBuildchain resolves every `(channel, surface)` pair. A preview alias such as\n`pr-12` becomes:\n\n```text\nhub: https://pr-12.preview.libkungfu.dev\ncore: https://core-pr-12.preview.libkungfu.dev\nbuildchain: https://buildchain-pr-12.preview.libkungfu.dev\nkfd: https://kfd-pr-12.preview.libkungfu.dev\n```\n\nWhen `surfaces` is omitted, Buildchain preserves the legacy single-surface\ncontract by creating an implicit `default` surface from the channel URL. When a\nsurface is intentionally path-only, declare it explicitly:\n\n```toml\n[surfaces.docs]\npath = \"/docs/\"\npath_only = true\n```\n\n`path_only = true` is an exception, not the default. Without it, every named\nsurface must declare `preview_url_pattern`, `staging_url`, and\n`production_url`. This makes staging/production mismatches fail during\nvalidation instead of becoming invisible deploy drift.\n\nAdapter strategy remains explicit. The default `aws-s3-cloudfront` plan uses the\nchannel deploy target for every surface, and each binding records its own\nbucket, distribution id, object prefix, manifest key, source path, and URL. A\nchannel can override target details per surface:\n\n```toml\n[deploy.staging.surfaces.core]\nbucket = \"libkungfu-dev-core-staging\"\ncloudfront_distribution = \"E-CORE-STAGING\"\norigin_path = \"/core\"\n```\n\nBuildchain validates these hard constraints:\n\n- `channels.preview.url_pattern` is required and must contain the alias shape\n used by preview deployments.\n- `channels.staging.access_control` must protect staging. Supported modes are\n `managed-network`, `edge-basic-auth`, `oidc`, and `app-auth`.\n- `channels.staging.edge_auth` records whether the edge layer owns auth. Use\n `edge_auth = \"none\"` when staging is protected by managed network controls\n such as WAF/IP allowlists or VPN access.\n- `channels.staging.noindex = true` is required.\n- `channels.production.url` is required.\n- deploy adapters must be declared per channel.\n- named surfaces must declare first-class URLs for every channel unless\n `path_only = true` is explicitly set.\n- secret material must be declared as reference names, such as\n `secret_refs = [\"AWS_ROLE_ARN\"]`; inline secret-like deploy keys are rejected.\n\nSupported adapter names are:\n\n| Adapter | Initial use |\n| --- | --- |\n| `aws-s3-cloudfront` | Static site artifact sync plus CDN invalidation plan |\n| `aws-elastic-beanstalk` | Future dynamic app environment adapter |\n| `aws-ecs-service` | Future dynamic service adapter |\n\nThe channel ontology is independent of the adapter. A future dynamic staging\nenvironment still remains `channel = \"staging\"` with protected/noindex/security\nrequirements.\n\n## Preview Aliases\n\nPreview uses subdomains, not path prefixes:\n\n```text\nhttps://pr-123.preview.kungfu.tech\nhttps://sha-abcdef123456.preview.kungfu.tech\n```\n\nAlias semantics are explicit:\n\n| Alias | Meaning | Mutable | Retention |\n| --- | --- | --- | --- |\n| `pr-123` | Current preview for a pull request | yes | short-lived |\n| `sha-abcdef123456` | Immutable preview for one source SHA | no | longer-lived |\n\nThis allows PR comments to stay stable while preserving immutable evidence for a\nspecific source commit.\n\n## Deployment Manifest\n\nBuildchain emits a manifest with the deployment facts that matter for audit and\nrollback:\n\n```json\n{\n \"schemaVersion\": 1,\n \"contract\": \"kungfu-buildchain-web-surface-deployment\",\n \"site\": \"libkungfu-dev\",\n \"channel\": \"preview\",\n \"alias\": \"sha-abcdef123456\",\n \"url\": \"https://sha-abcdef123456.preview.libkungfu.dev\",\n \"sourceSha\": \"...\",\n \"artifactHash\": \"...\",\n \"deployTarget\": \"libkungfu-dev-preview\",\n \"adapter\": \"aws-s3-cloudfront\",\n \"deployedAt\": \"2026-07-01T00:00:00.000Z\",\n \"retentionClass\": \"preview-sha-immutable\",\n \"expiresAt\": \"2026-09-29T00:00:00.000Z\",\n \"accessControl\": \"none\",\n \"edgeAuth\": \"none\",\n \"noindex\": true,\n \"secretRefs\": [\"AWS_ROLE_ARN\"],\n \"surfaceBindings\": [\n {\n \"surface\": \"hub\",\n \"channel\": \"preview\",\n \"alias\": \"sha-abcdef123456\",\n \"url\": \"https://sha-abcdef123456.preview.libkungfu.dev\",\n \"sourcePath\": \"/\",\n \"canonicalUrl\": \"https://libkungfu.dev\",\n \"bucket\": \"libkungfu-dev-preview\",\n \"distributionId\": \"E-PREVIEW\",\n \"originPath\": \"\",\n \"objectPrefix\": \"sha-abcdef123456\",\n \"manifestKey\": \".buildchain/deployments/sha-abcdef123456/hub.json\",\n \"noindex\": true,\n \"accessControl\": \"none\"\n }\n ]\n}\n```\n\nDynamic adapters can also fill `runtimeId`, `configFingerprint`,\n`healthCheck`, `migrationState`, `rollbackPointer`, and\n`rollbackLimitations`. Buildchain records secret reference names only, never\nsecret values.\n\n## Deploy Plans\n\nDeploy planning is the default behavior. It plans the adapter steps and writes\nmanifest JSON, but it does not touch AWS, DNS, CloudFront, or deployment\ncredentials.\n\n```bash\nnode scripts/web-surface.mjs \\\n --mode deploy-plan \\\n --cwd fixtures/web-surface-shaped \\\n --source-sha aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \\\n --alias sha-aaaaaaaaaaaa\n```\n\nFor manifest-only output:\n\n```bash\nnode scripts/web-surface.mjs \\\n --mode manifest \\\n --cwd fixtures/web-surface-shaped \\\n --source-sha aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \\\n --alias pr-123 \\\n --output .buildchain/web-surface-manifest.json\n```\n\nThe CLI emits GitHub outputs when `GITHUB_OUTPUT` is present:\n\n- `web-surface-channel`\n- `web-surface-alias`\n- `web-surface-url`\n- `web-surface-urls-json`\n- `web-surface-artifact-hash`\n- `web-surface-manifest-json`\n\n## Explicit Apply\n\n`deploy-apply` and `cleanup-apply` are explicit execution modes for the\n`aws-s3-cloudfront` static-site adapter. They still default to `--dry-run true`;\nlive AWS mutation requires `--dry-run false`.\n\nDeploy apply syncs the artifact, writes the deployment manifest, and invalidates\nCloudFront when a distribution id is configured:\n\n```bash\nnode scripts/web-surface.mjs \\\n --mode deploy-apply \\\n --cwd fixtures/web-surface-shaped \\\n --channel staging \\\n --source-sha aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \\\n --artifact-path dist \\\n --dry-run false \\\n --output .buildchain/web-surface-staging-apply.json\n```\n\nIt can also execute a previously saved deploy plan. In that mode Buildchain\nrecomputes the local artifact hash before running AWS commands and fails closed\nif the artifact no longer matches the saved plan:\n\n```bash\nnode scripts/web-surface.mjs \\\n --mode deploy-apply \\\n --cwd fixtures/web-surface-shaped \\\n --plan .buildchain/web-surface-staging-plan.json \\\n --dry-run false \\\n --output .buildchain/web-surface-staging-apply.json\n```\n\nCleanup apply deletes preview content, deletes the preview manifest, and\ninvalidates CloudFront:\n\n```bash\nnode scripts/web-surface.mjs \\\n --mode cleanup-apply \\\n --cwd fixtures/web-surface-shaped \\\n --event pull-request-closed \\\n --pull-number 123 \\\n --source-sha aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \\\n --dry-run false \\\n --output .buildchain/web-surface-cleanup-apply.json\n```\n\nCleanup apply can also execute a saved cleanup plan:\n\n```bash\nnode scripts/web-surface.mjs \\\n --mode cleanup-apply \\\n --cwd fixtures/web-surface-shaped \\\n --plan .buildchain/web-surface-cleanup-plan.json \\\n --dry-run false \\\n --output .buildchain/web-surface-cleanup-apply.json\n```\n\nApply output records the channel, alias, source SHA, artifact hash, target\nbucket, object prefix, manifest key, all surface URLs, all surface bindings, CDN\ninvalidation paths, actor/run metadata, and every adapter operation with\n`executed`, `exitCode`, `stdout`, and `stderr`. If an operation fails,\nBuildchain records the failed operation, stops subsequent adapter operations,\nand exits non-zero after writing the result JSON. Buildchain records secret\nreference names only; the runner must provide the AWS CLI and credentials\noutside Buildchain, typically through OIDC and the declared `secret_refs`.\n\n## Production Preflight And Health\n\nProduction promotion is not just `deploy-apply --channel production`. Before a\nlive production apply, the reusable workflow runs:\n\n```bash\nnode scripts/web-surface.mjs \\\n --mode production-preflight \\\n --cwd fixtures/web-surface-shaped \\\n --plan .buildchain/web-surface-production-plan.json \\\n --execute true \\\n --output .buildchain/web-surface-production-preflight.json\n```\n\nThe production preflight checks that:\n\n- `channels.production` is canonical and indexable;\n- every surface has concrete production bucket and CloudFront targets;\n- every production surface URL is HTTPS;\n- the production AWS role can inspect the declared bucket and distribution;\n- CloudFront aliases cover every surface host, including product hosts such as\n `kfd.libkungfu.dev`;\n- DNS resolves for every surface host.\n\nAfter production apply, the workflow runs:\n\n```bash\nnode scripts/web-surface.mjs \\\n --mode health-check \\\n --cwd fixtures/web-surface-shaped \\\n --result .buildchain/web-surface-production-apply.json \\\n --output .buildchain/web-surface-production-health.json\n```\n\nThe health check fetches every surface URL from the apply result and fails\nproduction if a response is unreachable, returns an unexpected status, or still\nsends `x-robots-tag: noindex`. It also verifies that each surface binding\nrecorded a deployment manifest pointer. The production release passport embeds\nthe deploy plan, apply result, production preflight, and health check so a\nreviewer or agent can audit why the production site changed and whether every\ndeclared host was actually covered.\n\n## Cleanup Plans\n\nPreview cleanup is an auditable cleanup contract. It can run as a dry-run plan,\nan apply-mode plan, or the explicit `cleanup-apply` executor with preview-only\ncredentials:\n\n```bash\nnode scripts/web-surface.mjs \\\n --mode cleanup-plan \\\n --cwd fixtures/web-surface-shaped \\\n --event pull-request-closed \\\n --pull-number 123 \\\n --aliases pr-123,sha-abcdef123456\n```\n\nThe plan and apply result keep mutable PR aliases and immutable SHA aliases\ndistinct so a caller can expire them with different retention windows. Closed-PR\ncleanup can derive `pr-N` from `--pull-number`, records the event, source SHA,\nactor, run id, preview bucket/prefix, manifest key, and adapter steps, and is an\nauditable no-op when no aliases are requested.\n\n## Reusable Workflow Shape\n\nBuildchain ships `.github/workflows/.web-surface.yml` for repositories that want\nthe standard PR review and promotion flow without copying bespoke glue:\n\n```yaml\njobs:\n web-surface:\n uses: kungfu-systems/buildchain/.github/workflows/.web-surface.yml@v2\n with:\n build-command: npm run build\n verify-command: npm run check\n artifact-path: dist\n```\n\nThe reusable workflow maps GitHub events to Buildchain web-surface semantics:\n\n| Event | Buildchain behavior |\n| --- | --- |\n| `pull_request` opened / synchronized / reopened | validate, build, verify, and plan `preview` for `pr-N` |\n| `pull_request` closed | plan apply-mode cleanup for the `pr-N` preview alias and manifest |\n| `push` to `main` | validate, build, verify, plan and apply `staging` from the merged `main` SHA, then optionally open a production release PR |\n| `push` to `main` from a matching release PR merge | validate the associated release PR, plan `production`, and enter the configured GitHub Environment gate |\n| `workflow_dispatch` with `production-approved = true` | plan `production` and enter the configured GitHub Environment gate |\n\nThe optional `buildchain-ref` input is empty by default. Empty keeps the\nweb-surface run on the stable Buildchain runtime selected by the reusable\nworkflow ref, normally `@v2`. A trusted maintainer can expose a\n`workflow_dispatch` input and pass it through for one-off train validation.\nSee [`runtime-train-validation.md`](runtime-train-validation.md) for the shared\ntrain protocol and notification template:\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 web-surface:\n uses: kungfu-systems/buildchain/.github/workflows/.web-surface.yml@v2\n with:\n buildchain-ref: ${{ inputs.buildchain-ref || '' }}\n build-command: pnpm run build\n verify-command: pnpm run check\n artifact-path: dist\n```\n\nOnly trusted `workflow_dispatch` runs by repository actors with write,\nmaintain, or admin permission may use a non-empty runtime override. Train refs\nsuch as `train/v2/v2.3/site-source-of-truth` are temporary validation refs, not\nstable production dependencies or pending merge targets. They may remain for a\nretention window after release as a fast-use and rollback channel, with old\ntrains handled by periodic Buildchain cleanup. The web-surface deployment\nmanifest records the resolved runtime SHA as `runtimeId` and the stable\nrollback ref as `rollbackPointer`.\n\nThe workflow deliberately plans and emits manifests by default. Live mutation is\nopt-in per channel:\n\n```yaml\npermissions:\n contents: read\n id-token: write\n pull-requests: write\n\njobs:\n web-surface:\n uses: kungfu-systems/buildchain/.github/workflows/.web-surface.yml@v2\n with:\n build-command: pnpm run build\n verify-command: pnpm run check\n artifact-path: dist\n preview-apply: true\n preview-cleanup-apply: true\n preview-aws-role-arn: arn:aws:iam::123456789012:role/site-preview-github-actions\n staging-apply: true\n staging-aws-role-arn: arn:aws:iam::123456789012:role/site-staging-github-actions\n production-apply: false\n production-release-on-main: false\n production-aws-role-arn: arn:aws:iam::123456789012:role/site-production-github-actions\n production-environment: production\n release-feedback-actor-privacy: public\n```\n\nWhen enabled, Buildchain owns the full release apply state machine:\n\n- PR preview deploys run `deploy-apply --dry-run false` with the preview role\n and update a single idempotent PR comment.\n- Closed PR cleanup runs `cleanup-apply --dry-run false` with the preview role\n only.\n- Pushes to `main` run staging `deploy-apply --dry-run false` with the staging\n role, then write a staging release feedback passport artifact and comment the\n associated merged PR with the staging URL, source SHA, artifact identity, run\n URL, and failure context when apply did not complete.\n- When `production-release-on-main=true`, successful staging applies open or\n update a Buildchain-owned release PR from\n `release/<channel>-<short-sha>` to `main`, unless the current push already\n came from a matching release PR merge. The release PR contains one empty\n release-intent commit, carries `production-release-label`, and includes the\n staging URLs, source SHA, artifact hash, and staging release-passport artifact\n link in the PR body.\n- Release pull requests that match the configured production gate get a\n Buildchain review comment with the staging URL and production target, so the\n operator can verify staging from the PR page and use merge as the approval\n action. Consumers do not need to hand-write `gh pr create` or production\n release-intent glue.\n- Production runs when `production-apply` is true and either:\n - a trusted `workflow_dispatch` passes `production-approved=true`; or\n - `production-release-on-main=true` and the `main` push commit is associated\n with exactly one same-repository, merged release pull request matching\n `production-release-label` and `production-release-head-prefix`.\n The production job is then gated by the configured GitHub Environment.\n- Production apply writes a production release feedback passport artifact and\n comments the release PR with the production URL, source SHA, artifact\n identity, run URL, rollback pointer, and failure context when apply did not\n complete.\n\nThe feedback passport records the release responsibility chain:\n\n- human decision actor;\n- trigger actor;\n- runner/execution actor;\n- OIDC/deploy identity reference;\n- decision type and time;\n- source event, PR number, merge commit, and required gate label/head-prefix.\n\n`release-feedback-actor-privacy` controls actor values in the passport and\ncomments. `public` records GitHub actor names, `redacted` records only the actor\nrole, and `private-ref` records a stable private reference hash without exposing\nthe actor name.\n\nFor release-PR publishing, callers opt in explicitly:\n\n```yaml\njobs:\n web-surface:\n uses: kungfu-systems/buildchain/.github/workflows/.web-surface.yml@v2\n with:\n build-command: npm run build\n verify-command: npm run check\n artifact-path: dist\n production-apply: ${{ github.event_name == 'push' && github.ref_name == 'main' }}\n production-release-on-main: true\n production-release-label: buildchain-release\n production-release-head-prefix: release/\n production-release-branch-channel: production\n production-aws-role-arn: arn:aws:iam::123456789012:role/site-production-github-actions\n production-environment: production\n```\n\nThe merge button becomes the production approval only for a PR that carries the\nrelease label and comes from the configured source-branch prefix. Ordinary pull\nrequests merged into `main` deploy staging and open a release-intent PR; merging\nthat release PR triggers production. A release PR merge push does not open\nanother release PR.\n\nApply-only inputs are validated before the caller build or verification command\nruns. If the current event would run preview, staging, or production apply,\nmissing role inputs or a production apply without `production-approved=true`\non manual dispatch fail immediately instead of spending the build and plan jobs\nfirst.\n\nCallers must grant `id-token: write` for OIDC role assumption. Preview comments\nneed `pull-requests: write`. Automatic release PR creation also needs\n`contents: write`, `pull-requests: write`, and `issues: write` so Buildchain can\ncreate the release branch, write the empty release-intent commit, open or update\nthe PR, and apply the release label. The AWS roles remain caller-owned and\nshould be scoped by channel: preview can mutate only preview resources, staging\ncan mutate only staging resources, and production can mutate only production\nresources.\n\nApply mode fails closed when the deploy config still contains placeholder AWS\ntargets such as `pending-preview-distribution`. Planning can use placeholders\nfor dry-run-only design work, but live apply requires concrete bucket and\nCloudFront distribution identifiers.\n\n## Site Repository Shape\n\nA site repository can start with:\n\n```toml\nschema = 1\n\n[project]\ntype = \"web-surface\"\nname = \"site-kungfu-tech\"\nsite = \"kungfu-tech\"\n\n[lifecycle.build]\ncommand = \"pnpm run build\"\n\n[lifecycle.verify]\ncommand = \"pnpm run check\"\n```\n\nThen add the channel, deploy, retention, and security declarations shown above.\nThe project may use pnpm, npm, yarn, Vite, Astro, Next static export, Sphinx,\nMkDocs, CMake-generated docs, or another lifecycle command source. Buildchain\nonly needs a deterministic artifact path and the manifest facts.\n\n## Boundaries\n\nBuildchain only performs live AWS mutations in explicit apply modes with\n`--dry-run false`. Production deploys must still be gated by a human-controlled\nworkflow, release, or GitHub Environment. DNS changes, staging auth\nimplementation, CloudFront distribution creation, and credential provisioning\nremain explicitly authorized infrastructure operations outside the web-surface\nartifact apply contract."
1283
+ },
1284
+ {
1285
+ "id": "fixture:infra-contract-aws-cdk-shaped",
1286
+ "title": "AWS CDK-shaped Infra Contract Fixture",
1287
+ "route": "/fixtures/infra-contract-aws-cdk-shaped",
1288
+ "category": "fixture",
1289
+ "sourcePath": "fixtures/infra-contract-aws-cdk-shaped/README.md",
1290
+ "digest": "sha256:87304783102305824523d0d2214a9072a38cc3f0904c23e7c38145804f1e596e",
1291
+ "headings": [
1292
+ {
1293
+ "level": 1,
1294
+ "title": "AWS CDK-shaped Infra Contract Fixture",
1295
+ "anchor": "aws-cdk-shaped-infra-contract-fixture"
1296
+ }
1297
+ ],
1298
+ "markdown": "# AWS CDK-shaped Infra Contract Fixture\n\nThis fixture proves the infra-contract model can represent AWS CDK synthesized\nassembly metadata and observed CloudFormation output shapes without deploying a\nstack.\n\nIt is static evidence only: no `cdk deploy` command is executed and no AWS\ncredentials are required."
1299
+ },
1300
+ {
1301
+ "id": "fixture:infra-contract-aws-cli-shaped",
1302
+ "title": "AWS CLI-shaped Infra Contract Fixture",
1303
+ "route": "/fixtures/infra-contract-aws-cli-shaped",
1304
+ "category": "fixture",
1305
+ "sourcePath": "fixtures/infra-contract-aws-cli-shaped/README.md",
1306
+ "digest": "sha256:78f4c30dc5ebf03bc591616d93a4adb5c7c913f5746bfb1cc8a404d4e73a538b",
1307
+ "headings": [
1308
+ {
1309
+ "level": 1,
1310
+ "title": "AWS CLI-shaped Infra Contract Fixture",
1311
+ "anchor": "aws-cli-shaped-infra-contract-fixture"
1312
+ }
1313
+ ],
1314
+ "markdown": "# AWS CLI-shaped Infra Contract Fixture\n\nThis fixture proves the infra-contract model can represent a generic AWS CLI\ndesired request and observed response shape without calling a live AWS service.\n\nIt is static evidence only: no AWS CLI command is executed and no AWS\ncredentials are required."
1315
+ },
1316
+ {
1317
+ "id": "fixture:infra-contract-cloudformation-shaped",
1318
+ "title": "CloudFormation-shaped Infra Contract Fixture",
1319
+ "route": "/fixtures/infra-contract-cloudformation-shaped",
1320
+ "category": "fixture",
1321
+ "sourcePath": "fixtures/infra-contract-cloudformation-shaped/README.md",
1322
+ "digest": "sha256:c25dc4d1651198bf3fa9ac0e32189ca59efba79952075d210dad7f8371023d74",
1323
+ "headings": [
1324
+ {
1325
+ "level": 1,
1326
+ "title": "CloudFormation-shaped Infra Contract Fixture",
1327
+ "anchor": "cloudformation-shaped-infra-contract-fixture"
1328
+ }
1329
+ ],
1330
+ "markdown": "# CloudFormation-shaped Infra Contract Fixture\n\nThis fixture proves the infra-contract model can represent CloudFormation\ndesired templates and observed stack outputs without making live AWS calls.\n\nIt is static evidence only: no change set is created, no stack is updated, and\nno AWS credentials are required."
1331
+ },
1332
+ {
1333
+ "id": "fixture:infra-contract-opentofu-shaped",
1334
+ "title": "OpenTofu-shaped Infra Contract Fixture",
1335
+ "route": "/fixtures/infra-contract-opentofu-shaped",
1336
+ "category": "fixture",
1337
+ "sourcePath": "fixtures/infra-contract-opentofu-shaped/README.md",
1338
+ "digest": "sha256:473e6960ef31e119539c7e6fe21fda157b29bbdcbfc9e90f4f2356c1432a86d0",
1339
+ "headings": [
1340
+ {
1341
+ "level": 1,
1342
+ "title": "OpenTofu-shaped Infra Contract Fixture",
1343
+ "anchor": "opentofu-shaped-infra-contract-fixture"
1344
+ }
1345
+ ],
1346
+ "markdown": "# OpenTofu-shaped Infra Contract Fixture\n\nThis fixture proves the infra-contract model can represent OpenTofu desired\nconfiguration and observed output shapes without reading OpenTofu state files.\n\nIt is static evidence only: no `tofu apply` command is executed and no provider\ncredentials are required."
1347
+ },
1348
+ {
1349
+ "id": "fixture:infra-contract-pulumi-shaped",
1350
+ "title": "Pulumi-shaped Infra Contract Fixture",
1351
+ "route": "/fixtures/infra-contract-pulumi-shaped",
1352
+ "category": "fixture",
1353
+ "sourcePath": "fixtures/infra-contract-pulumi-shaped/README.md",
1354
+ "digest": "sha256:9d0f29b5d4064c437baa5e6b7ca96e52ac0c8e64daa06a8e4cd3e4b69692f97e",
1355
+ "headings": [
1356
+ {
1357
+ "level": 1,
1358
+ "title": "Pulumi-shaped Infra Contract Fixture",
1359
+ "anchor": "pulumi-shaped-infra-contract-fixture"
1360
+ }
1361
+ ],
1362
+ "markdown": "# Pulumi-shaped Infra Contract Fixture\n\nThis fixture proves the infra-contract model can represent Pulumi preview and\nstack output shapes without reading Pulumi state or secrets files.\n\nIt is static evidence only: no `pulumi up` command is executed and no Pulumi\nsecrets material is committed."
1363
+ },
1364
+ {
1365
+ "id": "fixture:infra-contract-shaped",
1366
+ "title": "Infra Contract Shaped Fixture",
1367
+ "route": "/fixtures/infra-contract-shaped",
1368
+ "category": "fixture",
1369
+ "sourcePath": "fixtures/infra-contract-shaped/README.md",
1370
+ "digest": "sha256:c78c9fc097666d177f67be702d16a7b5f7bf2204759f1f29279cacc96dd12a8e",
1371
+ "headings": [
1372
+ {
1373
+ "level": 1,
1374
+ "title": "Infra Contract Shaped Fixture",
1375
+ "anchor": "infra-contract-shaped-fixture"
1376
+ }
1377
+ ],
1378
+ "markdown": "# Infra Contract Shaped Fixture\n\nThis fixture models an infrastructure repository that already has live resources\nand wants to publish observed output contracts before full IaC ownership exists.\n\nIt proves that `project.type = \"infra-contract\"` can validate desired files,\nread reviewed observed outputs, publish a deterministic contract artifact, and\nplan downstream consumer pull requests without mutating cloud infrastructure."
1379
+ },
1380
+ {
1381
+ "id": "fixture:infra-contract-terraform-shaped",
1382
+ "title": "Terraform-shaped Infra Contract Fixture",
1383
+ "route": "/fixtures/infra-contract-terraform-shaped",
1384
+ "category": "fixture",
1385
+ "sourcePath": "fixtures/infra-contract-terraform-shaped/README.md",
1386
+ "digest": "sha256:c32c5a512d742c0862c551e39dd757c8817535ea23e6846a82590134183886ce",
1387
+ "headings": [
1388
+ {
1389
+ "level": 1,
1390
+ "title": "Terraform-shaped Infra Contract Fixture",
1391
+ "anchor": "terraform-shaped-infra-contract-fixture"
1392
+ }
1393
+ ],
1394
+ "markdown": "# Terraform-shaped Infra Contract Fixture\n\nThis fixture proves the infra-contract model is not CloudFormation-specific.\nIt uses Terraform-shaped desired and output JSON fixtures as static evidence.\nNo Terraform state file is read and no provider command is executed."
1395
+ },
1396
+ {
1397
+ "id": "fixture:libnode-shaped",
1398
+ "title": "Libnode-shaped Fixture",
1399
+ "route": "/fixtures/libnode-shaped",
1400
+ "category": "fixture",
1401
+ "sourcePath": "fixtures/libnode-shaped/README.md",
1402
+ "digest": "sha256:a48d83f84772de7f9cc264b55bf5f9c3db16c0fee529f68f9297bd6e5274a509",
1403
+ "headings": [
1404
+ {
1405
+ "level": 1,
1406
+ "title": "Libnode-shaped Fixture",
1407
+ "anchor": "libnode-shaped-fixture"
1408
+ }
1409
+ ],
1410
+ "markdown": "# Libnode-shaped Fixture\n\nThis fixture models the Buildchain contract needed by `kungfu-systems/libnode`\nwithout running the real native build.\n\nIt is intentionally small, but it keeps the important shape:\n\n- `package.json` is the package version-state file;\n- `libnode.release.json` is the explicit upstream anchor manifest;\n- `buildchain.toml` declares `install`, `build`, `verify`, and `publish`\n lifecycle stages;\n- `version.strategy = \"anchored\"` and `version.next = \"manual\"` tell\n Buildchain to validate the current anchor instead of deriving the next Node\n anchor automatically;\n- lifecycle commands are Node-based and cross-platform;\n- build output lands under `dist/`, which the reusable build workflow uploads\n with a deterministic artifact name and manifest;\n- the fixture can be resolved through a publish-gate source lock, which binds\n the requested consumer version to `package.json` and `libnode.release.json`\n before any publish side effect is allowed;\n- `[publish]` declares the normal token-free path:\n `mode = \"publish-final-version\"` with `auth = \"trusted-publishing\"`, `latest`\n as the release dist-tag, and platform packages published before the main\n package."
1411
+ },
1412
+ {
1413
+ "id": "fixture:publish-transaction-shaped",
1414
+ "title": "publish-transaction-shaped",
1415
+ "route": "/fixtures/publish-transaction-shaped",
1416
+ "category": "fixture",
1417
+ "sourcePath": "fixtures/publish-transaction-shaped/README.md",
1418
+ "digest": "sha256:e6114ec1f74727c7a14123f5680d6bebfba1866b80d0c9737f381c7037cfac09",
1419
+ "headings": [
1420
+ {
1421
+ "level": 1,
1422
+ "title": "publish-transaction-shaped",
1423
+ "anchor": "publish-transaction-shaped"
1424
+ }
1425
+ ],
1426
+ "markdown": "# publish-transaction-shaped\n\nFixture for the Buildchain publish transaction contract.\n\nIt represents a release unit with three required artifact families:\n\n- npm package metadata;\n- OCI image digest;\n- binary archive digest.\n\nThe fixture does not publish to external services. `lifecycle.publish` writes\ngeneric Buildchain evidence to `BUILDCHAIN_PUBLISH_EVIDENCE`, which is enough for\ntests and for consumers to understand the expected shape.\n\n```bash\nBUILDCHAIN_VERSION=1.0.0 \\\nBUILDCHAIN_CHANNEL=release \\\nBUILDCHAIN_SOURCE_SHA=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \\\nBUILDCHAIN_RELEASE_SHA=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \\\nBUILDCHAIN_RELEASE_MATERIAL_SHA=bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb \\\nBUILDCHAIN_PUBLISH_TOOLING_SHA=cccccccccccccccccccccccccccccccccccccccc \\\nBUILDCHAIN_TARGET_REF=release/v1/v1.0 \\\nBUILDCHAIN_EVIDENCE_DIR=.buildchain/release-evidence/v1.0.0 \\\nBUILDCHAIN_PUBLISH_EVIDENCE=.buildchain/release-evidence/v1.0.0/evidence.json \\\nnode scripts/publish.mjs\n```"
1427
+ },
1428
+ {
1429
+ "id": "fixture:release-propagation-shaped",
1430
+ "title": "Release Propagation Fixture",
1431
+ "route": "/fixtures/release-propagation-shaped",
1432
+ "category": "fixture",
1433
+ "sourcePath": "fixtures/release-propagation-shaped/README.md",
1434
+ "digest": "sha256:6134eee39673dd29e019f941c241ddf8a9aba68f2e06dca9367d3fd304385cfa",
1435
+ "headings": [
1436
+ {
1437
+ "level": 1,
1438
+ "title": "Release Propagation Fixture",
1439
+ "anchor": "release-propagation-fixture"
1440
+ }
1441
+ ],
1442
+ "markdown": "# Release Propagation Fixture\n\nThis fixture demonstrates a generic release propagation graph with a\n`kfd -> site-libkungfu-dev` shaped edge. It is safe test data only; tests use it\nto prove that Buildchain preserves alpha/release channels and writes an exact\nupstream release lock."
1443
+ },
1444
+ {
1445
+ "id": "fixture:web-surface-shaped",
1446
+ "title": "Web Surface Shaped Fixture",
1447
+ "route": "/fixtures/web-surface-shaped",
1448
+ "category": "fixture",
1449
+ "sourcePath": "fixtures/web-surface-shaped/README.md",
1450
+ "digest": "sha256:87b8f216f1b112cd17e4acbefaea5b024e5d374c8d682f324b0b0d5f4df606c5",
1451
+ "headings": [
1452
+ {
1453
+ "level": 1,
1454
+ "title": "Web Surface Shaped Fixture",
1455
+ "anchor": "web-surface-shaped-fixture"
1456
+ }
1457
+ ],
1458
+ "markdown": "# Web Surface Shaped Fixture\n\nThis fixture models a static site repository that wants Buildchain deployment\nsemantics without opting into package release lines.\n\nIt proves that `project.type = \"web-surface\"` can declare preview, staging, and\nproduction channels, named surface host mappings, deterministic deployment\nmanifests, and dry-run deploy and cleanup plans without touching AWS.\n\nThe fixture is shaped like a `site-libkungfu-dev` repository with four\nfirst-class surfaces:\n\n```text\nhub https://libkungfu.dev\ncore https://core.libkungfu.dev\nbuildchain https://buildchain.libkungfu.dev\nkfd https://kfd.libkungfu.dev\n```\n\nFor preview and staging, Buildchain resolves the same surface names to the\nchannel-specific hosts and records them in `surfaceBindings`. Path-only pages\ncan still be declared with `path_only = true`, but this fixture intentionally\nuses first-class hosts for every surface so validation can catch missing\nchannel mappings."
1459
+ }
1460
+ ],
1461
+ "pageRegistry": {
1462
+ "path": "page-registry.json",
1463
+ "contract": "kungfu-buildchain-site-page-registry",
1464
+ "pageCount": 39,
1465
+ "categories": [
1466
+ "action",
1467
+ "api",
1468
+ "fixture",
1469
+ "manual",
1470
+ "overview"
1471
+ ]
1472
+ },
1473
+ "homepage": {
1474
+ "title": "Buildchain",
1475
+ "lead": "Buildchain Release Passport is a mature product release record for artifacts that users or agents depend on.",
1476
+ "mechanismSummary": [
1477
+ "Buildchain by Kungfu uses GitHub as the execution and trust substrate: protected refs, reviewed promotion PRs, exact tags, GitHub Releases, npm Trusted Publishing, and machine-readable evidence. Its job is to turn release intent into an auditable product record, not to ask a repository to migrate away from its existing CI.",
1478
+ "The same mechanism releases Buildchain itself."
1479
+ ],
1480
+ "sections": [
1481
+ {
1482
+ "id": "install-and-verify",
1483
+ "sourcePath": "README.md",
1484
+ "sourceHeading": "Install and Verify",
1485
+ "title": "Install and Verify",
1486
+ "renderRole": "primary",
1487
+ "homepagePriority": 10,
1488
+ "defaultPresentation": "release-passport-install",
1489
+ "includeInFirstScreen": true,
1490
+ "markdown": "For standalone use, install a platform archive from a GitHub Release and verify\nthe release passport before trusting the binary:\n\n```bash\n# Example for Linux x64. Use the archive that matches your platform.\ncurl -LO https://github.com/kungfu-systems/buildchain/releases/download/v2.2.1/buildchain-x86_64-unknown-linux-gnu.tar.gz\ncurl -LO https://github.com/kungfu-systems/buildchain/releases/download/v2.2.1/buildchain.release.json\ncurl -LO https://github.com/kungfu-systems/buildchain/releases/download/v2.2.1/artifact-evidence.json\nnpx @kungfu-tech/buildchain verify release-passport buildchain.release.json\ntar -xzf buildchain-x86_64-unknown-linux-gnu.tar.gz\n./buildchain version\n```\n\nRelease pages publish platform archives, checksums, release passport files, and\na single evidence bundle:\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- `checksums.txt`\n- `buildchain.release.json`\n- `artifact-evidence.json`\n- `product-mechanism.json`\n- `impact.json`\n- `agent-index.json`\n- `check-report.json`\n- `llms.txt`\n- `buildchain-release-bundle.tar.gz`\n- `buildchain-release-bundle.json`\n\nLoose top-level `buildchain` and `buildchain.exe` assets are intentionally not\npublished. The executable lives inside each platform archive, which prevents\nLinux and macOS artifacts from overwriting each other in a merged release lane.\n\nFor npm consumers:\n\n```bash\nnpm install -D @kungfu-tech/buildchain\nnpx buildchain version\nnpx buildchain doctor --json\n```\n\nThe npm package is also the Buildchain toolkit. Use the command when a workflow\nor shell step needs an executable; use the ESM APIs directly from JavaScript\nbuild scripts. JavaScript callers should import the package instead of spawning\nthe CLI or unpacking the standalone binary:\n\n```js\nimport {\n createBuildchainLogger,\n verifyBuildchainLogEvents,\n} from \"@kungfu-tech/buildchain/logging\";\n\nconst logger = createBuildchainLogger({\n path: \".buildchain/logs/native-build.jsonl\",\n source: \"user\",\n component: \"native-build\",\n});\n\nawait logger.span(\"native.compile\", { phase: \"build\" }, async () => {\n await compileNativeTargets();\n});\n\nconst report = verifyBuildchainLogEvents({\n path: logger.path,\n requireEvents: [\"native.compile.start\", \"native.compile.end\"],\n});\n```\n\nThe package also ships `dist/site/` as the Buildchain-owned fact source for\n`buildchain.libkungfu.dev`."
1491
+ },
1492
+ {
1493
+ "id": "use-buildchain",
1494
+ "sourcePath": "README.md",
1495
+ "sourceHeading": "Use Buildchain",
1496
+ "title": "Use Buildchain",
1497
+ "renderRole": "primary",
1498
+ "homepagePriority": 20,
1499
+ "defaultPresentation": "workflow-surface-list",
1500
+ "includeInFirstScreen": true,
1501
+ "markdown": "Bootstrap a repository:\n\n```bash\nnpx @kungfu-tech/buildchain init --type package --package-manager pnpm\nnpx @kungfu-tech/buildchain validate --require-version-state\nnpx @kungfu-tech/buildchain release --dry-run --target-ref alpha/v2/v2.2\n```\n\nBuildchain supports package and non-package projects through `buildchain.toml`.\nLifecycle commands can call pnpm, npm, yarn, pip, Conan, CMake, Make, custom\nscripts, or any other command that can run in the repository checkout.\n\nBuildchain's active GitHub Action surface is deliberately small:\n\n- `actions/validate-config`\n- `actions/run-lifecycle`\n- `actions/promote-buildchain-ref`\n- `actions/report-buildchain-issue`\n\nThe active reusable workflow surfaces are:\n\n- `.github/workflows/.build.yml` for deterministic multi-platform build and\n artifact contracts;\n- `.github/workflows/release-candidate-promote.yml` for post-merge\n promote-only publication from a PR-stage release candidate, without a second\n heavy build;\n- `.github/workflows/.web-surface.yml` for preview, staging, production, and\n cleanup plans for site/app repositories;\n- `.github/workflows/buildchain-ref-promotion.yml` for protected release\n promotion and version-state transactions;\n- `.github/workflows/binary-distribution.yml` for Buildchain's own release\n passport proof case.\n\nStable consumers should reference actions and workflows through floating major\nrefs after reviewing the exact release passport:\n\n```yaml\nuses: kungfu-systems/buildchain/actions/validate-config@v2\n```\n\n```yaml\nuses: kungfu-systems/buildchain/.github/workflows/.build.yml@v2\n```\n\n```yaml\nuses: kungfu-systems/buildchain/.github/workflows/release-candidate-promote.yml@v2\n```"
1502
+ },
1503
+ {
1504
+ "id": "release-model",
1505
+ "sourcePath": "README.md",
1506
+ "sourceHeading": "Release Model",
1507
+ "title": "Release Model",
1508
+ "renderRole": "primary",
1509
+ "homepagePriority": 30,
1510
+ "defaultPresentation": "release-model-table",
1511
+ "includeInFirstScreen": false,
1512
+ "markdown": "Buildchain treats a reviewed branch merge as release intent:\n\n| Merge path | Meaning | Exact tag | Floating refs |\n| --- | --- | --- | --- |\n| `dev/vX/vX.Y -> alpha/vX/vX.Y` | publish the next testable alpha for a minor line | `vX.Y.Z-alpha.N` | `vX.Y-alpha`, `alpha/vX/vX.Y`, `dev/vX/vX.Y` |\n| `alpha/vX/vX.Y -> release/vX/vX.Y` | publish production for that minor line | `vX.Y.Z` | `vX.Y`, usually `vX`, `release/vX/vX.Y` |\n| `release/vX/vX.Y -> publish-gate/major` | publish the next major from a reviewed production line | `v(X+1).0.0` | `v(X+1)`, `v(X+1).0`, new dev/alpha/release branches |\n\nExact tags are immutable. Floating channel tags and branches are machine-updated\nby Buildchain and must remain writable by the release authority.\n\nAfter a production release, Buildchain prepares the next alpha source commit for\nthe same minor line. That keeps production consumers pinned to the production\npassport while development can continue on the next testable patch.\n\n`publish-gate/major` is not an active development trunk. It is a reviewed\npromotion gate used when maintainers decide that the next production release\nshould open a new major line."
1513
+ },
1514
+ {
1515
+ "id": "toolkit-observability",
1516
+ "sourcePath": "README.md",
1517
+ "sourceHeading": "Toolkit Observability",
1518
+ "title": "Toolkit Observability",
1519
+ "renderRole": "support",
1520
+ "homepagePriority": 40,
1521
+ "defaultPresentation": "toolkit-example",
1522
+ "includeInFirstScreen": false,
1523
+ "markdown": "Buildchain includes a logging toolkit for release and build steps. Inside\nJavaScript build code, prefer the package API:\n\n```js\nimport { createBuildchainLogger } from \"@kungfu-tech/buildchain/logging\";\n\nconst logger = createBuildchainLogger({ source: \"user\", component: \"conan\" });\nlogger.mark(\"conan.profile.ready\", { phase: \"configure\" });\nawait logger.span(\"conan.install\", { phase: \"dependencies\" }, runConanInstall);\n```\n\nIn workflows or shell scripts, use the equivalent CLI:\n\n```bash\nbuildchain mark --event native.configure --phase configure --component cmake\nbuildchain span --event native.build --phase build -- cmake --build build\nbuildchain log summary --json\nbuildchain verify observability-log .buildchain/logs/events.jsonl --min-events 4\n```\n\nEvery event records a timestamp. `span` records duration. The API form can be\nimported from repository scripts so heavy builds can mark phases from inside\ntheir own code."
1524
+ },
1525
+ {
1526
+ "id": "site-fact-source",
1527
+ "sourcePath": "README.md",
1528
+ "sourceHeading": "Site Fact Source",
1529
+ "title": "Site Fact Source",
1530
+ "renderRole": "support",
1531
+ "homepagePriority": 50,
1532
+ "defaultPresentation": "site-fact-source",
1533
+ "includeInFirstScreen": false,
1534
+ "markdown": "`@kungfu-tech/buildchain` publishes `dist/site/`:\n\n- `buildchain-site.json`\n- `site-manifest.json`\n- `page-registry.json`\n- `cli-registry.json`\n- `workflow-registry.json`\n- `release-model.json`\n- `artifact-schemas.json`\n- `product-mechanism.json`\n- `release-provenance.json`\n- `agent-index.json`\n\n`buildchain.libkungfu.dev` should render from these package-owned facts, then\nlayer presentation around them. The site should not hand-write Buildchain's\ncurrent release mechanics. `page-registry.json` is the complete markdown page\nsource for the public site: README homepage content, all packaged `docs/*.md`\nmanuals, action READMEs, the Node API package overview, and fixture guides."
1535
+ }
1536
+ ],
1537
+ "displayPlan": {
1538
+ "firstScreen": {
1539
+ "include": [
1540
+ "title",
1541
+ "lead",
1542
+ "install-and-verify",
1543
+ "use-buildchain"
1544
+ ],
1545
+ "maxPrimarySections": 2,
1546
+ "note": "The first viewport should establish Buildchain identity, release-passport trust, and the primary reusable workflow entrypoint without rendering implementation notes."
1547
+ },
1548
+ "primary": [
1549
+ "install-and-verify",
1550
+ "use-buildchain",
1551
+ "release-model"
1552
+ ],
1553
+ "support": [
1554
+ "toolkit-observability",
1555
+ "site-fact-source"
1556
+ ],
1557
+ "rendererContract": [
1558
+ "homepage-content-contract"
1559
+ ]
1560
+ },
1561
+ "rendererContract": {
1562
+ "id": "homepage-content-contract",
1563
+ "sourcePath": "README.md",
1564
+ "sourceHeading": "Homepage Content Contract",
1565
+ "title": "Homepage Content Contract",
1566
+ "renderRole": "renderer-contract",
1567
+ "homepagePriority": 90,
1568
+ "defaultPresentation": "developer-note",
1569
+ "includeInFirstScreen": false,
1570
+ "markdown": "This README is also the homepage text source for `buildchain.libkungfu.dev`.\nWhen a site repository consumes the `@kungfu-tech/buildchain` npm package, it\nshould use the generated `dist/site/buildchain-site.json` homepage fields\ninstead of parsing this README or maintaining separate homepage copy.\n\nThe first screen should be derived from:\n\n- Page identity: the top-level heading.\n- Lead: the opening paragraph that defines Buildchain Release Passport.\n- Trust signal: the start of `Install and Verify`, especially passport-first\n binary verification.\n- Use signal: the start of `Use Buildchain`, especially the reusable workflow\n and action surfaces.\n\nThe package-owned site bundle exposes ordered `homepage.sections`,\n`homepage.displayPlan`, `homepage.rendererContract`, and a complete\n`pages` collection mirrored from `page-registry.json`. A site renderer may adapt\nlayout, navigation, typography, examples, and visual assets, but it should not\nmaintain separate wording for Buildchain's release mechanics, workflow surface,\noperation manuals, Node API overview, fixture guides, or release-passport trust\nmodel. Renderer-contract text is machine/implementation metadata, not ordinary\nhomepage content.",
1571
+ "renderAsHomepageContent": false,
1572
+ "note": "This is a machine/renderer contract for site implementers. It should not be rendered as ordinary homepage content."
1573
+ }
1574
+ },
29
1575
  "docs": [
1576
+ {
1577
+ "id": "map",
1578
+ "title": "Buildchain documentation map",
1579
+ "path": "docs/MAP.md",
1580
+ "plane": "use",
1581
+ "exists": true,
1582
+ "digest": "sha256:b5cfef531ba8ca655d8d66ffe0e530a0ca2c971daad5880943d2b824216ed043"
1583
+ },
30
1584
  {
31
1585
  "id": "install",
32
1586
  "title": "Install and verify Buildchain",
@@ -59,6 +1613,22 @@
59
1613
  "exists": true,
60
1614
  "digest": "sha256:36899140a9b2e9ce1565ed41f3d64f73a8829fad3d59a04b9498d9479c85c4be"
61
1615
  },
1616
+ {
1617
+ "id": "consumer-issue-reporting",
1618
+ "title": "Consumer issue reporting",
1619
+ "path": "docs/consumer-issue-reporting.md",
1620
+ "plane": "use",
1621
+ "exists": true,
1622
+ "digest": "sha256:8e2159312e47b42ab0bb644cb195362150acc8872e6ac0e7380ece0c5cf36955"
1623
+ },
1624
+ {
1625
+ "id": "infra-contract",
1626
+ "title": "Infra Contract",
1627
+ "path": "docs/infra-contract.md",
1628
+ "plane": "use",
1629
+ "exists": true,
1630
+ "digest": "sha256:7826e8c70ac2d90ddd8d4e38bcdd1bcfa36eef5106431d7ad94b2fe9c8d3d5dc"
1631
+ },
62
1632
  {
63
1633
  "id": "toolkit-observability",
64
1634
  "title": "Toolkit observability",
@@ -73,7 +1643,23 @@
73
1643
  "path": "docs/site-bundle-contract.md",
74
1644
  "plane": "use",
75
1645
  "exists": true,
76
- "digest": "sha256:e6b4f2e76c713063ff750b0a8d6d96595addae2fd48f913744dc86559add0641"
1646
+ "digest": "sha256:1977091fc18b816208e7af50a177fd15e114498bfa49041573812405b46585aa"
1647
+ },
1648
+ {
1649
+ "id": "migration-inventory",
1650
+ "title": "Migration inventory",
1651
+ "path": "docs/migration-inventory.md",
1652
+ "plane": "verify",
1653
+ "exists": true,
1654
+ "digest": "sha256:80018cf78785431e67bbc5278d82dda80d0baa320cdb5e4abda26a0b05e5c0bc"
1655
+ },
1656
+ {
1657
+ "id": "ownership",
1658
+ "title": "Ownership",
1659
+ "path": "docs/ownership.md",
1660
+ "plane": "why",
1661
+ "exists": true,
1662
+ "digest": "sha256:49074fb520c404d3c9f5b49b33562d4bdc4e3ed407cf22543fa8e19e312a6b8e"
77
1663
  },
78
1664
  {
79
1665
  "id": "product-mechanism",
@@ -131,6 +1717,14 @@
131
1717
  "exists": true,
132
1718
  "digest": "sha256:0a2f46501a64905067cc5872b45ac4824f9e632d59bfdfb2f6a794dfc5f959ea"
133
1719
  },
1720
+ {
1721
+ "id": "runtime-train-validation",
1722
+ "title": "Runtime train validation",
1723
+ "path": "docs/runtime-train-validation.md",
1724
+ "plane": "verify",
1725
+ "exists": true,
1726
+ "digest": "sha256:bb053594407bd0f78aa43352a249a2ffa19825374147cc712cd56ca6ad50dfa3"
1727
+ },
134
1728
  {
135
1729
  "id": "versioning",
136
1730
  "title": "Versioning",
@@ -145,15 +1739,7 @@
145
1739
  "path": "docs/web-surface-deployments.md",
146
1740
  "plane": "use",
147
1741
  "exists": true,
148
- "digest": "sha256:796e891819f03f0a7ac91f56f1bb74d9e3443d8bb0bee33a3cd053d70bde6a62"
149
- },
150
- {
151
- "id": "infra-contract",
152
- "title": "Infra Contract",
153
- "path": "docs/infra-contract.md",
154
- "plane": "use",
155
- "exists": true,
156
- "digest": "sha256:7826e8c70ac2d90ddd8d4e38bcdd1bcfa36eef5106431d7ad94b2fe9c8d3d5dc"
1742
+ "digest": "sha256:61891635707e9ed27b8754b83713db61cf9a7a6bdf65beb6a9ac8aa39356e168"
157
1743
  }
158
1744
  ],
159
1745
  "releaseModel": {
@@ -203,5 +1789,28 @@
203
1789
  ],
204
1790
  "owner": "promote-buildchain-ref"
205
1791
  }
1792
+ },
1793
+ "renderingBoundary": {
1794
+ "ownedByBuildchain": [
1795
+ "homepage title and text",
1796
+ "homepage section projection from README.md",
1797
+ "complete markdown page registry for Buildchain public docs, action manuals, Node API overview, and fixtures",
1798
+ "release model facts",
1799
+ "workflow and action registries",
1800
+ "CLI command registry",
1801
+ "manual and Node API registries",
1802
+ "KFD claim registry",
1803
+ "release-passport evidence vocabulary"
1804
+ ],
1805
+ "ownedBySite": [
1806
+ "HTML structure",
1807
+ "CSS",
1808
+ "responsive layout",
1809
+ "navigation layout",
1810
+ "visual assets",
1811
+ "decorative images",
1812
+ "markdown-to-HTML renderer",
1813
+ "section presentation and progressive disclosure within Buildchain displayPlan constraints"
1814
+ ]
206
1815
  }
207
1816
  }