@kungfu-tech/buildchain 2.13.0 → 2.14.0-alpha.0
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/bin/buildchain.mjs +13 -0
- package/dist/site/buildchain-contract.json +23 -18
- package/dist/site/buildchain-site.json +33 -28
- package/dist/site/capability-registry.json +1 -1
- package/dist/site/cli-registry.json +12 -0
- package/dist/site/controller-registry.json +6 -2
- package/dist/site/kfd-claims.json +21 -8
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +8 -8
- package/dist/site/node-api-registry.json +5 -5
- package/dist/site/page-registry.json +21 -16
- package/dist/site/public-surface-audit.json +27 -6
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +12 -12
- package/dist/site/workflow-registry.json +2 -1
- package/docs/MAP.md +2 -1
- package/docs/cli.md +19 -0
- package/docs/publication-authority.md +24 -0
- package/docs/release-flow.md +2 -1
- package/docs/release-governance.md +49 -2
- package/docs/release-propagation.md +9 -0
- package/docs/versioning.md +1 -0
- package/docs/web-surface-deployments.md +18 -4
- package/package.json +2 -2
- package/packages/core/index.js +8 -0
- package/packages/core/publication-authority.js +52 -2
- package/packages/core/release-line-bootstrap.js +5 -0
- package/packages/core/web-surface-publication-candidate.js +162 -0
- package/scripts/assemble-web-surface-publication-admission.mjs +204 -0
- package/scripts/check-action-bundles.mjs +50 -0
- package/scripts/dev-merge-queue.mjs +257 -0
- package/scripts/generate-site-bundle.mjs +2 -0
- package/scripts/verify-web-surface-publication-capability.mjs +78 -0
- package/scripts/web-surface-production-decision.mjs +138 -0
|
@@ -3,11 +3,11 @@
|
|
|
3
3
|
"contract": "kungfu-buildchain-public-surface-reverse-audit",
|
|
4
4
|
"status": "passed",
|
|
5
5
|
"summary": {
|
|
6
|
-
"cliCommandCount":
|
|
6
|
+
"cliCommandCount": 82,
|
|
7
7
|
"workflowCount": 47,
|
|
8
8
|
"actionCount": 4,
|
|
9
9
|
"sitePageCount": 50,
|
|
10
|
-
"docCommandRefCount":
|
|
10
|
+
"docCommandRefCount": 253,
|
|
11
11
|
"failureCount": 0
|
|
12
12
|
},
|
|
13
13
|
"enumerated": {
|
|
@@ -57,6 +57,11 @@
|
|
|
57
57
|
"source": "bin/buildchain.mjs",
|
|
58
58
|
"usage": "buildchain create publication-admission --input-json <file-or-json> [--output <file>] [--json]"
|
|
59
59
|
},
|
|
60
|
+
{
|
|
61
|
+
"id": "dev",
|
|
62
|
+
"source": "bin/buildchain.mjs",
|
|
63
|
+
"usage": "buildchain dev merge-queue --repository <owner/repo> --branch <dev/vN/vN.M>"
|
|
64
|
+
},
|
|
60
65
|
{
|
|
61
66
|
"id": "diagnostics",
|
|
62
67
|
"source": "bin/buildchain.mjs",
|
|
@@ -932,6 +937,7 @@
|
|
|
932
937
|
"publication-admission-json",
|
|
933
938
|
"publication-control-plane-audit-json",
|
|
934
939
|
"publication-expected-json",
|
|
940
|
+
"publication-gate-aggregate-json",
|
|
935
941
|
"publication-runner-provenance-json",
|
|
936
942
|
"publication-used-nonces-json",
|
|
937
943
|
"release-feedback-actor-privacy",
|
|
@@ -941,7 +947,7 @@
|
|
|
941
947
|
"verify-command",
|
|
942
948
|
"working-directory"
|
|
943
949
|
],
|
|
944
|
-
"inputCount":
|
|
950
|
+
"inputCount": 39,
|
|
945
951
|
"secrets": [
|
|
946
952
|
"production-release-app-private-key"
|
|
947
953
|
],
|
|
@@ -2409,6 +2415,21 @@
|
|
|
2409
2415
|
"path": "docs/release-passport.md",
|
|
2410
2416
|
"command": "buildchain collect github-release"
|
|
2411
2417
|
},
|
|
2418
|
+
{
|
|
2419
|
+
"id": "dev",
|
|
2420
|
+
"path": "docs/cli.md",
|
|
2421
|
+
"command": "buildchain dev merge-queue"
|
|
2422
|
+
},
|
|
2423
|
+
{
|
|
2424
|
+
"id": "dev",
|
|
2425
|
+
"path": "docs/cli.md",
|
|
2426
|
+
"command": "buildchain dev merge-queue"
|
|
2427
|
+
},
|
|
2428
|
+
{
|
|
2429
|
+
"id": "dev",
|
|
2430
|
+
"path": "docs/release-governance.md",
|
|
2431
|
+
"command": "buildchain dev merge-queue"
|
|
2432
|
+
},
|
|
2412
2433
|
{
|
|
2413
2434
|
"id": "diagnostics-summary",
|
|
2414
2435
|
"path": "docs/cli.md",
|
|
@@ -3440,9 +3461,9 @@
|
|
|
3440
3461
|
"cliRegistryPath": "dist/site/cli-registry.json",
|
|
3441
3462
|
"workflowRegistryPath": "dist/site/workflow-registry.json",
|
|
3442
3463
|
"pageRegistryPath": "dist/site/page-registry.json",
|
|
3443
|
-
"cliRegistryDigest": "
|
|
3444
|
-
"workflowRegistryDigest": "
|
|
3445
|
-
"pageRegistryDigest": "
|
|
3464
|
+
"cliRegistryDigest": "b07ed2241d34696ad0500c3431b2106b1499a0d4372a77385a8c0e0698421d76",
|
|
3465
|
+
"workflowRegistryDigest": "62b7ca87803c461e1e1436a477c3b6b70103eed84dbf14d855d383e810d7d71e",
|
|
3466
|
+
"pageRegistryDigest": "453e38e1964516ad602ec8bb6a8b23e54177effafdc867069ac0e6218c6b46ed"
|
|
3446
3467
|
},
|
|
3447
3468
|
"comparison": {
|
|
3448
3469
|
"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-16T17:11:20.307Z",
|
|
5
|
+
"publishedAt": "2026-07-16T17:11:20.307Z",
|
|
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": "d20ec69c151eacc49d4fe22afbd738f960f2553c",
|
|
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.
|
|
35
|
+
"version": "2.14.0-alpha.0",
|
|
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-16T17:11:20.307Z",
|
|
5
|
+
"publishedAt": "2026-07-16T17:11:20.307Z",
|
|
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": "d20ec69c151eacc49d4fe22afbd738f960f2553c",
|
|
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.
|
|
40
|
+
"version": "2.14.0-alpha.0",
|
|
41
41
|
"versionSource": "package.json#version"
|
|
42
42
|
},
|
|
43
43
|
"entrypoint": "buildchain-site.json",
|
|
@@ -53,7 +53,7 @@
|
|
|
53
53
|
"path": "docs/MAP.md",
|
|
54
54
|
"plane": "use",
|
|
55
55
|
"exists": true,
|
|
56
|
-
"digest": "sha256:
|
|
56
|
+
"digest": "sha256:a9a9594c0bd9584b145a8f41847db83e297c1c4d1b8b2d7c4bf8d10264ab1cef"
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
"id": "install",
|
|
@@ -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:e191d248a52fc6488aef48050949ed0fd31064ab2a64cca2a5b529eeb68f0ff6"
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
"id": "release-candidate",
|
|
@@ -101,7 +101,7 @@
|
|
|
101
101
|
"path": "docs/release-propagation.md",
|
|
102
102
|
"plane": "use",
|
|
103
103
|
"exists": true,
|
|
104
|
-
"digest": "sha256:
|
|
104
|
+
"digest": "sha256:d5877075eb41a3d41e531549da113756d29d6f34c91e3b68b8ce650753d5ca1d"
|
|
105
105
|
},
|
|
106
106
|
{
|
|
107
107
|
"id": "readme-badges",
|
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
"path": "docs/cli.md",
|
|
190
190
|
"plane": "use",
|
|
191
191
|
"exists": true,
|
|
192
|
-
"digest": "sha256:
|
|
192
|
+
"digest": "sha256:a7a31bbec048acbc9759324c5421c7ea0734f394f8d6705b63d70654867fdfa6"
|
|
193
193
|
},
|
|
194
194
|
{
|
|
195
195
|
"id": "build-facts",
|
|
@@ -237,7 +237,7 @@
|
|
|
237
237
|
"path": "docs/release-governance.md",
|
|
238
238
|
"plane": "why",
|
|
239
239
|
"exists": true,
|
|
240
|
-
"digest": "sha256:
|
|
240
|
+
"digest": "sha256:e97fd55d09facff9a6a5087fca5881d9756f33e791c9c3b9f9a8164ed2030c1d"
|
|
241
241
|
},
|
|
242
242
|
{
|
|
243
243
|
"id": "release-flow",
|
|
@@ -245,7 +245,7 @@
|
|
|
245
245
|
"path": "docs/release-flow.md",
|
|
246
246
|
"plane": "verify",
|
|
247
247
|
"exists": true,
|
|
248
|
-
"digest": "sha256:
|
|
248
|
+
"digest": "sha256:a2f68d42f34acc35940e135285df5ba510d91b15b9d9ede8cabbe8bfa6ab0305"
|
|
249
249
|
},
|
|
250
250
|
{
|
|
251
251
|
"id": "runtime-train-validation",
|
|
@@ -261,7 +261,7 @@
|
|
|
261
261
|
"path": "docs/versioning.md",
|
|
262
262
|
"plane": "why",
|
|
263
263
|
"exists": true,
|
|
264
|
-
"digest": "sha256:
|
|
264
|
+
"digest": "sha256:c3dce313b846fb36c69e4a725d086226ff2e875c376cc10e8554a0aff2f67c93"
|
|
265
265
|
},
|
|
266
266
|
{
|
|
267
267
|
"id": "web-surface-deployments",
|
|
@@ -269,7 +269,7 @@
|
|
|
269
269
|
"path": "docs/web-surface-deployments.md",
|
|
270
270
|
"plane": "use",
|
|
271
271
|
"exists": true,
|
|
272
|
-
"digest": "sha256:
|
|
272
|
+
"digest": "sha256:797d8f0e81974a49125b17256bb8b4a85fc60673e06d6bbecbbf399651163437"
|
|
273
273
|
}
|
|
274
274
|
],
|
|
275
275
|
"facts": [
|
|
@@ -555,6 +555,7 @@
|
|
|
555
555
|
"publication-admission-json",
|
|
556
556
|
"publication-control-plane-audit-json",
|
|
557
557
|
"publication-expected-json",
|
|
558
|
+
"publication-gate-aggregate-json",
|
|
558
559
|
"publication-runner-provenance-json",
|
|
559
560
|
"publication-used-nonces-json",
|
|
560
561
|
"release-feedback-actor-privacy",
|
|
@@ -564,7 +565,7 @@
|
|
|
564
565
|
"verify-command",
|
|
565
566
|
"working-directory"
|
|
566
567
|
],
|
|
567
|
-
"inputCount":
|
|
568
|
+
"inputCount": 39,
|
|
568
569
|
"secrets": [
|
|
569
570
|
"production-release-app-private-key"
|
|
570
571
|
],
|
package/docs/MAP.md
CHANGED
|
@@ -34,7 +34,7 @@ workflow, action, and Node API export also carries a `capabilityGroup`,
|
|
|
34
34
|
| Publication Artifacts | `publication-registry.json`, `workflow-registry.json`, `node-api-registry.json`, `manual-registry.json`, `kungfu-buildchain-publication-artifact-registry` | [`publication-artifacts.md`](publication-artifacts.md), [`reusable-build-surface.md`](reusable-build-surface.md) |
|
|
35
35
|
| Distribution Indexes and Badges | `badge-endpoint-registry.json`, `node-api-registry.json`, `manual-registry.json` | [`readme-badges.md`](readme-badges.md), [`homebrew.md`](homebrew.md) |
|
|
36
36
|
| Build Facts, Observability, and Diagnostics | `cli-registry.json`, `node-api-registry.json`, lifecycle artifacts | [`build-facts.md`](build-facts.md), [`toolkit-observability.md`](toolkit-observability.md), [`consumer-issue-reporting.md`](consumer-issue-reporting.md) |
|
|
37
|
-
| Governance, Versioning, and Runtime Drift | `buildchain-contract.json`, `workflow-registry.json`, `release-model.json` | [`release-governance.md`](release-governance.md), [`release-flow.md`](release-flow.md), [`versioning.md`](versioning.md), [`runtime-train-validation.md`](runtime-train-validation.md) |
|
|
37
|
+
| Governance, Versioning, and Runtime Drift | `buildchain-contract.json`, `workflow-registry.json`, `release-model.json` | [`release-governance.md`](release-governance.md), [`release-flow.md`](release-flow.md), [`versioning.md`](versioning.md), [`runtime-train-validation.md`](runtime-train-validation.md), [`cli.md`](cli.md) |
|
|
38
38
|
| CLI and Node API Reference | `cli-registry.json`, `node-api-registry.json`, `workflow-registry.json`, `manual-registry.json` | [`cli.md`](cli.md), [`../packages/core/README.md`](../packages/core/README.md) |
|
|
39
39
|
|
|
40
40
|
| Capability | Machine-readable entry | Manual entry |
|
|
@@ -72,6 +72,7 @@ replace them.
|
|
|
72
72
|
| How do I initialize a new repository? | [`cli.md`](cli.md) + [`lifecycle-protocol.md`](lifecycle-protocol.md) | use | stable |
|
|
73
73
|
| Why does Buildchain use branch-driven release governance? | [`release-governance.md`](release-governance.md) | why | stable |
|
|
74
74
|
| How do protected dev branches and scheduled ready-PR merging work? | [`release-governance.md`](release-governance.md#protected-dev-branches) | use | stable |
|
|
75
|
+
| How do slow required checks land reliably on a busy dev channel? | [`release-governance.md`](release-governance.md#protected-dev-branches) + [`cli.md`](cli.md#commands) | use | preview |
|
|
75
76
|
| How do I run daily, weekly, or monthly repository patrols? | [`release-governance.md`](release-governance.md#buildchain-patrol) | use | stable |
|
|
76
77
|
| How does Buildchain decide patch, minor, and major release lines? | [`versioning.md`](versioning.md) | why | stable |
|
|
77
78
|
| What exact branch/tag state machine runs on alpha, release, and major gate? | [`release-flow.md`](release-flow.md) | verify | stable |
|
package/docs/cli.md
CHANGED
|
@@ -152,6 +152,25 @@ buildchain lifecycle run build \
|
|
|
152
152
|
--artifact-name "{repo}-{version}-{platform}"
|
|
153
153
|
```
|
|
154
154
|
|
|
155
|
+
`buildchain dev merge-queue` plans a GitHub merge-queue policy for a protected
|
|
156
|
+
Buildchain dev channel. Declare every workflow that emits a required check; the
|
|
157
|
+
command fails closed unless each file handles both `pull_request` and
|
|
158
|
+
`merge_group` without reading `github.event.pull_request` directly:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
buildchain dev merge-queue \
|
|
162
|
+
--repository kungfu-systems/example \
|
|
163
|
+
--branch dev/v4/v4.0 \
|
|
164
|
+
--workflow .github/workflows/source-acceptance.yml \
|
|
165
|
+
--workflow .github/workflows/affected-native-pr.yml
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
The default output is a read-only plan. Add `--apply` only after reviewing it.
|
|
169
|
+
Apply creates the exact-branch merge-queue ruleset before changing classic
|
|
170
|
+
required status checks from strict to loose, preserves the required check
|
|
171
|
+
identities, and is safe to repeat. `gh` must be authenticated with repository
|
|
172
|
+
Administration write permission for apply mode.
|
|
173
|
+
|
|
155
174
|
`buildchain release line open` plans or writes the first version-state commit
|
|
156
175
|
for a new semver minor line. It does not publish anything. The dry-run mode is
|
|
157
176
|
the default and returns the dev/alpha/release refs, protection contract, default
|
|
@@ -136,6 +136,30 @@ publication capability.
|
|
|
136
136
|
Evidence publication is a separate authority class and never grants product
|
|
137
137
|
publication.
|
|
138
138
|
|
|
139
|
+
## Managed web-surface production
|
|
140
|
+
|
|
141
|
+
The reusable web-surface controller owns a complete standard producer path for
|
|
142
|
+
its documented production mechanisms. A reviewed matching release-PR merge or a
|
|
143
|
+
manual dispatch by an actor with current repository write authority creates a
|
|
144
|
+
signed decision bound to the exact source SHA. After build, verify, and
|
|
145
|
+
production planning, the workflow creates a qualifying pre-publication
|
|
146
|
+
controller receipt and assembles a ten-minute admission over the source tree,
|
|
147
|
+
immutable Buildchain runtime, deployment plan, artifact hash, production
|
|
148
|
+
Environment, AWS role/deploy target, runner provenance, decision digest, and
|
|
149
|
+
nonce. The independent verifier emits the scoped `web-production` capability.
|
|
150
|
+
|
|
151
|
+
The production job rechecks the capability and candidate against the same plan
|
|
152
|
+
before downloading product artifacts. AWS authorization is deliberately
|
|
153
|
+
recorded as `provider-at-transaction`: the capability binds the exact role and
|
|
154
|
+
Environment, while `configure-aws-credentials` performs the live OIDC exchange
|
|
155
|
+
and remains the final provider authorization gate before mutation. Buildchain
|
|
156
|
+
does not claim that an IAM trust relationship passed before that transaction.
|
|
157
|
+
|
|
158
|
+
Externally assembled admissions remain an optional compatibility path and must
|
|
159
|
+
provide the full admission, runner, control-plane, Gate aggregate, expected
|
|
160
|
+
bindings, and nonce set. They are not required for the managed web-surface
|
|
161
|
+
release-PR or trusted-manual paths.
|
|
162
|
+
|
|
139
163
|
## Consumer qualification handoff
|
|
140
164
|
|
|
141
165
|
Consumers may explicitly opt in to a final, consumer-owned qualification
|
package/docs/release-flow.md
CHANGED
|
@@ -106,7 +106,8 @@ When the workflow is run with `apply=true`, Buildchain:
|
|
|
106
106
|
- creates `dev/v2/v2.10` from that commit;
|
|
107
107
|
- creates `alpha/v2/v2.10` and `release/v2/v2.10` from the selected source ref;
|
|
108
108
|
- applies branch protection with one approving review and the configured
|
|
109
|
-
required status check;
|
|
109
|
+
required status check; dev starts strict, while alpha and release also require
|
|
110
|
+
the pair-specific `verify` aggregate without a source-up-to-date ancestry loop;
|
|
110
111
|
- switches the repository default branch to the new dev line when requested;
|
|
111
112
|
- opens the first `dev/v2/v2.10 -> alpha/v2/v2.10` channel PR when requested.
|
|
112
113
|
|
|
@@ -84,6 +84,13 @@ The implementation is intentionally stricter than a local release script:
|
|
|
84
84
|
- non-dry-run promotion must be driven by a completed `Verify` workflow;
|
|
85
85
|
- target branch protection details must be readable, and branch protection must
|
|
86
86
|
apply to administrators as well as regular contributors;
|
|
87
|
+
- `alpha/vX/vX.Y` and `release/vX/vX.Y` branch protection must require both the
|
|
88
|
+
general `check` context and the Release Verify aggregate `verify` context, so
|
|
89
|
+
an invalid channel pair cannot merge even when repository checks pass;
|
|
90
|
+
- release targets keep those checks non-strict with respect to source-branch
|
|
91
|
+
ancestry: generated channel bookkeeping intentionally makes the source and
|
|
92
|
+
target histories diverge, while the pair-specific `verify` context validates
|
|
93
|
+
the legal channel transition;
|
|
87
94
|
- alpha promotion must come from a merged same-repository PR from
|
|
88
95
|
`dev/vX/vX.Y` to `alpha/vX/vX.Y`;
|
|
89
96
|
- release promotion must come from a merged same-repository PR from
|
|
@@ -385,6 +392,37 @@ This keeps the earliest development channel audit-friendly:
|
|
|
385
392
|
- later `dev -> alpha -> release` promotion inherits a reviewable source
|
|
386
393
|
lineage instead of trying to reconstruct how the dev branch changed.
|
|
387
394
|
|
|
395
|
+
When required checks take longer than the normal dev-channel commit interval,
|
|
396
|
+
classic strict up-to-date protection can become a non-converging retry loop:
|
|
397
|
+
each base update invalidates a completed check set and rebasing restarts the
|
|
398
|
+
same slow checks. Buildchain supports GitHub merge queues for that channel
|
|
399
|
+
shape. The queue validates the projected merged result and serializes the final
|
|
400
|
+
ref update, so concurrent channel movement no longer invalidates the candidate.
|
|
401
|
+
|
|
402
|
+
Every required workflow must handle both `pull_request` and `merge_group`
|
|
403
|
+
before the queue is enabled. Queue runs do not provide
|
|
404
|
+
`github.event.pull_request`; required workflows must use the checked-out
|
|
405
|
+
`github.sha` or event-neutral source facts. The governance command is dry-run by
|
|
406
|
+
default and refuses to enable a queue when a declared required workflow lacks
|
|
407
|
+
either trigger or still reads the pull-request-only payload directly:
|
|
408
|
+
|
|
409
|
+
```bash
|
|
410
|
+
buildchain dev merge-queue \
|
|
411
|
+
--repository owner/repository \
|
|
412
|
+
--branch dev/v4/v4.0 \
|
|
413
|
+
--workflow .github/workflows/source-acceptance.yml \
|
|
414
|
+
--workflow .github/workflows/affected-native-pr.yml
|
|
415
|
+
```
|
|
416
|
+
|
|
417
|
+
After reviewing the plan, repeat with `--apply`. Buildchain creates or updates
|
|
418
|
+
an exact-branch `merge_queue` ruleset first, then changes only the classic
|
|
419
|
+
required-status-check policy from strict to loose. Reviews, administrator
|
|
420
|
+
enforcement, conversation resolution, required check identities, force-push
|
|
421
|
+
protection, and deletion protection remain owned by the existing branch
|
|
422
|
+
protection. The ruleset uses the first merge method that the repository itself
|
|
423
|
+
allows, and fails closed when the repository has no enabled merge method.
|
|
424
|
+
Re-running the command is idempotent.
|
|
425
|
+
|
|
388
426
|
Buildchain provides the reusable
|
|
389
427
|
`.github/workflows/dev-pr-auto-merge.yml` workflow for repositories that want a
|
|
390
428
|
scheduled or manual "merge ready dev PRs" pass. The consumer repository owns
|
|
@@ -561,8 +599,11 @@ to the action, that explicit command overrides `lifecycle.verify`.
|
|
|
561
599
|
|
|
562
600
|
Protected release-line branches keep their normal human review gate. Managed
|
|
563
601
|
`dev/vN/vN.M`, `alpha/vN/vN.M`, and `release/vN/vN.M` branches are configured
|
|
564
|
-
with one required approving review,
|
|
565
|
-
enforcement, conversation resolution, no force pushes, and no deletions.
|
|
602
|
+
with one required approving review, required GitHub Actions checks, administrator
|
|
603
|
+
enforcement, conversation resolution, no force pushes, and no deletions. Dev
|
|
604
|
+
keeps its repository-selected strict or merge-queue policy. Alpha and release
|
|
605
|
+
require both `check` and the pair-specific `verify` aggregate without requiring
|
|
606
|
+
the source branch to contain the target's generated bookkeeping history. The
|
|
566
607
|
reusable `release-candidate-promote.yml` wrapper defaults
|
|
567
608
|
`branch-protection-bypass-apps` to `github-actions`, which lets the workflow's
|
|
568
609
|
automation identity apply generated version-state or post-publish channel
|
|
@@ -662,6 +703,12 @@ the supported path for downstream
|
|
|
662
703
|
`release.published` propagation across semver, major, and promote-only release
|
|
663
704
|
candidate publication models.
|
|
664
705
|
|
|
706
|
+
Published GitHub Release assets are immutable evidence. A repeated promotion
|
|
707
|
+
preserves an existing asset when its SHA-256 digest matches the regenerated
|
|
708
|
+
bytes, uploads only missing assets, and fails with an immutable-release
|
|
709
|
+
collision when a same-name asset has different bytes. It never deletes and
|
|
710
|
+
replaces an existing asset during retry or duplicate workflow delivery.
|
|
711
|
+
|
|
665
712
|
Buildchain also does not maintain bare exact tags such as `1.0.0`. The supported
|
|
666
713
|
exact release and alpha refs are v-prefixed:
|
|
667
714
|
|
|
@@ -187,6 +187,15 @@ jobs:
|
|
|
187
187
|
propagation-token: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}
|
|
188
188
|
```
|
|
189
189
|
|
|
190
|
+
The downstream branch name may be reused across upstream releases. Before
|
|
191
|
+
replacing an existing managed branch, the workflow reads its exact remote SHA
|
|
192
|
+
and pushes with an explicit `--force-with-lease=<ref>:<sha>`. A surviving branch
|
|
193
|
+
from a merged PR is therefore reconciled without manual deletion, while a
|
|
194
|
+
concurrent writer makes the lease fail closed. The controller receipt includes a
|
|
195
|
+
`propagation-branch-reconciliation` evidence file recording the branch, observed
|
|
196
|
+
remote SHA, pushed SHA, lease mode, and the deterministically created or updated
|
|
197
|
+
open PR.
|
|
198
|
+
|
|
190
199
|
The workflow checks out the Buildchain runtime selected by
|
|
191
200
|
`buildchain-repository` and `buildchain-ref` into `.buildchain/runtime`, invokes
|
|
192
201
|
that runtime for the propagation plan and lock write, then checks out the
|
package/docs/versioning.md
CHANGED
|
@@ -61,6 +61,7 @@ repository changes are patch".
|
|
|
61
61
|
|
|
62
62
|
| Date | Action | Line | Faces | Class | Rationale | PR |
|
|
63
63
|
| --- | --- | --- | --- | --- | --- | --- |
|
|
64
|
+
| 2026-07-16 | open-minor | `v2.14` | dev-merge-queue-governance | additive | The public CLI adds a dry-run-first, idempotent merge-queue governance command that verifies required workflow event compatibility before applying an exact dev-channel ruleset and removing the strict up-to-date race. | |
|
|
64
65
|
| 2026-07-15 | open-minor | `v2.13` | artifact-verification-envelope, package-subpaths | additive | The public envelope seals exact artifact, provenance, identity, lifecycle, revocation, and existing KFD assessment roots into one consumer-ready KFX admission input, with a dedicated Node API export and fail-closed verifier. | |
|
|
65
66
|
| 2026-07-11 | open-minor | `v2.12` | channel-build-router, channel-selection-protocol | additive | The public `build.yml` reusable workflow lets consumers declare one build job while Buildchain selects generic major alpha for development/prerelease intent and stable major for production release intent, with explicit overrides, separate locks, and fail-closed ambiguity handling. | |
|
|
66
67
|
| 2026-07-08 | open-minor | `v2.9` | build-facts-contract | additive | Build Facts add a public CLI command family, Node API export, config protocol, module/product fact contracts, release-passport evidence section, and Kungfu legacy buildinfo projection from the same source facts. | |
|
|
@@ -746,11 +746,25 @@ When enabled, Buildchain owns the full release apply state machine:
|
|
|
746
746
|
action. Consumers do not need to hand-write `gh pr create` or production
|
|
747
747
|
release-intent glue.
|
|
748
748
|
- Production runs when `production-apply` is true and either:
|
|
749
|
-
- a
|
|
749
|
+
- a `workflow_dispatch` passes `production-approved=true` and the triggering
|
|
750
|
+
actor currently has `write`, `maintain`, or `admin` permission; or
|
|
750
751
|
- `production-release-on-main=true` and the `main` push commit is associated
|
|
751
752
|
with exactly one same-repository, merged release pull request matching
|
|
752
753
|
`production-release-label` and `production-release-head-prefix`.
|
|
753
754
|
The production job is then gated by the configured GitHub Environment.
|
|
755
|
+
- Before production artifact download, Buildchain assembles a managed sealed
|
|
756
|
+
publication capability from the exact source/runtime SHAs, production plan
|
|
757
|
+
and artifact hash, a qualifying pre-publication controller receipt, the
|
|
758
|
+
trusted manual or reviewed-release-PR decision, production Environment and
|
|
759
|
+
AWS role target, an ephemeral-runner receipt, and a fresh nonce. Production
|
|
760
|
+
revalidates that capability against the downloaded plan before it downloads
|
|
761
|
+
product bytes. The later AWS OIDC exchange remains the provider's final
|
|
762
|
+
transaction-time authorization decision and fails closed before deploy apply.
|
|
763
|
+
- The `publication-*-json` inputs are an advanced external-evidence
|
|
764
|
+
compatibility path, not a prerequisite for the standard release-PR or trusted
|
|
765
|
+
manual mechanisms. External evidence must now include
|
|
766
|
+
`publication-gate-aggregate-json`; supplying only a partial set still fails
|
|
767
|
+
closed.
|
|
754
768
|
- Production apply writes a production release feedback passport artifact and
|
|
755
769
|
comments the release PR with the production URL, source SHA, artifact
|
|
756
770
|
identity, run URL, rollback pointer, and failure context when apply did not
|
|
@@ -844,9 +858,9 @@ another release PR.
|
|
|
844
858
|
|
|
845
859
|
Apply-only inputs are validated before the caller build or verification command
|
|
846
860
|
runs. If the current event would run preview, staging, or production apply,
|
|
847
|
-
missing role inputs
|
|
848
|
-
|
|
849
|
-
first.
|
|
861
|
+
missing role inputs, a production apply without `production-approved=true` on
|
|
862
|
+
manual dispatch, or a manual actor without repository write authority fail
|
|
863
|
+
immediately instead of spending the build and plan jobs first.
|
|
850
864
|
|
|
851
865
|
Callers must grant `id-token: write` for OIDC role assumption. Preview comments
|
|
852
866
|
need `pull-requests: write`. Automatic release PR creation also needs
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungfu-tech/buildchain",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.14.0-alpha.0",
|
|
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",
|
|
@@ -85,7 +85,7 @@
|
|
|
85
85
|
},
|
|
86
86
|
"packageManager": "pnpm@11.7.0",
|
|
87
87
|
"scripts": {
|
|
88
|
-
"check": "node scripts/check-inventory.mjs && pnpm run check:site && pnpm run check:workflows && pnpm run test:unit &&
|
|
88
|
+
"check": "node scripts/check-inventory.mjs && pnpm run check:site && pnpm run check:workflows && pnpm run test:unit && node scripts/check-action-bundles.mjs",
|
|
89
89
|
"check:workflows": "bash scripts/check-workflows.sh",
|
|
90
90
|
"generate:site": "node scripts/generate-site-bundle.mjs",
|
|
91
91
|
"check:site": "node scripts/generate-site-bundle.mjs --check",
|
package/packages/core/index.js
CHANGED
|
@@ -166,6 +166,14 @@ export {
|
|
|
166
166
|
resolvePublicationCandidateFile,
|
|
167
167
|
} from "./publication-artifact-candidate.js";
|
|
168
168
|
|
|
169
|
+
export {
|
|
170
|
+
WEB_SURFACE_PRODUCTION_DECISION_CONTRACT,
|
|
171
|
+
WEB_SURFACE_PUBLICATION_CANDIDATE_CONTRACT,
|
|
172
|
+
createWebSurfaceProductionDecision,
|
|
173
|
+
createWebSurfacePublicationCandidate,
|
|
174
|
+
webSurfacePublicationDigest,
|
|
175
|
+
} from "./web-surface-publication-candidate.js";
|
|
176
|
+
|
|
169
177
|
export {
|
|
170
178
|
buildchainPublicationAuthorityDescriptors,
|
|
171
179
|
createBuildchainPublicationAuthorityRegistry,
|
|
@@ -3,6 +3,7 @@ import crypto from "node:crypto";
|
|
|
3
3
|
import { validateControllerReceipt } from "./controller-evidence.js";
|
|
4
4
|
import { createPublicationArtifactCandidate } from "./publication-artifact-candidate.js";
|
|
5
5
|
import { sha256Json, validateReleaseCandidatePassport } from "./release-candidate.js";
|
|
6
|
+
import { createWebSurfacePublicationCandidate } from "./web-surface-publication-candidate.js";
|
|
6
7
|
|
|
7
8
|
export const PUBLICATION_AUTHORITY_REGISTRY_CONTRACT =
|
|
8
9
|
"kungfu-buildchain-publication-authority-registry";
|
|
@@ -451,9 +452,9 @@ export function publicationGateAggregateBindings(gateAggregate) {
|
|
|
451
452
|
};
|
|
452
453
|
}
|
|
453
454
|
|
|
454
|
-
function validateGateAggregate(gateAggregate, { admission, passport }) {
|
|
455
|
+
function validateGateAggregate(gateAggregate, { admission, passport, sourceSha = "" }) {
|
|
455
456
|
const bindings = publicationGateAggregateBindings(gateAggregate);
|
|
456
|
-
const passportSourceSha = passport
|
|
457
|
+
const passportSourceSha = sourceSha || passport?.source?.headSha || passport?.source?.sha;
|
|
457
458
|
if (![admission.sourceSha, passportSourceSha].includes(bindings.sourceSha)) {
|
|
458
459
|
throw new Error("gate aggregate source SHA mismatch");
|
|
459
460
|
}
|
|
@@ -464,6 +465,55 @@ function validatePublicationEvidence(publicationEvidence, admission) {
|
|
|
464
465
|
if (!publicationEvidence || typeof publicationEvidence !== "object" || Array.isArray(publicationEvidence)) {
|
|
465
466
|
throw new Error("independent publication evidence is required");
|
|
466
467
|
}
|
|
468
|
+
if (publicationEvidence.webSurfaceCandidate) {
|
|
469
|
+
const evidence = publicationEvidence.webSurfaceCandidate;
|
|
470
|
+
const candidate = createWebSurfacePublicationCandidate(evidence);
|
|
471
|
+
const controllerReceiptDigest = normalizeDigest(
|
|
472
|
+
evidence.controllerReceipt.digest,
|
|
473
|
+
"controllerReceipt.digest",
|
|
474
|
+
);
|
|
475
|
+
if (
|
|
476
|
+
controllerReceiptDigest !==
|
|
477
|
+
normalizeDigest(admission.controllerReceiptDigest, "admission.controllerReceiptDigest")
|
|
478
|
+
) {
|
|
479
|
+
throw new Error("controller receipt evidence binding mismatch");
|
|
480
|
+
}
|
|
481
|
+
const contractDigest = normalizeDigest(
|
|
482
|
+
evidence.controllerReceipt.runtime?.contractDigest,
|
|
483
|
+
"controllerReceipt.runtime.contractDigest",
|
|
484
|
+
);
|
|
485
|
+
if (contractDigest !== normalizeDigest(admission.contractDigest, "admission.contractDigest")) {
|
|
486
|
+
throw new Error("runtime contract evidence binding mismatch");
|
|
487
|
+
}
|
|
488
|
+
const gate = validateGateAggregate(publicationEvidence.gateAggregate, {
|
|
489
|
+
admission,
|
|
490
|
+
sourceSha: candidate.sourceSha,
|
|
491
|
+
});
|
|
492
|
+
if (gate.gateAggregateDigest !== normalizeDigest(admission.gateAggregateDigest, "admission.gateAggregateDigest")) {
|
|
493
|
+
throw new Error("Gate aggregate evidence binding mismatch");
|
|
494
|
+
}
|
|
495
|
+
if (gate.policyDigest !== normalizeDigest(admission.policyDigest, "admission.policyDigest")) {
|
|
496
|
+
throw new Error("Gate policy evidence binding mismatch");
|
|
497
|
+
}
|
|
498
|
+
if (candidate.candidateDigest !== normalizeDigest(admission.artifactDigest, "admission.artifactDigest")) {
|
|
499
|
+
throw new Error("web-surface publication candidate evidence binding mismatch");
|
|
500
|
+
}
|
|
501
|
+
return {
|
|
502
|
+
sourceTreeSha: candidate.sourceTreeSha,
|
|
503
|
+
controllerReceiptDigest,
|
|
504
|
+
contractDigest,
|
|
505
|
+
gateAggregateDigest: gate.gateAggregateDigest,
|
|
506
|
+
policyDigest: gate.policyDigest,
|
|
507
|
+
gateRegistryDigest: gate.registryDigest,
|
|
508
|
+
artifactDigest: candidate.candidateDigest,
|
|
509
|
+
evidenceDigest: publicationAuthorityDigest({
|
|
510
|
+
sourceTreeSha: candidate.sourceTreeSha,
|
|
511
|
+
controllerReceiptDigest,
|
|
512
|
+
gateAggregateDigest: gate.gateAggregateDigest,
|
|
513
|
+
artifactDigest: candidate.candidateDigest,
|
|
514
|
+
}),
|
|
515
|
+
};
|
|
516
|
+
}
|
|
467
517
|
if (publicationEvidence.publicationArtifactCandidate) {
|
|
468
518
|
const candidate = createPublicationArtifactCandidate(publicationEvidence.publicationArtifactCandidate);
|
|
469
519
|
const passport = publicationEvidence.publicationArtifactCandidate.passport;
|
|
@@ -191,6 +191,11 @@ export function planReleaseLineBootstrap({
|
|
|
191
191
|
protection: {
|
|
192
192
|
requiredStatusCheck,
|
|
193
193
|
strictStatusChecks: true,
|
|
194
|
+
strictStatusChecksByChannel: {
|
|
195
|
+
dev: true,
|
|
196
|
+
alpha: false,
|
|
197
|
+
release: false,
|
|
198
|
+
},
|
|
194
199
|
requiredApprovingReviewCount: approvalCount,
|
|
195
200
|
requiredConversationResolution: true,
|
|
196
201
|
enforceAdmins: true,
|