@kungfu-tech/buildchain 2.11.0 → 2.11.1-alpha.2
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/README.md +1 -1
- package/bin/buildchain.mjs +7 -3
- package/dist/site/buildchain-contract.json +5 -5
- package/dist/site/buildchain-site.json +26 -26
- package/dist/site/cli-registry.json +2 -2
- package/dist/site/kfd-claims.json +6 -6
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +5 -5
- package/dist/site/node-api-registry.json +7 -7
- package/dist/site/page-registry.json +16 -16
- package/dist/site/public-surface-audit.json +15 -5
- package/dist/site/site-manifest.json +9 -9
- package/docs/MAP.md +1 -1
- package/docs/cli.md +17 -6
- package/docs/kfd-support.md +11 -9
- package/docs/publication-artifacts.md +12 -9
- package/docs/release-candidate.md +3 -3
- package/docs/release-passport.md +9 -4
- package/package.json +1 -1
- package/packages/core/README.md +3 -1
- package/packages/core/artifact-passport.js +70 -2
- package/packages/core/buildchain-layout.js +103 -8
- package/packages/core/index.js +16 -0
- package/packages/core/kfd.js +6 -0
- package/packages/core/kfd3-surface-register.js +1 -1
- package/scripts/generate-buildchain-kfd-witnesses.mjs +11 -4
- package/scripts/init-repo.mjs +7 -2
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
"workflowCount": 36,
|
|
8
8
|
"actionCount": 4,
|
|
9
9
|
"sitePageCount": 45,
|
|
10
|
-
"docCommandRefCount":
|
|
10
|
+
"docCommandRefCount": 229,
|
|
11
11
|
"failureCount": 0
|
|
12
12
|
},
|
|
13
13
|
"enumerated": {
|
|
@@ -70,7 +70,7 @@
|
|
|
70
70
|
{
|
|
71
71
|
"id": "explain-artifact",
|
|
72
72
|
"source": "bin/buildchain.mjs",
|
|
73
|
-
"usage": "buildchain explain artifact <subject> [--passport <file-or-url>] [--for human|agent] [--json]"
|
|
73
|
+
"usage": "buildchain explain artifact <subject> [--passport <file-or-url>] [--npm-registry <url>] [--for human|agent] [--json]"
|
|
74
74
|
},
|
|
75
75
|
{
|
|
76
76
|
"id": "explain-release",
|
|
@@ -120,7 +120,7 @@
|
|
|
120
120
|
{
|
|
121
121
|
"id": "inspect-artifact",
|
|
122
122
|
"source": "bin/buildchain.mjs",
|
|
123
|
-
"usage": "buildchain inspect artifact <subject> [--passport <file-or-url>] [--json]"
|
|
123
|
+
"usage": "buildchain inspect artifact <subject> [--passport <file-or-url>] [--npm-registry <url>] [--json]"
|
|
124
124
|
},
|
|
125
125
|
{
|
|
126
126
|
"id": "inspect-release",
|
|
@@ -1937,6 +1937,11 @@
|
|
|
1937
1937
|
"path": "docs/kfd-support.md",
|
|
1938
1938
|
"command": "buildchain kfd migrate-layout --write"
|
|
1939
1939
|
},
|
|
1940
|
+
{
|
|
1941
|
+
"id": "kfd-migrate-layout",
|
|
1942
|
+
"path": "docs/kfd-support.md",
|
|
1943
|
+
"command": "buildchain kfd migrate-layout --write"
|
|
1944
|
+
},
|
|
1940
1945
|
{
|
|
1941
1946
|
"id": "kfd-schema-list",
|
|
1942
1947
|
"path": "docs/cli.md",
|
|
@@ -2332,6 +2337,11 @@
|
|
|
2332
2337
|
"path": "docs/cli.md",
|
|
2333
2338
|
"command": "buildchain verify artifact"
|
|
2334
2339
|
},
|
|
2340
|
+
{
|
|
2341
|
+
"id": "verify-artifact",
|
|
2342
|
+
"path": "docs/cli.md",
|
|
2343
|
+
"command": "buildchain verify artifact npm"
|
|
2344
|
+
},
|
|
2335
2345
|
{
|
|
2336
2346
|
"id": "verify-artifact",
|
|
2337
2347
|
"path": "docs/release-passport.md",
|
|
@@ -2438,9 +2448,9 @@
|
|
|
2438
2448
|
"cliRegistryPath": "dist/site/cli-registry.json",
|
|
2439
2449
|
"workflowRegistryPath": "dist/site/workflow-registry.json",
|
|
2440
2450
|
"pageRegistryPath": "dist/site/page-registry.json",
|
|
2441
|
-
"cliRegistryDigest": "
|
|
2451
|
+
"cliRegistryDigest": "53833f92021caa7cc5feaff5d21f38b0a77317ace11a43795be180d1dec3699f",
|
|
2442
2452
|
"workflowRegistryDigest": "67572429a83124370b9ffd46f56923aa2b252873c9624ded39a26675fb0ee815",
|
|
2443
|
-
"pageRegistryDigest": "
|
|
2453
|
+
"pageRegistryDigest": "14b3d852445462c23c9c48d786844353a8c3e2764092323fabe60dcab9e39aae"
|
|
2444
2454
|
},
|
|
2445
2455
|
"comparison": {
|
|
2446
2456
|
"missingCliRegistry": [],
|
|
@@ -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-09T10:17:37.497Z",
|
|
5
|
+
"publishedAt": "2026-07-09T10:17:37.497Z",
|
|
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": "85d3b04ebed5b161f019095bdb5ff5e18d4513db",
|
|
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.11.
|
|
40
|
+
"version": "2.11.1-alpha.2",
|
|
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:795464d3d84af5698b19a26821dbd16040c258b708e070daaaba6d55e6ad81f7"
|
|
57
57
|
},
|
|
58
58
|
{
|
|
59
59
|
"id": "install",
|
|
@@ -69,7 +69,7 @@
|
|
|
69
69
|
"path": "docs/release-passport.md",
|
|
70
70
|
"plane": "verify",
|
|
71
71
|
"exists": true,
|
|
72
|
-
"digest": "sha256:
|
|
72
|
+
"digest": "sha256:f278f148e36f508f7217ad0e41501fa1cf5fe4d0a54d81dfbab867b3d35465c7"
|
|
73
73
|
},
|
|
74
74
|
{
|
|
75
75
|
"id": "release-candidate",
|
|
@@ -77,7 +77,7 @@
|
|
|
77
77
|
"path": "docs/release-candidate.md",
|
|
78
78
|
"plane": "verify",
|
|
79
79
|
"exists": true,
|
|
80
|
-
"digest": "sha256:
|
|
80
|
+
"digest": "sha256:841d6f3281ba6dfe80527e4f149807bdbd05d41f9e94afe1c446fcd6d29e307c"
|
|
81
81
|
},
|
|
82
82
|
{
|
|
83
83
|
"id": "release-propagation",
|
|
@@ -173,7 +173,7 @@
|
|
|
173
173
|
"path": "docs/cli.md",
|
|
174
174
|
"plane": "use",
|
|
175
175
|
"exists": true,
|
|
176
|
-
"digest": "sha256:
|
|
176
|
+
"digest": "sha256:4b31f7ff5330cde8ab32b237f533c7af76463cce570d67dd14669c3a14c83c84"
|
|
177
177
|
},
|
|
178
178
|
{
|
|
179
179
|
"id": "build-facts",
|
|
@@ -189,7 +189,7 @@
|
|
|
189
189
|
"path": "docs/kfd-support.md",
|
|
190
190
|
"plane": "verify",
|
|
191
191
|
"exists": true,
|
|
192
|
-
"digest": "sha256:
|
|
192
|
+
"digest": "sha256:ce1bbf5c085a69649ee2e6ae76a52419eef94304e59efc0d0dcd4466c714709e"
|
|
193
193
|
},
|
|
194
194
|
{
|
|
195
195
|
"id": "lifecycle-protocol",
|
package/docs/MAP.md
CHANGED
|
@@ -42,7 +42,7 @@ workflow, action, and Node API export also carries a `capabilityGroup`,
|
|
|
42
42
|
| Capability-grouped KFD navigation | `dist/site/capability-registry.json`, `dist/site/page-registry.json`, `dist/site/manual-registry.json`, `dist/site/cli-registry.json`, `dist/site/node-api-registry.json` | this map, [`site-bundle-contract.md`](site-bundle-contract.md), [`kfd-support.md`](kfd-support.md) |
|
|
43
43
|
| KFD-1 / KFD-2 / KFD-3 release-passport gates | `dist/site/kfd-claims.json`, `dist/site/buildchain-contract.json`, `dist/site/artifact-schemas.json` | [`release-passport.md`](release-passport.md) |
|
|
44
44
|
| KFD-3 public surface reverse audit | `dist/site/public-surface-audit.json`, `dist/site/cli-registry.json`, `dist/site/workflow-registry.json`, `dist/site/page-registry.json` | [`cli.md`](cli.md), [`site-bundle-contract.md`](site-bundle-contract.md) |
|
|
45
|
-
| KFD-1 / KFD-2 / KFD-3 first-class CLI and Node API | `.buildchain/kfd/kfd-3
|
|
45
|
+
| KFD-1 / KFD-2 / KFD-3 first-class CLI and Node API | `.buildchain/kfd/kfd-3/surfaces.json`, `dist/site/kfd-claims.json`, `buildchain.release.json`, KFD schemas from `@kungfu-tech/kfd` | [`kfd-support.md`](kfd-support.md), [`cli.md`](cli.md#commands) |
|
|
46
46
|
| Floating `@v2` drift detection and compatibility issues | `dist/site/buildchain-contract.json` | [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock) |
|
|
47
47
|
| npm publish transactions, evidence, dist-tags, and recovery | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`publish-transaction.md`](publish-transaction.md) |
|
|
48
48
|
| Git/source/version/module/product build facts | `dist/site/node-api-registry.json`, `dist/site/cli-registry.json`, `kungfu-buildchain-module-build-facts`, `kungfu-buildchain-product-build-facts` | [`build-facts.md`](build-facts.md) |
|
package/docs/cli.md
CHANGED
|
@@ -104,7 +104,10 @@ Supported presets:
|
|
|
104
104
|
plans by default, and only configured `[infra.commands]` hooks can execute.
|
|
105
105
|
- `--type publication-artifact` for papers, reports, specifications, and other
|
|
106
106
|
publication repositories that produce PDFs, metadata, source bundles, and
|
|
107
|
-
site-consumable manifests without becoming web-surface repositories.
|
|
107
|
+
site-consumable manifests without becoming web-surface repositories. The
|
|
108
|
+
scaffold uses Buildchain's pinned
|
|
109
|
+
`ghcr.io/kungfu-systems/build-images/latex-pdf-builder:v1.2.0` toolchain for
|
|
110
|
+
LaTeX PDF builds.
|
|
108
111
|
- `--type distribution-index` for Homebrew taps and other index repositories
|
|
109
112
|
whose files are projections of upstream release passport evidence.
|
|
110
113
|
- `--type anchored-package` for packages whose version is anchored to an
|
|
@@ -219,7 +222,7 @@ buildchain kfd schema show kfd-3 --json
|
|
|
219
222
|
buildchain kfd 3 detect --kind node-api --kind cli --json
|
|
220
223
|
buildchain kfd 3 register node-api --product Buildchain
|
|
221
224
|
buildchain kfd 3 audit --json
|
|
222
|
-
buildchain kfd 3 witness --kind prebuild --output .buildchain/kfd-3/collaboration-interface.prebuild.json
|
|
225
|
+
buildchain kfd 3 witness --kind prebuild --output .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json
|
|
223
226
|
buildchain kfd 3 query buildchain --json
|
|
224
227
|
buildchain kfd 4 schema --json
|
|
225
228
|
```
|
|
@@ -400,7 +403,7 @@ The command writes `.buildchain/publication/publication-artifact.json`,
|
|
|
400
403
|
and, when `[publication.archive]` is configured,
|
|
401
404
|
`.buildchain/publication/publication-registry.json` by default. See
|
|
402
405
|
[`publication-artifacts.md`](publication-artifacts.md) for the repository
|
|
403
|
-
contract and reusable workflow.
|
|
406
|
+
contract, pinned LaTeX builder, and reusable workflow.
|
|
404
407
|
|
|
405
408
|
Generate, check, or update the managed README badge block:
|
|
406
409
|
|
|
@@ -477,9 +480,9 @@ buildchain collect github-release \
|
|
|
477
480
|
--platform-manifest-json .buildchain/artifacts/darwin-arm64/manifest.json \
|
|
478
481
|
--platform-manifest-json .buildchain/artifacts/win32-x64/manifest.json \
|
|
479
482
|
--dist-tag-evidence-json .buildchain/release-evidence/v2.3.2/dist-tag-evidence.json \
|
|
480
|
-
--kfd-1-witness-json .buildchain/kfd-1/contract-world.witness.json \
|
|
481
|
-
--kfd-2-claim-json .buildchain/kfd-2/release-claims.json \
|
|
482
|
-
--kfd-3-prebuild-witness-json .buildchain/kfd-3/collaboration-interface.prebuild.json \
|
|
483
|
+
--kfd-1-witness-json .buildchain/kfd/kfd-1/contract-world.witness.json \
|
|
484
|
+
--kfd-2-claim-json .buildchain/kfd/kfd-2/release-claims.json \
|
|
485
|
+
--kfd-3-prebuild-witness-json .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json \
|
|
483
486
|
--kfd-3-artifact-verify-cmd "kungfu agent verify --json" \
|
|
484
487
|
--release-extra-json '{"channel":"release","targetRef":"release/v2/v2.3"}' \
|
|
485
488
|
--output-dir .buildchain/release-passport
|
|
@@ -576,6 +579,10 @@ Verify a published artifact by subject:
|
|
|
576
579
|
buildchain verify artifact ./Kungfu-2.8.0-windows-x64.exe
|
|
577
580
|
buildchain inspect artifact ./Kungfu-2.8.0-windows-x64.exe --json
|
|
578
581
|
buildchain explain artifact ./Kungfu-2.8.0-windows-x64.exe --for agent --json
|
|
582
|
+
buildchain verify artifact npm:@kungfu-tech/libnode@22.22.3-kf.3-alpha.18 \
|
|
583
|
+
--repository kungfu-systems/libnode \
|
|
584
|
+
--tag v22.22.3-kf.3-alpha.18 \
|
|
585
|
+
--json
|
|
579
586
|
```
|
|
580
587
|
|
|
581
588
|
`verify artifact` computes or obtains the subject digest, discovers the
|
|
@@ -583,6 +590,10 @@ detached release passport, verifies the passport, then requires that the
|
|
|
583
590
|
subject digest appears in the passport's release assets, package set, publish
|
|
584
591
|
evidence, or artifact evidence. Outcomes are explicit: `pass`, `fail`, or
|
|
585
592
|
`unverifiable`. A filename is only a hint; trust comes from digest equality.
|
|
593
|
+
For `npm:<name>@<version>` subjects, Buildchain resolves `dist.integrity` from
|
|
594
|
+
the npm registry before matching passport evidence. Use `--npm-registry <url>`
|
|
595
|
+
to verify packages from a custom registry; otherwise Buildchain uses
|
|
596
|
+
`npm_config_registry` or `https://registry.npmjs.org/`.
|
|
586
597
|
|
|
587
598
|
Discovery is fail-closed and ordered:
|
|
588
599
|
|
package/docs/kfd-support.md
CHANGED
|
@@ -10,14 +10,16 @@ facts, not as README prose. The machine-readable sources are:
|
|
|
10
10
|
- `buildchain.release.json` for release-specific KFD-1, KFD-2, and KFD-3
|
|
11
11
|
passport results;
|
|
12
12
|
- `.buildchain/buildchain.toml` for repository-owned Buildchain configuration;
|
|
13
|
-
- `.buildchain/kfd/kfd-3
|
|
13
|
+
- `.buildchain/kfd/kfd-3/surfaces.json` for product-owned KFD-3 surface
|
|
14
14
|
registration;
|
|
15
15
|
- `.buildchain/contract-lock.json` for accepted floating runtime contracts.
|
|
16
16
|
|
|
17
17
|
Buildchain still reads the legacy root files `buildchain.toml`,
|
|
18
|
-
`buildchain.contract-lock.json`,
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
`buildchain.contract-lock.json`, `buildchain.kfd3.json`, and the historical
|
|
19
|
+
`.buildchain/kfd/kfd-3-surfaces.json` registry so existing consumers can run
|
|
20
|
+
`buildchain kfd migrate-layout --write`. New repositories should keep
|
|
21
|
+
repo-owned Buildchain files under `.buildchain/`, with all KFD evidence under
|
|
22
|
+
`.buildchain/kfd/`.
|
|
21
23
|
|
|
22
24
|
## Unified Namespace
|
|
23
25
|
|
|
@@ -145,9 +147,9 @@ package = "@kungfu-tech/kfd"
|
|
|
145
147
|
repository = "kungfu-systems/kfd"
|
|
146
148
|
evidence = [
|
|
147
149
|
"package:kfd.release.json",
|
|
148
|
-
"package:.buildchain/kfd-1/contract-world.witness.json",
|
|
149
|
-
"package:.buildchain/kfd-2/
|
|
150
|
-
"package:.buildchain/kfd-3/collaboration-interface.json",
|
|
150
|
+
"package:.buildchain/kfd/kfd-1/contract-world.witness.json",
|
|
151
|
+
"package:.buildchain/kfd/kfd-2/release-claims.json",
|
|
152
|
+
"package:.buildchain/kfd/kfd-3/collaboration-interface.json",
|
|
151
153
|
"package:standards.json",
|
|
152
154
|
]
|
|
153
155
|
```
|
|
@@ -251,7 +253,7 @@ KFD-3 surface registration uses three states.
|
|
|
251
253
|
| State | Meaning |
|
|
252
254
|
| --- | --- |
|
|
253
255
|
| `detected` | Buildchain found a candidate public surface from package metadata, wheel metadata, CLI bins, binary artifacts, docs, or site bundle facts. |
|
|
254
|
-
| `declared` | The product owner accepted that candidate into `.buildchain/kfd/kfd-3
|
|
256
|
+
| `declared` | The product owner accepted that candidate into `.buildchain/kfd/kfd-3/surfaces.json`. |
|
|
255
257
|
| `enforced` | The product has promoted a declared surface to a hard release boundary. Missing enforced surfaces fail release verification. |
|
|
256
258
|
|
|
257
259
|
Detection does not silently become product intent. `register` is the boundary
|
|
@@ -298,7 +300,7 @@ Generate a witness for release passport collection:
|
|
|
298
300
|
```bash
|
|
299
301
|
buildchain kfd 3 witness \
|
|
300
302
|
--kind prebuild \
|
|
301
|
-
--output .buildchain/kfd-3/collaboration-interface.prebuild.json
|
|
303
|
+
--output .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json
|
|
302
304
|
```
|
|
303
305
|
|
|
304
306
|
Query capability facts for agents or downstream sites:
|
|
@@ -46,8 +46,8 @@ registry_path = ".buildchain/publication/publication-registry.json"
|
|
|
46
46
|
|
|
47
47
|
[publication.toolchain]
|
|
48
48
|
type = "latex-docker"
|
|
49
|
-
image = "ghcr.io/kungfu-systems/latex"
|
|
50
|
-
digest = "sha256:
|
|
49
|
+
image = "ghcr.io/kungfu-systems/build-images/latex-pdf-builder"
|
|
50
|
+
digest = "sha256:c20f3809e96836c1c78e97c76939d12f1de3fed0ea9b7c40c43332ec2ea480f8"
|
|
51
51
|
command = "latexmk -pdf -outdir=_build paper/main.tex"
|
|
52
52
|
|
|
53
53
|
[lifecycle.build]
|
|
@@ -82,11 +82,14 @@ if PDF, source bundle, route, metadata, or toolchain evidence changes for an
|
|
|
82
82
|
existing version, Buildchain fails before the registry is rewritten.
|
|
83
83
|
|
|
84
84
|
`publication.toolchain` makes the source-to-PDF transformation part of the
|
|
85
|
-
machine-readable contract. `latex-docker` is the preferred LaTeX profile
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
command
|
|
85
|
+
machine-readable contract. `latex-docker` is the preferred LaTeX profile. The
|
|
86
|
+
Buildchain paper scaffold and reusable workflow default to
|
|
87
|
+
`ghcr.io/kungfu-systems/build-images/latex-pdf-builder:v1.2.0`, pinned by the
|
|
88
|
+
digest above. The workflow pulls the declared image by digest and runs the
|
|
89
|
+
declared command in that pinned container. `custom-command` remains available
|
|
90
|
+
for compatibility, but the passport records it as lower trust because
|
|
91
|
+
Buildchain can record the command boundary without proving the compiler or
|
|
92
|
+
LaTeX distribution digest.
|
|
90
93
|
|
|
91
94
|
## Reusable Workflow
|
|
92
95
|
|
|
@@ -109,8 +112,8 @@ The workflow:
|
|
|
109
112
|
any paper build runs;
|
|
110
113
|
- resolves the declared publication toolchain from `[publication.toolchain]` or
|
|
111
114
|
workflow inputs;
|
|
112
|
-
- for `latex-docker`, pulls the pinned
|
|
113
|
-
command in the container;
|
|
115
|
+
- for `latex-docker`, pulls the pinned build-images LaTeX builder digest and
|
|
116
|
+
runs the declared command in the container;
|
|
114
117
|
- for `custom-command`, runs the declared command and records the lower-trust
|
|
115
118
|
boundary in the passport;
|
|
116
119
|
- runs the verify command;
|
|
@@ -105,9 +105,9 @@ jobs:
|
|
|
105
105
|
with:
|
|
106
106
|
channel: alpha
|
|
107
107
|
artifact-name: libnode
|
|
108
|
-
release-passport-kfd-1-witness-jsons: .buildchain/kfd-1/standard-contract.witness.json
|
|
109
|
-
release-passport-kfd-2-claim-jsons: .buildchain/kfd-2/release-claims.json
|
|
110
|
-
release-passport-kfd-3-prebuild-witness-jsons: .buildchain/kfd-3/collaboration-interface.prebuild.json
|
|
108
|
+
release-passport-kfd-1-witness-jsons: .buildchain/kfd/kfd-1/standard-contract.witness.json
|
|
109
|
+
release-passport-kfd-2-claim-jsons: .buildchain/kfd/kfd-2/release-claims.json
|
|
110
|
+
release-passport-kfd-3-prebuild-witness-jsons: .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json
|
|
111
111
|
release-passport-kfd-3-artifact-verify-command: kungfu agent verify --json
|
|
112
112
|
```
|
|
113
113
|
|
package/docs/release-passport.md
CHANGED
|
@@ -109,8 +109,8 @@ buildchain collect github-release \
|
|
|
109
109
|
--platform-manifest-json .buildchain/artifacts/darwin-arm64/manifest.json \
|
|
110
110
|
--platform-manifest-json .buildchain/artifacts/win32-x64/manifest.json \
|
|
111
111
|
--dist-tag-evidence-json .buildchain/release-evidence/v2.2.0/dist-tag-evidence.json \
|
|
112
|
-
--kfd-1-witness-json .buildchain/kfd-1/contract-world.witness.json \
|
|
113
|
-
--kfd-2-claim-json .buildchain/kfd-2/release-claims.json \
|
|
112
|
+
--kfd-1-witness-json .buildchain/kfd/kfd-1/contract-world.witness.json \
|
|
113
|
+
--kfd-2-claim-json .buildchain/kfd/kfd-2/release-claims.json \
|
|
114
114
|
--output-dir .buildchain/release-passport
|
|
115
115
|
```
|
|
116
116
|
|
|
@@ -279,7 +279,7 @@ pre-build witness:
|
|
|
279
279
|
|
|
280
280
|
```bash
|
|
281
281
|
kungfu sdk collaboration-interface witness --json \
|
|
282
|
-
> .buildchain/kfd-3/collaboration-interface.prebuild.json
|
|
282
|
+
> .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json
|
|
283
283
|
```
|
|
284
284
|
|
|
285
285
|
That witness must contain, or point to, the product-owned KFD-3 collaboration
|
|
@@ -292,7 +292,7 @@ either as a JSON file or a command:
|
|
|
292
292
|
|
|
293
293
|
```bash
|
|
294
294
|
buildchain collect github-release \
|
|
295
|
-
--kfd-3-prebuild-witness-json .buildchain/kfd-3/collaboration-interface.prebuild.json \
|
|
295
|
+
--kfd-3-prebuild-witness-json .buildchain/kfd/kfd-3/collaboration-interface.prebuild.json \
|
|
296
296
|
--kfd-3-artifact-verify-cmd "kungfu agent verify --json"
|
|
297
297
|
```
|
|
298
298
|
|
|
@@ -376,6 +376,11 @@ appears in the passport's artifacts, package set, publish evidence, or artifact
|
|
|
376
376
|
evidence. The command returns `pass`, `fail`, or `unverifiable`; missing
|
|
377
377
|
passports and digest mismatches fail closed.
|
|
378
378
|
|
|
379
|
+
For npm subjects, Buildchain treats the registry as the package digest source:
|
|
380
|
+
`npm:<name>@<version>` resolves `dist.integrity` and matches it against
|
|
381
|
+
`packageSet.main.digest`, `packageSet.platforms[].digest`, and publish evidence.
|
|
382
|
+
Use `--npm-registry <url>` when the package comes from a non-default registry.
|
|
383
|
+
|
|
379
384
|
Discovery is ordered and auditable:
|
|
380
385
|
|
|
381
386
|
1. explicit `--passport`;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@kungfu-tech/buildchain",
|
|
3
|
-
"version": "2.11.
|
|
3
|
+
"version": "2.11.1-alpha.2",
|
|
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",
|
package/packages/core/README.md
CHANGED
|
@@ -69,7 +69,9 @@ writeBuildFacts({ fact, output: ".buildchain/facts/native-core.json" });
|
|
|
69
69
|
Publication repositories can produce site-consumable paper/report facts without
|
|
70
70
|
becoming web-surface repositories. When `[publication.archive]` is configured,
|
|
71
71
|
the same API also maintains the append-only publication registry used by site
|
|
72
|
-
repositories for latest and historical version pages
|
|
72
|
+
repositories for latest and historical version pages. The preferred
|
|
73
|
+
`latex-docker` toolchain records the pinned build-images LaTeX builder digest in
|
|
74
|
+
the publication artifact passport:
|
|
73
75
|
|
|
74
76
|
```js
|
|
75
77
|
import { writePublicationArtifact } from "@kungfu-tech/buildchain/publication-artifact";
|
|
@@ -8,6 +8,7 @@ import { readJsonFromLocation, sha256File, verifyReleasePassport } from "./relea
|
|
|
8
8
|
export const ARTIFACT_VERIFICATION_CONTRACT = "kungfu-buildchain-artifact-verification";
|
|
9
9
|
export const ARTIFACT_PASSPORT_POINTER_CONTRACT = "kungfu-buildchain-artifact-passport-pointer";
|
|
10
10
|
export const ARTIFACT_PASSPORT_LOCATOR_CONTRACT = "kungfu-buildchain-artifact-passport-locator";
|
|
11
|
+
export const DEFAULT_NPM_REGISTRY_BASE_URL = "https://registry.npmjs.org/";
|
|
11
12
|
|
|
12
13
|
function optionalString(value) {
|
|
13
14
|
return value === undefined || value === null ? "" : String(value);
|
|
@@ -118,6 +119,45 @@ function parseNpmSubject(subject) {
|
|
|
118
119
|
return { name: spec.slice(0, atIndex), version: spec.slice(atIndex + 1) };
|
|
119
120
|
}
|
|
120
121
|
|
|
122
|
+
function normalizeNpmRegistryBaseUrl(value = "") {
|
|
123
|
+
const registry = optionalString(value || process.env.npm_config_registry || DEFAULT_NPM_REGISTRY_BASE_URL).trim();
|
|
124
|
+
return registry.endsWith("/") ? registry : `${registry}/`;
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
function npmRegistryPackageMetadataUrl(name, registryBaseUrl = "") {
|
|
128
|
+
return new URL(encodeURIComponent(name), normalizeNpmRegistryBaseUrl(registryBaseUrl)).toString();
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
async function resolveNpmSubjectDigest({ name, version, registryBaseUrl = "" } = {}) {
|
|
132
|
+
if (!name || !version) {
|
|
133
|
+
return { status: "skipped", reason: "missing-name-or-version" };
|
|
134
|
+
}
|
|
135
|
+
const metadataUrl = npmRegistryPackageMetadataUrl(name, registryBaseUrl);
|
|
136
|
+
const metadata = await readJsonFromLocation(metadataUrl);
|
|
137
|
+
const versionMetadata = metadata?.versions?.[version];
|
|
138
|
+
if (!versionMetadata) {
|
|
139
|
+
return {
|
|
140
|
+
status: "missing",
|
|
141
|
+
reason: "version-not-found",
|
|
142
|
+
registry: normalizeNpmRegistryBaseUrl(registryBaseUrl),
|
|
143
|
+
metadataUrl,
|
|
144
|
+
};
|
|
145
|
+
}
|
|
146
|
+
const integrity = optionalString(versionMetadata.dist?.integrity);
|
|
147
|
+
const shasum = optionalString(versionMetadata.dist?.shasum);
|
|
148
|
+
const digest = integrity || (shasum ? `sha1:${shasum}` : "");
|
|
149
|
+
return {
|
|
150
|
+
status: digest ? "resolved" : "missing",
|
|
151
|
+
reason: digest ? "" : "dist-integrity-missing",
|
|
152
|
+
registry: normalizeNpmRegistryBaseUrl(registryBaseUrl),
|
|
153
|
+
metadataUrl,
|
|
154
|
+
digest,
|
|
155
|
+
integrity,
|
|
156
|
+
shasum,
|
|
157
|
+
tarball: optionalString(versionMetadata.dist?.tarball),
|
|
158
|
+
};
|
|
159
|
+
}
|
|
160
|
+
|
|
121
161
|
function parseGitHubReleaseSubject(subject) {
|
|
122
162
|
const value = subject.replace(/^github-release:/, "");
|
|
123
163
|
const match = value.match(/^([^/]+\/[^@/]+)@([^/]+)\/(.+)$/);
|
|
@@ -328,6 +368,7 @@ export async function resolveArtifactSubject(subject, {
|
|
|
328
368
|
cwd = process.cwd(),
|
|
329
369
|
subjectDigest = "",
|
|
330
370
|
subjectKind = "",
|
|
371
|
+
npmRegistryBaseUrl = "",
|
|
331
372
|
} = {}) {
|
|
332
373
|
const input = optionalString(subject).trim();
|
|
333
374
|
if (!input) {
|
|
@@ -335,12 +376,38 @@ export async function resolveArtifactSubject(subject, {
|
|
|
335
376
|
}
|
|
336
377
|
if (/^npm:/i.test(input)) {
|
|
337
378
|
const parsed = parseNpmSubject(input);
|
|
379
|
+
let npmDigest = {};
|
|
380
|
+
if (!subjectDigest) {
|
|
381
|
+
try {
|
|
382
|
+
npmDigest = await resolveNpmSubjectDigest({
|
|
383
|
+
name: parsed.name,
|
|
384
|
+
version: parsed.version,
|
|
385
|
+
registryBaseUrl: npmRegistryBaseUrl,
|
|
386
|
+
});
|
|
387
|
+
} catch (error) {
|
|
388
|
+
npmDigest = {
|
|
389
|
+
status: "error",
|
|
390
|
+
registry: normalizeNpmRegistryBaseUrl(npmRegistryBaseUrl),
|
|
391
|
+
error: error.message,
|
|
392
|
+
};
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
const digest = subjectDigest || npmDigest.digest || "";
|
|
338
396
|
return {
|
|
339
397
|
input,
|
|
340
398
|
kind: subjectKind || "npm-package",
|
|
341
399
|
name: parsed.name,
|
|
342
400
|
version: parsed.version,
|
|
343
|
-
digest
|
|
401
|
+
digest,
|
|
402
|
+
integrity: npmDigest.integrity || (digest.startsWith("sha512-") ? digest : ""),
|
|
403
|
+
shasum: npmDigest.shasum || "",
|
|
404
|
+
registry: npmDigest.registry || normalizeNpmRegistryBaseUrl(npmRegistryBaseUrl),
|
|
405
|
+
npm: {
|
|
406
|
+
digestResolution: npmDigest.status || (subjectDigest ? "provided" : "skipped"),
|
|
407
|
+
metadataUrl: npmDigest.metadataUrl || "",
|
|
408
|
+
tarball: npmDigest.tarball || "",
|
|
409
|
+
error: npmDigest.error || "",
|
|
410
|
+
},
|
|
344
411
|
localPath: "",
|
|
345
412
|
};
|
|
346
413
|
}
|
|
@@ -640,8 +707,9 @@ export async function verifyArtifactPassport({
|
|
|
640
707
|
githubReleaseBaseUrl = "",
|
|
641
708
|
subjectDigest = "",
|
|
642
709
|
subjectKind = "",
|
|
710
|
+
npmRegistryBaseUrl = "",
|
|
643
711
|
} = {}) {
|
|
644
|
-
const resolvedSubject = await resolveArtifactSubject(subject, { cwd, subjectDigest, subjectKind });
|
|
712
|
+
const resolvedSubject = await resolveArtifactSubject(subject, { cwd, subjectDigest, subjectKind, npmRegistryBaseUrl });
|
|
645
713
|
const issues = [];
|
|
646
714
|
if (resolvedSubject.missing) {
|
|
647
715
|
issues.push(issue("error", "subject.missing", "artifact subject does not exist locally", { subject: resolvedSubject.input }));
|
|
@@ -6,8 +6,27 @@ export const BUILDCHAIN_CONFIG_PATH = ".buildchain/buildchain.toml";
|
|
|
6
6
|
export const LEGACY_BUILDCHAIN_CONFIG_PATH = "buildchain.toml";
|
|
7
7
|
export const BUILDCHAIN_CONTRACT_LOCK_PATH = ".buildchain/contract-lock.json";
|
|
8
8
|
export const LEGACY_BUILDCHAIN_CONTRACT_LOCK_PATH = "buildchain.contract-lock.json";
|
|
9
|
-
export const
|
|
9
|
+
export const BUILDCHAIN_KFD_ROOT = ".buildchain/kfd";
|
|
10
|
+
export const BUILDCHAIN_KFD1_DIR = ".buildchain/kfd/kfd-1";
|
|
11
|
+
export const BUILDCHAIN_KFD2_DIR = ".buildchain/kfd/kfd-2";
|
|
12
|
+
export const BUILDCHAIN_KFD3_DIR = ".buildchain/kfd/kfd-3";
|
|
13
|
+
export const BUILDCHAIN_KFD4_DIR = ".buildchain/kfd/kfd-4";
|
|
14
|
+
export const BUILDCHAIN_KFD1_CONTRACT_WORLD_WITNESS_PATH = ".buildchain/kfd/kfd-1/contract-world.witness.json";
|
|
15
|
+
export const BUILDCHAIN_KFD1_RELEASE_GATE_PATH = ".buildchain/kfd/kfd-1/release-gate.json";
|
|
16
|
+
export const BUILDCHAIN_KFD1_VERIFY_RESULT_PATH = ".buildchain/kfd/kfd-1/verify-result.json";
|
|
17
|
+
export const BUILDCHAIN_KFD2_RELEASE_CLAIMS_PATH = ".buildchain/kfd/kfd-2/release-claims.json";
|
|
18
|
+
export const BUILDCHAIN_KFD2_CLAIM_ARGS_PATH = ".buildchain/kfd/kfd-2/buildchain-claim-args.txt";
|
|
19
|
+
export const BUILDCHAIN_KFD2_CLAIMS_DIR = ".buildchain/kfd/kfd-2/claims";
|
|
20
|
+
export const BUILDCHAIN_KFD3_SURFACE_REGISTRY_PATH = ".buildchain/kfd/kfd-3/surfaces.json";
|
|
21
|
+
export const BUILDCHAIN_KFD3_COLLABORATION_INTERFACE_PATH = ".buildchain/kfd/kfd-3/collaboration-interface.json";
|
|
22
|
+
export const BUILDCHAIN_KFD3_PREBUILD_WITNESS_PATH = ".buildchain/kfd/kfd-3/collaboration-interface.prebuild.json";
|
|
23
|
+
export const BUILDCHAIN_KFD3_ARTIFACT_WITNESS_PATH = ".buildchain/kfd/kfd-3/collaboration-interface.artifact.json";
|
|
24
|
+
export const BUILDCHAIN_KFD3_CAPABILITY_QUERY_PATH = ".buildchain/kfd/kfd-3/capability-query.json";
|
|
10
25
|
export const LEGACY_BUILDCHAIN_KFD3_SURFACE_REGISTRY_PATH = "buildchain.kfd3.json";
|
|
26
|
+
export const LEGACY_BUILDCHAIN_KFD3_SURFACE_REGISTRY_PATHS = Object.freeze([
|
|
27
|
+
".buildchain/kfd/kfd-3-surfaces.json",
|
|
28
|
+
LEGACY_BUILDCHAIN_KFD3_SURFACE_REGISTRY_PATH,
|
|
29
|
+
]);
|
|
11
30
|
export const BUILDCHAIN_RELEASE_PASSPORT_PATH = ".buildchain/release-passport/buildchain.release.json";
|
|
12
31
|
export const LEGACY_BUILDCHAIN_RELEASE_PASSPORT_PATH = "buildchain.release.json";
|
|
13
32
|
|
|
@@ -59,7 +78,7 @@ export function resolveBuildchainContractLockPath(cwd = process.cwd()) {
|
|
|
59
78
|
export function resolveKfd3SurfaceRegistryPath(cwd = process.cwd()) {
|
|
60
79
|
return firstExistingRepoPath(cwd, [
|
|
61
80
|
BUILDCHAIN_KFD3_SURFACE_REGISTRY_PATH,
|
|
62
|
-
|
|
81
|
+
...LEGACY_BUILDCHAIN_KFD3_SURFACE_REGISTRY_PATHS,
|
|
63
82
|
]);
|
|
64
83
|
}
|
|
65
84
|
|
|
@@ -87,7 +106,79 @@ export function discoverBuildchainRepoFiles(cwd = process.cwd()) {
|
|
|
87
106
|
{
|
|
88
107
|
kind: "kfd-3-surface-registry",
|
|
89
108
|
canonical: BUILDCHAIN_KFD3_SURFACE_REGISTRY_PATH,
|
|
90
|
-
legacy:
|
|
109
|
+
legacy: LEGACY_BUILDCHAIN_KFD3_SURFACE_REGISTRY_PATHS,
|
|
110
|
+
tracked: true,
|
|
111
|
+
},
|
|
112
|
+
{
|
|
113
|
+
kind: "kfd-1-contract-world-witness",
|
|
114
|
+
canonical: BUILDCHAIN_KFD1_CONTRACT_WORLD_WITNESS_PATH,
|
|
115
|
+
legacy: [
|
|
116
|
+
".buildchain/kfd-1/contract-world.witness.json",
|
|
117
|
+
".buildchain/kfd/buildchain-kfd-1-witness.json",
|
|
118
|
+
],
|
|
119
|
+
tracked: true,
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
kind: "kfd-1-release-gate",
|
|
123
|
+
canonical: BUILDCHAIN_KFD1_RELEASE_GATE_PATH,
|
|
124
|
+
legacy: [".buildchain/kfd-1/release-gate.json"],
|
|
125
|
+
tracked: true,
|
|
126
|
+
},
|
|
127
|
+
{
|
|
128
|
+
kind: "kfd-1-verify-result",
|
|
129
|
+
canonical: BUILDCHAIN_KFD1_VERIFY_RESULT_PATH,
|
|
130
|
+
legacy: [".buildchain/kfd-1/verify-result.json"],
|
|
131
|
+
tracked: false,
|
|
132
|
+
},
|
|
133
|
+
{
|
|
134
|
+
kind: "kfd-2-release-claims",
|
|
135
|
+
canonical: BUILDCHAIN_KFD2_RELEASE_CLAIMS_PATH,
|
|
136
|
+
legacy: [
|
|
137
|
+
".buildchain/kfd-2/release-claims.json",
|
|
138
|
+
".buildchain/kfd-2/public-release-trust.claim.json",
|
|
139
|
+
],
|
|
140
|
+
tracked: true,
|
|
141
|
+
},
|
|
142
|
+
{
|
|
143
|
+
kind: "kfd-2-claim-args",
|
|
144
|
+
canonical: BUILDCHAIN_KFD2_CLAIM_ARGS_PATH,
|
|
145
|
+
legacy: [".buildchain/kfd-2/buildchain-claim-args.txt"],
|
|
146
|
+
tracked: true,
|
|
147
|
+
},
|
|
148
|
+
{
|
|
149
|
+
kind: "kfd-2-claims",
|
|
150
|
+
canonical: BUILDCHAIN_KFD2_CLAIMS_DIR,
|
|
151
|
+
legacy: [".buildchain/kfd/kfd-2-claims", ".buildchain/kfd-2/claims"],
|
|
152
|
+
tracked: false,
|
|
153
|
+
},
|
|
154
|
+
{
|
|
155
|
+
kind: "kfd-3-collaboration-interface",
|
|
156
|
+
canonical: BUILDCHAIN_KFD3_COLLABORATION_INTERFACE_PATH,
|
|
157
|
+
legacy: [".buildchain/kfd-3/collaboration-interface.json"],
|
|
158
|
+
tracked: true,
|
|
159
|
+
},
|
|
160
|
+
{
|
|
161
|
+
kind: "kfd-3-prebuild-witness",
|
|
162
|
+
canonical: BUILDCHAIN_KFD3_PREBUILD_WITNESS_PATH,
|
|
163
|
+
legacy: [
|
|
164
|
+
".buildchain/kfd-3/collaboration-interface.prebuild.json",
|
|
165
|
+
".buildchain/kfd/buildchain-kfd-3-prebuild-witness.json",
|
|
166
|
+
],
|
|
167
|
+
tracked: true,
|
|
168
|
+
},
|
|
169
|
+
{
|
|
170
|
+
kind: "kfd-3-artifact-witness",
|
|
171
|
+
canonical: BUILDCHAIN_KFD3_ARTIFACT_WITNESS_PATH,
|
|
172
|
+
legacy: [
|
|
173
|
+
".buildchain/kfd-3/collaboration-interface.artifact.json",
|
|
174
|
+
".buildchain/kfd/buildchain-kfd-3-artifact-witness.json",
|
|
175
|
+
],
|
|
176
|
+
tracked: true,
|
|
177
|
+
},
|
|
178
|
+
{
|
|
179
|
+
kind: "kfd-3-capability-query",
|
|
180
|
+
canonical: BUILDCHAIN_KFD3_CAPABILITY_QUERY_PATH,
|
|
181
|
+
legacy: [".buildchain/kfd-3/capability-query.json"],
|
|
91
182
|
tracked: true,
|
|
92
183
|
},
|
|
93
184
|
{
|
|
@@ -99,12 +190,16 @@ export function discoverBuildchainRepoFiles(cwd = process.cwd()) {
|
|
|
99
190
|
];
|
|
100
191
|
return files.map((entry) => {
|
|
101
192
|
const canonicalExists = fs.existsSync(repoPath(cwd, entry.canonical));
|
|
102
|
-
const
|
|
193
|
+
const legacyPaths = Array.isArray(entry.legacy) ? entry.legacy : [entry.legacy].filter(Boolean);
|
|
194
|
+
const existingLegacyPaths = legacyPaths.filter((legacy) => fs.existsSync(repoPath(cwd, legacy)));
|
|
195
|
+
const legacyExists = existingLegacyPaths.length > 0;
|
|
103
196
|
return {
|
|
104
197
|
...entry,
|
|
198
|
+
legacy: legacyPaths,
|
|
105
199
|
canonicalExists,
|
|
106
200
|
legacyExists,
|
|
107
|
-
|
|
201
|
+
existingLegacyPaths,
|
|
202
|
+
activePath: canonicalExists ? entry.canonical : legacyExists ? existingLegacyPaths[0] : entry.canonical,
|
|
108
203
|
migrationNeeded: !canonicalExists && legacyExists,
|
|
109
204
|
};
|
|
110
205
|
});
|
|
@@ -114,12 +209,12 @@ export function planBuildchainLayoutMigration({ cwd = process.cwd() } = {}) {
|
|
|
114
209
|
const entries = discoverBuildchainRepoFiles(cwd);
|
|
115
210
|
const moves = entries
|
|
116
211
|
.filter((entry) => entry.migrationNeeded)
|
|
117
|
-
.
|
|
212
|
+
.flatMap((entry) => entry.existingLegacyPaths.map((legacy) => ({
|
|
118
213
|
kind: entry.kind,
|
|
119
|
-
from:
|
|
214
|
+
from: legacy,
|
|
120
215
|
to: entry.canonical,
|
|
121
216
|
tracked: entry.tracked,
|
|
122
|
-
}));
|
|
217
|
+
})));
|
|
123
218
|
return {
|
|
124
219
|
schemaVersion: 1,
|
|
125
220
|
contract: "kungfu-buildchain-repository-layout-migration",
|