@kungfu-tech/buildchain 2.12.7-alpha.3 → 2.12.7-alpha.5
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/site/buildchain-contract.json +11 -11
- package/dist/site/buildchain-site.json +11 -11
- package/dist/site/kfd-claims.json +7 -4
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +1 -1
- package/dist/site/node-api-registry.json +1 -1
- package/dist/site/page-registry.json +6 -6
- package/dist/site/public-surface-audit.json +7 -4
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +5 -5
- package/dist/site/workflow-registry.json +5 -2
- package/docs/publication-artifacts.md +8 -1
- package/docs/publication-authority.md +11 -2
- package/docs/shifu-gate-profiles.md +6 -0
- package/package.json +1 -1
- package/packages/core/controller-evidence.js +1 -1
- package/scripts/assemble-self-publication-admission.mjs +2 -1
- package/scripts/check-inventory.mjs +3 -0
- package/scripts/workflow-friction-report.mjs +13 -2
|
@@ -4,7 +4,7 @@
|
|
|
4
4
|
"product": {
|
|
5
5
|
"name": "Buildchain",
|
|
6
6
|
"package": "@kungfu-tech/buildchain",
|
|
7
|
-
"version": "2.12.7-alpha.
|
|
7
|
+
"version": "2.12.7-alpha.5",
|
|
8
8
|
"repository": "https://github.com/kungfu-systems/buildchain"
|
|
9
9
|
},
|
|
10
10
|
"majorLine": "v2",
|
|
@@ -50,7 +50,7 @@
|
|
|
50
50
|
"retryable GitHub fallback fetches use a bounded attempt budget before exact source SHA and tree verification"
|
|
51
51
|
],
|
|
52
52
|
"breakingDigest": "sha256:a6a35370d6b0d0f46e1b2712dcc01961fe53c2febde95409a27a485c10a36650",
|
|
53
|
-
"auditDigest": "sha256:
|
|
53
|
+
"auditDigest": "sha256:4dc810c734e3b597297932839d3919219b93c69a985fc1b8ecc91a08299b940e"
|
|
54
54
|
},
|
|
55
55
|
{
|
|
56
56
|
"contractVersion": 1,
|
|
@@ -159,7 +159,7 @@
|
|
|
159
159
|
"GitHub Release passport and evidence publication is delegated to promote-buildchain-ref after the semver release transaction completes"
|
|
160
160
|
],
|
|
161
161
|
"breakingDigest": "sha256:6dbae32ce3d7aab3be6957065105af574794581847b7637314dad45f5349c919",
|
|
162
|
-
"auditDigest": "sha256:
|
|
162
|
+
"auditDigest": "sha256:10c3132362feab7e8e3f612eedc2e62b9b90ff0ed2fcf8445ce75caef55c26d5"
|
|
163
163
|
},
|
|
164
164
|
{
|
|
165
165
|
"contractVersion": 1,
|
|
@@ -269,7 +269,7 @@
|
|
|
269
269
|
"semver GitHub Releases are created or updated only after transaction completion, with prerelease/latest metadata derived from the public release tag"
|
|
270
270
|
],
|
|
271
271
|
"breakingDigest": "sha256:a59f0910e6df842e7699139472e5dd69ac2fdd7f7213bf2cb346d1d622556874",
|
|
272
|
-
"auditDigest": "sha256:
|
|
272
|
+
"auditDigest": "sha256:0a6b261a43f59477497d99f840e83b11a2cfa6545a3d89c9952f47d7ebed33dc"
|
|
273
273
|
},
|
|
274
274
|
{
|
|
275
275
|
"contractVersion": 1,
|
|
@@ -527,7 +527,7 @@
|
|
|
527
527
|
"manual entries carry source file digests so downstream sites and agents can detect stale hand-written documentation"
|
|
528
528
|
],
|
|
529
529
|
"breakingDigest": "sha256:7d0d2819e3a3e72989d9c57b5efe9d0bc0a79bc0f2c82a0c7b9d6c5a211a91f2",
|
|
530
|
-
"auditDigest": "sha256:
|
|
530
|
+
"auditDigest": "sha256:653df5708fa73f074129b3bf1e047f7f204f42e4521e2b0d7521618f01f9f345"
|
|
531
531
|
},
|
|
532
532
|
{
|
|
533
533
|
"contractVersion": 1,
|
|
@@ -549,7 +549,7 @@
|
|
|
549
549
|
"agents can discover supported Node APIs without importing internal file paths"
|
|
550
550
|
],
|
|
551
551
|
"breakingDigest": "sha256:48f925608d3e2131d90936b07dc2a30341204cae3e6e785c0f77d61ad755c945",
|
|
552
|
-
"auditDigest": "sha256:
|
|
552
|
+
"auditDigest": "sha256:69ff5a1b9407cae5c97cd8328bd1937a19ce8ac3c25e6262717a27164592eb9e"
|
|
553
553
|
},
|
|
554
554
|
{
|
|
555
555
|
"contractVersion": 1,
|
|
@@ -1001,7 +1001,7 @@
|
|
|
1001
1001
|
"missing receipts are non-qualifying and must not be represented as a successful controller run"
|
|
1002
1002
|
],
|
|
1003
1003
|
"breakingDigest": "sha256:e264a79f9f399038c2fcfd21e4168c68c2e1485ee5c651c02242a02b622ac2be",
|
|
1004
|
-
"auditDigest": "sha256:
|
|
1004
|
+
"auditDigest": "sha256:4dc810c734e3b597297932839d3919219b93c69a985fc1b8ecc91a08299b940e"
|
|
1005
1005
|
},
|
|
1006
1006
|
{
|
|
1007
1007
|
"contractVersion": 1,
|
|
@@ -1520,7 +1520,7 @@
|
|
|
1520
1520
|
"missing receipts are non-qualifying and must not be represented as a successful controller run"
|
|
1521
1521
|
],
|
|
1522
1522
|
"breakingDigest": "sha256:5f1868478b7ccd9fb79aea76bc771289d2ca6bd2dccd1abf57575426f1eae5fb",
|
|
1523
|
-
"auditDigest": "sha256:
|
|
1523
|
+
"auditDigest": "sha256:f478f291726cd47d998c37d454d9fc3e97f1d4a45dc60fe756d8c239fa1245bd"
|
|
1524
1524
|
},
|
|
1525
1525
|
{
|
|
1526
1526
|
"contractVersion": 1,
|
|
@@ -2155,7 +2155,7 @@
|
|
|
2155
2155
|
"missing receipts are non-qualifying and must not be represented as a successful controller run"
|
|
2156
2156
|
],
|
|
2157
2157
|
"breakingDigest": "sha256:0eb318df455ef9cb737a7c2515a2411b685d34ed0bde7b5f5b173a7a42513114",
|
|
2158
|
-
"auditDigest": "sha256:
|
|
2158
|
+
"auditDigest": "sha256:f5f11c5c5d27884e0b93ce99b7dc5d2e58d956a004a0001707a21f0939f3226e"
|
|
2159
2159
|
},
|
|
2160
2160
|
{
|
|
2161
2161
|
"contractVersion": 1,
|
|
@@ -2525,7 +2525,7 @@
|
|
|
2525
2525
|
"missing receipts are non-qualifying and must not be represented as a successful controller run"
|
|
2526
2526
|
],
|
|
2527
2527
|
"breakingDigest": "sha256:46238f8fc3c20924decc57ecad142a462fc4739c6bc21409d5cd2457fc1c3cdd",
|
|
2528
|
-
"auditDigest": "sha256:
|
|
2528
|
+
"auditDigest": "sha256:10c3132362feab7e8e3f612eedc2e62b9b90ff0ed2fcf8445ce75caef55c26d5"
|
|
2529
2529
|
},
|
|
2530
2530
|
{
|
|
2531
2531
|
"contractVersion": 1,
|
|
@@ -2654,5 +2654,5 @@
|
|
|
2654
2654
|
}
|
|
2655
2655
|
],
|
|
2656
2656
|
"compatibilityDigest": "sha256:af162b86ab4506e9b5f1d3c59b41f3fd57fbad79ff4d749a7f12ff16460517f8",
|
|
2657
|
-
"contractDigest": "sha256:
|
|
2657
|
+
"contractDigest": "sha256:9d102ee81f219a5ec4d6dc421e22e3b2b857e706a2ccfbe367636acf59ec9c9f"
|
|
2658
2658
|
}
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-site-bundle",
|
|
4
|
-
"generatedAt": "2026-07-
|
|
5
|
-
"publishedAt": "2026-07-
|
|
4
|
+
"generatedAt": "2026-07-14T23:35:00.122Z",
|
|
5
|
+
"publishedAt": "2026-07-14T23:35:00.122Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "0729934d3442d37667544dd469c43e14ea1cd2f2",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"package": {
|
|
39
39
|
"name": "@kungfu-tech/buildchain",
|
|
40
|
-
"version": "2.12.7-alpha.
|
|
40
|
+
"version": "2.12.7-alpha.5",
|
|
41
41
|
"versionSource": "package.json#version"
|
|
42
42
|
},
|
|
43
43
|
"source": {
|
|
@@ -1031,7 +1031,7 @@
|
|
|
1031
1031
|
],
|
|
1032
1032
|
"maturity": "stable",
|
|
1033
1033
|
"sourcePath": "docs/publication-artifacts.md",
|
|
1034
|
-
"digest": "sha256:
|
|
1034
|
+
"digest": "sha256:24429efd2c39cfcbf3ed2c0f7265cadc44b28fa3e1dab1f115f2b8a7a3d7c028",
|
|
1035
1035
|
"headings": [
|
|
1036
1036
|
{
|
|
1037
1037
|
"level": 1,
|
|
@@ -1064,7 +1064,7 @@
|
|
|
1064
1064
|
"anchor": "site-consumption"
|
|
1065
1065
|
}
|
|
1066
1066
|
],
|
|
1067
|
-
"markdown": "# Publication Artifact Workflow\n\nBuildchain supports `project.type = \"publication-artifact\"` for repositories\nthat produce auditable papers, reports, specifications, or similar publication\npackages. These repositories are artifact producers. They should not be forced\nto become `web-surface` repositories just because a downstream site later\nrenders the paper.\n\nThe split is:\n\n```text\npaper repo = source, PDF, metadata, source bundle, publication manifest\npapers site = layout, navigation, public web surface, downstream rendering\n```\n\n## Configuration\n\nThe paper repository owns `.buildchain/buildchain.toml`:\n\n```toml\nschema = 1\n\n[project]\ntype = \"publication-artifact\"\nname = \"paper-observer-declared-timelines\"\n\n[publication]\nkind = \"paper\"\ntitle = \"Observer-Declared Timelines for Real-World Agent Work\"\nversion = \"0.1.0\"\nprimary_artifact = \"_build/main.pdf\"\nartifact_paths = [\"_build/main.pdf\"]\nmetadata_paths = [\"README.md\", \"docs/MAP.md\"]\nsource_paths = [\"paper\", \"README.md\", \"LICENSE\", \"Makefile\"]\nsite_consumers = [\"papers.libkungfu.dev\"]\nmanifest_path = \".buildchain/publication/publication-artifact.json\"\nsource_bundle_path = \".buildchain/publication/source.tar.gz\"\n\n[publication.archive]\nid = \"observer-declared-timelines\"\ncanonical_url = \"https://papers.libkungfu.dev/observer-declared-timelines/\"\nlatest_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/\"\nlatest_evidence_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/buildchain.release.json\"\nimmutable_base_url = \"https://papers.libkungfu.dev/archive\"\nregistry_path = \".buildchain/publication/publication-registry.json\"\n\n[publication.toolchain]\ntype = \"latex-docker\"\nimage = \"ghcr.io/kungfu-systems/build-images/latex-pdf-builder\"\ndigest = \"sha256:c20f3809e96836c1c78e97c76939d12f1de3fed0ea9b7c40c43332ec2ea480f8\"\ncommand = \"latexmk -pdf -outdir=_build paper/main.tex\"\n\n[publish]\nkind = \"npm-paper-package\"\npackage = \"@kungfu-tech/paper-observer-declared-timelines\"\nauth = \"trusted-publishing\"\n\n[lifecycle.build]\ncommand = \"make pdf\"\n\n[lifecycle.verify]\ncommand = \"make check\"\n```\n\n`primary_artifact` is the human-facing publication output, usually a PDF.\n`source_paths` are archived into a source bundle. `metadata_paths` are hashed\nand recorded so a site can consume the paper facts without scraping prose.\n\n`publication.archive` turns the publication into an append-only public archive\ncontract:\n\n- `canonical_url` is the stable human reader page.\n- `latest_url` and `latest_evidence_url` are movable aliases for the latest\n reader page and latest evidence.\n- `immutable_base_url` plus `id` and `publication.version` produce a versioned\n prefix such as\n `https://papers.libkungfu.dev/archive/observer-declared-timelines/v0.1.0/`.\n- `immutable_url_prefix` can be used instead when the repository already owns\n the full version prefix.\n- `registry_path` records every published version and its manifest, passport,\n source bundle, primary artifact, URLs, and SHA-256 digests.\n\nImmutable archive prefixes are append-only. Do not run site deployment commands\nwith `sync --delete` or equivalent deletion semantics over those prefixes. A\nsame-version republish is allowed only when the immutable digest is unchanged;\nif PDF, source bundle, route, metadata, or toolchain evidence changes for an\nexisting version, Buildchain fails before the registry is rewritten.\n\nThe Buildchain web-surface adapter consumes this boundary from a surface-local\n`manifest.json` whose `archivePolicy.contract` is\n`kungfu-buildchain-publication-archive-policy`. It excludes the derived archive\nroot from every owning or parent `sync --delete`, verifies existing object\ndigests, uploads only missing immutable files with `--no-overwrite`, and verifies\nthem again before mutable site content is synchronized. A current package set\ndoes not need to rebuild or enumerate every historical version: the protected\narchive root remains outside deletion even when older versions disappear from\nthe current artifact.\n\n`publication.toolchain` makes the source-to-PDF transformation part of the\nmachine-readable contract. `latex-docker` is the preferred LaTeX profile. The\nBuildchain paper scaffold and reusable workflow default to\n`ghcr.io/kungfu-systems/build-images/latex-pdf-builder:v1.2.0`, pinned by the\ndigest above. The workflow pulls the declared image by digest and runs the\ndeclared command in that pinned container. `custom-command` remains available\nfor compatibility, but the passport records it as lower trust because\nBuildchain can record the command boundary without proving the compiler or\nLaTeX distribution digest.\n\n`publish.kind = \"npm-paper-package\"` declares that Buildchain, not the consumer\nrepository, owns the standard paper npm package shape and release transaction\nmechanics. `publish.package` is the public npm package that contains the PDF,\npublication manifest, publication passport, optional archive registry, source\nbundle, and declared metadata files.\n\n## Reusable Workflow\n\nConsumer repositories that only need to build and upload paper evidence can\ncall the build-only wrapper directly:\n\n```yaml\njobs:\n publication:\n uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2\n with:\n toolchain-type: config\n verify-command: make check\n artifact-name: observer-declared-timelines\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe build-only workflow:\n\n- resolves the Buildchain runtime and checks the floating contract lock before\n any paper build runs;\n- resolves the declared publication toolchain from `[publication.toolchain]` or\n workflow inputs;\n- for `latex-docker`, pulls the pinned build-images LaTeX builder digest and\n runs the declared command in the container;\n- for `custom-command`, runs the declared command and records the lower-trust\n boundary in the passport;\n- runs the verify command;\n- creates a source bundle from `publication.source_paths`;\n- writes `.buildchain/publication/publication-artifact.json`;\n- writes `.buildchain/publication/publication-artifact-passport.json`;\n- when `[publication.archive]` is configured, writes\n `.buildchain/publication/publication-registry.json` and verifies same-version\n immutability;\n- uploads one GitHub artifact containing the PDF, manifest, passport, optional\n registry, and source bundle.\n\nIt does not publish npm packages, deploy web pages, or create GitHub Releases.\n\nThe paper release preset additionally hydrates every prior published package\nregistry from the npm registry before generating the current manifest. npm\npackage integrity authenticates each downloaded source; Buildchain verifies the\nregistry self-digest, merges immutable records, and fails if a cumulative\nregistry drops an accepted version or changes immutable route/artifact facts.\nThe synthesized package therefore carries complete history even on a clean\nrunner. Its cumulative registry and file SHA-256 values are bound into the paper\nrelease build summary and release passport evidence.\n\n## Paper Release Preset\n\nPaper repositories that publish a versioned npm package should use the\nBuildchain-managed release preset instead of copying npm transaction scripts or\npromotion YAML:\n\n```yaml\nname: Paper Release\n\non:\n push:\n branches:\n - alpha/v1/v1.0\n - release/v1/v1.0\n workflow_dispatch:\n inputs:\n buildchain-ref:\n description: \"Temporary Buildchain runtime ref\"\n required: false\n default: \"\"\n\njobs:\n paper-release:\n uses: kungfu-systems/buildchain/.github/workflows/paper-release.yml@v2\n permissions:\n checks: write\n contents: write\n id-token: write\n issues: write\n with:\n buildchain-ref: ${{ inputs.buildchain-ref || '' }}\n publication-admission-json: ${{ needs.authority.outputs.admission-json }}\n publication-runner-provenance-json: ${{ needs.authority.outputs.runner-provenance-json }}\n publication-control-plane-audit-json: ${{ needs.authority.outputs.control-plane-audit-json }}\n publication-expected-json: ${{ needs.authority.outputs.expected-json }}\n toolchain-type: config\n verify-command: make check\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe publication job does not accept a long-lived promotion token. The caller\nmust first produce a fresh sealed admission, runner provenance, external\ncontrol-plane audit, and exact expected bindings. The credential-free verifier\njob checks those receipts; only then can the publication job use its short-lived\n`github.token` and caller-bound OIDC trusted publisher identity. npm binds that\nidentity to the consumer workflow filename; an npm Environment restriction is\noptional and must be represented explicitly when configured. The workflow fails\nbefore the publication build when the target branch protection cannot be read.\n\nThe preset:\n\n- resolves the same floating Buildchain runtime and contract lock as the build\n workflow;\n- verifies that the declared promotion authority can read the protected target\n channel before starting the publication build;\n- builds the PDF through the declared pinned LaTeX Docker toolchain or custom\n command;\n- verifies the paper repository;\n- writes the publication manifest, publication passport, optional archive\n registry, and source bundle;\n- synthesizes an npm package from `[publication]` and `[publish]` declarations\n under `.buildchain/publication/npm-package`;\n- computes npm-style `sha512` integrity from `npm pack --dry-run` and passes\n it as `publish-required-artifacts-json`;\n- creates a `publish-gate/<alpha|release>/.../<version>` source lock for the\n channel commit and requires `promote-buildchain-ref` to verify that lock\n before any publish side effect;\n- publishes the package through npm Trusted Publishing;\n- writes Buildchain release/passport evidence; and\n- creates or updates the exact-version GitHub Release by default.\n\nConsumers can opt out of the GitHub Release with `github-release: false`, but\nthe default is on so downstream release propagation can observe\n`release.published` without hand-written `gh release` steps.\n\nFor npm Trusted Publishing, register the consumer workflow file that calls this\npreset, for example `.github/workflows/paper-release.yml`, against the declared\npackage in npm. The trusted publisher is the consumer repository and workflow\nfile; the implementation still runs inside Buildchain's reusable workflow.\n\nStandard paper repositories should not carry local copies of\n`scripts/npm-publish-transaction.mjs`, package-generation scripts, or\npromotion/ref-lock YAML. If the default package shape is insufficient, extend\nBuildchain rather than forking the mechanics into each paper repository.\n\n## CLI And Node API\n\nGenerate the publication manifest locally or in CI:\n\n```sh\nbuildchain publication-artifact manifest --source-sha \"$(git rev-parse HEAD)\" --json\n```\n\nGenerate the npm package contents after the manifest exists:\n\n```sh\nbuildchain publication-artifact npm-package --json\n```\n\nNode API:\n\n```js\nimport {\n collectPublicationArtifact,\n writePublicationArtifact,\n} from \"@kungfu-tech/buildchain/publication-artifact\";\n\nimport {\n collectPublicationPackageFacts,\n preparePublicationNpmPackage,\n} from \"@kungfu-tech/buildchain/publication-package\";\n```\n\n`writePublicationArtifact()` is the single implementation used by the CLI and\nthe reusable workflow. The generated manifest records:\n\n- publication title, kind, authors, and primary artifact;\n- artifact paths, byte sizes, and SHA-256 digests;\n- metadata paths and SHA-256 digests;\n- source SHA, tree SHA, source files, and source bundle digest;\n- publication toolchain type, image, digest, command, invocation mode, and trust\n classification;\n- timestamp and reproducibility policy;\n- downstream site-consumption hints;\n- optional archive routes for canonical, latest, latest evidence, immutable\n version prefix, and public artifact URLs.\n\nThe companion publication artifact passport records the same source and\nartifact evidence plus an explicit responsibility split. Buildchain proves\ndeclared files and hashes; it does not peer-review paper claims.\n\nWhen archive config is present, the registry uses the\n`kungfu-buildchain-publication-artifact-registry` contract. A site repository\ncan render latest pages and historical version indexes from that registry\nwithout rebuilding old PDFs from the latest npm package or paper source.\n\n## Site Consumption\n\nA downstream papers site should treat the publication manifest as the single\nfact source for the artifact. The site owns rendering and navigation; it should\nnot reinterpret the paper repository as a web deployment source.\nFor registry-level routing, sites should first consume the package-owned\nBuildchain fact source:\n\n```text\nnode_modules/@kungfu-tech/buildchain/dist/site/publication-registry.json\n```\n\nor the equivalent package export:\n\n```js\nimport registry from \"@kungfu-tech/buildchain/site/publication-registry.json\" with { type: \"json\" };\n```\n\nThat registry uses the `kungfu-buildchain-publication-release-registry`\ncontract. It separates mutable canonical/latest reader routes from immutable\nversion prefixes, publication artifacts, source bundles, and passport evidence\nso site repositories can render `/papers/**` without maintaining a parallel\nfixture truth source.\n\nFor `paper-observer-declared-timelines`, the expected adoption path is:\n\n```text\npaper repo builds PDF + manifest + source bundle\npaper repo updates publication-registry.json\npapers site consumes publication-artifact.json\npapers site consumes publication-registry.json for history\nsite renders paper page and links the PDF/source bundle\n```\n\nThis mirrors web-surface governance without mixing producer and renderer\nresponsibilities."
|
|
1067
|
+
"markdown": "# Publication Artifact Workflow\n\nBuildchain supports `project.type = \"publication-artifact\"` for repositories\nthat produce auditable papers, reports, specifications, or similar publication\npackages. These repositories are artifact producers. They should not be forced\nto become `web-surface` repositories just because a downstream site later\nrenders the paper.\n\nThe split is:\n\n```text\npaper repo = source, PDF, metadata, source bundle, publication manifest\npapers site = layout, navigation, public web surface, downstream rendering\n```\n\n## Configuration\n\nThe paper repository owns `.buildchain/buildchain.toml`:\n\n```toml\nschema = 1\n\n[project]\ntype = \"publication-artifact\"\nname = \"paper-observer-declared-timelines\"\n\n[publication]\nkind = \"paper\"\ntitle = \"Observer-Declared Timelines for Real-World Agent Work\"\nversion = \"0.1.0\"\nprimary_artifact = \"_build/main.pdf\"\nartifact_paths = [\"_build/main.pdf\"]\nmetadata_paths = [\"README.md\", \"docs/MAP.md\"]\nsource_paths = [\"paper\", \"README.md\", \"LICENSE\", \"Makefile\"]\nsite_consumers = [\"papers.libkungfu.dev\"]\nmanifest_path = \".buildchain/publication/publication-artifact.json\"\nsource_bundle_path = \".buildchain/publication/source.tar.gz\"\n\n[publication.archive]\nid = \"observer-declared-timelines\"\ncanonical_url = \"https://papers.libkungfu.dev/observer-declared-timelines/\"\nlatest_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/\"\nlatest_evidence_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/buildchain.release.json\"\nimmutable_base_url = \"https://papers.libkungfu.dev/archive\"\nregistry_path = \".buildchain/publication/publication-registry.json\"\n\n[publication.toolchain]\ntype = \"latex-docker\"\nimage = \"ghcr.io/kungfu-systems/build-images/latex-pdf-builder\"\ndigest = \"sha256:c20f3809e96836c1c78e97c76939d12f1de3fed0ea9b7c40c43332ec2ea480f8\"\ncommand = \"latexmk -pdf -outdir=_build paper/main.tex\"\n\n[publish]\nkind = \"npm-paper-package\"\npackage = \"@kungfu-tech/paper-observer-declared-timelines\"\nauth = \"trusted-publishing\"\n\n[lifecycle.build]\ncommand = \"make pdf\"\n\n[lifecycle.verify]\ncommand = \"make check\"\n```\n\n`primary_artifact` is the human-facing publication output, usually a PDF.\n`source_paths` are archived into a source bundle. `metadata_paths` are hashed\nand recorded so a site can consume the paper facts without scraping prose.\n\n`publication.archive` turns the publication into an append-only public archive\ncontract:\n\n- `canonical_url` is the stable human reader page.\n- `latest_url` and `latest_evidence_url` are movable aliases for the latest\n reader page and latest evidence.\n- `immutable_base_url` plus `id` and `publication.version` produce a versioned\n prefix such as\n `https://papers.libkungfu.dev/archive/observer-declared-timelines/v0.1.0/`.\n- `immutable_url_prefix` can be used instead when the repository already owns\n the full version prefix.\n- `registry_path` records every published version and its manifest, passport,\n source bundle, primary artifact, URLs, and SHA-256 digests.\n\nImmutable archive prefixes are append-only. Do not run site deployment commands\nwith `sync --delete` or equivalent deletion semantics over those prefixes. A\nsame-version republish is allowed only when the immutable digest is unchanged;\nif PDF, source bundle, route, metadata, or toolchain evidence changes for an\nexisting version, Buildchain fails before the registry is rewritten.\n\nThe Buildchain web-surface adapter consumes this boundary from a surface-local\n`manifest.json` whose `archivePolicy.contract` is\n`kungfu-buildchain-publication-archive-policy`. It excludes the derived archive\nroot from every owning or parent `sync --delete`, verifies existing object\ndigests, uploads only missing immutable files with `--no-overwrite`, and verifies\nthem again before mutable site content is synchronized. A current package set\ndoes not need to rebuild or enumerate every historical version: the protected\narchive root remains outside deletion even when older versions disappear from\nthe current artifact.\n\n`publication.toolchain` makes the source-to-PDF transformation part of the\nmachine-readable contract. `latex-docker` is the preferred LaTeX profile. The\nBuildchain paper scaffold and reusable workflow default to\n`ghcr.io/kungfu-systems/build-images/latex-pdf-builder:v1.2.0`, pinned by the\ndigest above. The workflow pulls the declared image by digest and runs the\ndeclared command in that pinned container. `custom-command` remains available\nfor compatibility, but the passport records it as lower trust because\nBuildchain can record the command boundary without proving the compiler or\nLaTeX distribution digest.\n\n`publish.kind = \"npm-paper-package\"` declares that Buildchain, not the consumer\nrepository, owns the standard paper npm package shape and release transaction\nmechanics. `publish.package` is the public npm package that contains the PDF,\npublication manifest, publication passport, optional archive registry, source\nbundle, and declared metadata files.\n\n## Reusable Workflow\n\nConsumer repositories that only need to build and upload paper evidence can\ncall the build-only wrapper directly:\n\n```yaml\njobs:\n publication:\n uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2\n with:\n toolchain-type: config\n verify-command: make check\n artifact-name: observer-declared-timelines\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe build-only workflow:\n\n- resolves the Buildchain runtime and checks the floating contract lock before\n any paper build runs;\n- resolves the declared publication toolchain from `[publication.toolchain]` or\n workflow inputs;\n- for `latex-docker`, pulls the pinned build-images LaTeX builder digest and\n runs the declared command in the container;\n- for `custom-command`, runs the declared command and records the lower-trust\n boundary in the passport;\n- runs the verify command;\n- creates a source bundle from `publication.source_paths`;\n- writes `.buildchain/publication/publication-artifact.json`;\n- writes `.buildchain/publication/publication-artifact-passport.json`;\n- when `[publication.archive]` is configured, writes\n `.buildchain/publication/publication-registry.json` and verifies same-version\n immutability;\n- uploads one GitHub artifact containing the PDF, manifest, passport, optional\n registry, and source bundle.\n\nIt does not publish npm packages, deploy web pages, or create GitHub Releases.\n\nThe paper release preset additionally hydrates every prior published package\nregistry from the npm registry before generating the current manifest. npm\npackage integrity authenticates each downloaded source; Buildchain verifies the\nregistry self-digest, merges immutable records, and fails if a cumulative\nregistry drops an accepted version or changes immutable route/artifact facts.\nThe synthesized package therefore carries complete history even on a clean\nrunner. Its cumulative registry and file SHA-256 values are bound into the paper\nrelease build summary and release passport evidence.\n\n## Paper Release Preset\n\nPaper repositories that publish a versioned npm package should use the\nBuildchain-managed release preset instead of copying npm transaction scripts or\npromotion YAML:\n\n```yaml\nname: Paper Release\n\non:\n push:\n branches:\n - alpha/v1/v1.0\n - release/v1/v1.0\n workflow_dispatch:\n inputs:\n buildchain-ref:\n description: \"Temporary Buildchain runtime ref\"\n required: false\n default: \"\"\n\njobs:\n paper-release:\n uses: kungfu-systems/buildchain/.github/workflows/paper-release.yml@v2\n permissions:\n checks: write\n contents: write\n id-token: write\n issues: write\n with:\n buildchain-ref: ${{ inputs.buildchain-ref || '' }}\n publication-admission-json: ${{ needs.authority.outputs.admission-json }}\n publication-runner-provenance-json: ${{ needs.authority.outputs.runner-provenance-json }}\n publication-control-plane-audit-json: ${{ needs.authority.outputs.control-plane-audit-json }}\n publication-expected-json: ${{ needs.authority.outputs.expected-json }}\n toolchain-type: config\n verify-command: make check\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe publication job does not accept a long-lived promotion token. The caller\nmust first produce a fresh sealed admission, runner provenance, external\ncontrol-plane audit, and exact expected bindings. The credential-free verifier\njob checks those receipts; only then can the publication job use its short-lived\n`github.token` and caller-bound OIDC trusted publisher identity. npm binds that\nidentity to the consumer workflow filename; an npm Environment restriction is\noptional and must be represented explicitly when configured. The workflow fails\nbefore the publication build when the target branch protection cannot be read.\n\nThe preset:\n\n- resolves the same floating Buildchain runtime and contract lock as the build\n workflow;\n- verifies that the declared promotion authority can read the protected target\n channel before starting the publication build;\n- builds the PDF through the declared pinned LaTeX Docker toolchain or custom\n command;\n- verifies the paper repository;\n- writes the publication manifest, publication passport, optional archive\n registry, and source bundle;\n- synthesizes an npm package from `[publication]` and `[publish]` declarations\n under `.buildchain/publication/npm-package`;\n- computes npm-style `sha512` integrity from `npm pack --dry-run` and passes\n it as `publish-required-artifacts-json`;\n- creates a `publish-gate/<alpha|release>/.../<version>` source lock for the\n channel commit and requires `promote-buildchain-ref` to verify that lock\n before any publish side effect;\n- publishes the package through npm Trusted Publishing;\n- writes Buildchain release/passport evidence; and\n- creates or updates the exact-version GitHub Release by default, uploading\n every file declared by `publication.primary_artifact` and\n `publication.artifact_paths` alongside the release evidence.\n\nConsumers can opt out of the GitHub Release with `github-release: false`, but\nthe default is on so downstream release propagation can observe\n`release.published` without hand-written `gh release` steps.\n\nDeclared publication artifacts are resolved from the generated publication\nmanifest rather than repeated in consumer workflow YAML. Publication fails\nbefore upload if a declared artifact is missing or if its basename would\ncollide with another GitHub Release asset.\n\nFor npm Trusted Publishing, register the consumer workflow file that calls this\npreset, for example `.github/workflows/paper-release.yml`, against the declared\npackage in npm. The trusted publisher is the consumer repository and workflow\nfile; the implementation still runs inside Buildchain's reusable workflow.\n\nStandard paper repositories should not carry local copies of\n`scripts/npm-publish-transaction.mjs`, package-generation scripts, or\npromotion/ref-lock YAML. If the default package shape is insufficient, extend\nBuildchain rather than forking the mechanics into each paper repository.\n\n## CLI And Node API\n\nGenerate the publication manifest locally or in CI:\n\n```sh\nbuildchain publication-artifact manifest --source-sha \"$(git rev-parse HEAD)\" --json\n```\n\nGenerate the npm package contents after the manifest exists:\n\n```sh\nbuildchain publication-artifact npm-package --json\n```\n\nNode API:\n\n```js\nimport {\n collectPublicationArtifact,\n writePublicationArtifact,\n} from \"@kungfu-tech/buildchain/publication-artifact\";\n\nimport {\n collectPublicationPackageFacts,\n preparePublicationNpmPackage,\n} from \"@kungfu-tech/buildchain/publication-package\";\n```\n\n`writePublicationArtifact()` is the single implementation used by the CLI and\nthe reusable workflow. The generated manifest records:\n\n- publication title, kind, authors, and primary artifact;\n- artifact paths, byte sizes, and SHA-256 digests;\n- metadata paths and SHA-256 digests;\n- source SHA, tree SHA, source files, and source bundle digest;\n- publication toolchain type, image, digest, command, invocation mode, and trust\n classification;\n- timestamp and reproducibility policy;\n- downstream site-consumption hints;\n- optional archive routes for canonical, latest, latest evidence, immutable\n version prefix, and public artifact URLs.\n\nThe companion publication artifact passport records the same source and\nartifact evidence plus an explicit responsibility split. Buildchain proves\ndeclared files and hashes; it does not peer-review paper claims.\n\nWhen archive config is present, the registry uses the\n`kungfu-buildchain-publication-artifact-registry` contract. A site repository\ncan render latest pages and historical version indexes from that registry\nwithout rebuilding old PDFs from the latest npm package or paper source.\n\n## Site Consumption\n\nA downstream papers site should treat the publication manifest as the single\nfact source for the artifact. The site owns rendering and navigation; it should\nnot reinterpret the paper repository as a web deployment source.\nFor registry-level routing, sites should first consume the package-owned\nBuildchain fact source:\n\n```text\nnode_modules/@kungfu-tech/buildchain/dist/site/publication-registry.json\n```\n\nor the equivalent package export:\n\n```js\nimport registry from \"@kungfu-tech/buildchain/site/publication-registry.json\" with { type: \"json\" };\n```\n\nThat registry uses the `kungfu-buildchain-publication-release-registry`\ncontract. It separates mutable canonical/latest reader routes from immutable\nversion prefixes, publication artifacts, source bundles, and passport evidence\nso site repositories can render `/papers/**` without maintaining a parallel\nfixture truth source.\n\nFor `paper-observer-declared-timelines`, the expected adoption path is:\n\n```text\npaper repo builds PDF + manifest + source bundle\npaper repo updates publication-registry.json\npapers site consumes publication-artifact.json\npapers site consumes publication-registry.json for history\nsite renders paper page and links the PDF/source bundle\n```\n\nThis mirrors web-surface governance without mixing producer and renderer\nresponsibilities."
|
|
1068
1068
|
},
|
|
1069
1069
|
{
|
|
1070
1070
|
"id": "manual:publication-authority",
|
|
@@ -1078,7 +1078,7 @@
|
|
|
1078
1078
|
],
|
|
1079
1079
|
"maturity": "preview",
|
|
1080
1080
|
"sourcePath": "docs/publication-authority.md",
|
|
1081
|
-
"digest": "sha256:
|
|
1081
|
+
"digest": "sha256:06ba05f9d8a2685a0896334b6013a97c45b7d71163cf6898e5a6274baf7f0296",
|
|
1082
1082
|
"headings": [
|
|
1083
1083
|
{
|
|
1084
1084
|
"level": 1,
|
|
@@ -1111,7 +1111,7 @@
|
|
|
1111
1111
|
"anchor": "publication-lanes"
|
|
1112
1112
|
}
|
|
1113
1113
|
],
|
|
1114
|
-
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: sealed-publication-authority\ndoc_type: protocol\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-07-14\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-14\n limits: Live provider configuration must be re-audited; no credential values are represented.\n---\n\n# Sealed Publication Authority\n\nBuildchain publication authority is a closed-world, fail-closed protocol. It does\nnot mint registry or cloud credentials. It independently verifies whether an\nalready protected publication job is allowed to request a short-lived provider\ncredential for one exact product, target, version, channel, and artifact digest.\n\nThe machine-readable authority inventory is\n`dist/site/publication-authority-registry.json`. Any workflow with a write,\nenvironment, OIDC, cloud credential, registry publish, release, or Git push\nsignal must have an explicit descriptor. A new authority-bearing workflow that\nis absent from the inventory fails site generation. Unknown workflows and every\ndescriptor not marked `product-publication` are denied product publication.\n\n## Evidence chain\n\nA qualifying admission binds exact source and runtime SHAs; contract, consumer\npolicy, qualifying controller receipt, Shifu/Gate aggregate, artifact, runner,\nand control-plane digests; repository, authority workflow, provider publisher\nworkflow, Environment policy,\nproduct, target, version, and channel; plus a unique nonce and a lifetime of no\nmore than 15 minutes. Every expected binding is mandatory at verification time;\nan omitted expected field is not a wildcard.\n\nThe independent verifier recomputes every digest and ignores a producer's own\nallow/deny conclusion. It fetches the exact evidence run, validates the actual\nrelease-candidate passport and referenced qualifying controller receipt,\nrecomputes the Shifu Gate aggregate or explicit consumer-owned no-Gate policy,\nrecomputes the downloaded artifact manifests, and hashes every declared product\npayload file against those manifests. The `.buildchain/` diagnostics envelope is\nbound by the manifest digest but excluded from the product-byte set because it can\nbe finalized after the lifecycle scan. The verifier also compares the PR evidence tree to the\nadmitted post-merge source commit tree. It rejects an unknown\nworkflow, stale or replayed nonce, runner downgrade, control-plane drift,\nsource/runtime mismatch, and artifact substitution. A successful result is a\nscoped capability receipt, not a bearer credential.\n\n## Runner and control-plane evidence\n\nRunner evidence uses exactly four classes: `ephemeral`, `reimaged`,\n`persistent-measured`, and `unqualified`. Ephemeral runners also record their\njob-isolation boundary. Reimaged and persistent runners qualify only when a\nclean baseline is proven and baseline, toolchain, cache-contract, and task-\nisolation digests are all present. Otherwise they still emit diagnostic\nevidence with `qualificationStatus = unqualified`, but cannot receive a product\ncapability.\n\nThe external audit records digests and pass/fail status for repository Actions\ndefaults, classic branch protection or an active matching repository ruleset,\ndeclared protected Environment policy or an explicit no-Environment binding,\njob-scoped credentials,\nabsence of long-lived workflow publication credentials, provider authority,\nand authorized runner class. Provider modes are `npm-trusted-publisher`,\n`github-token`, and `oidc-role`. The OIDC-role mode consumes only a sanitized\nprovider audit containing a role digest and qualifying decision; raw IAM policy,\ntokens, or credentials are rejected. Package-owner, cloud-root, GitHub\nadministrator, and registry-root credentials remain outside Buildchain's trust\nboundary. Missing or unreadable facts fail closed.\n\nAn unauthenticated local npm CLI is not evidence that Trusted Publishing is\nmissing. `npm whoami` reports only the local CLI session and does not report the\nOIDC identity that npm creates during `npm publish`. The default read-only audit\ntherefore binds the exact provider, repository, caller workflow, optional\nEnvironment, job-scoped OIDC permission, and absence of long-lived credentials,\nthen records `provider-at-transaction`: npm makes the final authorization\ndecision when `npm publish` exchanges the job's OIDC token. A missing or drifted\ntrusted-publisher configuration consequently denies the transaction safely; it\nis not preflighted through an unrelated long-lived npm login.\n\nAn authenticated external auditor can add stronger point-in-time evidence by\nsupplying sanitized `npm trust list --json` output with `--npm-trust-json`. This\nchanges the publisher fact to `audited-control-plane`; the workflow never runs\n`npm trust list` itself and never receives that auditor's npm credential.\n\nThe credential-free collector proves effective Actions and runner scope from\nthe publication workflow fetched at `--workflow-ref`: explicit read-only\nworkflow defaults, job-scoped write/OIDC permissions, and an exact GitHub-hosted\nrunner label. It does not call repository Actions-default or self-hosted-runner\nadministration endpoints. Branch/ruleset and OIDC subject facts remain live\nread-only provider queries. When the detailed branch-protection endpoint is not\nreadable with the workflow token, `--source-sha` binds the provider's public\nprotected-branch summary to the exact merged PR, independent approval, required\nsuccessful check, same-repository lineage, and current branch head. This records\nprovider-enforced transaction evidence without treating an unavailable\nadministration endpoint as an unprotected branch. It avoids turning a\nrepository-admin token into a publication prerequisite.\n\nFor non-dry-run workflows, missing admission, runner, control-plane, Gate, or\nexpected-binding evidence is rejected before Buildchain downloads candidate\nartifacts. The denial explicitly records that npm Trusted Publishing and OIDC\nwere not evaluated, so downstream diagnostics cannot misclassify an admission\nassembly failure as an npm authentication failure.\n\nBuildchain's own `workflow_run` promotion lane may assemble those inputs only\nfor `kungfu-systems/buildchain`. It downloads the exact prior RC passport,\nsummary, referenced controller receipt, manifests, and product payloads; proves\nthe admitted channel commit has the same Git tree as the RC; performs the live\nread-only control-plane audit; records the GitHub-hosted job as ephemeral runner\nprovenance; and creates an explicit Buildchain-owned no-Gate decision. The\nindependent verifier then recomputes every receipt and payload digest exactly as\nit does for externally supplied admission. The self-assembly mode rejects other\nrepositories, unknown refs, non-exact source SHAs, and any caller other than\n`.github/workflows/buildchain-ref-promotion.yml`. Manual apply and external\nconsumer workflows still require their own explicit admission inputs.\n\nEvidence publication is a separate authority class and never grants product\npublication.\n\n## API and CLI\n\nUse `@kungfu-tech/buildchain/publication-authority` or run:\n\n```bash\nbuildchain verify publication-admission admission.json \\\n --registry-json publication-authority-registry.json \\\n --runner-json runner.json \\\n --control-plane-audit-json control-plane.json \\\n --publication-evidence-json publication-evidence.json \\\n --expected-json expected.json \\\n --used-nonce previous-run-nonce \\\n --json\n```\n\nThe read-only live collector defaults to npm trusted publishing. Other product\nproviders select an explicit adapter:\n\n```bash\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch dev/v2/v2.12 \\\n --source-sha <exact-merged-branch-sha> \\\n --workflow .github/workflows/release-candidate-promote.yml \\\n --workflow-ref <exact-buildchain-sha> \\\n --publisher-workflow .github/workflows/buildchain-ref-promotion.yml \\\n --job promote \\\n --environment none\n\n# Optional stronger external evidence; generate the JSON outside the workflow.\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch dev/v2/v2.12 \\\n --workflow .github/workflows/release-candidate-promote.yml \\\n --publisher-workflow .github/workflows/buildchain-ref-promotion.yml \\\n --job promote \\\n --environment none \\\n --npm-trust-json sanitized-npm-trust.json\n\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch release/v2/v2.12 \\\n --workflow .github/workflows/.binary-release-assets.yml \\\n --job publish \\\n --environment buildchain-release-assets \\\n --publisher-mode github-token\n\nbuildchain audit publication-control-plane \\\n --repository OWNER/CONSUMER \\\n --workflow-repository kungfu-systems/buildchain \\\n --branch main \\\n --workflow .github/workflows/.web-surface.yml \\\n --job production-apply \\\n --environment production \\\n --publisher-mode oidc-role \\\n --provider-audit-json sanitized-oidc-role-audit.json\n```\n\nThe authority workflow identifies the reusable implementation that performs the\npublication job. The publisher workflow identifies the caller filename bound by\nthe provider's trusted-publisher policy; these identities are deliberately\nseparate. `--environment none` is an explicit assertion that the job declares no\nGitHub Environment and the provider policy has no Environment restriction. A\nnamed Environment must exist, be protected, and be declared by the job. The\nBuildchain receipt alone is never sufficient authorization.\n\n## Publication lanes\n\n`Binary Distribution` is evidence-only. It builds platform archives and a\nrelease evidence bundle with read-only repository permissions. GitHub Release\nasset writes live in `Binary Release Assets`, which downloads an exact prior\nevidence run, verifies its bundle digest against the sealed capability, and is\nthe only binary job with `contents: write` in the protected\n`buildchain-release-assets` Environment.\n\nThe npm/promotion, paper, binary-release, and web-production lanes all depend on\nthe independent verifier. Preview, staging, build, source-check, controller,\nand failure-evidence lanes do not inherit product publication capability."
|
|
1114
|
+
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: sealed-publication-authority\ndoc_type: protocol\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-07-15\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-15\n limits: Live provider configuration must be re-audited; no credential values are represented.\n---\n\n# Sealed Publication Authority\n\nBuildchain publication authority is a closed-world, fail-closed protocol. It does\nnot mint registry or cloud credentials. It independently verifies whether an\nalready protected publication job is allowed to request a short-lived provider\ncredential for one exact product, target, version, channel, and artifact digest.\n\nThe machine-readable authority inventory is\n`dist/site/publication-authority-registry.json`. Any workflow with a write,\nenvironment, OIDC, cloud credential, registry publish, release, or Git push\nsignal must have an explicit descriptor. A new authority-bearing workflow that\nis absent from the inventory fails site generation. Unknown workflows and every\ndescriptor not marked `product-publication` are denied product publication.\n\n## Evidence chain\n\nA qualifying admission binds exact source and runtime SHAs; contract, consumer\npolicy, qualifying controller receipt, Shifu/Gate aggregate, artifact, runner,\nand control-plane digests; repository, authority workflow, provider publisher\nworkflow, Environment policy,\nproduct, target, version, and channel; plus a unique nonce and a lifetime of no\nmore than 15 minutes. Every expected binding is mandatory at verification time;\nan omitted expected field is not a wildcard.\n\nThe independent verifier recomputes every digest and ignores a producer's own\nallow/deny conclusion. It fetches the exact evidence run, validates the actual\nrelease-candidate passport and referenced qualifying controller receipt,\nrecomputes the Shifu Gate aggregate or explicit consumer-owned no-Gate policy,\nrecomputes the downloaded artifact manifests, and hashes every declared product\npayload file against those manifests. The `.buildchain/` diagnostics envelope is\nbound by the manifest digest but excluded from the product-byte set because it can\nbe finalized after the lifecycle scan. The verifier also compares the PR evidence tree to the\nadmitted post-merge source commit tree. It rejects an unknown\nworkflow, stale or replayed nonce, runner downgrade, control-plane drift,\nsource/runtime mismatch, and artifact substitution. A successful result is a\nscoped capability receipt, not a bearer credential.\n\n## Runner and control-plane evidence\n\nRunner evidence uses exactly four classes: `ephemeral`, `reimaged`,\n`persistent-measured`, and `unqualified`. Ephemeral runners also record their\njob-isolation boundary. Reimaged and persistent runners qualify only when a\nclean baseline is proven and baseline, toolchain, cache-contract, and task-\nisolation digests are all present. Otherwise they still emit diagnostic\nevidence with `qualificationStatus = unqualified`, but cannot receive a product\ncapability.\n\nThe external audit records digests and pass/fail status for repository Actions\ndefaults, classic branch protection or an active matching repository ruleset,\ndeclared protected Environment policy or an explicit no-Environment binding,\njob-scoped credentials,\nabsence of long-lived workflow publication credentials, provider authority,\nand authorized runner class. Provider modes are `npm-trusted-publisher`,\n`github-token`, and `oidc-role`. The OIDC-role mode consumes only a sanitized\nprovider audit containing a role digest and qualifying decision; raw IAM policy,\ntokens, or credentials are rejected. Package-owner, cloud-root, GitHub\nadministrator, and registry-root credentials remain outside Buildchain's trust\nboundary. Missing or unreadable facts fail closed.\n\nAn unauthenticated local npm CLI is not evidence that Trusted Publishing is\nmissing. `npm whoami` reports only the local CLI session and does not report the\nOIDC identity that npm creates during `npm publish`. The default read-only audit\ntherefore binds the exact provider, repository, caller workflow, optional\nEnvironment, job-scoped OIDC permission, and absence of long-lived credentials,\nthen records `provider-at-transaction`: npm makes the final authorization\ndecision when `npm publish` exchanges the job's OIDC token. A missing or drifted\ntrusted-publisher configuration consequently denies the transaction safely; it\nis not preflighted through an unrelated long-lived npm login.\n\nAn authenticated external auditor can add stronger point-in-time evidence by\nsupplying sanitized `npm trust list --json` output with `--npm-trust-json`. This\nchanges the publisher fact to `audited-control-plane`; the workflow never runs\n`npm trust list` itself and never receives that auditor's npm credential.\n\nThe credential-free collector proves effective Actions and runner scope from\nthe publication workflow fetched at `--workflow-ref`: explicit read-only\nworkflow defaults, job-scoped write/OIDC permissions, and an exact GitHub-hosted\nrunner label. It does not call repository Actions-default or self-hosted-runner\nadministration endpoints. Branch/ruleset and OIDC subject facts remain live\nread-only provider queries. When the detailed branch-protection endpoint is not\nreadable with the workflow token, `--source-sha` binds the provider's public\nprotected-branch summary to the exact merged PR, independent approval, required\nsuccessful check, same-repository lineage, and current branch head. This records\nprovider-enforced transaction evidence without treating an unavailable\nadministration endpoint as an unprotected branch. It avoids turning a\nrepository-admin token into a publication prerequisite.\n\nFor non-dry-run workflows, missing admission, runner, control-plane, Gate, or\nexpected-binding evidence is rejected before Buildchain downloads candidate\nartifacts. The denial explicitly records that npm Trusted Publishing and OIDC\nwere not evaluated, so downstream diagnostics cannot misclassify an admission\nassembly failure as an npm authentication failure.\n\nBuildchain's own `workflow_run` promotion lane may assemble those inputs only\nfor `kungfu-systems/buildchain`. It downloads the exact prior RC passport,\nsummary, referenced controller receipt, manifests, and product payloads; proves\nthe admitted channel commit has the same Git tree as the RC; performs the live\nread-only control-plane audit; records the GitHub-hosted job as ephemeral runner\nprovenance; and creates an explicit Buildchain-owned no-Gate decision. The\nindependent verifier then recomputes every receipt and payload digest exactly as\nit does for externally supplied admission. The self-assembly mode rejects other\nrepositories, unknown refs, non-exact source SHAs, and any caller other than\n`.github/workflows/buildchain-ref-promotion.yml`. Manual apply and external\nconsumer workflows still require their own explicit admission inputs.\n\nBefore authority verification, the reusable promotion controller runs the same\nrelease transaction selector in read-only mode. That plan supplies one exact\npublication version and tag to the admission verifier, the publish-gate source\nlock, and the real promotion action. The verifier rejects a capability for a\ndifferent version, and the promotion action rechecks the planned version before\nany publish transaction side effect. Release-candidate fixture versions are\nartifact evidence only; they never name Buildchain's own source-lock or\npublication capability.\n\nEvidence publication is a separate authority class and never grants product\npublication.\n\n## API and CLI\n\nUse `@kungfu-tech/buildchain/publication-authority` or run:\n\n```bash\nbuildchain verify publication-admission admission.json \\\n --registry-json publication-authority-registry.json \\\n --runner-json runner.json \\\n --control-plane-audit-json control-plane.json \\\n --publication-evidence-json publication-evidence.json \\\n --expected-json expected.json \\\n --used-nonce previous-run-nonce \\\n --json\n```\n\nThe read-only live collector defaults to npm trusted publishing. Other product\nproviders select an explicit adapter:\n\n```bash\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch dev/v2/v2.12 \\\n --source-sha <exact-merged-branch-sha> \\\n --workflow .github/workflows/release-candidate-promote.yml \\\n --workflow-ref <exact-buildchain-sha> \\\n --publisher-workflow .github/workflows/buildchain-ref-promotion.yml \\\n --job promote \\\n --environment none\n\n# Optional stronger external evidence; generate the JSON outside the workflow.\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch dev/v2/v2.12 \\\n --workflow .github/workflows/release-candidate-promote.yml \\\n --publisher-workflow .github/workflows/buildchain-ref-promotion.yml \\\n --job promote \\\n --environment none \\\n --npm-trust-json sanitized-npm-trust.json\n\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch release/v2/v2.12 \\\n --workflow .github/workflows/.binary-release-assets.yml \\\n --job publish \\\n --environment buildchain-release-assets \\\n --publisher-mode github-token\n\nbuildchain audit publication-control-plane \\\n --repository OWNER/CONSUMER \\\n --workflow-repository kungfu-systems/buildchain \\\n --branch main \\\n --workflow .github/workflows/.web-surface.yml \\\n --job production-apply \\\n --environment production \\\n --publisher-mode oidc-role \\\n --provider-audit-json sanitized-oidc-role-audit.json\n```\n\nThe authority workflow identifies the reusable implementation that performs the\npublication job. The publisher workflow identifies the caller filename bound by\nthe provider's trusted-publisher policy; these identities are deliberately\nseparate. `--environment none` is an explicit assertion that the job declares no\nGitHub Environment and the provider policy has no Environment restriction. A\nnamed Environment must exist, be protected, and be declared by the job. The\nBuildchain receipt alone is never sufficient authorization.\n\n## Publication lanes\n\n`Binary Distribution` is evidence-only. It builds platform archives and a\nrelease evidence bundle with read-only repository permissions. GitHub Release\nasset writes live in `Binary Release Assets`, which downloads an exact prior\nevidence run, verifies its bundle digest against the sealed capability, and is\nthe only binary job with `contents: write` in the protected\n`buildchain-release-assets` Environment.\n\nThe npm/promotion, paper, binary-release, and web-production lanes all depend on\nthe independent verifier. Preview, staging, build, source-check, controller,\nand failure-evidence lanes do not inherit product publication capability."
|
|
1115
1115
|
},
|
|
1116
1116
|
{
|
|
1117
1117
|
"id": "manual:publish-transaction",
|
|
@@ -1711,7 +1711,7 @@
|
|
|
1711
1711
|
],
|
|
1712
1712
|
"maturity": "stable",
|
|
1713
1713
|
"sourcePath": "docs/shifu-gate-profiles.md",
|
|
1714
|
-
"digest": "sha256:
|
|
1714
|
+
"digest": "sha256:919c163a414df5ed562148e4da9e0e3a94718488e7477eb120073e2ee35b5288",
|
|
1715
1715
|
"headings": [
|
|
1716
1716
|
{
|
|
1717
1717
|
"level": 1,
|
|
@@ -1749,7 +1749,7 @@
|
|
|
1749
1749
|
"anchor": "validation-boundary"
|
|
1750
1750
|
}
|
|
1751
1751
|
],
|
|
1752
|
-
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: buildchain-shifu-gate-orchestration\ndoc_type: technical-manual\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: self-reviewed\nlast_reviewed: 2026-07-13\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-13\n invisible_context_boundary: No private runner configuration, credentials, or unpublished Shifu implementation state was used.\n---\n\n# Shifu Gate profile orchestration\n\nBuildchain can schedule and aggregate a project-owned Shifu Gate profile without\nowning that project's gate ids, commands, dependencies, or dev/alpha/release\npolicy. The reusable workflow is\n`.github/workflows/.gate-profile.yml`.\n\n## Ownership boundary\n\n| Concern | Owner | Enforced surface |\n| ----------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------- |\n| Gate schema, profile planning, execution, receipt qualification | Shifu | `shifu gate plan`, `shifu gate run --profile`, `shifu gate receipt validate` |\n| Concrete gate catalog and profile decisions | Consumer project | project Gate registry and detailed Gate docs |\n| Runner labels and declared capabilities | Consumer workflow / Buildchain preset | `runner-preset` or `platforms-json` |\n| Deterministic runner matrix, immutable checkout, receipt transport, aggregate check | Buildchain | `.gate-profile.yml` and `shifu-gate-profile.mjs` |\n| Whether a profile aggregate is required for dev, alpha, or release | Consumer project | protected-branch required-check policy and caller workflow |\n\nBuildchain treats the Shifu plan and receipt as versioned input contracts. It\ndoes not reimplement policy selection, execute raw shell strings, convert an\nexplicit diagnostic gate run into qualification, or mint missing evidence.\n\n## Runner matrix\n\nThe plan job asks the consumer's Shifu entrypoint for one plan per configured\nplatform. A platform is dispatchable only when:\n\n- the Shifu plan is qualifying;\n- every required selection is supported on that platform;\n- the runner declares every capability requested by the selected gates; and\n- all platform plans carry the same project id and registry digest.\n\nConfigured platforms are required by default. A required platform that cannot\nhost the profile fails before runner dispatch. A platform with\n`\"required\": false` may be omitted, but the omission and reasons remain in the\nmatrix and aggregate. Matrix entries retain the Shifu plan digest, ordered gate\ngroups, required/advisory modes, action ids, definition digests, skips, and\nunsupported selections.\n\n`github-hosted` declares only the inherent `node` capability. Projects that\nneed a native compiler, product artifacts, devices, or other facilities must\nuse a suitable preset or declare a custom matrix. Capabilities are scheduling\nclaims, not installation instructions.\n\n```json\n[\n {\n \"id\": \"linux-native\",\n \"name\": \"Linux native\",\n \"platform\": \"linux\",\n \"runner\": \"[\\\"self-hosted\\\",\\\"Linux\\\",\\\"X64\\\",\\\"product-build\\\"]\",\n \"capabilities\": [\"node\", \"native-toolchain\", \"product-artifacts\"]\n }\n]\n```\n\n## Execution and receipts\n\nEvery matrix job checks out the exact source SHA planned by Buildchain, invokes\n`shifu gate run --profile`, writes the receipt outside the source checkout, and\nthen invokes `shifu gate receipt validate`. Buildchain uploads the original\nreceipt and validation result even when the run fails.\n\nThe fixed `Gate profile / aggregate` job fails closed for missing receipts,\ninvalid or stale Shifu validation, dirty or mismatched source SHA, registry or\nplan drift, missing required results, required failures/skips, or gate action\nand definition digest drift. Advisory failures remain visible but do not turn a\nShifu-qualifying receipt into a required failure. Buildchain's aggregate is\n`buildchain.shifu-gate-aggregate/v1`; its digest covers the matrix, receipts,\nper-gate evidence pointers, omissions, and issues.\n\n## Consumer workflow\n\n```yaml\njobs:\n gates:\n uses: kungfu-systems/buildchain/.github/workflows/.gate-profile.yml@v2\n with:\n gate-profile: alpha-pr\n runner-preset: kungfu-v4-self-hosted\n include-advisory: true\n\n build:\n needs: gates\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v2\n with:\n release-candidate: true\n gate-profile-aggregate-json: ${{ needs.gates.outputs.gate-aggregate-json }}\n```\n\nThe command input is an argv map, not a shell string. The default supports the\nordinary Shifu launcher names on all three platforms. A project with a\ndifferent launcher can override it without teaching Buildchain project tasks:\n\n```yaml\ngate-command-json: >-\n {\"linux\":[\"./tools/shifu\"],\"macos\":[\"./tools/shifu\"],\"windows\":[\"./tools/shifu.cmd\"]}\n```\n\n`gate-command-json` is the execution command. If execution needs a cache,\ncontainer, or other project-owned wrapper that should not make the read-only\nplan depend on that service, pass a separate lightweight argv map through\n`gate-plan-command-json`. It defaults to the execution command for backward\ncompatibility; Buildchain still treats both inputs as argv and never evaluates\na shell string.\n\nProjects may also pass non-sensitive scalar environment through\n`gate-environment-json`; Buildchain validates the JSON shape and forwards it\nwithout interpreting names or values. Cache profile references use the same\nopaque `shifu-cache-profile-ref` and `shifu-cache-profile-digest` inputs as the\nreusable build. Do not place tokens, credentials, or other secrets in workflow\ninputs or Gate receipts.\n\nWhen a qualifying aggregate is passed to the build workflow, the\nrelease-candidate passport binds its profile, source SHA, registry digest,\nmatrix digest, aggregate digest, receipt count, and result count. A failed,\nnon-qualifying, or source-mismatched aggregate cannot produce a valid passport.\nPromote-only release validation preserves that same Gate evidence summary in\nthe final Release Passport release identity, so promotion cannot silently drop\nthe qualified profile provenance.\n\n## Failure diagnosis and rollback\n\nStart with the aggregate artifact, then the platform receipt named in its\nissues. Reproduce the exact project decision with Shifu, for example:\n\n```bash\n./shifu gate explain <gate-id> --profile <profile>\n./shifu gate plan <profile> --platform <platform> --json\n./shifu gate receipt validate <receipt.json> --json\n```\n\nThe existing reusable build workflow remains usable without Gate inputs. To\nroll back Gate orchestration, remove the caller's `gates` job and\n`gate-profile-aggregate-json` handoff; this does not alter the consumer's Shifu\nregistry or its direct diagnostic commands.\n\n## Validation boundary\n\nUnit fixtures prove deterministic matrix generation and required/advisory,\ncapability, unsupported, missing, stale, failure, and definition-drift\npropagation. Because a train ref changes runtime scripts but not the outer\nreusable workflow topology, an unreleased `.gate-profile.yml` must also be\nvalidated through a trusted `workflow_dispatch` canary that references the\ntemporary workflow ref or exact SHA. See\n[`runtime-train-validation.md`](runtime-train-validation.md)."
|
|
1752
|
+
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: buildchain-shifu-gate-orchestration\ndoc_type: technical-manual\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: self-reviewed\nlast_reviewed: 2026-07-13\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-13\n invisible_context_boundary: No private runner configuration, credentials, or unpublished Shifu implementation state was used.\n---\n\n# Shifu Gate profile orchestration\n\nBuildchain can schedule and aggregate a project-owned Shifu Gate profile without\nowning that project's gate ids, commands, dependencies, or dev/alpha/release\npolicy. The reusable workflow is\n`.github/workflows/.gate-profile.yml`.\n\n## Ownership boundary\n\n| Concern | Owner | Enforced surface |\n| ----------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------- |\n| Gate schema, profile planning, execution, receipt qualification | Shifu | `shifu gate plan`, `shifu gate run --profile`, `shifu gate receipt validate` |\n| Concrete gate catalog and profile decisions | Consumer project | project Gate registry and detailed Gate docs |\n| Runner labels and declared capabilities | Consumer workflow / Buildchain preset | `runner-preset` or `platforms-json` |\n| Deterministic runner matrix, immutable checkout, receipt transport, aggregate check | Buildchain | `.gate-profile.yml` and `shifu-gate-profile.mjs` |\n| Whether a profile aggregate is required for dev, alpha, or release | Consumer project | protected-branch required-check policy and caller workflow |\n\nBuildchain treats the Shifu plan and receipt as versioned input contracts. It\ndoes not reimplement policy selection, execute raw shell strings, convert an\nexplicit diagnostic gate run into qualification, or mint missing evidence.\n\n## Runner matrix\n\nThe plan job asks the consumer's Shifu entrypoint for one plan per configured\nplatform. A platform is dispatchable only when:\n\n- the Shifu plan is qualifying;\n- every required selection is supported on that platform;\n- the runner declares every capability requested by the selected gates; and\n- all platform plans carry the same project id and registry digest.\n\nConfigured platforms are required by default. A required platform that cannot\nhost the profile fails before runner dispatch. A platform with\n`\"required\": false` may be omitted, but the omission and reasons remain in the\nmatrix and aggregate. Matrix entries retain the Shifu plan digest, ordered gate\ngroups, required/advisory modes, action ids, definition digests, skips, and\nunsupported selections.\n\n`github-hosted` declares only the inherent `node` capability. Projects that\nneed a native compiler, product artifacts, devices, or other facilities must\nuse a suitable preset or declare a custom matrix. Capabilities are scheduling\nclaims, not installation instructions.\n\n```json\n[\n {\n \"id\": \"linux-native\",\n \"name\": \"Linux native\",\n \"platform\": \"linux\",\n \"runner\": \"[\\\"self-hosted\\\",\\\"Linux\\\",\\\"X64\\\",\\\"product-build\\\"]\",\n \"capabilities\": [\"node\", \"native-toolchain\", \"product-artifacts\"]\n }\n]\n```\n\n## Execution and receipts\n\nEvery matrix job checks out the exact source SHA planned by Buildchain, invokes\n`shifu gate run --profile`, writes the receipt outside the source checkout, and\nthen invokes `shifu gate receipt validate`. Buildchain uploads the original\nreceipt and validation result even when the run fails.\n\nBefore invoking the project-owned command, the workflow adds the runner\naccount's `~/.local/bin` directory to `PATH` on Windows, Linux, and macOS. This\nkeeps user-scoped tools such as `uv` available to strict Shifu cache profiles\nwithout assuming an administrator-managed system installation. The consumer or\nrunner owner remains responsible for provisioning the declared tools.\n\nThe fixed `Gate profile / aggregate` job fails closed for missing receipts,\ninvalid or stale Shifu validation, dirty or mismatched source SHA, registry or\nplan drift, missing required results, required failures/skips, or gate action\nand definition digest drift. Advisory failures remain visible but do not turn a\nShifu-qualifying receipt into a required failure. Buildchain's aggregate is\n`buildchain.shifu-gate-aggregate/v1`; its digest covers the matrix, receipts,\nper-gate evidence pointers, omissions, and issues.\n\n## Consumer workflow\n\n```yaml\njobs:\n gates:\n uses: kungfu-systems/buildchain/.github/workflows/.gate-profile.yml@v2\n with:\n gate-profile: alpha-pr\n runner-preset: kungfu-v4-self-hosted\n include-advisory: true\n\n build:\n needs: gates\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v2\n with:\n release-candidate: true\n gate-profile-aggregate-json: ${{ needs.gates.outputs.gate-aggregate-json }}\n```\n\nThe command input is an argv map, not a shell string. The default supports the\nordinary Shifu launcher names on all three platforms. A project with a\ndifferent launcher can override it without teaching Buildchain project tasks:\n\n```yaml\ngate-command-json: >-\n {\"linux\":[\"./tools/shifu\"],\"macos\":[\"./tools/shifu\"],\"windows\":[\"./tools/shifu.cmd\"]}\n```\n\n`gate-command-json` is the execution command. If execution needs a cache,\ncontainer, or other project-owned wrapper that should not make the read-only\nplan depend on that service, pass a separate lightweight argv map through\n`gate-plan-command-json`. It defaults to the execution command for backward\ncompatibility; Buildchain still treats both inputs as argv and never evaluates\na shell string.\n\nProjects may also pass non-sensitive scalar environment through\n`gate-environment-json`; Buildchain validates the JSON shape and forwards it\nwithout interpreting names or values. Cache profile references use the same\nopaque `shifu-cache-profile-ref` and `shifu-cache-profile-digest` inputs as the\nreusable build. Do not place tokens, credentials, or other secrets in workflow\ninputs or Gate receipts.\n\nWhen a qualifying aggregate is passed to the build workflow, the\nrelease-candidate passport binds its profile, source SHA, registry digest,\nmatrix digest, aggregate digest, receipt count, and result count. A failed,\nnon-qualifying, or source-mismatched aggregate cannot produce a valid passport.\nPromote-only release validation preserves that same Gate evidence summary in\nthe final Release Passport release identity, so promotion cannot silently drop\nthe qualified profile provenance.\n\n## Failure diagnosis and rollback\n\nStart with the aggregate artifact, then the platform receipt named in its\nissues. Reproduce the exact project decision with Shifu, for example:\n\n```bash\n./shifu gate explain <gate-id> --profile <profile>\n./shifu gate plan <profile> --platform <platform> --json\n./shifu gate receipt validate <receipt.json> --json\n```\n\nThe existing reusable build workflow remains usable without Gate inputs. To\nroll back Gate orchestration, remove the caller's `gates` job and\n`gate-profile-aggregate-json` handoff; this does not alter the consumer's Shifu\nregistry or its direct diagnostic commands.\n\n## Validation boundary\n\nUnit fixtures prove deterministic matrix generation and required/advisory,\ncapability, unsupported, missing, stale, failure, and definition-drift\npropagation. Because a train ref changes runtime scripts but not the outer\nreusable workflow topology, an unreleased `.gate-profile.yml` must also be\nvalidated through a trusted `workflow_dispatch` canary that references the\ntemporary workflow ref or exact SHA. See\n[`runtime-train-validation.md`](runtime-train-validation.md)."
|
|
1753
1753
|
},
|
|
1754
1754
|
{
|
|
1755
1755
|
"id": "manual:site-bundle-contract",
|
|
@@ -2474,7 +2474,7 @@
|
|
|
2474
2474
|
"path": "docs/publication-authority.md",
|
|
2475
2475
|
"plane": "verify",
|
|
2476
2476
|
"exists": true,
|
|
2477
|
-
"digest": "sha256:
|
|
2477
|
+
"digest": "sha256:06ba05f9d8a2685a0896334b6013a97c45b7d71163cf6898e5a6274baf7f0296"
|
|
2478
2478
|
},
|
|
2479
2479
|
{
|
|
2480
2480
|
"id": "release-candidate",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"contract": "kungfu-buildchain-public-surface-reverse-audit",
|
|
22
22
|
"path": "dist/site/public-surface-audit.json",
|
|
23
23
|
"status": "passed",
|
|
24
|
-
"sha256": "
|
|
24
|
+
"sha256": "7bafa611c991c1b808267f22e6708bed2cf00b655ebd6bee60c50dd27fcefa37",
|
|
25
25
|
"summary": {
|
|
26
26
|
"cliCommandCount": 79,
|
|
27
27
|
"workflowCount": 46,
|
|
@@ -225,7 +225,7 @@
|
|
|
225
225
|
"contract": "kungfu-buildchain-public-surface-reverse-audit",
|
|
226
226
|
"path": "dist/site/public-surface-audit.json",
|
|
227
227
|
"status": "passed",
|
|
228
|
-
"sha256": "
|
|
228
|
+
"sha256": "7bafa611c991c1b808267f22e6708bed2cf00b655ebd6bee60c50dd27fcefa37",
|
|
229
229
|
"summary": {
|
|
230
230
|
"cliCommandCount": 79,
|
|
231
231
|
"workflowCount": 46,
|
|
@@ -2642,7 +2642,7 @@
|
|
|
2642
2642
|
"visibility": "public",
|
|
2643
2643
|
"participantFacing": true,
|
|
2644
2644
|
"public": true,
|
|
2645
|
-
"inputCount":
|
|
2645
|
+
"inputCount": 23,
|
|
2646
2646
|
"inputs": [
|
|
2647
2647
|
"admission-json",
|
|
2648
2648
|
"auto-admission",
|
|
@@ -2661,6 +2661,7 @@
|
|
|
2661
2661
|
"package-name",
|
|
2662
2662
|
"product",
|
|
2663
2663
|
"publication-target",
|
|
2664
|
+
"publication-version",
|
|
2664
2665
|
"publisher-workflow-path",
|
|
2665
2666
|
"runner-provenance-json",
|
|
2666
2667
|
"source-sha",
|
|
@@ -3671,16 +3672,18 @@
|
|
|
3671
3672
|
"visibility": "public",
|
|
3672
3673
|
"participantFacing": true,
|
|
3673
3674
|
"public": true,
|
|
3674
|
-
"inputCount":
|
|
3675
|
+
"inputCount": 54,
|
|
3675
3676
|
"inputs": [
|
|
3676
3677
|
"allow-repository",
|
|
3677
3678
|
"branch-protection-bypass-apps",
|
|
3678
3679
|
"branch-protection-bypass-teams",
|
|
3679
3680
|
"branch-protection-bypass-users",
|
|
3680
3681
|
"dry-run",
|
|
3682
|
+
"expected-publication-version",
|
|
3681
3683
|
"generated-ref-update-token",
|
|
3682
3684
|
"generated-status-check-token",
|
|
3683
3685
|
"github-release",
|
|
3686
|
+
"github-release-artifact-paths",
|
|
3684
3687
|
"github-release-notes",
|
|
3685
3688
|
"github-release-title",
|
|
3686
3689
|
"promote-only-release-candidate",
|
|
@@ -65,7 +65,7 @@
|
|
|
65
65
|
"title": "Sealed publication authority",
|
|
66
66
|
"path": "docs/publication-authority.md",
|
|
67
67
|
"plane": "verify",
|
|
68
|
-
"digest": "sha256:
|
|
68
|
+
"digest": "sha256:06ba05f9d8a2685a0896334b6013a97c45b7d71163cf6898e5a6274baf7f0296",
|
|
69
69
|
"capabilityGroup": "release-passport-trust",
|
|
70
70
|
"audience": [
|
|
71
71
|
"release-operator",
|
|
@@ -86,7 +86,7 @@
|
|
|
86
86
|
"specifier": "@kungfu-tech/buildchain/controller-evidence",
|
|
87
87
|
"export": "./controller-evidence",
|
|
88
88
|
"target": "./packages/core/controller-evidence.js",
|
|
89
|
-
"digest": "sha256:
|
|
89
|
+
"digest": "sha256:3c9cf557ee0e2e4376335bb7d0e61b6e8c9a1d8699962dd8a1e7adc529e13f89",
|
|
90
90
|
"summary": "Project-independent controller descriptors, source/runtime-bound plans, receipts, aggregates, and validation APIs.",
|
|
91
91
|
"capabilityGroup": "reusable-build",
|
|
92
92
|
"audience": [
|
|
@@ -965,7 +965,7 @@
|
|
|
965
965
|
],
|
|
966
966
|
"maturity": "stable",
|
|
967
967
|
"sourcePath": "docs/publication-artifacts.md",
|
|
968
|
-
"digest": "sha256:
|
|
968
|
+
"digest": "sha256:24429efd2c39cfcbf3ed2c0f7265cadc44b28fa3e1dab1f115f2b8a7a3d7c028",
|
|
969
969
|
"headings": [
|
|
970
970
|
{
|
|
971
971
|
"level": 1,
|
|
@@ -998,7 +998,7 @@
|
|
|
998
998
|
"anchor": "site-consumption"
|
|
999
999
|
}
|
|
1000
1000
|
],
|
|
1001
|
-
"markdown": "# Publication Artifact Workflow\n\nBuildchain supports `project.type = \"publication-artifact\"` for repositories\nthat produce auditable papers, reports, specifications, or similar publication\npackages. These repositories are artifact producers. They should not be forced\nto become `web-surface` repositories just because a downstream site later\nrenders the paper.\n\nThe split is:\n\n```text\npaper repo = source, PDF, metadata, source bundle, publication manifest\npapers site = layout, navigation, public web surface, downstream rendering\n```\n\n## Configuration\n\nThe paper repository owns `.buildchain/buildchain.toml`:\n\n```toml\nschema = 1\n\n[project]\ntype = \"publication-artifact\"\nname = \"paper-observer-declared-timelines\"\n\n[publication]\nkind = \"paper\"\ntitle = \"Observer-Declared Timelines for Real-World Agent Work\"\nversion = \"0.1.0\"\nprimary_artifact = \"_build/main.pdf\"\nartifact_paths = [\"_build/main.pdf\"]\nmetadata_paths = [\"README.md\", \"docs/MAP.md\"]\nsource_paths = [\"paper\", \"README.md\", \"LICENSE\", \"Makefile\"]\nsite_consumers = [\"papers.libkungfu.dev\"]\nmanifest_path = \".buildchain/publication/publication-artifact.json\"\nsource_bundle_path = \".buildchain/publication/source.tar.gz\"\n\n[publication.archive]\nid = \"observer-declared-timelines\"\ncanonical_url = \"https://papers.libkungfu.dev/observer-declared-timelines/\"\nlatest_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/\"\nlatest_evidence_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/buildchain.release.json\"\nimmutable_base_url = \"https://papers.libkungfu.dev/archive\"\nregistry_path = \".buildchain/publication/publication-registry.json\"\n\n[publication.toolchain]\ntype = \"latex-docker\"\nimage = \"ghcr.io/kungfu-systems/build-images/latex-pdf-builder\"\ndigest = \"sha256:c20f3809e96836c1c78e97c76939d12f1de3fed0ea9b7c40c43332ec2ea480f8\"\ncommand = \"latexmk -pdf -outdir=_build paper/main.tex\"\n\n[publish]\nkind = \"npm-paper-package\"\npackage = \"@kungfu-tech/paper-observer-declared-timelines\"\nauth = \"trusted-publishing\"\n\n[lifecycle.build]\ncommand = \"make pdf\"\n\n[lifecycle.verify]\ncommand = \"make check\"\n```\n\n`primary_artifact` is the human-facing publication output, usually a PDF.\n`source_paths` are archived into a source bundle. `metadata_paths` are hashed\nand recorded so a site can consume the paper facts without scraping prose.\n\n`publication.archive` turns the publication into an append-only public archive\ncontract:\n\n- `canonical_url` is the stable human reader page.\n- `latest_url` and `latest_evidence_url` are movable aliases for the latest\n reader page and latest evidence.\n- `immutable_base_url` plus `id` and `publication.version` produce a versioned\n prefix such as\n `https://papers.libkungfu.dev/archive/observer-declared-timelines/v0.1.0/`.\n- `immutable_url_prefix` can be used instead when the repository already owns\n the full version prefix.\n- `registry_path` records every published version and its manifest, passport,\n source bundle, primary artifact, URLs, and SHA-256 digests.\n\nImmutable archive prefixes are append-only. Do not run site deployment commands\nwith `sync --delete` or equivalent deletion semantics over those prefixes. A\nsame-version republish is allowed only when the immutable digest is unchanged;\nif PDF, source bundle, route, metadata, or toolchain evidence changes for an\nexisting version, Buildchain fails before the registry is rewritten.\n\nThe Buildchain web-surface adapter consumes this boundary from a surface-local\n`manifest.json` whose `archivePolicy.contract` is\n`kungfu-buildchain-publication-archive-policy`. It excludes the derived archive\nroot from every owning or parent `sync --delete`, verifies existing object\ndigests, uploads only missing immutable files with `--no-overwrite`, and verifies\nthem again before mutable site content is synchronized. A current package set\ndoes not need to rebuild or enumerate every historical version: the protected\narchive root remains outside deletion even when older versions disappear from\nthe current artifact.\n\n`publication.toolchain` makes the source-to-PDF transformation part of the\nmachine-readable contract. `latex-docker` is the preferred LaTeX profile. The\nBuildchain paper scaffold and reusable workflow default to\n`ghcr.io/kungfu-systems/build-images/latex-pdf-builder:v1.2.0`, pinned by the\ndigest above. The workflow pulls the declared image by digest and runs the\ndeclared command in that pinned container. `custom-command` remains available\nfor compatibility, but the passport records it as lower trust because\nBuildchain can record the command boundary without proving the compiler or\nLaTeX distribution digest.\n\n`publish.kind = \"npm-paper-package\"` declares that Buildchain, not the consumer\nrepository, owns the standard paper npm package shape and release transaction\nmechanics. `publish.package` is the public npm package that contains the PDF,\npublication manifest, publication passport, optional archive registry, source\nbundle, and declared metadata files.\n\n## Reusable Workflow\n\nConsumer repositories that only need to build and upload paper evidence can\ncall the build-only wrapper directly:\n\n```yaml\njobs:\n publication:\n uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2\n with:\n toolchain-type: config\n verify-command: make check\n artifact-name: observer-declared-timelines\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe build-only workflow:\n\n- resolves the Buildchain runtime and checks the floating contract lock before\n any paper build runs;\n- resolves the declared publication toolchain from `[publication.toolchain]` or\n workflow inputs;\n- for `latex-docker`, pulls the pinned build-images LaTeX builder digest and\n runs the declared command in the container;\n- for `custom-command`, runs the declared command and records the lower-trust\n boundary in the passport;\n- runs the verify command;\n- creates a source bundle from `publication.source_paths`;\n- writes `.buildchain/publication/publication-artifact.json`;\n- writes `.buildchain/publication/publication-artifact-passport.json`;\n- when `[publication.archive]` is configured, writes\n `.buildchain/publication/publication-registry.json` and verifies same-version\n immutability;\n- uploads one GitHub artifact containing the PDF, manifest, passport, optional\n registry, and source bundle.\n\nIt does not publish npm packages, deploy web pages, or create GitHub Releases.\n\nThe paper release preset additionally hydrates every prior published package\nregistry from the npm registry before generating the current manifest. npm\npackage integrity authenticates each downloaded source; Buildchain verifies the\nregistry self-digest, merges immutable records, and fails if a cumulative\nregistry drops an accepted version or changes immutable route/artifact facts.\nThe synthesized package therefore carries complete history even on a clean\nrunner. Its cumulative registry and file SHA-256 values are bound into the paper\nrelease build summary and release passport evidence.\n\n## Paper Release Preset\n\nPaper repositories that publish a versioned npm package should use the\nBuildchain-managed release preset instead of copying npm transaction scripts or\npromotion YAML:\n\n```yaml\nname: Paper Release\n\non:\n push:\n branches:\n - alpha/v1/v1.0\n - release/v1/v1.0\n workflow_dispatch:\n inputs:\n buildchain-ref:\n description: \"Temporary Buildchain runtime ref\"\n required: false\n default: \"\"\n\njobs:\n paper-release:\n uses: kungfu-systems/buildchain/.github/workflows/paper-release.yml@v2\n permissions:\n checks: write\n contents: write\n id-token: write\n issues: write\n with:\n buildchain-ref: ${{ inputs.buildchain-ref || '' }}\n publication-admission-json: ${{ needs.authority.outputs.admission-json }}\n publication-runner-provenance-json: ${{ needs.authority.outputs.runner-provenance-json }}\n publication-control-plane-audit-json: ${{ needs.authority.outputs.control-plane-audit-json }}\n publication-expected-json: ${{ needs.authority.outputs.expected-json }}\n toolchain-type: config\n verify-command: make check\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe publication job does not accept a long-lived promotion token. The caller\nmust first produce a fresh sealed admission, runner provenance, external\ncontrol-plane audit, and exact expected bindings. The credential-free verifier\njob checks those receipts; only then can the publication job use its short-lived\n`github.token` and caller-bound OIDC trusted publisher identity. npm binds that\nidentity to the consumer workflow filename; an npm Environment restriction is\noptional and must be represented explicitly when configured. The workflow fails\nbefore the publication build when the target branch protection cannot be read.\n\nThe preset:\n\n- resolves the same floating Buildchain runtime and contract lock as the build\n workflow;\n- verifies that the declared promotion authority can read the protected target\n channel before starting the publication build;\n- builds the PDF through the declared pinned LaTeX Docker toolchain or custom\n command;\n- verifies the paper repository;\n- writes the publication manifest, publication passport, optional archive\n registry, and source bundle;\n- synthesizes an npm package from `[publication]` and `[publish]` declarations\n under `.buildchain/publication/npm-package`;\n- computes npm-style `sha512` integrity from `npm pack --dry-run` and passes\n it as `publish-required-artifacts-json`;\n- creates a `publish-gate/<alpha|release>/.../<version>` source lock for the\n channel commit and requires `promote-buildchain-ref` to verify that lock\n before any publish side effect;\n- publishes the package through npm Trusted Publishing;\n- writes Buildchain release/passport evidence; and\n- creates or updates the exact-version GitHub Release by default.\n\nConsumers can opt out of the GitHub Release with `github-release: false`, but\nthe default is on so downstream release propagation can observe\n`release.published` without hand-written `gh release` steps.\n\nFor npm Trusted Publishing, register the consumer workflow file that calls this\npreset, for example `.github/workflows/paper-release.yml`, against the declared\npackage in npm. The trusted publisher is the consumer repository and workflow\nfile; the implementation still runs inside Buildchain's reusable workflow.\n\nStandard paper repositories should not carry local copies of\n`scripts/npm-publish-transaction.mjs`, package-generation scripts, or\npromotion/ref-lock YAML. If the default package shape is insufficient, extend\nBuildchain rather than forking the mechanics into each paper repository.\n\n## CLI And Node API\n\nGenerate the publication manifest locally or in CI:\n\n```sh\nbuildchain publication-artifact manifest --source-sha \"$(git rev-parse HEAD)\" --json\n```\n\nGenerate the npm package contents after the manifest exists:\n\n```sh\nbuildchain publication-artifact npm-package --json\n```\n\nNode API:\n\n```js\nimport {\n collectPublicationArtifact,\n writePublicationArtifact,\n} from \"@kungfu-tech/buildchain/publication-artifact\";\n\nimport {\n collectPublicationPackageFacts,\n preparePublicationNpmPackage,\n} from \"@kungfu-tech/buildchain/publication-package\";\n```\n\n`writePublicationArtifact()` is the single implementation used by the CLI and\nthe reusable workflow. The generated manifest records:\n\n- publication title, kind, authors, and primary artifact;\n- artifact paths, byte sizes, and SHA-256 digests;\n- metadata paths and SHA-256 digests;\n- source SHA, tree SHA, source files, and source bundle digest;\n- publication toolchain type, image, digest, command, invocation mode, and trust\n classification;\n- timestamp and reproducibility policy;\n- downstream site-consumption hints;\n- optional archive routes for canonical, latest, latest evidence, immutable\n version prefix, and public artifact URLs.\n\nThe companion publication artifact passport records the same source and\nartifact evidence plus an explicit responsibility split. Buildchain proves\ndeclared files and hashes; it does not peer-review paper claims.\n\nWhen archive config is present, the registry uses the\n`kungfu-buildchain-publication-artifact-registry` contract. A site repository\ncan render latest pages and historical version indexes from that registry\nwithout rebuilding old PDFs from the latest npm package or paper source.\n\n## Site Consumption\n\nA downstream papers site should treat the publication manifest as the single\nfact source for the artifact. The site owns rendering and navigation; it should\nnot reinterpret the paper repository as a web deployment source.\nFor registry-level routing, sites should first consume the package-owned\nBuildchain fact source:\n\n```text\nnode_modules/@kungfu-tech/buildchain/dist/site/publication-registry.json\n```\n\nor the equivalent package export:\n\n```js\nimport registry from \"@kungfu-tech/buildchain/site/publication-registry.json\" with { type: \"json\" };\n```\n\nThat registry uses the `kungfu-buildchain-publication-release-registry`\ncontract. It separates mutable canonical/latest reader routes from immutable\nversion prefixes, publication artifacts, source bundles, and passport evidence\nso site repositories can render `/papers/**` without maintaining a parallel\nfixture truth source.\n\nFor `paper-observer-declared-timelines`, the expected adoption path is:\n\n```text\npaper repo builds PDF + manifest + source bundle\npaper repo updates publication-registry.json\npapers site consumes publication-artifact.json\npapers site consumes publication-registry.json for history\nsite renders paper page and links the PDF/source bundle\n```\n\nThis mirrors web-surface governance without mixing producer and renderer\nresponsibilities."
|
|
1001
|
+
"markdown": "# Publication Artifact Workflow\n\nBuildchain supports `project.type = \"publication-artifact\"` for repositories\nthat produce auditable papers, reports, specifications, or similar publication\npackages. These repositories are artifact producers. They should not be forced\nto become `web-surface` repositories just because a downstream site later\nrenders the paper.\n\nThe split is:\n\n```text\npaper repo = source, PDF, metadata, source bundle, publication manifest\npapers site = layout, navigation, public web surface, downstream rendering\n```\n\n## Configuration\n\nThe paper repository owns `.buildchain/buildchain.toml`:\n\n```toml\nschema = 1\n\n[project]\ntype = \"publication-artifact\"\nname = \"paper-observer-declared-timelines\"\n\n[publication]\nkind = \"paper\"\ntitle = \"Observer-Declared Timelines for Real-World Agent Work\"\nversion = \"0.1.0\"\nprimary_artifact = \"_build/main.pdf\"\nartifact_paths = [\"_build/main.pdf\"]\nmetadata_paths = [\"README.md\", \"docs/MAP.md\"]\nsource_paths = [\"paper\", \"README.md\", \"LICENSE\", \"Makefile\"]\nsite_consumers = [\"papers.libkungfu.dev\"]\nmanifest_path = \".buildchain/publication/publication-artifact.json\"\nsource_bundle_path = \".buildchain/publication/source.tar.gz\"\n\n[publication.archive]\nid = \"observer-declared-timelines\"\ncanonical_url = \"https://papers.libkungfu.dev/observer-declared-timelines/\"\nlatest_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/\"\nlatest_evidence_url = \"https://papers.libkungfu.dev/observer-declared-timelines/latest/buildchain.release.json\"\nimmutable_base_url = \"https://papers.libkungfu.dev/archive\"\nregistry_path = \".buildchain/publication/publication-registry.json\"\n\n[publication.toolchain]\ntype = \"latex-docker\"\nimage = \"ghcr.io/kungfu-systems/build-images/latex-pdf-builder\"\ndigest = \"sha256:c20f3809e96836c1c78e97c76939d12f1de3fed0ea9b7c40c43332ec2ea480f8\"\ncommand = \"latexmk -pdf -outdir=_build paper/main.tex\"\n\n[publish]\nkind = \"npm-paper-package\"\npackage = \"@kungfu-tech/paper-observer-declared-timelines\"\nauth = \"trusted-publishing\"\n\n[lifecycle.build]\ncommand = \"make pdf\"\n\n[lifecycle.verify]\ncommand = \"make check\"\n```\n\n`primary_artifact` is the human-facing publication output, usually a PDF.\n`source_paths` are archived into a source bundle. `metadata_paths` are hashed\nand recorded so a site can consume the paper facts without scraping prose.\n\n`publication.archive` turns the publication into an append-only public archive\ncontract:\n\n- `canonical_url` is the stable human reader page.\n- `latest_url` and `latest_evidence_url` are movable aliases for the latest\n reader page and latest evidence.\n- `immutable_base_url` plus `id` and `publication.version` produce a versioned\n prefix such as\n `https://papers.libkungfu.dev/archive/observer-declared-timelines/v0.1.0/`.\n- `immutable_url_prefix` can be used instead when the repository already owns\n the full version prefix.\n- `registry_path` records every published version and its manifest, passport,\n source bundle, primary artifact, URLs, and SHA-256 digests.\n\nImmutable archive prefixes are append-only. Do not run site deployment commands\nwith `sync --delete` or equivalent deletion semantics over those prefixes. A\nsame-version republish is allowed only when the immutable digest is unchanged;\nif PDF, source bundle, route, metadata, or toolchain evidence changes for an\nexisting version, Buildchain fails before the registry is rewritten.\n\nThe Buildchain web-surface adapter consumes this boundary from a surface-local\n`manifest.json` whose `archivePolicy.contract` is\n`kungfu-buildchain-publication-archive-policy`. It excludes the derived archive\nroot from every owning or parent `sync --delete`, verifies existing object\ndigests, uploads only missing immutable files with `--no-overwrite`, and verifies\nthem again before mutable site content is synchronized. A current package set\ndoes not need to rebuild or enumerate every historical version: the protected\narchive root remains outside deletion even when older versions disappear from\nthe current artifact.\n\n`publication.toolchain` makes the source-to-PDF transformation part of the\nmachine-readable contract. `latex-docker` is the preferred LaTeX profile. The\nBuildchain paper scaffold and reusable workflow default to\n`ghcr.io/kungfu-systems/build-images/latex-pdf-builder:v1.2.0`, pinned by the\ndigest above. The workflow pulls the declared image by digest and runs the\ndeclared command in that pinned container. `custom-command` remains available\nfor compatibility, but the passport records it as lower trust because\nBuildchain can record the command boundary without proving the compiler or\nLaTeX distribution digest.\n\n`publish.kind = \"npm-paper-package\"` declares that Buildchain, not the consumer\nrepository, owns the standard paper npm package shape and release transaction\nmechanics. `publish.package` is the public npm package that contains the PDF,\npublication manifest, publication passport, optional archive registry, source\nbundle, and declared metadata files.\n\n## Reusable Workflow\n\nConsumer repositories that only need to build and upload paper evidence can\ncall the build-only wrapper directly:\n\n```yaml\njobs:\n publication:\n uses: kungfu-systems/buildchain/.github/workflows/publication-artifact.yml@v2\n with:\n toolchain-type: config\n verify-command: make check\n artifact-name: observer-declared-timelines\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe build-only workflow:\n\n- resolves the Buildchain runtime and checks the floating contract lock before\n any paper build runs;\n- resolves the declared publication toolchain from `[publication.toolchain]` or\n workflow inputs;\n- for `latex-docker`, pulls the pinned build-images LaTeX builder digest and\n runs the declared command in the container;\n- for `custom-command`, runs the declared command and records the lower-trust\n boundary in the passport;\n- runs the verify command;\n- creates a source bundle from `publication.source_paths`;\n- writes `.buildchain/publication/publication-artifact.json`;\n- writes `.buildchain/publication/publication-artifact-passport.json`;\n- when `[publication.archive]` is configured, writes\n `.buildchain/publication/publication-registry.json` and verifies same-version\n immutability;\n- uploads one GitHub artifact containing the PDF, manifest, passport, optional\n registry, and source bundle.\n\nIt does not publish npm packages, deploy web pages, or create GitHub Releases.\n\nThe paper release preset additionally hydrates every prior published package\nregistry from the npm registry before generating the current manifest. npm\npackage integrity authenticates each downloaded source; Buildchain verifies the\nregistry self-digest, merges immutable records, and fails if a cumulative\nregistry drops an accepted version or changes immutable route/artifact facts.\nThe synthesized package therefore carries complete history even on a clean\nrunner. Its cumulative registry and file SHA-256 values are bound into the paper\nrelease build summary and release passport evidence.\n\n## Paper Release Preset\n\nPaper repositories that publish a versioned npm package should use the\nBuildchain-managed release preset instead of copying npm transaction scripts or\npromotion YAML:\n\n```yaml\nname: Paper Release\n\non:\n push:\n branches:\n - alpha/v1/v1.0\n - release/v1/v1.0\n workflow_dispatch:\n inputs:\n buildchain-ref:\n description: \"Temporary Buildchain runtime ref\"\n required: false\n default: \"\"\n\njobs:\n paper-release:\n uses: kungfu-systems/buildchain/.github/workflows/paper-release.yml@v2\n permissions:\n checks: write\n contents: write\n id-token: write\n issues: write\n with:\n buildchain-ref: ${{ inputs.buildchain-ref || '' }}\n publication-admission-json: ${{ needs.authority.outputs.admission-json }}\n publication-runner-provenance-json: ${{ needs.authority.outputs.runner-provenance-json }}\n publication-control-plane-audit-json: ${{ needs.authority.outputs.control-plane-audit-json }}\n publication-expected-json: ${{ needs.authority.outputs.expected-json }}\n toolchain-type: config\n verify-command: make check\n buildchain-contract-lock-path: .buildchain/contract-lock.json\n```\n\nThe publication job does not accept a long-lived promotion token. The caller\nmust first produce a fresh sealed admission, runner provenance, external\ncontrol-plane audit, and exact expected bindings. The credential-free verifier\njob checks those receipts; only then can the publication job use its short-lived\n`github.token` and caller-bound OIDC trusted publisher identity. npm binds that\nidentity to the consumer workflow filename; an npm Environment restriction is\noptional and must be represented explicitly when configured. The workflow fails\nbefore the publication build when the target branch protection cannot be read.\n\nThe preset:\n\n- resolves the same floating Buildchain runtime and contract lock as the build\n workflow;\n- verifies that the declared promotion authority can read the protected target\n channel before starting the publication build;\n- builds the PDF through the declared pinned LaTeX Docker toolchain or custom\n command;\n- verifies the paper repository;\n- writes the publication manifest, publication passport, optional archive\n registry, and source bundle;\n- synthesizes an npm package from `[publication]` and `[publish]` declarations\n under `.buildchain/publication/npm-package`;\n- computes npm-style `sha512` integrity from `npm pack --dry-run` and passes\n it as `publish-required-artifacts-json`;\n- creates a `publish-gate/<alpha|release>/.../<version>` source lock for the\n channel commit and requires `promote-buildchain-ref` to verify that lock\n before any publish side effect;\n- publishes the package through npm Trusted Publishing;\n- writes Buildchain release/passport evidence; and\n- creates or updates the exact-version GitHub Release by default, uploading\n every file declared by `publication.primary_artifact` and\n `publication.artifact_paths` alongside the release evidence.\n\nConsumers can opt out of the GitHub Release with `github-release: false`, but\nthe default is on so downstream release propagation can observe\n`release.published` without hand-written `gh release` steps.\n\nDeclared publication artifacts are resolved from the generated publication\nmanifest rather than repeated in consumer workflow YAML. Publication fails\nbefore upload if a declared artifact is missing or if its basename would\ncollide with another GitHub Release asset.\n\nFor npm Trusted Publishing, register the consumer workflow file that calls this\npreset, for example `.github/workflows/paper-release.yml`, against the declared\npackage in npm. The trusted publisher is the consumer repository and workflow\nfile; the implementation still runs inside Buildchain's reusable workflow.\n\nStandard paper repositories should not carry local copies of\n`scripts/npm-publish-transaction.mjs`, package-generation scripts, or\npromotion/ref-lock YAML. If the default package shape is insufficient, extend\nBuildchain rather than forking the mechanics into each paper repository.\n\n## CLI And Node API\n\nGenerate the publication manifest locally or in CI:\n\n```sh\nbuildchain publication-artifact manifest --source-sha \"$(git rev-parse HEAD)\" --json\n```\n\nGenerate the npm package contents after the manifest exists:\n\n```sh\nbuildchain publication-artifact npm-package --json\n```\n\nNode API:\n\n```js\nimport {\n collectPublicationArtifact,\n writePublicationArtifact,\n} from \"@kungfu-tech/buildchain/publication-artifact\";\n\nimport {\n collectPublicationPackageFacts,\n preparePublicationNpmPackage,\n} from \"@kungfu-tech/buildchain/publication-package\";\n```\n\n`writePublicationArtifact()` is the single implementation used by the CLI and\nthe reusable workflow. The generated manifest records:\n\n- publication title, kind, authors, and primary artifact;\n- artifact paths, byte sizes, and SHA-256 digests;\n- metadata paths and SHA-256 digests;\n- source SHA, tree SHA, source files, and source bundle digest;\n- publication toolchain type, image, digest, command, invocation mode, and trust\n classification;\n- timestamp and reproducibility policy;\n- downstream site-consumption hints;\n- optional archive routes for canonical, latest, latest evidence, immutable\n version prefix, and public artifact URLs.\n\nThe companion publication artifact passport records the same source and\nartifact evidence plus an explicit responsibility split. Buildchain proves\ndeclared files and hashes; it does not peer-review paper claims.\n\nWhen archive config is present, the registry uses the\n`kungfu-buildchain-publication-artifact-registry` contract. A site repository\ncan render latest pages and historical version indexes from that registry\nwithout rebuilding old PDFs from the latest npm package or paper source.\n\n## Site Consumption\n\nA downstream papers site should treat the publication manifest as the single\nfact source for the artifact. The site owns rendering and navigation; it should\nnot reinterpret the paper repository as a web deployment source.\nFor registry-level routing, sites should first consume the package-owned\nBuildchain fact source:\n\n```text\nnode_modules/@kungfu-tech/buildchain/dist/site/publication-registry.json\n```\n\nor the equivalent package export:\n\n```js\nimport registry from \"@kungfu-tech/buildchain/site/publication-registry.json\" with { type: \"json\" };\n```\n\nThat registry uses the `kungfu-buildchain-publication-release-registry`\ncontract. It separates mutable canonical/latest reader routes from immutable\nversion prefixes, publication artifacts, source bundles, and passport evidence\nso site repositories can render `/papers/**` without maintaining a parallel\nfixture truth source.\n\nFor `paper-observer-declared-timelines`, the expected adoption path is:\n\n```text\npaper repo builds PDF + manifest + source bundle\npaper repo updates publication-registry.json\npapers site consumes publication-artifact.json\npapers site consumes publication-registry.json for history\nsite renders paper page and links the PDF/source bundle\n```\n\nThis mirrors web-surface governance without mixing producer and renderer\nresponsibilities."
|
|
1002
1002
|
},
|
|
1003
1003
|
{
|
|
1004
1004
|
"id": "manual:publication-authority",
|
|
@@ -1012,7 +1012,7 @@
|
|
|
1012
1012
|
],
|
|
1013
1013
|
"maturity": "preview",
|
|
1014
1014
|
"sourcePath": "docs/publication-authority.md",
|
|
1015
|
-
"digest": "sha256:
|
|
1015
|
+
"digest": "sha256:06ba05f9d8a2685a0896334b6013a97c45b7d71163cf6898e5a6274baf7f0296",
|
|
1016
1016
|
"headings": [
|
|
1017
1017
|
{
|
|
1018
1018
|
"level": 1,
|
|
@@ -1045,7 +1045,7 @@
|
|
|
1045
1045
|
"anchor": "publication-lanes"
|
|
1046
1046
|
}
|
|
1047
1047
|
],
|
|
1048
|
-
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: sealed-publication-authority\ndoc_type: protocol\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-07-14\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-14\n limits: Live provider configuration must be re-audited; no credential values are represented.\n---\n\n# Sealed Publication Authority\n\nBuildchain publication authority is a closed-world, fail-closed protocol. It does\nnot mint registry or cloud credentials. It independently verifies whether an\nalready protected publication job is allowed to request a short-lived provider\ncredential for one exact product, target, version, channel, and artifact digest.\n\nThe machine-readable authority inventory is\n`dist/site/publication-authority-registry.json`. Any workflow with a write,\nenvironment, OIDC, cloud credential, registry publish, release, or Git push\nsignal must have an explicit descriptor. A new authority-bearing workflow that\nis absent from the inventory fails site generation. Unknown workflows and every\ndescriptor not marked `product-publication` are denied product publication.\n\n## Evidence chain\n\nA qualifying admission binds exact source and runtime SHAs; contract, consumer\npolicy, qualifying controller receipt, Shifu/Gate aggregate, artifact, runner,\nand control-plane digests; repository, authority workflow, provider publisher\nworkflow, Environment policy,\nproduct, target, version, and channel; plus a unique nonce and a lifetime of no\nmore than 15 minutes. Every expected binding is mandatory at verification time;\nan omitted expected field is not a wildcard.\n\nThe independent verifier recomputes every digest and ignores a producer's own\nallow/deny conclusion. It fetches the exact evidence run, validates the actual\nrelease-candidate passport and referenced qualifying controller receipt,\nrecomputes the Shifu Gate aggregate or explicit consumer-owned no-Gate policy,\nrecomputes the downloaded artifact manifests, and hashes every declared product\npayload file against those manifests. The `.buildchain/` diagnostics envelope is\nbound by the manifest digest but excluded from the product-byte set because it can\nbe finalized after the lifecycle scan. The verifier also compares the PR evidence tree to the\nadmitted post-merge source commit tree. It rejects an unknown\nworkflow, stale or replayed nonce, runner downgrade, control-plane drift,\nsource/runtime mismatch, and artifact substitution. A successful result is a\nscoped capability receipt, not a bearer credential.\n\n## Runner and control-plane evidence\n\nRunner evidence uses exactly four classes: `ephemeral`, `reimaged`,\n`persistent-measured`, and `unqualified`. Ephemeral runners also record their\njob-isolation boundary. Reimaged and persistent runners qualify only when a\nclean baseline is proven and baseline, toolchain, cache-contract, and task-\nisolation digests are all present. Otherwise they still emit diagnostic\nevidence with `qualificationStatus = unqualified`, but cannot receive a product\ncapability.\n\nThe external audit records digests and pass/fail status for repository Actions\ndefaults, classic branch protection or an active matching repository ruleset,\ndeclared protected Environment policy or an explicit no-Environment binding,\njob-scoped credentials,\nabsence of long-lived workflow publication credentials, provider authority,\nand authorized runner class. Provider modes are `npm-trusted-publisher`,\n`github-token`, and `oidc-role`. The OIDC-role mode consumes only a sanitized\nprovider audit containing a role digest and qualifying decision; raw IAM policy,\ntokens, or credentials are rejected. Package-owner, cloud-root, GitHub\nadministrator, and registry-root credentials remain outside Buildchain's trust\nboundary. Missing or unreadable facts fail closed.\n\nAn unauthenticated local npm CLI is not evidence that Trusted Publishing is\nmissing. `npm whoami` reports only the local CLI session and does not report the\nOIDC identity that npm creates during `npm publish`. The default read-only audit\ntherefore binds the exact provider, repository, caller workflow, optional\nEnvironment, job-scoped OIDC permission, and absence of long-lived credentials,\nthen records `provider-at-transaction`: npm makes the final authorization\ndecision when `npm publish` exchanges the job's OIDC token. A missing or drifted\ntrusted-publisher configuration consequently denies the transaction safely; it\nis not preflighted through an unrelated long-lived npm login.\n\nAn authenticated external auditor can add stronger point-in-time evidence by\nsupplying sanitized `npm trust list --json` output with `--npm-trust-json`. This\nchanges the publisher fact to `audited-control-plane`; the workflow never runs\n`npm trust list` itself and never receives that auditor's npm credential.\n\nThe credential-free collector proves effective Actions and runner scope from\nthe publication workflow fetched at `--workflow-ref`: explicit read-only\nworkflow defaults, job-scoped write/OIDC permissions, and an exact GitHub-hosted\nrunner label. It does not call repository Actions-default or self-hosted-runner\nadministration endpoints. Branch/ruleset and OIDC subject facts remain live\nread-only provider queries. When the detailed branch-protection endpoint is not\nreadable with the workflow token, `--source-sha` binds the provider's public\nprotected-branch summary to the exact merged PR, independent approval, required\nsuccessful check, same-repository lineage, and current branch head. This records\nprovider-enforced transaction evidence without treating an unavailable\nadministration endpoint as an unprotected branch. It avoids turning a\nrepository-admin token into a publication prerequisite.\n\nFor non-dry-run workflows, missing admission, runner, control-plane, Gate, or\nexpected-binding evidence is rejected before Buildchain downloads candidate\nartifacts. The denial explicitly records that npm Trusted Publishing and OIDC\nwere not evaluated, so downstream diagnostics cannot misclassify an admission\nassembly failure as an npm authentication failure.\n\nBuildchain's own `workflow_run` promotion lane may assemble those inputs only\nfor `kungfu-systems/buildchain`. It downloads the exact prior RC passport,\nsummary, referenced controller receipt, manifests, and product payloads; proves\nthe admitted channel commit has the same Git tree as the RC; performs the live\nread-only control-plane audit; records the GitHub-hosted job as ephemeral runner\nprovenance; and creates an explicit Buildchain-owned no-Gate decision. The\nindependent verifier then recomputes every receipt and payload digest exactly as\nit does for externally supplied admission. The self-assembly mode rejects other\nrepositories, unknown refs, non-exact source SHAs, and any caller other than\n`.github/workflows/buildchain-ref-promotion.yml`. Manual apply and external\nconsumer workflows still require their own explicit admission inputs.\n\nEvidence publication is a separate authority class and never grants product\npublication.\n\n## API and CLI\n\nUse `@kungfu-tech/buildchain/publication-authority` or run:\n\n```bash\nbuildchain verify publication-admission admission.json \\\n --registry-json publication-authority-registry.json \\\n --runner-json runner.json \\\n --control-plane-audit-json control-plane.json \\\n --publication-evidence-json publication-evidence.json \\\n --expected-json expected.json \\\n --used-nonce previous-run-nonce \\\n --json\n```\n\nThe read-only live collector defaults to npm trusted publishing. Other product\nproviders select an explicit adapter:\n\n```bash\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch dev/v2/v2.12 \\\n --source-sha <exact-merged-branch-sha> \\\n --workflow .github/workflows/release-candidate-promote.yml \\\n --workflow-ref <exact-buildchain-sha> \\\n --publisher-workflow .github/workflows/buildchain-ref-promotion.yml \\\n --job promote \\\n --environment none\n\n# Optional stronger external evidence; generate the JSON outside the workflow.\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch dev/v2/v2.12 \\\n --workflow .github/workflows/release-candidate-promote.yml \\\n --publisher-workflow .github/workflows/buildchain-ref-promotion.yml \\\n --job promote \\\n --environment none \\\n --npm-trust-json sanitized-npm-trust.json\n\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch release/v2/v2.12 \\\n --workflow .github/workflows/.binary-release-assets.yml \\\n --job publish \\\n --environment buildchain-release-assets \\\n --publisher-mode github-token\n\nbuildchain audit publication-control-plane \\\n --repository OWNER/CONSUMER \\\n --workflow-repository kungfu-systems/buildchain \\\n --branch main \\\n --workflow .github/workflows/.web-surface.yml \\\n --job production-apply \\\n --environment production \\\n --publisher-mode oidc-role \\\n --provider-audit-json sanitized-oidc-role-audit.json\n```\n\nThe authority workflow identifies the reusable implementation that performs the\npublication job. The publisher workflow identifies the caller filename bound by\nthe provider's trusted-publisher policy; these identities are deliberately\nseparate. `--environment none` is an explicit assertion that the job declares no\nGitHub Environment and the provider policy has no Environment restriction. A\nnamed Environment must exist, be protected, and be declared by the job. The\nBuildchain receipt alone is never sufficient authorization.\n\n## Publication lanes\n\n`Binary Distribution` is evidence-only. It builds platform archives and a\nrelease evidence bundle with read-only repository permissions. GitHub Release\nasset writes live in `Binary Release Assets`, which downloads an exact prior\nevidence run, verifies its bundle digest against the sealed capability, and is\nthe only binary job with `contents: write` in the protected\n`buildchain-release-assets` Environment.\n\nThe npm/promotion, paper, binary-release, and web-production lanes all depend on\nthe independent verifier. Preview, staging, build, source-check, controller,\nand failure-evidence lanes do not inherit product publication capability."
|
|
1048
|
+
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: sealed-publication-authority\ndoc_type: protocol\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: unreviewed\nlast_reviewed: 2026-07-15\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-15\n limits: Live provider configuration must be re-audited; no credential values are represented.\n---\n\n# Sealed Publication Authority\n\nBuildchain publication authority is a closed-world, fail-closed protocol. It does\nnot mint registry or cloud credentials. It independently verifies whether an\nalready protected publication job is allowed to request a short-lived provider\ncredential for one exact product, target, version, channel, and artifact digest.\n\nThe machine-readable authority inventory is\n`dist/site/publication-authority-registry.json`. Any workflow with a write,\nenvironment, OIDC, cloud credential, registry publish, release, or Git push\nsignal must have an explicit descriptor. A new authority-bearing workflow that\nis absent from the inventory fails site generation. Unknown workflows and every\ndescriptor not marked `product-publication` are denied product publication.\n\n## Evidence chain\n\nA qualifying admission binds exact source and runtime SHAs; contract, consumer\npolicy, qualifying controller receipt, Shifu/Gate aggregate, artifact, runner,\nand control-plane digests; repository, authority workflow, provider publisher\nworkflow, Environment policy,\nproduct, target, version, and channel; plus a unique nonce and a lifetime of no\nmore than 15 minutes. Every expected binding is mandatory at verification time;\nan omitted expected field is not a wildcard.\n\nThe independent verifier recomputes every digest and ignores a producer's own\nallow/deny conclusion. It fetches the exact evidence run, validates the actual\nrelease-candidate passport and referenced qualifying controller receipt,\nrecomputes the Shifu Gate aggregate or explicit consumer-owned no-Gate policy,\nrecomputes the downloaded artifact manifests, and hashes every declared product\npayload file against those manifests. The `.buildchain/` diagnostics envelope is\nbound by the manifest digest but excluded from the product-byte set because it can\nbe finalized after the lifecycle scan. The verifier also compares the PR evidence tree to the\nadmitted post-merge source commit tree. It rejects an unknown\nworkflow, stale or replayed nonce, runner downgrade, control-plane drift,\nsource/runtime mismatch, and artifact substitution. A successful result is a\nscoped capability receipt, not a bearer credential.\n\n## Runner and control-plane evidence\n\nRunner evidence uses exactly four classes: `ephemeral`, `reimaged`,\n`persistent-measured`, and `unqualified`. Ephemeral runners also record their\njob-isolation boundary. Reimaged and persistent runners qualify only when a\nclean baseline is proven and baseline, toolchain, cache-contract, and task-\nisolation digests are all present. Otherwise they still emit diagnostic\nevidence with `qualificationStatus = unqualified`, but cannot receive a product\ncapability.\n\nThe external audit records digests and pass/fail status for repository Actions\ndefaults, classic branch protection or an active matching repository ruleset,\ndeclared protected Environment policy or an explicit no-Environment binding,\njob-scoped credentials,\nabsence of long-lived workflow publication credentials, provider authority,\nand authorized runner class. Provider modes are `npm-trusted-publisher`,\n`github-token`, and `oidc-role`. The OIDC-role mode consumes only a sanitized\nprovider audit containing a role digest and qualifying decision; raw IAM policy,\ntokens, or credentials are rejected. Package-owner, cloud-root, GitHub\nadministrator, and registry-root credentials remain outside Buildchain's trust\nboundary. Missing or unreadable facts fail closed.\n\nAn unauthenticated local npm CLI is not evidence that Trusted Publishing is\nmissing. `npm whoami` reports only the local CLI session and does not report the\nOIDC identity that npm creates during `npm publish`. The default read-only audit\ntherefore binds the exact provider, repository, caller workflow, optional\nEnvironment, job-scoped OIDC permission, and absence of long-lived credentials,\nthen records `provider-at-transaction`: npm makes the final authorization\ndecision when `npm publish` exchanges the job's OIDC token. A missing or drifted\ntrusted-publisher configuration consequently denies the transaction safely; it\nis not preflighted through an unrelated long-lived npm login.\n\nAn authenticated external auditor can add stronger point-in-time evidence by\nsupplying sanitized `npm trust list --json` output with `--npm-trust-json`. This\nchanges the publisher fact to `audited-control-plane`; the workflow never runs\n`npm trust list` itself and never receives that auditor's npm credential.\n\nThe credential-free collector proves effective Actions and runner scope from\nthe publication workflow fetched at `--workflow-ref`: explicit read-only\nworkflow defaults, job-scoped write/OIDC permissions, and an exact GitHub-hosted\nrunner label. It does not call repository Actions-default or self-hosted-runner\nadministration endpoints. Branch/ruleset and OIDC subject facts remain live\nread-only provider queries. When the detailed branch-protection endpoint is not\nreadable with the workflow token, `--source-sha` binds the provider's public\nprotected-branch summary to the exact merged PR, independent approval, required\nsuccessful check, same-repository lineage, and current branch head. This records\nprovider-enforced transaction evidence without treating an unavailable\nadministration endpoint as an unprotected branch. It avoids turning a\nrepository-admin token into a publication prerequisite.\n\nFor non-dry-run workflows, missing admission, runner, control-plane, Gate, or\nexpected-binding evidence is rejected before Buildchain downloads candidate\nartifacts. The denial explicitly records that npm Trusted Publishing and OIDC\nwere not evaluated, so downstream diagnostics cannot misclassify an admission\nassembly failure as an npm authentication failure.\n\nBuildchain's own `workflow_run` promotion lane may assemble those inputs only\nfor `kungfu-systems/buildchain`. It downloads the exact prior RC passport,\nsummary, referenced controller receipt, manifests, and product payloads; proves\nthe admitted channel commit has the same Git tree as the RC; performs the live\nread-only control-plane audit; records the GitHub-hosted job as ephemeral runner\nprovenance; and creates an explicit Buildchain-owned no-Gate decision. The\nindependent verifier then recomputes every receipt and payload digest exactly as\nit does for externally supplied admission. The self-assembly mode rejects other\nrepositories, unknown refs, non-exact source SHAs, and any caller other than\n`.github/workflows/buildchain-ref-promotion.yml`. Manual apply and external\nconsumer workflows still require their own explicit admission inputs.\n\nBefore authority verification, the reusable promotion controller runs the same\nrelease transaction selector in read-only mode. That plan supplies one exact\npublication version and tag to the admission verifier, the publish-gate source\nlock, and the real promotion action. The verifier rejects a capability for a\ndifferent version, and the promotion action rechecks the planned version before\nany publish transaction side effect. Release-candidate fixture versions are\nartifact evidence only; they never name Buildchain's own source-lock or\npublication capability.\n\nEvidence publication is a separate authority class and never grants product\npublication.\n\n## API and CLI\n\nUse `@kungfu-tech/buildchain/publication-authority` or run:\n\n```bash\nbuildchain verify publication-admission admission.json \\\n --registry-json publication-authority-registry.json \\\n --runner-json runner.json \\\n --control-plane-audit-json control-plane.json \\\n --publication-evidence-json publication-evidence.json \\\n --expected-json expected.json \\\n --used-nonce previous-run-nonce \\\n --json\n```\n\nThe read-only live collector defaults to npm trusted publishing. Other product\nproviders select an explicit adapter:\n\n```bash\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch dev/v2/v2.12 \\\n --source-sha <exact-merged-branch-sha> \\\n --workflow .github/workflows/release-candidate-promote.yml \\\n --workflow-ref <exact-buildchain-sha> \\\n --publisher-workflow .github/workflows/buildchain-ref-promotion.yml \\\n --job promote \\\n --environment none\n\n# Optional stronger external evidence; generate the JSON outside the workflow.\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch dev/v2/v2.12 \\\n --workflow .github/workflows/release-candidate-promote.yml \\\n --publisher-workflow .github/workflows/buildchain-ref-promotion.yml \\\n --job promote \\\n --environment none \\\n --npm-trust-json sanitized-npm-trust.json\n\nbuildchain audit publication-control-plane \\\n --repository kungfu-systems/buildchain \\\n --branch release/v2/v2.12 \\\n --workflow .github/workflows/.binary-release-assets.yml \\\n --job publish \\\n --environment buildchain-release-assets \\\n --publisher-mode github-token\n\nbuildchain audit publication-control-plane \\\n --repository OWNER/CONSUMER \\\n --workflow-repository kungfu-systems/buildchain \\\n --branch main \\\n --workflow .github/workflows/.web-surface.yml \\\n --job production-apply \\\n --environment production \\\n --publisher-mode oidc-role \\\n --provider-audit-json sanitized-oidc-role-audit.json\n```\n\nThe authority workflow identifies the reusable implementation that performs the\npublication job. The publisher workflow identifies the caller filename bound by\nthe provider's trusted-publisher policy; these identities are deliberately\nseparate. `--environment none` is an explicit assertion that the job declares no\nGitHub Environment and the provider policy has no Environment restriction. A\nnamed Environment must exist, be protected, and be declared by the job. The\nBuildchain receipt alone is never sufficient authorization.\n\n## Publication lanes\n\n`Binary Distribution` is evidence-only. It builds platform archives and a\nrelease evidence bundle with read-only repository permissions. GitHub Release\nasset writes live in `Binary Release Assets`, which downloads an exact prior\nevidence run, verifies its bundle digest against the sealed capability, and is\nthe only binary job with `contents: write` in the protected\n`buildchain-release-assets` Environment.\n\nThe npm/promotion, paper, binary-release, and web-production lanes all depend on\nthe independent verifier. Preview, staging, build, source-check, controller,\nand failure-evidence lanes do not inherit product publication capability."
|
|
1049
1049
|
},
|
|
1050
1050
|
{
|
|
1051
1051
|
"id": "manual:publish-transaction",
|
|
@@ -1645,7 +1645,7 @@
|
|
|
1645
1645
|
],
|
|
1646
1646
|
"maturity": "stable",
|
|
1647
1647
|
"sourcePath": "docs/shifu-gate-profiles.md",
|
|
1648
|
-
"digest": "sha256:
|
|
1648
|
+
"digest": "sha256:919c163a414df5ed562148e4da9e0e3a94718488e7477eb120073e2ee35b5288",
|
|
1649
1649
|
"headings": [
|
|
1650
1650
|
{
|
|
1651
1651
|
"level": 1,
|
|
@@ -1683,7 +1683,7 @@
|
|
|
1683
1683
|
"anchor": "validation-boundary"
|
|
1684
1684
|
}
|
|
1685
1685
|
],
|
|
1686
|
-
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: buildchain-shifu-gate-orchestration\ndoc_type: technical-manual\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: self-reviewed\nlast_reviewed: 2026-07-13\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-13\n invisible_context_boundary: No private runner configuration, credentials, or unpublished Shifu implementation state was used.\n---\n\n# Shifu Gate profile orchestration\n\nBuildchain can schedule and aggregate a project-owned Shifu Gate profile without\nowning that project's gate ids, commands, dependencies, or dev/alpha/release\npolicy. The reusable workflow is\n`.github/workflows/.gate-profile.yml`.\n\n## Ownership boundary\n\n| Concern | Owner | Enforced surface |\n| ----------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------- |\n| Gate schema, profile planning, execution, receipt qualification | Shifu | `shifu gate plan`, `shifu gate run --profile`, `shifu gate receipt validate` |\n| Concrete gate catalog and profile decisions | Consumer project | project Gate registry and detailed Gate docs |\n| Runner labels and declared capabilities | Consumer workflow / Buildchain preset | `runner-preset` or `platforms-json` |\n| Deterministic runner matrix, immutable checkout, receipt transport, aggregate check | Buildchain | `.gate-profile.yml` and `shifu-gate-profile.mjs` |\n| Whether a profile aggregate is required for dev, alpha, or release | Consumer project | protected-branch required-check policy and caller workflow |\n\nBuildchain treats the Shifu plan and receipt as versioned input contracts. It\ndoes not reimplement policy selection, execute raw shell strings, convert an\nexplicit diagnostic gate run into qualification, or mint missing evidence.\n\n## Runner matrix\n\nThe plan job asks the consumer's Shifu entrypoint for one plan per configured\nplatform. A platform is dispatchable only when:\n\n- the Shifu plan is qualifying;\n- every required selection is supported on that platform;\n- the runner declares every capability requested by the selected gates; and\n- all platform plans carry the same project id and registry digest.\n\nConfigured platforms are required by default. A required platform that cannot\nhost the profile fails before runner dispatch. A platform with\n`\"required\": false` may be omitted, but the omission and reasons remain in the\nmatrix and aggregate. Matrix entries retain the Shifu plan digest, ordered gate\ngroups, required/advisory modes, action ids, definition digests, skips, and\nunsupported selections.\n\n`github-hosted` declares only the inherent `node` capability. Projects that\nneed a native compiler, product artifacts, devices, or other facilities must\nuse a suitable preset or declare a custom matrix. Capabilities are scheduling\nclaims, not installation instructions.\n\n```json\n[\n {\n \"id\": \"linux-native\",\n \"name\": \"Linux native\",\n \"platform\": \"linux\",\n \"runner\": \"[\\\"self-hosted\\\",\\\"Linux\\\",\\\"X64\\\",\\\"product-build\\\"]\",\n \"capabilities\": [\"node\", \"native-toolchain\", \"product-artifacts\"]\n }\n]\n```\n\n## Execution and receipts\n\nEvery matrix job checks out the exact source SHA planned by Buildchain, invokes\n`shifu gate run --profile`, writes the receipt outside the source checkout, and\nthen invokes `shifu gate receipt validate`. Buildchain uploads the original\nreceipt and validation result even when the run fails.\n\nThe fixed `Gate profile / aggregate` job fails closed for missing receipts,\ninvalid or stale Shifu validation, dirty or mismatched source SHA, registry or\nplan drift, missing required results, required failures/skips, or gate action\nand definition digest drift. Advisory failures remain visible but do not turn a\nShifu-qualifying receipt into a required failure. Buildchain's aggregate is\n`buildchain.shifu-gate-aggregate/v1`; its digest covers the matrix, receipts,\nper-gate evidence pointers, omissions, and issues.\n\n## Consumer workflow\n\n```yaml\njobs:\n gates:\n uses: kungfu-systems/buildchain/.github/workflows/.gate-profile.yml@v2\n with:\n gate-profile: alpha-pr\n runner-preset: kungfu-v4-self-hosted\n include-advisory: true\n\n build:\n needs: gates\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v2\n with:\n release-candidate: true\n gate-profile-aggregate-json: ${{ needs.gates.outputs.gate-aggregate-json }}\n```\n\nThe command input is an argv map, not a shell string. The default supports the\nordinary Shifu launcher names on all three platforms. A project with a\ndifferent launcher can override it without teaching Buildchain project tasks:\n\n```yaml\ngate-command-json: >-\n {\"linux\":[\"./tools/shifu\"],\"macos\":[\"./tools/shifu\"],\"windows\":[\"./tools/shifu.cmd\"]}\n```\n\n`gate-command-json` is the execution command. If execution needs a cache,\ncontainer, or other project-owned wrapper that should not make the read-only\nplan depend on that service, pass a separate lightweight argv map through\n`gate-plan-command-json`. It defaults to the execution command for backward\ncompatibility; Buildchain still treats both inputs as argv and never evaluates\na shell string.\n\nProjects may also pass non-sensitive scalar environment through\n`gate-environment-json`; Buildchain validates the JSON shape and forwards it\nwithout interpreting names or values. Cache profile references use the same\nopaque `shifu-cache-profile-ref` and `shifu-cache-profile-digest` inputs as the\nreusable build. Do not place tokens, credentials, or other secrets in workflow\ninputs or Gate receipts.\n\nWhen a qualifying aggregate is passed to the build workflow, the\nrelease-candidate passport binds its profile, source SHA, registry digest,\nmatrix digest, aggregate digest, receipt count, and result count. A failed,\nnon-qualifying, or source-mismatched aggregate cannot produce a valid passport.\nPromote-only release validation preserves that same Gate evidence summary in\nthe final Release Passport release identity, so promotion cannot silently drop\nthe qualified profile provenance.\n\n## Failure diagnosis and rollback\n\nStart with the aggregate artifact, then the platform receipt named in its\nissues. Reproduce the exact project decision with Shifu, for example:\n\n```bash\n./shifu gate explain <gate-id> --profile <profile>\n./shifu gate plan <profile> --platform <platform> --json\n./shifu gate receipt validate <receipt.json> --json\n```\n\nThe existing reusable build workflow remains usable without Gate inputs. To\nroll back Gate orchestration, remove the caller's `gates` job and\n`gate-profile-aggregate-json` handoff; this does not alter the consumer's Shifu\nregistry or its direct diagnostic commands.\n\n## Validation boundary\n\nUnit fixtures prove deterministic matrix generation and required/advisory,\ncapability, unsupported, missing, stale, failure, and definition-drift\npropagation. Because a train ref changes runtime scripts but not the outer\nreusable workflow topology, an unreleased `.gate-profile.yml` must also be\nvalidated through a trusted `workflow_dispatch` canary that references the\ntemporary workflow ref or exact SHA. See\n[`runtime-train-validation.md`](runtime-train-validation.md)."
|
|
1686
|
+
"markdown": "---\nstatus: draft\nperiod: ongoing\ntheme: buildchain-shifu-gate-orchestration\ndoc_type: technical-manual\nsource_level: local-files\nconfidence: high\nsensitivity: public\nevidence_grade: B\nreview_state: self-reviewed\nlast_reviewed: 2026-07-13\nai_provenance:\n model_family: GPT-5\n product: Codex\n generated_at: 2026-07-13\n invisible_context_boundary: No private runner configuration, credentials, or unpublished Shifu implementation state was used.\n---\n\n# Shifu Gate profile orchestration\n\nBuildchain can schedule and aggregate a project-owned Shifu Gate profile without\nowning that project's gate ids, commands, dependencies, or dev/alpha/release\npolicy. The reusable workflow is\n`.github/workflows/.gate-profile.yml`.\n\n## Ownership boundary\n\n| Concern | Owner | Enforced surface |\n| ----------------------------------------------------------------------------------- | ------------------------------------- | ---------------------------------------------------------------------------- |\n| Gate schema, profile planning, execution, receipt qualification | Shifu | `shifu gate plan`, `shifu gate run --profile`, `shifu gate receipt validate` |\n| Concrete gate catalog and profile decisions | Consumer project | project Gate registry and detailed Gate docs |\n| Runner labels and declared capabilities | Consumer workflow / Buildchain preset | `runner-preset` or `platforms-json` |\n| Deterministic runner matrix, immutable checkout, receipt transport, aggregate check | Buildchain | `.gate-profile.yml` and `shifu-gate-profile.mjs` |\n| Whether a profile aggregate is required for dev, alpha, or release | Consumer project | protected-branch required-check policy and caller workflow |\n\nBuildchain treats the Shifu plan and receipt as versioned input contracts. It\ndoes not reimplement policy selection, execute raw shell strings, convert an\nexplicit diagnostic gate run into qualification, or mint missing evidence.\n\n## Runner matrix\n\nThe plan job asks the consumer's Shifu entrypoint for one plan per configured\nplatform. A platform is dispatchable only when:\n\n- the Shifu plan is qualifying;\n- every required selection is supported on that platform;\n- the runner declares every capability requested by the selected gates; and\n- all platform plans carry the same project id and registry digest.\n\nConfigured platforms are required by default. A required platform that cannot\nhost the profile fails before runner dispatch. A platform with\n`\"required\": false` may be omitted, but the omission and reasons remain in the\nmatrix and aggregate. Matrix entries retain the Shifu plan digest, ordered gate\ngroups, required/advisory modes, action ids, definition digests, skips, and\nunsupported selections.\n\n`github-hosted` declares only the inherent `node` capability. Projects that\nneed a native compiler, product artifacts, devices, or other facilities must\nuse a suitable preset or declare a custom matrix. Capabilities are scheduling\nclaims, not installation instructions.\n\n```json\n[\n {\n \"id\": \"linux-native\",\n \"name\": \"Linux native\",\n \"platform\": \"linux\",\n \"runner\": \"[\\\"self-hosted\\\",\\\"Linux\\\",\\\"X64\\\",\\\"product-build\\\"]\",\n \"capabilities\": [\"node\", \"native-toolchain\", \"product-artifacts\"]\n }\n]\n```\n\n## Execution and receipts\n\nEvery matrix job checks out the exact source SHA planned by Buildchain, invokes\n`shifu gate run --profile`, writes the receipt outside the source checkout, and\nthen invokes `shifu gate receipt validate`. Buildchain uploads the original\nreceipt and validation result even when the run fails.\n\nBefore invoking the project-owned command, the workflow adds the runner\naccount's `~/.local/bin` directory to `PATH` on Windows, Linux, and macOS. This\nkeeps user-scoped tools such as `uv` available to strict Shifu cache profiles\nwithout assuming an administrator-managed system installation. The consumer or\nrunner owner remains responsible for provisioning the declared tools.\n\nThe fixed `Gate profile / aggregate` job fails closed for missing receipts,\ninvalid or stale Shifu validation, dirty or mismatched source SHA, registry or\nplan drift, missing required results, required failures/skips, or gate action\nand definition digest drift. Advisory failures remain visible but do not turn a\nShifu-qualifying receipt into a required failure. Buildchain's aggregate is\n`buildchain.shifu-gate-aggregate/v1`; its digest covers the matrix, receipts,\nper-gate evidence pointers, omissions, and issues.\n\n## Consumer workflow\n\n```yaml\njobs:\n gates:\n uses: kungfu-systems/buildchain/.github/workflows/.gate-profile.yml@v2\n with:\n gate-profile: alpha-pr\n runner-preset: kungfu-v4-self-hosted\n include-advisory: true\n\n build:\n needs: gates\n uses: kungfu-systems/buildchain/.github/workflows/build.yml@v2\n with:\n release-candidate: true\n gate-profile-aggregate-json: ${{ needs.gates.outputs.gate-aggregate-json }}\n```\n\nThe command input is an argv map, not a shell string. The default supports the\nordinary Shifu launcher names on all three platforms. A project with a\ndifferent launcher can override it without teaching Buildchain project tasks:\n\n```yaml\ngate-command-json: >-\n {\"linux\":[\"./tools/shifu\"],\"macos\":[\"./tools/shifu\"],\"windows\":[\"./tools/shifu.cmd\"]}\n```\n\n`gate-command-json` is the execution command. If execution needs a cache,\ncontainer, or other project-owned wrapper that should not make the read-only\nplan depend on that service, pass a separate lightweight argv map through\n`gate-plan-command-json`. It defaults to the execution command for backward\ncompatibility; Buildchain still treats both inputs as argv and never evaluates\na shell string.\n\nProjects may also pass non-sensitive scalar environment through\n`gate-environment-json`; Buildchain validates the JSON shape and forwards it\nwithout interpreting names or values. Cache profile references use the same\nopaque `shifu-cache-profile-ref` and `shifu-cache-profile-digest` inputs as the\nreusable build. Do not place tokens, credentials, or other secrets in workflow\ninputs or Gate receipts.\n\nWhen a qualifying aggregate is passed to the build workflow, the\nrelease-candidate passport binds its profile, source SHA, registry digest,\nmatrix digest, aggregate digest, receipt count, and result count. A failed,\nnon-qualifying, or source-mismatched aggregate cannot produce a valid passport.\nPromote-only release validation preserves that same Gate evidence summary in\nthe final Release Passport release identity, so promotion cannot silently drop\nthe qualified profile provenance.\n\n## Failure diagnosis and rollback\n\nStart with the aggregate artifact, then the platform receipt named in its\nissues. Reproduce the exact project decision with Shifu, for example:\n\n```bash\n./shifu gate explain <gate-id> --profile <profile>\n./shifu gate plan <profile> --platform <platform> --json\n./shifu gate receipt validate <receipt.json> --json\n```\n\nThe existing reusable build workflow remains usable without Gate inputs. To\nroll back Gate orchestration, remove the caller's `gates` job and\n`gate-profile-aggregate-json` handoff; this does not alter the consumer's Shifu\nregistry or its direct diagnostic commands.\n\n## Validation boundary\n\nUnit fixtures prove deterministic matrix generation and required/advisory,\ncapability, unsupported, missing, stale, failure, and definition-drift\npropagation. Because a train ref changes runtime scripts but not the outer\nreusable workflow topology, an unreleased `.gate-profile.yml` must also be\nvalidated through a trusted `workflow_dispatch` canary that references the\ntemporary workflow ref or exact SHA. See\n[`runtime-train-validation.md`](runtime-train-validation.md)."
|
|
1687
1687
|
},
|
|
1688
1688
|
{
|
|
1689
1689
|
"id": "manual:site-bundle-contract",
|
|
@@ -625,13 +625,14 @@
|
|
|
625
625
|
"package-name",
|
|
626
626
|
"product",
|
|
627
627
|
"publication-target",
|
|
628
|
+
"publication-version",
|
|
628
629
|
"publisher-workflow-path",
|
|
629
630
|
"runner-provenance-json",
|
|
630
631
|
"source-sha",
|
|
631
632
|
"target-ref",
|
|
632
633
|
"used-nonces-json"
|
|
633
634
|
],
|
|
634
|
-
"inputCount":
|
|
635
|
+
"inputCount": 23,
|
|
635
636
|
"secrets": [],
|
|
636
637
|
"secretCount": 0,
|
|
637
638
|
"outputs": [
|
|
@@ -1754,9 +1755,11 @@
|
|
|
1754
1755
|
"branch-protection-bypass-teams",
|
|
1755
1756
|
"branch-protection-bypass-users",
|
|
1756
1757
|
"dry-run",
|
|
1758
|
+
"expected-publication-version",
|
|
1757
1759
|
"generated-ref-update-token",
|
|
1758
1760
|
"generated-status-check-token",
|
|
1759
1761
|
"github-release",
|
|
1762
|
+
"github-release-artifact-paths",
|
|
1760
1763
|
"github-release-notes",
|
|
1761
1764
|
"github-release-title",
|
|
1762
1765
|
"promote-only-release-candidate",
|
|
@@ -1802,7 +1805,7 @@
|
|
|
1802
1805
|
"transaction-state-path",
|
|
1803
1806
|
"verification-command"
|
|
1804
1807
|
],
|
|
1805
|
-
"inputCount":
|
|
1808
|
+
"inputCount": 54
|
|
1806
1809
|
},
|
|
1807
1810
|
{
|
|
1808
1811
|
"id": "report-buildchain-issue",
|
|
@@ -3328,8 +3331,8 @@
|
|
|
3328
3331
|
"workflowRegistryPath": "dist/site/workflow-registry.json",
|
|
3329
3332
|
"pageRegistryPath": "dist/site/page-registry.json",
|
|
3330
3333
|
"cliRegistryDigest": "a6daf4822365bf576425777230246046ebca67b3f8dcfea61fc7a61773776185",
|
|
3331
|
-
"workflowRegistryDigest": "
|
|
3332
|
-
"pageRegistryDigest": "
|
|
3334
|
+
"workflowRegistryDigest": "2b36c3c532082a835a2054ce565b4b5ca39ef1c09b8188a080d5dc4a5909218b",
|
|
3335
|
+
"pageRegistryDigest": "dc526c6f9aefa92aa566a9664374eb4f177f4b3ae5b9480eb94abbbf3a257a30"
|
|
3333
3336
|
},
|
|
3334
3337
|
"comparison": {
|
|
3335
3338
|
"missingCliRegistry": [],
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-publication-release-registry",
|
|
4
|
-
"generatedAt": "2026-07-
|
|
5
|
-
"publishedAt": "2026-07-
|
|
4
|
+
"generatedAt": "2026-07-14T23:35:00.122Z",
|
|
5
|
+
"publishedAt": "2026-07-14T23:35:00.122Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "0729934d3442d37667544dd469c43e14ea1cd2f2",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -32,7 +32,7 @@
|
|
|
32
32
|
},
|
|
33
33
|
"package": {
|
|
34
34
|
"name": "@kungfu-tech/buildchain",
|
|
35
|
-
"version": "2.12.7-alpha.
|
|
35
|
+
"version": "2.12.7-alpha.5",
|
|
36
36
|
"versionSource": "package.json#version"
|
|
37
37
|
},
|
|
38
38
|
"sourceKind": "package-site-bundle",
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
{
|
|
2
2
|
"schemaVersion": 1,
|
|
3
3
|
"contract": "kungfu-buildchain-site-manifest",
|
|
4
|
-
"generatedAt": "2026-07-
|
|
5
|
-
"publishedAt": "2026-07-
|
|
4
|
+
"generatedAt": "2026-07-14T23:35:00.122Z",
|
|
5
|
+
"publishedAt": "2026-07-14T23:35:00.122Z",
|
|
6
6
|
"reproducible": true,
|
|
7
7
|
"timestampPolicy": "ci-injected",
|
|
8
8
|
"deterministicInputs": [
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
"declared Buildchain surface manifest contract"
|
|
20
20
|
],
|
|
21
21
|
"sourceDateEpoch": "0",
|
|
22
|
-
"sourceRevision": "
|
|
22
|
+
"sourceRevision": "0729934d3442d37667544dd469c43e14ea1cd2f2",
|
|
23
23
|
"timestampPolicyDetails": {
|
|
24
24
|
"contract": "kungfu-buildchain-surface-timestamp-policy",
|
|
25
25
|
"timestampFields": [
|
|
@@ -37,7 +37,7 @@
|
|
|
37
37
|
},
|
|
38
38
|
"package": {
|
|
39
39
|
"name": "@kungfu-tech/buildchain",
|
|
40
|
-
"version": "2.12.7-alpha.
|
|
40
|
+
"version": "2.12.7-alpha.5",
|
|
41
41
|
"versionSource": "package.json#version"
|
|
42
42
|
},
|
|
43
43
|
"entrypoint": "buildchain-site.json",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
"path": "docs/publication-authority.md",
|
|
86
86
|
"plane": "verify",
|
|
87
87
|
"exists": true,
|
|
88
|
-
"digest": "sha256:
|
|
88
|
+
"digest": "sha256:06ba05f9d8a2685a0896334b6013a97c45b7d71163cf6898e5a6274baf7f0296"
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
"id": "release-candidate",
|
|
@@ -231,13 +231,14 @@
|
|
|
231
231
|
"package-name",
|
|
232
232
|
"product",
|
|
233
233
|
"publication-target",
|
|
234
|
+
"publication-version",
|
|
234
235
|
"publisher-workflow-path",
|
|
235
236
|
"runner-provenance-json",
|
|
236
237
|
"source-sha",
|
|
237
238
|
"target-ref",
|
|
238
239
|
"used-nonces-json"
|
|
239
240
|
],
|
|
240
|
-
"inputCount":
|
|
241
|
+
"inputCount": 23,
|
|
241
242
|
"secrets": [],
|
|
242
243
|
"secretCount": 0,
|
|
243
244
|
"outputs": [
|
|
@@ -1487,9 +1488,11 @@
|
|
|
1487
1488
|
"branch-protection-bypass-teams",
|
|
1488
1489
|
"branch-protection-bypass-users",
|
|
1489
1490
|
"dry-run",
|
|
1491
|
+
"expected-publication-version",
|
|
1490
1492
|
"generated-ref-update-token",
|
|
1491
1493
|
"generated-status-check-token",
|
|
1492
1494
|
"github-release",
|
|
1495
|
+
"github-release-artifact-paths",
|
|
1493
1496
|
"github-release-notes",
|
|
1494
1497
|
"github-release-title",
|
|
1495
1498
|
"promote-only-release-candidate",
|
|
@@ -1535,7 +1538,7 @@
|
|
|
1535
1538
|
"transaction-state-path",
|
|
1536
1539
|
"verification-command"
|
|
1537
1540
|
],
|
|
1538
|
-
"inputCount":
|
|
1541
|
+
"inputCount": 54,
|
|
1539
1542
|
"capabilityGroup": "release-passport-trust",
|
|
1540
1543
|
"status": "active"
|
|
1541
1544
|
},
|
|
@@ -228,12 +228,19 @@ The preset:
|
|
|
228
228
|
before any publish side effect;
|
|
229
229
|
- publishes the package through npm Trusted Publishing;
|
|
230
230
|
- writes Buildchain release/passport evidence; and
|
|
231
|
-
- creates or updates the exact-version GitHub Release by default
|
|
231
|
+
- creates or updates the exact-version GitHub Release by default, uploading
|
|
232
|
+
every file declared by `publication.primary_artifact` and
|
|
233
|
+
`publication.artifact_paths` alongside the release evidence.
|
|
232
234
|
|
|
233
235
|
Consumers can opt out of the GitHub Release with `github-release: false`, but
|
|
234
236
|
the default is on so downstream release propagation can observe
|
|
235
237
|
`release.published` without hand-written `gh release` steps.
|
|
236
238
|
|
|
239
|
+
Declared publication artifacts are resolved from the generated publication
|
|
240
|
+
manifest rather than repeated in consumer workflow YAML. Publication fails
|
|
241
|
+
before upload if a declared artifact is missing or if its basename would
|
|
242
|
+
collide with another GitHub Release asset.
|
|
243
|
+
|
|
237
244
|
For npm Trusted Publishing, register the consumer workflow file that calls this
|
|
238
245
|
preset, for example `.github/workflows/paper-release.yml`, against the declared
|
|
239
246
|
package in npm. The trusted publisher is the consumer repository and workflow
|
|
@@ -8,11 +8,11 @@ confidence: high
|
|
|
8
8
|
sensitivity: public
|
|
9
9
|
evidence_grade: B
|
|
10
10
|
review_state: unreviewed
|
|
11
|
-
last_reviewed: 2026-07-
|
|
11
|
+
last_reviewed: 2026-07-15
|
|
12
12
|
ai_provenance:
|
|
13
13
|
model_family: GPT-5
|
|
14
14
|
product: Codex
|
|
15
|
-
generated_at: 2026-07-
|
|
15
|
+
generated_at: 2026-07-15
|
|
16
16
|
limits: Live provider configuration must be re-audited; no credential values are represented.
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -121,6 +121,15 @@ repositories, unknown refs, non-exact source SHAs, and any caller other than
|
|
|
121
121
|
`.github/workflows/buildchain-ref-promotion.yml`. Manual apply and external
|
|
122
122
|
consumer workflows still require their own explicit admission inputs.
|
|
123
123
|
|
|
124
|
+
Before authority verification, the reusable promotion controller runs the same
|
|
125
|
+
release transaction selector in read-only mode. That plan supplies one exact
|
|
126
|
+
publication version and tag to the admission verifier, the publish-gate source
|
|
127
|
+
lock, and the real promotion action. The verifier rejects a capability for a
|
|
128
|
+
different version, and the promotion action rechecks the planned version before
|
|
129
|
+
any publish transaction side effect. Release-candidate fixture versions are
|
|
130
|
+
artifact evidence only; they never name Buildchain's own source-lock or
|
|
131
|
+
publication capability.
|
|
132
|
+
|
|
124
133
|
Evidence publication is a separate authority class and never grants product
|
|
125
134
|
publication.
|
|
126
135
|
|
|
@@ -78,6 +78,12 @@ Every matrix job checks out the exact source SHA planned by Buildchain, invokes
|
|
|
78
78
|
then invokes `shifu gate receipt validate`. Buildchain uploads the original
|
|
79
79
|
receipt and validation result even when the run fails.
|
|
80
80
|
|
|
81
|
+
Before invoking the project-owned command, the workflow adds the runner
|
|
82
|
+
account's `~/.local/bin` directory to `PATH` on Windows, Linux, and macOS. This
|
|
83
|
+
keeps user-scoped tools such as `uv` available to strict Shifu cache profiles
|
|
84
|
+
without assuming an administrator-managed system installation. The consumer or
|
|
85
|
+
runner owner remains responsible for provisioning the declared tools.
|
|
86
|
+
|
|
81
87
|
The fixed `Gate profile / aggregate` job fails closed for missing receipts,
|
|
82
88
|
invalid or stale Shifu validation, dirty or mismatched source SHA, registry or
|
|
83
89
|
plan drift, missing required results, required failures/skips, or gate action
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungfu-tech/buildchain",
|
|
3
|
-
"version": "2.12.7-alpha.
|
|
3
|
+
"version": "2.12.7-alpha.5",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "Buildchain Release Passport, release governance, CLI toolkit, and site facts.",
|
|
6
6
|
"repository": "https://github.com/kungfu-systems/buildchain",
|
|
@@ -303,7 +303,7 @@ function normalizeEvidence(entries = []) {
|
|
|
303
303
|
function receiptStatus(plan, stages) {
|
|
304
304
|
if (stages.some((stage) => stage.status === "failed")) return "failed";
|
|
305
305
|
if (stages.length > 0 && stages.every((stage) => stage.status === "skipped")) return "skipped";
|
|
306
|
-
if (stages.some((stage) => stage.status === "cancelled" || stage.status === "missing")) return "partial";
|
|
306
|
+
if (stages.some((stage) => stage.status === "cancelled" || (stage.required && stage.status === "missing"))) return "partial";
|
|
307
307
|
const required = new Set(plan.expected.stages.filter((stage) => stage.required).map((stage) => stage.id));
|
|
308
308
|
if (stages.filter((stage) => required.has(stage.id)).every((stage) => stage.status === "passed")) return "passed";
|
|
309
309
|
return "partial";
|
|
@@ -137,6 +137,7 @@ async function main() {
|
|
|
137
137
|
isolation: "github-hosted-single-job",
|
|
138
138
|
});
|
|
139
139
|
const packageJson = JSON.parse(fs.readFileSync(path.join(runtimeRoot, "package.json"), "utf8"));
|
|
140
|
+
const publicationVersion = required("BUILDCHAIN_PUBLICATION_VERSION");
|
|
140
141
|
const issuedAt = new Date();
|
|
141
142
|
const admission = createPublicationAdmission({
|
|
142
143
|
registryDigest: registry.registryDigest,
|
|
@@ -154,7 +155,7 @@ async function main() {
|
|
|
154
155
|
environment: process.env.BUILDCHAIN_PUBLICATION_ENVIRONMENT || "none",
|
|
155
156
|
product: process.env.BUILDCHAIN_PUBLICATION_PRODUCT || "Buildchain",
|
|
156
157
|
target: process.env.BUILDCHAIN_PUBLICATION_TARGET || `npm:${packageJson.name}`,
|
|
157
|
-
version:
|
|
158
|
+
version: publicationVersion,
|
|
158
159
|
channel: required("BUILDCHAIN_PUBLICATION_CHANNEL"),
|
|
159
160
|
artifactDigest: artifactSet.manifestSetDigest,
|
|
160
161
|
nonce: `${required("GITHUB_RUN_ID")}:${required("GITHUB_RUN_ATTEMPT")}:${sourceSha}`,
|
|
@@ -840,6 +840,9 @@ for (const requiredSnippet of [
|
|
|
840
840
|
"publish-source-ref: ${{ steps.publish-gate.outputs.ref }}",
|
|
841
841
|
"publish-source-sha: ${{ steps.publish-gate.outputs.sha }}",
|
|
842
842
|
"publish-source-locked: ${{ steps.publish-gate.outputs.locked }}",
|
|
843
|
+
"expected-publication-version: ${{ needs.publication-plan.outputs.version }}",
|
|
844
|
+
"publication-version: ${{ needs.publication-plan.outputs.version }}",
|
|
845
|
+
"name: Plan exact publication version",
|
|
843
846
|
"DRY_RUN: ${{ inputs.dry-run }}",
|
|
844
847
|
"if (dryRun) {",
|
|
845
848
|
"Enforce Buildchain stable release canary gate",
|
|
@@ -202,6 +202,8 @@ export async function classifyWorkflowFriction({
|
|
|
202
202
|
buildWorkflowName = DEFAULT_BUILD_WORKFLOW_NAME,
|
|
203
203
|
releaseCandidateOutcome = env("BUILDCHAIN_RC_RESOLVE_OUTCOME"),
|
|
204
204
|
releaseCandidateDiagnosis = env("BUILDCHAIN_RC_DIAGNOSIS"),
|
|
205
|
+
promotionOutcome = env("BUILDCHAIN_PROMOTION_OUTCOME"),
|
|
206
|
+
promotionDiagnosis = env("BUILDCHAIN_PROMOTION_DIAGNOSIS"),
|
|
205
207
|
runUrl = env("BUILDCHAIN_WORKFLOW_RUN_URL"),
|
|
206
208
|
outputDir = ".buildchain/workflow-friction",
|
|
207
209
|
fetchImpl = globalThis.fetch,
|
|
@@ -256,14 +258,23 @@ export async function classifyWorkflowFriction({
|
|
|
256
258
|
if (releaseCandidateOutcome === "failure") {
|
|
257
259
|
diagnosisParts.push("Promotion reached the post-Verify workflow before required PR-stage RC evidence could be resolved.");
|
|
258
260
|
}
|
|
259
|
-
if (releaseCandidateDiagnosis) {
|
|
261
|
+
if (releaseCandidateOutcome === "failure" && releaseCandidateDiagnosis) {
|
|
260
262
|
diagnosisParts.push(releaseCandidateDiagnosis);
|
|
261
263
|
}
|
|
264
|
+
if (promotionOutcome === "failure") {
|
|
265
|
+
diagnosisParts.push(
|
|
266
|
+
promotionDiagnosis
|
|
267
|
+
? `Promotion failed: ${promotionDiagnosis}`
|
|
268
|
+
: "Promotion failed after PR-stage release-candidate evidence resolved successfully.",
|
|
269
|
+
);
|
|
270
|
+
}
|
|
262
271
|
diagnosisParts.push(...workflowRunDiagnostics);
|
|
263
272
|
const diagnosis = diagnosisParts.join(" ") || "Buildchain ref promotion failed after Verify succeeded; inspect the classified evidence and keep the fix in Buildchain.";
|
|
264
273
|
const nextAction = frictionClass === "late-fail-fast"
|
|
265
274
|
? "Move the missing/stale RC evidence check earlier or make the promotion workflow consume the exact PR-stage RC passport before any publish side effect."
|
|
266
|
-
: "
|
|
275
|
+
: ["duplicate-channel-pr", "duplicate-heavy-build"].includes(frictionClass)
|
|
276
|
+
? "Deduplicate the PR/build path or tighten Buildchain workflow gates so the next channel promotion reaches publish exactly once."
|
|
277
|
+
: "Fix the concrete promotion failure above, then rerun through the protected channel workflow; do not treat successful RC resolution as the failure diagnosis.";
|
|
267
278
|
fs.mkdirSync(outputDir, { recursive: true });
|
|
268
279
|
const bodyFile = path.join(outputDir, "issue-body.md");
|
|
269
280
|
const body = buildWorkflowFrictionBody({
|