@kungfu-tech/buildchain 2.12.7-alpha.21 → 2.12.7-alpha.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/actions/promote-buildchain-ref/README.md +1 -5
- package/dist/site/buildchain-contract.json +23 -48
- package/dist/site/buildchain-site.json +16 -16
- package/dist/site/capability-registry.json +1 -1
- package/dist/site/controller-registry.json +3 -23
- package/dist/site/kfd-claims.json +9 -63
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +2 -2
- package/dist/site/node-api-registry.json +6 -6
- package/dist/site/page-registry.json +10 -10
- package/dist/site/public-surface-audit.json +9 -72
- package/dist/site/publication-authority-registry.json +1 -25
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/site-manifest.json +6 -6
- package/dist/site/workflow-registry.json +6 -72
- package/docs/publication-artifacts.md +20 -30
- package/docs/publication-authority.md +9 -21
- package/docs/release-candidate.md +0 -19
- package/docs/shifu-gate-profiles.md +0 -6
- package/package.json +1 -1
- package/packages/core/buildchain-publication-authority.js +0 -1
- package/packages/core/controller-evidence.js +1 -1
- package/packages/core/index.js +0 -7
- package/packages/core/publication-authority.js +2 -41
- package/packages/core/publication-control-plane-audit.js +1 -3
- package/scripts/assemble-self-publication-admission.mjs +9 -19
- package/scripts/audit-publication-control-plane.mjs +2 -5
- package/scripts/check-inventory.mjs +0 -3
- package/scripts/locked-source-checkout.mjs +2 -22
- package/scripts/workflow-friction-report.mjs +2 -13
- package/packages/core/publication-artifact-candidate.js +0 -128
- package/scripts/assemble-publication-artifact-admission.mjs +0 -190
- package/scripts/publication-artifact-candidate.mjs +0 -122
|
@@ -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-14T16:58:46.295Z",
|
|
5
|
+
"publishedAt": "2026-07-14T16:58:46.295Z",
|
|
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": "a80e367748620f3c1cb16a08d81c854131ed6d89",
|
|
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.3",
|
|
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-14T16:58:46.295Z",
|
|
5
|
+
"publishedAt": "2026-07-14T16:58:46.295Z",
|
|
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": "a80e367748620f3c1cb16a08d81c854131ed6d89",
|
|
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.3",
|
|
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:fc08e6657a1b586b6b8b5618ca4f49dfaa85955687f5bba8e2e69e7513fe6c71"
|
|
89
89
|
},
|
|
90
90
|
{
|
|
91
91
|
"id": "release-candidate",
|
|
@@ -93,7 +93,7 @@
|
|
|
93
93
|
"path": "docs/release-candidate.md",
|
|
94
94
|
"plane": "verify",
|
|
95
95
|
"exists": true,
|
|
96
|
-
"digest": "sha256:
|
|
96
|
+
"digest": "sha256:841d6f3281ba6dfe80527e4f149807bdbd05d41f9e94afe1c446fcd6d29e307c"
|
|
97
97
|
},
|
|
98
98
|
{
|
|
99
99
|
"id": "release-propagation",
|
|
@@ -215,19 +215,14 @@
|
|
|
215
215
|
"reusable": true,
|
|
216
216
|
"inputs": [
|
|
217
217
|
"admission-json",
|
|
218
|
-
"authority-workflow-path",
|
|
219
218
|
"auto-admission",
|
|
220
|
-
"auto-admission-kind",
|
|
221
|
-
"auto-no-gate",
|
|
222
219
|
"buildchain-ref",
|
|
223
220
|
"buildchain-repository",
|
|
224
221
|
"control-plane-audit-json",
|
|
225
222
|
"dry-run",
|
|
226
|
-
"evidence-controller-artifact",
|
|
227
223
|
"evidence-manifest-pattern",
|
|
228
224
|
"evidence-passport-artifact",
|
|
229
225
|
"evidence-payload-pattern",
|
|
230
|
-
"evidence-publication-artifact",
|
|
231
226
|
"evidence-repository",
|
|
232
227
|
"evidence-run-id",
|
|
233
228
|
"evidence-summary-artifact",
|
|
@@ -236,15 +231,13 @@
|
|
|
236
231
|
"package-name",
|
|
237
232
|
"product",
|
|
238
233
|
"publication-target",
|
|
239
|
-
"publication-version",
|
|
240
234
|
"publisher-workflow-path",
|
|
241
|
-
"required-status-check",
|
|
242
235
|
"runner-provenance-json",
|
|
243
236
|
"source-sha",
|
|
244
237
|
"target-ref",
|
|
245
238
|
"used-nonces-json"
|
|
246
239
|
],
|
|
247
|
-
"inputCount":
|
|
240
|
+
"inputCount": 22,
|
|
248
241
|
"secrets": [],
|
|
249
242
|
"secretCount": 0,
|
|
250
243
|
"outputs": [
|
|
@@ -1031,54 +1024,6 @@
|
|
|
1031
1024
|
"capabilityGroup": "api-cli-reference",
|
|
1032
1025
|
"status": "active"
|
|
1033
1026
|
},
|
|
1034
|
-
{
|
|
1035
|
-
"id": "paper-release-sealed",
|
|
1036
|
-
"path": ".github/workflows/paper-release-sealed.yml",
|
|
1037
|
-
"reusable": true,
|
|
1038
|
-
"inputs": [
|
|
1039
|
-
"artifact-name",
|
|
1040
|
-
"artifact-paths",
|
|
1041
|
-
"artifact-retention-days",
|
|
1042
|
-
"branch-protection-bypass-apps",
|
|
1043
|
-
"branch-protection-bypass-teams",
|
|
1044
|
-
"branch-protection-bypass-users",
|
|
1045
|
-
"buildchain-contract-lock-path",
|
|
1046
|
-
"buildchain-ref",
|
|
1047
|
-
"buildchain-repository",
|
|
1048
|
-
"dry-run",
|
|
1049
|
-
"github-release",
|
|
1050
|
-
"github-release-notes",
|
|
1051
|
-
"github-release-title",
|
|
1052
|
-
"package-name",
|
|
1053
|
-
"publish-dist-tag",
|
|
1054
|
-
"publisher-workflow-path",
|
|
1055
|
-
"release-passport-impact-json",
|
|
1056
|
-
"release-passport-output-dir",
|
|
1057
|
-
"release-passport-product-name",
|
|
1058
|
-
"required-status-check",
|
|
1059
|
-
"target-ref",
|
|
1060
|
-
"target-sha",
|
|
1061
|
-
"toolchain-type",
|
|
1062
|
-
"verify-command",
|
|
1063
|
-
"working-directory"
|
|
1064
|
-
],
|
|
1065
|
-
"inputCount": 25,
|
|
1066
|
-
"secrets": [
|
|
1067
|
-
"BUILDCHAIN_PROMOTION_TOKEN"
|
|
1068
|
-
],
|
|
1069
|
-
"secretCount": 1,
|
|
1070
|
-
"outputs": [
|
|
1071
|
-
"github-release-url",
|
|
1072
|
-
"package-name",
|
|
1073
|
-
"package-version",
|
|
1074
|
-
"public-release-tag",
|
|
1075
|
-
"release-passport-path"
|
|
1076
|
-
],
|
|
1077
|
-
"outputCount": 5,
|
|
1078
|
-
"surface": "repository-workflow",
|
|
1079
|
-
"capabilityGroup": "api-cli-reference",
|
|
1080
|
-
"status": "active"
|
|
1081
|
-
},
|
|
1082
1027
|
{
|
|
1083
1028
|
"id": "paper-release",
|
|
1084
1029
|
"path": ".github/workflows/paper-release.yml",
|
|
@@ -1248,11 +1193,7 @@
|
|
|
1248
1193
|
"buildchain-ref",
|
|
1249
1194
|
"buildchain-repository",
|
|
1250
1195
|
"node-version",
|
|
1251
|
-
"package-name",
|
|
1252
|
-
"prepare-paper-package",
|
|
1253
|
-
"publish-dist-tag",
|
|
1254
1196
|
"setup-node",
|
|
1255
|
-
"target-ref",
|
|
1256
1197
|
"toolchain-command",
|
|
1257
1198
|
"toolchain-digest",
|
|
1258
1199
|
"toolchain-image",
|
|
@@ -1260,7 +1201,7 @@
|
|
|
1260
1201
|
"verify-command",
|
|
1261
1202
|
"working-directory"
|
|
1262
1203
|
],
|
|
1263
|
-
"inputCount":
|
|
1204
|
+
"inputCount": 17,
|
|
1264
1205
|
"secrets": [],
|
|
1265
1206
|
"secretCount": 0,
|
|
1266
1207
|
"outputs": [
|
|
@@ -1271,17 +1212,13 @@
|
|
|
1271
1212
|
"controller-receipt-digest",
|
|
1272
1213
|
"controller-receipt-json",
|
|
1273
1214
|
"controller-receipt-status",
|
|
1274
|
-
"package-name",
|
|
1275
|
-
"package-version",
|
|
1276
1215
|
"publication-artifact-name",
|
|
1277
1216
|
"publication-manifest-json",
|
|
1278
1217
|
"publication-manifest-path",
|
|
1279
1218
|
"publication-passport-path",
|
|
1280
|
-
"publication-registry-path"
|
|
1281
|
-
"publish-dist-tag",
|
|
1282
|
-
"runtime-sha"
|
|
1219
|
+
"publication-registry-path"
|
|
1283
1220
|
],
|
|
1284
|
-
"outputCount":
|
|
1221
|
+
"outputCount": 12,
|
|
1285
1222
|
"surface": "repository-workflow",
|
|
1286
1223
|
"capabilityGroup": "reusable-build",
|
|
1287
1224
|
"status": "active"
|
|
@@ -1310,7 +1247,6 @@
|
|
|
1310
1247
|
"package-manager",
|
|
1311
1248
|
"publication-admission-json",
|
|
1312
1249
|
"publication-auto-admission",
|
|
1313
|
-
"publication-auto-no-gate",
|
|
1314
1250
|
"publication-control-plane-audit-json",
|
|
1315
1251
|
"publication-expected-json",
|
|
1316
1252
|
"publication-gate-aggregate-json",
|
|
@@ -1348,7 +1284,7 @@
|
|
|
1348
1284
|
"target-sha",
|
|
1349
1285
|
"trusted-publishing"
|
|
1350
1286
|
],
|
|
1351
|
-
"inputCount":
|
|
1287
|
+
"inputCount": 55,
|
|
1352
1288
|
"secrets": [
|
|
1353
1289
|
"BUILDCHAIN_ISSUE_APP_ID",
|
|
1354
1290
|
"BUILDCHAIN_ISSUE_APP_PRIVATE_KEY",
|
|
@@ -1551,11 +1487,9 @@
|
|
|
1551
1487
|
"branch-protection-bypass-teams",
|
|
1552
1488
|
"branch-protection-bypass-users",
|
|
1553
1489
|
"dry-run",
|
|
1554
|
-
"expected-publication-version",
|
|
1555
1490
|
"generated-ref-update-token",
|
|
1556
1491
|
"generated-status-check-token",
|
|
1557
1492
|
"github-release",
|
|
1558
|
-
"github-release-artifact-paths",
|
|
1559
1493
|
"github-release-notes",
|
|
1560
1494
|
"github-release-title",
|
|
1561
1495
|
"promote-only-release-candidate",
|
|
@@ -1601,7 +1535,7 @@
|
|
|
1601
1535
|
"transaction-state-path",
|
|
1602
1536
|
"verification-command"
|
|
1603
1537
|
],
|
|
1604
|
-
"inputCount":
|
|
1538
|
+
"inputCount": 52,
|
|
1605
1539
|
"capabilityGroup": "release-passport-trust",
|
|
1606
1540
|
"status": "active"
|
|
1607
1541
|
},
|
|
@@ -182,42 +182,40 @@ on:
|
|
|
182
182
|
|
|
183
183
|
jobs:
|
|
184
184
|
paper-release:
|
|
185
|
-
uses: kungfu-systems/buildchain/.github/workflows/paper-release
|
|
185
|
+
uses: kungfu-systems/buildchain/.github/workflows/paper-release.yml@v2
|
|
186
186
|
permissions:
|
|
187
|
-
actions: read
|
|
188
187
|
checks: write
|
|
189
188
|
contents: write
|
|
190
189
|
id-token: write
|
|
191
190
|
issues: write
|
|
192
191
|
with:
|
|
193
192
|
buildchain-ref: ${{ inputs.buildchain-ref || '' }}
|
|
194
|
-
|
|
193
|
+
publication-admission-json: ${{ needs.authority.outputs.admission-json }}
|
|
194
|
+
publication-runner-provenance-json: ${{ needs.authority.outputs.runner-provenance-json }}
|
|
195
|
+
publication-control-plane-audit-json: ${{ needs.authority.outputs.control-plane-audit-json }}
|
|
196
|
+
publication-expected-json: ${{ needs.authority.outputs.expected-json }}
|
|
195
197
|
toolchain-type: config
|
|
196
198
|
verify-command: make check
|
|
197
|
-
artifact-paths: _build/paper-name.pdf
|
|
198
199
|
buildchain-contract-lock-path: .buildchain/contract-lock.json
|
|
199
|
-
secrets:
|
|
200
|
-
BUILDCHAIN_PROMOTION_TOKEN: ${{ secrets.BUILDCHAIN_PROMOTION_TOKEN }}
|
|
201
200
|
```
|
|
202
201
|
|
|
203
|
-
The
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
admitted candidate, recomputes the capability binding, and publishes without
|
|
212
|
-
executing consumer build commands. npm binds the OIDC identity to the consumer
|
|
213
|
-
workflow named by `publisher-workflow-path`.
|
|
202
|
+
The publication job does not accept a long-lived promotion token. The caller
|
|
203
|
+
must first produce a fresh sealed admission, runner provenance, external
|
|
204
|
+
control-plane audit, and exact expected bindings. The credential-free verifier
|
|
205
|
+
job checks those receipts; only then can the publication job use its short-lived
|
|
206
|
+
`github.token` and caller-bound OIDC trusted publisher identity. npm binds that
|
|
207
|
+
identity to the consumer workflow filename; an npm Environment restriction is
|
|
208
|
+
optional and must be represented explicitly when configured. The workflow fails
|
|
209
|
+
before the publication build when the target branch protection cannot be read.
|
|
214
210
|
|
|
215
211
|
The preset:
|
|
216
212
|
|
|
217
|
-
- resolves the floating Buildchain runtime
|
|
218
|
-
|
|
213
|
+
- resolves the same floating Buildchain runtime and contract lock as the build
|
|
214
|
+
workflow;
|
|
215
|
+
- verifies that the declared promotion authority can read the protected target
|
|
216
|
+
channel before starting the publication build;
|
|
219
217
|
- builds the PDF through the declared pinned LaTeX Docker toolchain or custom
|
|
220
|
-
command
|
|
218
|
+
command;
|
|
221
219
|
- verifies the paper repository;
|
|
222
220
|
- writes the publication manifest, publication passport, optional archive
|
|
223
221
|
registry, and source bundle;
|
|
@@ -228,22 +226,14 @@ The preset:
|
|
|
228
226
|
- creates a `publish-gate/<alpha|release>/.../<version>` source lock for the
|
|
229
227
|
channel commit and requires `promote-buildchain-ref` to verify that lock
|
|
230
228
|
before any publish side effect;
|
|
231
|
-
-
|
|
232
|
-
package through npm Trusted Publishing without rebuilding it;
|
|
229
|
+
- publishes the package through npm Trusted Publishing;
|
|
233
230
|
- writes Buildchain release/passport evidence; and
|
|
234
|
-
- creates or updates the exact-version GitHub Release by default
|
|
235
|
-
every file declared by `publication.primary_artifact` and
|
|
236
|
-
`publication.artifact_paths` alongside the release evidence.
|
|
231
|
+
- creates or updates the exact-version GitHub Release by default.
|
|
237
232
|
|
|
238
233
|
Consumers can opt out of the GitHub Release with `github-release: false`, but
|
|
239
234
|
the default is on so downstream release propagation can observe
|
|
240
235
|
`release.published` without hand-written `gh release` steps.
|
|
241
236
|
|
|
242
|
-
Declared publication artifacts are resolved from the generated publication
|
|
243
|
-
manifest rather than repeated in consumer workflow YAML. Publication fails
|
|
244
|
-
before upload if a declared artifact is missing or if its basename would
|
|
245
|
-
collide with another GitHub Release asset.
|
|
246
|
-
|
|
247
237
|
For npm Trusted Publishing, register the consumer workflow file that calls this
|
|
248
238
|
preset, for example `.github/workflows/paper-release.yml`, against the declared
|
|
249
239
|
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-14
|
|
12
12
|
ai_provenance:
|
|
13
13
|
model_family: GPT-5
|
|
14
14
|
product: Codex
|
|
15
|
-
generated_at: 2026-07-
|
|
15
|
+
generated_at: 2026-07-14
|
|
16
16
|
limits: Live provider configuration must be re-audited; no credential values are represented.
|
|
17
17
|
---
|
|
18
18
|
|
|
@@ -109,29 +109,17 @@ artifacts. The denial explicitly records that npm Trusted Publishing and OIDC
|
|
|
109
109
|
were not evaluated, so downstream diagnostics cannot misclassify an admission
|
|
110
110
|
assembly failure as an npm authentication failure.
|
|
111
111
|
|
|
112
|
-
|
|
113
|
-
|
|
112
|
+
Buildchain's own `workflow_run` promotion lane may assemble those inputs only
|
|
113
|
+
for `kungfu-systems/buildchain`. It downloads the exact prior RC passport,
|
|
114
114
|
summary, referenced controller receipt, manifests, and product payloads; proves
|
|
115
115
|
the admitted channel commit has the same Git tree as the RC; performs the live
|
|
116
116
|
read-only control-plane audit; records the GitHub-hosted job as ephemeral runner
|
|
117
|
-
provenance; and
|
|
118
|
-
caller no-Gate decision. The
|
|
117
|
+
provenance; and creates an explicit Buildchain-owned no-Gate decision. The
|
|
119
118
|
independent verifier then recomputes every receipt and payload digest exactly as
|
|
120
|
-
it does for externally supplied admission.
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
Manual apply and consumers that do not opt in still require their own explicit
|
|
125
|
-
admission inputs.
|
|
126
|
-
|
|
127
|
-
Before authority verification, the reusable promotion controller runs the same
|
|
128
|
-
release transaction selector in read-only mode. That plan supplies one exact
|
|
129
|
-
publication version and tag to the admission verifier, the publish-gate source
|
|
130
|
-
lock, and the real promotion action. The verifier rejects a capability for a
|
|
131
|
-
different version, and the promotion action rechecks the planned version before
|
|
132
|
-
any publish transaction side effect. Release-candidate fixture versions are
|
|
133
|
-
artifact evidence only; they never name Buildchain's own source-lock or
|
|
134
|
-
publication capability.
|
|
119
|
+
it does for externally supplied admission. The self-assembly mode rejects other
|
|
120
|
+
repositories, unknown refs, non-exact source SHAs, and any caller other than
|
|
121
|
+
`.github/workflows/buildchain-ref-promotion.yml`. Manual apply and external
|
|
122
|
+
consumer workflows still require their own explicit admission inputs.
|
|
135
123
|
|
|
136
124
|
Evidence publication is a separate authority class and never grants product
|
|
137
125
|
publication.
|
|
@@ -116,22 +116,3 @@ KFD-1 source/artifact contract surfaces, audits KFD-2 public release claims, and
|
|
|
116
116
|
compares KFD-3 declared shipped public surfaces with artifact-exposed public
|
|
117
117
|
surfaces. The release passport records the results under `kfd-1`, `kfd-2`, and
|
|
118
118
|
the KFD-provided `kfd-3` section.
|
|
119
|
-
|
|
120
|
-
Managed consumers may also ask the promotion wrapper to assemble sealed
|
|
121
|
-
publication evidence from the exact release candidate instead of producing
|
|
122
|
-
short-lived admission JSON in repository-specific workflow code:
|
|
123
|
-
|
|
124
|
-
```yaml
|
|
125
|
-
publication-auto-admission: true
|
|
126
|
-
publication-auto-no-gate: true
|
|
127
|
-
publication-publisher-workflow-path: .github/workflows/buildchain-ref-promotion.yml
|
|
128
|
-
publication-product: Example Product
|
|
129
|
-
publication-target: npm:@example/product
|
|
130
|
-
publication-package-name: "@example/product"
|
|
131
|
-
```
|
|
132
|
-
|
|
133
|
-
`publication-auto-no-gate` is an explicit consumer decision, not a default. A
|
|
134
|
-
consumer with a Shifu Gate registry supplies `publication-gate-aggregate-json`
|
|
135
|
-
instead. Buildchain still requires caller-owned RC evidence, an exact authority
|
|
136
|
-
runtime and source SHA, a repository-local publisher workflow, matching npm
|
|
137
|
-
target/package identity, and a qualifying control-plane audit.
|
|
@@ -78,12 +78,6 @@ 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
|
-
|
|
87
81
|
The fixed `Gate profile / aggregate` job fails closed for missing receipts,
|
|
88
82
|
invalid or stale Shifu validation, dirty or mismatched source SHA, registry or
|
|
89
83
|
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.3",
|
|
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",
|
|
@@ -27,7 +27,6 @@ const DESCRIPTORS = Object.freeze([
|
|
|
27
27
|
[".github/workflows/buildchain-stable-candidate-patrol.yml", "governance-write"],
|
|
28
28
|
[".github/workflows/dev-pr-auto-merge.yml", "governance-write"],
|
|
29
29
|
[".github/workflows/npm-publish.yml", "dry-run-only"],
|
|
30
|
-
[".github/workflows/paper-release-sealed.yml", "product-publication", true, ["npm-publish", "github-release"], "trusted-publishing", "none", "fixed", "caller-bound"],
|
|
31
30
|
[".github/workflows/paper-release.yml", "product-publication", true, ["npm-publish", "github-release"], "trusted-publishing", "none", "fixed", "caller-bound"],
|
|
32
31
|
[".github/workflows/patrol-daily.yml", "governance-write"],
|
|
33
32
|
[".github/workflows/patrol-monthly.yml", "governance-write"],
|
|
@@ -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" ||
|
|
306
|
+
if (stages.some((stage) => stage.status === "cancelled" || 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";
|
package/packages/core/index.js
CHANGED
|
@@ -153,13 +153,6 @@ export {
|
|
|
153
153
|
verifyPublicationAdmission,
|
|
154
154
|
} from "./publication-authority.js";
|
|
155
155
|
|
|
156
|
-
export {
|
|
157
|
-
PUBLICATION_ARTIFACT_CANDIDATE_CONTRACT,
|
|
158
|
-
createPublicationArtifactCandidate,
|
|
159
|
-
publicationArtifactCandidateDigest,
|
|
160
|
-
resolvePublicationCandidateFile,
|
|
161
|
-
} from "./publication-artifact-candidate.js";
|
|
162
|
-
|
|
163
156
|
export {
|
|
164
157
|
buildchainPublicationAuthorityDescriptors,
|
|
165
158
|
createBuildchainPublicationAuthorityRegistry,
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import crypto from "node:crypto";
|
|
2
2
|
|
|
3
3
|
import { validateControllerReceipt } from "./controller-evidence.js";
|
|
4
|
-
import { createPublicationArtifactCandidate } from "./publication-artifact-candidate.js";
|
|
5
4
|
import { sha256Json, validateReleaseCandidatePassport } from "./release-candidate.js";
|
|
6
5
|
|
|
7
6
|
export const PUBLICATION_AUTHORITY_REGISTRY_CONTRACT =
|
|
@@ -382,7 +381,6 @@ export function createPublicationArtifactManifestSet({
|
|
|
382
381
|
}
|
|
383
382
|
|
|
384
383
|
function validateGateAggregate(gateAggregate, { admission, passport }) {
|
|
385
|
-
const passportSourceSha = passport.source?.headSha || passport.source?.sha;
|
|
386
384
|
if (gateAggregate?.contract === "buildchain.shifu-gate-aggregate/v1") {
|
|
387
385
|
const { digest, ...payload } = gateAggregate;
|
|
388
386
|
const actualDigest = sha256Json(payload);
|
|
@@ -392,7 +390,7 @@ function validateGateAggregate(gateAggregate, { admission, passport }) {
|
|
|
392
390
|
if (gateAggregate.status !== "pass" || gateAggregate.qualifying !== true) {
|
|
393
391
|
throw new Error("gate aggregate is not qualifying");
|
|
394
392
|
}
|
|
395
|
-
if (![admission.sourceSha,
|
|
393
|
+
if (![admission.sourceSha, passport.source?.headSha].includes(gateAggregate.sourceSha)) {
|
|
396
394
|
throw new Error("gate aggregate source SHA mismatch");
|
|
397
395
|
}
|
|
398
396
|
normalizeDigest(gateAggregate.registry?.digest, "gateAggregate.registry.digest");
|
|
@@ -410,7 +408,7 @@ function validateGateAggregate(gateAggregate, { admission, passport }) {
|
|
|
410
408
|
if (gateAggregate.required !== false) {
|
|
411
409
|
throw new Error("a required Gate policy must supply a qualifying Shifu Gate aggregate");
|
|
412
410
|
}
|
|
413
|
-
if (![admission.sourceSha,
|
|
411
|
+
if (![admission.sourceSha, passport.source?.headSha].includes(gateAggregate.sourceSha)) {
|
|
414
412
|
throw new Error("publication Gate decision source SHA mismatch");
|
|
415
413
|
}
|
|
416
414
|
const normalizedPolicy = {
|
|
@@ -430,43 +428,6 @@ function validatePublicationEvidence(publicationEvidence, admission) {
|
|
|
430
428
|
if (!publicationEvidence || typeof publicationEvidence !== "object" || Array.isArray(publicationEvidence)) {
|
|
431
429
|
throw new Error("independent publication evidence is required");
|
|
432
430
|
}
|
|
433
|
-
if (publicationEvidence.publicationArtifactCandidate) {
|
|
434
|
-
const candidate = createPublicationArtifactCandidate(publicationEvidence.publicationArtifactCandidate);
|
|
435
|
-
const passport = publicationEvidence.publicationArtifactCandidate.passport;
|
|
436
|
-
const controllerReceipt = publicationEvidence.publicationArtifactCandidate.controllerReceipt;
|
|
437
|
-
const controllerReceiptDigest = normalizeDigest(controllerReceipt.digest, "controllerReceipt.digest");
|
|
438
|
-
if (controllerReceiptDigest !== normalizeDigest(admission.controllerReceiptDigest, "admission.controllerReceiptDigest")) {
|
|
439
|
-
throw new Error("controller receipt evidence binding mismatch");
|
|
440
|
-
}
|
|
441
|
-
const contractDigest = normalizeDigest(controllerReceipt.runtime?.contractDigest, "controllerReceipt.runtime.contractDigest");
|
|
442
|
-
if (contractDigest !== normalizeDigest(admission.contractDigest, "admission.contractDigest")) {
|
|
443
|
-
throw new Error("runtime contract evidence binding mismatch");
|
|
444
|
-
}
|
|
445
|
-
const gate = validateGateAggregate(publicationEvidence.gateAggregate, { admission, passport });
|
|
446
|
-
if (gate.gateAggregateDigest !== normalizeDigest(admission.gateAggregateDigest, "admission.gateAggregateDigest")) {
|
|
447
|
-
throw new Error("Gate aggregate evidence binding mismatch");
|
|
448
|
-
}
|
|
449
|
-
if (gate.policyDigest !== normalizeDigest(admission.policyDigest, "admission.policyDigest")) {
|
|
450
|
-
throw new Error("Gate policy evidence binding mismatch");
|
|
451
|
-
}
|
|
452
|
-
if (candidate.candidateDigest !== normalizeDigest(admission.artifactDigest, "admission.artifactDigest")) {
|
|
453
|
-
throw new Error("publication artifact candidate evidence binding mismatch");
|
|
454
|
-
}
|
|
455
|
-
return {
|
|
456
|
-
sourceTreeSha: candidate.sourceTreeSha,
|
|
457
|
-
controllerReceiptDigest,
|
|
458
|
-
contractDigest,
|
|
459
|
-
gateAggregateDigest: gate.gateAggregateDigest,
|
|
460
|
-
policyDigest: gate.policyDigest,
|
|
461
|
-
artifactDigest: candidate.candidateDigest,
|
|
462
|
-
evidenceDigest: publicationAuthorityDigest({
|
|
463
|
-
sourceTreeSha: candidate.sourceTreeSha,
|
|
464
|
-
controllerReceiptDigest,
|
|
465
|
-
gateAggregateDigest: gate.gateAggregateDigest,
|
|
466
|
-
artifactDigest: candidate.candidateDigest,
|
|
467
|
-
}),
|
|
468
|
-
};
|
|
469
|
-
}
|
|
470
431
|
const passport = publicationEvidence.releaseCandidatePassport;
|
|
471
432
|
const buildSummary = publicationEvidence.buildSummary;
|
|
472
433
|
const passportValidation = validateReleaseCandidatePassport({
|
|
@@ -16,7 +16,6 @@ export function evaluatePublicationControlPlaneSnapshot({
|
|
|
16
16
|
branch,
|
|
17
17
|
packageName,
|
|
18
18
|
publisherMode = "npm-trusted-publisher",
|
|
19
|
-
requiredStatusCheck = "check",
|
|
20
19
|
snapshot,
|
|
21
20
|
observedAt,
|
|
22
21
|
expiresAt,
|
|
@@ -73,8 +72,7 @@ export function evaluatePublicationControlPlaneSnapshot({
|
|
|
73
72
|
branchPolicy.protected === true &&
|
|
74
73
|
branchPolicy.enforcementLevel === "everyone" &&
|
|
75
74
|
Array.isArray(branchPolicy.requiredStatusChecks) &&
|
|
76
|
-
branchPolicy.
|
|
77
|
-
branchPolicy.requiredStatusChecks.includes(requiredStatusCheck) &&
|
|
75
|
+
branchPolicy.requiredStatusChecks.includes("check") &&
|
|
78
76
|
branchPolicy.requiredCheckPassed === true &&
|
|
79
77
|
branchPolicy.sourceSha === branchPolicy.headSha &&
|
|
80
78
|
branchPolicy.mergedPullRequest === true &&
|
|
@@ -115,22 +115,13 @@ async function main() {
|
|
|
115
115
|
manifests,
|
|
116
116
|
payloads: manifests.map((manifest) => payloadFor(manifest, path.join(evidenceRoot, "payloads"))),
|
|
117
117
|
});
|
|
118
|
-
const
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
}
|
|
126
|
-
gateAggregate = createPublicationGateDecision({
|
|
127
|
-
sourceSha,
|
|
128
|
-
profile: process.env.BUILDCHAIN_GATE_PROFILE || "managed-release-candidate-no-gate",
|
|
129
|
-
required: false,
|
|
130
|
-
rationale: process.env.BUILDCHAIN_GATE_RATIONALE || "The consumer explicitly declared no Shifu Gate registry for this publication transaction.",
|
|
131
|
-
policy: { scope: "managed-release-candidate", repository },
|
|
132
|
-
});
|
|
133
|
-
}
|
|
118
|
+
const gateAggregate = createPublicationGateDecision({
|
|
119
|
+
sourceSha,
|
|
120
|
+
profile: process.env.BUILDCHAIN_GATE_PROFILE || "buildchain-self-publication",
|
|
121
|
+
required: false,
|
|
122
|
+
rationale: process.env.BUILDCHAIN_GATE_RATIONALE || "Buildchain self-publication has no consumer-owned Shifu Gate registry.",
|
|
123
|
+
policy: { scope: "buildchain-self-publication", repository },
|
|
124
|
+
});
|
|
134
125
|
const runnerProvenance = createRunnerProvenance({
|
|
135
126
|
runnerClass: "ephemeral",
|
|
136
127
|
os: required("RUNNER_OS"),
|
|
@@ -146,7 +137,6 @@ async function main() {
|
|
|
146
137
|
isolation: "github-hosted-single-job",
|
|
147
138
|
});
|
|
148
139
|
const packageJson = JSON.parse(fs.readFileSync(path.join(runtimeRoot, "package.json"), "utf8"));
|
|
149
|
-
const publicationVersion = required("BUILDCHAIN_PUBLICATION_VERSION");
|
|
150
140
|
const issuedAt = new Date();
|
|
151
141
|
const admission = createPublicationAdmission({
|
|
152
142
|
registryDigest: registry.registryDigest,
|
|
@@ -164,7 +154,7 @@ async function main() {
|
|
|
164
154
|
environment: process.env.BUILDCHAIN_PUBLICATION_ENVIRONMENT || "none",
|
|
165
155
|
product: process.env.BUILDCHAIN_PUBLICATION_PRODUCT || "Buildchain",
|
|
166
156
|
target: process.env.BUILDCHAIN_PUBLICATION_TARGET || `npm:${packageJson.name}`,
|
|
167
|
-
version:
|
|
157
|
+
version: process.env.BUILDCHAIN_PUBLICATION_VERSION || packageJson.version,
|
|
168
158
|
channel: required("BUILDCHAIN_PUBLICATION_CHANNEL"),
|
|
169
159
|
artifactDigest: artifactSet.manifestSetDigest,
|
|
170
160
|
nonce: `${required("GITHUB_RUN_ID")}:${required("GITHUB_RUN_ATTEMPT")}:${sourceSha}`,
|
|
@@ -187,6 +177,6 @@ async function main() {
|
|
|
187
177
|
}
|
|
188
178
|
|
|
189
179
|
main().catch((error) => {
|
|
190
|
-
console.error(`assemble
|
|
180
|
+
console.error(`assemble self publication admission: ${error.message}`);
|
|
191
181
|
process.exitCode = 1;
|
|
192
182
|
});
|
|
@@ -191,7 +191,6 @@ function main() {
|
|
|
191
191
|
const workflowPath = flag("workflow", ".github/workflows/release-candidate-promote.yml");
|
|
192
192
|
const workflowRef = flag("workflow-ref");
|
|
193
193
|
const publisherWorkflowPath = flag("publisher-workflow", workflowPath);
|
|
194
|
-
const requiredStatusCheck = flag("required-status-check", "check");
|
|
195
194
|
const jobId = flag("job", "promote");
|
|
196
195
|
const environment = flag("environment", "none");
|
|
197
196
|
const providerEnvironment = environment === "none" ? "" : environment;
|
|
@@ -281,16 +280,15 @@ function main() {
|
|
|
281
280
|
const checkRuns = githubJson(`repos/${repository}/commits/${sourceSha}/check-runs?per_page=100`, "source check runs");
|
|
282
281
|
const requiredStatusCheckPolicy = branchState.protection?.required_status_checks || {};
|
|
283
282
|
const requiredStatusChecks = requiredStatusCheckPolicy.contexts || [];
|
|
284
|
-
const requiredCheckSource = (requiredStatusCheckPolicy.checks || []).find((entry) => entry.context ===
|
|
283
|
+
const requiredCheckSource = (requiredStatusCheckPolicy.checks || []).find((entry) => entry.context === "check");
|
|
285
284
|
branchPolicy = {
|
|
286
285
|
ref: branch,
|
|
287
286
|
policyMode: "provider-enforced-transaction",
|
|
288
287
|
protected: branchState.protected === true,
|
|
289
288
|
enforcementLevel: branchState.protection?.required_status_checks?.enforcement_level || "",
|
|
290
289
|
requiredStatusChecks,
|
|
291
|
-
requiredStatusCheck,
|
|
292
290
|
requiredCheckPassed: (checkRuns.check_runs || []).some((entry) =>
|
|
293
|
-
entry.name ===
|
|
291
|
+
entry.name === "check" &&
|
|
294
292
|
entry.conclusion === "success" &&
|
|
295
293
|
(!requiredCheckSource?.app_id || entry.app?.id === requiredCheckSource.app_id)
|
|
296
294
|
),
|
|
@@ -352,7 +350,6 @@ function main() {
|
|
|
352
350
|
branch,
|
|
353
351
|
packageName,
|
|
354
352
|
publisherMode,
|
|
355
|
-
requiredStatusCheck,
|
|
356
353
|
observedAt: observedAt.toISOString(),
|
|
357
354
|
expiresAt: expiresAt.toISOString(),
|
|
358
355
|
snapshot: {
|