@kungfu-tech/buildchain 2.8.17 → 2.9.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.
@@ -9,6 +9,8 @@
9
9
  },
10
10
  "exports": {
11
11
  ".": "./packages/core/index.js",
12
+ "./badges": "./packages/core/badges.js",
13
+ "./build-facts": "./packages/core/build-facts.js",
12
14
  "./core": "./packages/core/index.js",
13
15
  "./artifact-passport": "./packages/core/artifact-passport.js",
14
16
  "./buildchain-contract": "./packages/core/buildchain-contract.js",
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "schemaVersion": 1,
3
3
  "contract": "kungfu-buildchain-site-manifest",
4
- "generatedAt": "2026-07-08T00:24:24.491Z",
5
- "publishedAt": "2026-07-08T00:24:24.491Z",
4
+ "generatedAt": "2026-07-08T02:47:46.506Z",
5
+ "publishedAt": "2026-07-08T02:47:46.506Z",
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": "186482073690d8f922f5f4ecbea20849dda724a4",
22
+ "sourceRevision": "2142b74c1ce1b6be6e2227ffe53ba87750afde07",
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.8.17",
40
+ "version": "2.9.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:03f52660d03223fff7daf500f995645d78a46fffd8cddec9d8c01bbee0863145"
56
+ "digest": "sha256:2d95d0dd56088efb1a9a16d026810cf2e74659963612451f903e37825c260122"
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:56c9000305e9dc23993e6c401568c4063dd496c3586382a44cd44db108a95094"
72
+ "digest": "sha256:495e1c46ce45268a9ed6502fe115af45a8cd1d8e644cb4332da9b551f919f578"
73
73
  },
74
74
  {
75
75
  "id": "release-propagation",
@@ -85,7 +85,7 @@
85
85
  "path": "docs/readme-badges.md",
86
86
  "plane": "use",
87
87
  "exists": true,
88
- "digest": "sha256:c886d5d469d143571ae68497643be754b1616b562fddc780a5708f49b4c46242"
88
+ "digest": "sha256:06eaef737dcc73a6526d856d79275ee87af9670f0e2be39a5596758bfc3527c9"
89
89
  },
90
90
  {
91
91
  "id": "homebrew",
@@ -165,7 +165,15 @@
165
165
  "path": "docs/cli.md",
166
166
  "plane": "use",
167
167
  "exists": true,
168
- "digest": "sha256:cfb0bf32f2b8b44bf352e79c27e34b7980e0f66e5fa10e4f202975fbb4780ad1"
168
+ "digest": "sha256:60686b5b4d5fe7f3944cb53ab709231fd00bb02b6d51770f1fe8b018122afd8f"
169
+ },
170
+ {
171
+ "id": "build-facts",
172
+ "title": "Build Facts",
173
+ "path": "docs/build-facts.md",
174
+ "plane": "use",
175
+ "exists": true,
176
+ "digest": "sha256:75dcf7a6628dac9e982a455de9966044ae771611d4efc04e7264a2d4adb0bd3e"
169
177
  },
170
178
  {
171
179
  "id": "lifecycle-protocol",
@@ -221,7 +229,7 @@
221
229
  "path": "docs/versioning.md",
222
230
  "plane": "why",
223
231
  "exists": true,
224
- "digest": "sha256:77b92fc979cc100beab3f8a13cd791dea992737b986ace505104edff4810a296"
232
+ "digest": "sha256:2c79f7d1a072a40c75d889beac38ae843b2170587fc570ce40722d3968b6506e"
225
233
  },
226
234
  {
227
235
  "id": "web-surface-deployments",
@@ -229,7 +237,7 @@
229
237
  "path": "docs/web-surface-deployments.md",
230
238
  "plane": "use",
231
239
  "exists": true,
232
- "digest": "sha256:5063ebb76db3cd36797561782e6c741e30d60bfa0dac8f798dbbd34c4ab2b3c0"
240
+ "digest": "sha256:70995864ece77573756e1c197a936d86011f84b356d75683881b59b5aa537d8c"
233
241
  }
234
242
  ],
235
243
  "facts": [
package/docs/MAP.md CHANGED
@@ -23,9 +23,10 @@ manuals explain those facts and give operator examples.
23
23
  | 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) |
24
24
  | Floating `@v2` drift detection and compatibility issues | `dist/site/buildchain-contract.json` | [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock) |
25
25
  | npm publish transactions, evidence, dist-tags, and recovery | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`publish-transaction.md`](publish-transaction.md) |
26
+ | 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) |
26
27
  | GitHub Release passport/evidence publication | `dist/site/release-model.json`, `dist/site/artifact-schemas.json` | [`release-governance.md`](release-governance.md), [`release-candidate.md`](release-candidate.md) |
27
28
  | release propagation for package/site chains | `dist/site/release-model.json` | [`release-propagation.md`](release-propagation.md) |
28
- | Generated README badge blocks and badge facts | `dist/site/node-api-registry.json`, `dist/site/manual-registry.json`, `kungfu-buildchain-readme-badge-facts` | [`readme-badges.md`](readme-badges.md) |
29
+ | Generated badge bundles, README badge blocks, and badge facts | `dist/site/node-api-registry.json`, `dist/site/manual-registry.json`, `kungfu-buildchain-badge-bundle-facts`, `kungfu-buildchain-readme-badge-facts` | [`readme-badges.md`](readme-badges.md) |
29
30
  | Homebrew tap distribution indexes | `dist/site/node-api-registry.json`, `dist/site/buildchain-contract.json` | [`homebrew.md`](homebrew.md) |
30
31
  | Buildchain CLI manual | `dist/site/cli-registry.json`, `dist/site/manual-registry.json` | [`cli.md`](cli.md) |
31
32
  | Node API / package exports | `dist/site/node-api-registry.json`, `dist/site/release-provenance.json` | [`cli.md`](cli.md#node-api-and-package-exports) |
@@ -55,13 +56,14 @@ replace them.
55
56
  | What is the active action and workflow source of truth? | [`ownership.md`](ownership.md) | verify | stable |
56
57
  | How do I declare version files and custom lifecycle commands? | [`lifecycle-protocol.md`](lifecycle-protocol.md) | use | stable |
57
58
  | How does publish evidence, recovery, and finalization work? | [`publish-transaction.md`](publish-transaction.md) | verify | stable |
59
+ | How do I collect and verify module/product build facts from Git source, version files, and outputs? | [`build-facts.md`](build-facts.md) + [`cli.md`](cli.md) | use/verify | stable |
58
60
  | How do I publish or verify release passport artifacts? | [`release-passport.md`](release-passport.md) | use | stable |
59
61
  | How do I gate release artifacts with KFD-1 contract-world witnesses? | [`release-passport.md`](release-passport.md#kfd-1-contract-world-release-gate) | verify/use | stable |
60
62
  | How do I audit public KFD-2 release trust claims? | [`release-passport.md`](release-passport.md#kfd-2-release-trust-passport-audit) + [`cli.md`](cli.md) | verify/use | stable |
61
63
  | How do I gate KFD-3 collaboration-interface releases? | [`release-passport.md`](release-passport.md#kfd-3-collaboration-interface-release-gate) + [`cli.md`](cli.md) | verify/use | stable |
62
64
  | How do I keep `@v2` floating refs while detecting Buildchain contract drift? | [`reusable-build-surface.md`](reusable-build-surface.md#floating-ref-contract-lock) | verify/use | stable |
63
65
  | How do I propagate finalized upstream releases to downstream package/site PRs? | [`release-propagation.md`](release-propagation.md) | use | preview |
64
- | How do I generate README status badges without hand-maintaining Markdown? | [`readme-badges.md`](readme-badges.md) + [`cli.md`](cli.md) | use | stable |
66
+ | How do I generate KFD / Release Passport badge bundles without hand-maintaining Markdown? | [`readme-badges.md`](readme-badges.md) + [`cli.md`](cli.md) | use | stable |
65
67
  | How do I generate and verify a Homebrew tap from release passport evidence? | [`homebrew.md`](homebrew.md) + [`cli.md`](cli.md) | use/verify | stable |
66
68
  | How do I prove a PR-stage reusable build is the artifact source promoted later? | [`release-candidate.md`](release-candidate.md) + [`reusable-build-surface.md`](reusable-build-surface.md) | verify | stable |
67
69
  | Why are binary release assets archived by platform, and where is the single bundle? | [`binary-distribution.md`](binary-distribution.md) | verify | stable |
@@ -120,9 +122,11 @@ replace them.
120
122
  and [`release-passport.md`](release-passport.md).
121
123
  - **Trusted Publishing / npm / publish evidence / recovery** ->
122
124
  [`cli.md`](cli.md) and [`publish-transaction.md`](publish-transaction.md).
125
+ - **Git source digest / module build facts / product build facts / legacy
126
+ Kungfu build info** -> [`build-facts.md`](build-facts.md) and [`cli.md`](cli.md).
123
127
  - **release chains / upstream package as source of truth / site synchronization** ->
124
128
  [`release-propagation.md`](release-propagation.md).
125
- - **README status badges / KFD badge blocks / badge facts JSON** ->
129
+ - **README status badges / KFD badge bundles / badge facts JSON** ->
126
130
  [`readme-badges.md`](readme-badges.md) and [`cli.md`](cli.md).
127
131
  - **Homebrew taps / distribution indexes / Formula drift checks** ->
128
132
  [`homebrew.md`](homebrew.md) and [`cli.md`](cli.md).
@@ -0,0 +1,164 @@
1
+ # Build Facts
2
+
3
+ Build Facts are Buildchain's machine-readable record of what a repository
4
+ built. They sit between lifecycle logs and release passports:
5
+
6
+ - lifecycle logs explain what ran and how long it took;
7
+ - module build facts bind one module to its Git source digest, version source,
8
+ platform, lifecycle invocation, and output digests;
9
+ - product build facts aggregate module facts and product artifacts;
10
+ - release passports can carry build facts as first-class evidence.
11
+
12
+ The goal is to remove handwritten build metadata from consumer repositories.
13
+ Consumers declare where their version and outputs live; Buildchain collects and
14
+ verifies the facts.
15
+
16
+ ## Config
17
+
18
+ Declare build facts in `buildchain.toml`:
19
+
20
+ ```toml
21
+ schema = 1
22
+
23
+ [[facts.version_sources]]
24
+ id = "package"
25
+ type = "json"
26
+ path = "package.json"
27
+ key = "version"
28
+
29
+ [[facts.modules]]
30
+ id = "native-core"
31
+ root = "src/core"
32
+ scope = "core"
33
+ version_source = "package"
34
+ lifecycle = "build"
35
+ outputs = ["dist/core.node"]
36
+
37
+ [[facts.products]]
38
+ id = "kungfu"
39
+ module_facts = [".buildchain/facts/native-core.json"]
40
+ artifacts = ["dist/kungfu.zip"]
41
+
42
+ [[facts.legacy_projections]]
43
+ type = "kungfu-buildinfo"
44
+ module = "native-core"
45
+ path = "framework/core/src/kungfu/yijinjing/kungfubuildinfo.json"
46
+ ```
47
+
48
+ Supported version sources:
49
+
50
+ - `static`: an explicit `value`;
51
+ - `json`: a JSON file plus dotted `key`;
52
+ - `toml`: a TOML file plus dotted `key`;
53
+ - `regex`: a text file plus regex `pattern`, using a named `version` group or
54
+ the first capture group;
55
+ - `command`: an explicit command whose output is the version.
56
+
57
+ Prefer file-based sources. Command sources are allowed for legacy projects but
58
+ are marked as less reproducible because the command output is not a static
59
+ source file.
60
+
61
+ ## CLI
62
+
63
+ Collect a module fact:
64
+
65
+ ```bash
66
+ buildchain facts module \
67
+ --module native-core \
68
+ --output .buildchain/facts/native-core.json
69
+ ```
70
+
71
+ Override declarative config from a workflow step when needed:
72
+
73
+ ```bash
74
+ buildchain facts module \
75
+ --cwd "$GITHUB_WORKSPACE" \
76
+ --module native-core \
77
+ --module-root src/core \
78
+ --version-source package \
79
+ --output-path dist/core.node \
80
+ --output .buildchain/facts/native-core.json \
81
+ --json
82
+ ```
83
+
84
+ Write the Kungfu legacy `kungfubuildinfo.json` projection from the same module
85
+ fact:
86
+
87
+ ```bash
88
+ buildchain facts module \
89
+ --module native-core \
90
+ --output .buildchain/facts/native-core.json \
91
+ --legacy-kungfu-buildinfo framework/core/src/kungfu/yijinjing/kungfubuildinfo.json
92
+ ```
93
+
94
+ Aggregate product facts:
95
+
96
+ ```bash
97
+ buildchain facts aggregate \
98
+ --product kungfu \
99
+ --module-fact .buildchain/facts/native-core.json \
100
+ --artifact dist/kungfu.zip \
101
+ --output .buildchain/facts/kungfu.json
102
+ ```
103
+
104
+ Verify a fact before publishing:
105
+
106
+ ```bash
107
+ buildchain facts verify --fact .buildchain/facts/kungfu.json
108
+ ```
109
+
110
+ Verification fails closed when a declared output is missing, an output digest is
111
+ stale, a module fact was collected from a different Git `HEAD`, or a source
112
+ digest no longer matches the tracked source files.
113
+
114
+ ## Node API
115
+
116
+ ```js
117
+ import {
118
+ aggregateBuildFacts,
119
+ collectModuleBuildFacts,
120
+ verifyBuildFacts,
121
+ writeBuildFacts,
122
+ writeKungfuBuildInfoProjection,
123
+ } from "@kungfu-tech/buildchain/build-facts";
124
+
125
+ const moduleFact = collectModuleBuildFacts({ moduleId: "native-core" });
126
+ writeBuildFacts({ fact: moduleFact, output: ".buildchain/facts/native-core.json" });
127
+
128
+ const productFact = aggregateBuildFacts({ productId: "kungfu" });
129
+ const verification = verifyBuildFacts({ fact: productFact });
130
+ ```
131
+
132
+ The root package export also re-exports these APIs from
133
+ `@kungfu-tech/buildchain`.
134
+
135
+ ## Release Passport Integration
136
+
137
+ Pass build facts into a release passport:
138
+
139
+ ```bash
140
+ buildchain collect github-release \
141
+ --tag "$TAG" \
142
+ --assets-dir dist \
143
+ --build-facts-json .buildchain/facts/native-core.json \
144
+ --build-facts-json .buildchain/facts/kungfu.json \
145
+ --output-dir .buildchain/release-passport
146
+ ```
147
+
148
+ The passport records the full build facts in `buildFacts[]` and a compact
149
+ evidence index in `evidence.buildFacts[]`. Agents can start from
150
+ `buildchain.release.json`, discover the module/product facts, and verify that
151
+ the released artifacts still match the declared source, version, and output
152
+ facts.
153
+
154
+ ## Kungfu Legacy Projection
155
+
156
+ Kungfu historically consumes `kungfubuildinfo.json`. Buildchain now treats that
157
+ file as a projection of module build facts, not as an independent source of
158
+ truth. The projection preserves legacy fields such as `version`,
159
+ `python_version`, `git_branch`, `git_revision`, and `git_pristine`, while adding
160
+ a `buildchain` section that points back to the module fact digest, version
161
+ source digest, and source digest.
162
+
163
+ Repositories that no longer need the legacy file should consume the module and
164
+ product facts directly.
package/docs/cli.md CHANGED
@@ -64,8 +64,10 @@ Current public import families include:
64
64
  ```js
65
65
  import * as buildchain from "@kungfu-tech/buildchain";
66
66
  import { createBuildchainLogger } from "@kungfu-tech/buildchain/logging";
67
+ import { collectModuleBuildFacts } from "@kungfu-tech/buildchain/build-facts";
67
68
  import { checkHomebrewTap } from "@kungfu-tech/buildchain/homebrew";
68
69
  import { verifyKfd1ReleaseGate } from "@kungfu-tech/buildchain/kfd-gate";
70
+ import { collectBadgeBundleFacts } from "@kungfu-tech/buildchain/badges";
69
71
  import { collectReadmeBadgeFacts } from "@kungfu-tech/buildchain/readme-badges";
70
72
  import { verifyReleasePassport } from "@kungfu-tech/buildchain/release-passport";
71
73
  import { createReleasePropagationPlan } from "@kungfu-tech/buildchain/release-propagation";
@@ -199,6 +201,30 @@ install/build/verify/publish, artifact scan/upload, total, warning, and error
199
201
  columns for each platform, plus `jobs` and `active` columns for requested and
200
202
  observed process concurrency when sampler data is present.
201
203
 
204
+ `buildchain facts` collects and verifies source/version/output facts for
205
+ modules and products:
206
+
207
+ ```bash
208
+ buildchain facts module \
209
+ --module native-core \
210
+ --output .buildchain/facts/native-core.json \
211
+ --legacy-kungfu-buildinfo framework/core/src/kungfu/yijinjing/kungfubuildinfo.json
212
+
213
+ buildchain facts aggregate \
214
+ --product kungfu \
215
+ --module-fact .buildchain/facts/native-core.json \
216
+ --artifact dist/kungfu.zip \
217
+ --output .buildchain/facts/kungfu.json
218
+
219
+ buildchain facts verify --fact .buildchain/facts/kungfu.json
220
+ ```
221
+
222
+ The same implementation is available from
223
+ `@kungfu-tech/buildchain/build-facts`. Release passports can include these
224
+ facts with repeated `--build-facts-json` arguments to
225
+ `buildchain collect github-release`. See
226
+ [`build-facts.md`](build-facts.md) for the config schema and Node API.
227
+
202
228
  `buildchain sample process-tree` wraps a long-running command and periodically
203
229
  writes process-tree snapshots:
204
230
 
@@ -259,6 +285,10 @@ Generate, check, or update the managed README badge block:
259
285
  buildchain badges readme --json
260
286
  buildchain badges readme --check
261
287
  buildchain badges readme --write
288
+ buildchain badges bundle --json
289
+ buildchain badges bundle --check
290
+ buildchain badges bundle --write
291
+ buildchain badges bundle --claims kfd-1,release-passport --write
262
292
  ```
263
293
 
264
294
  The `--json` form emits the `kungfu-buildchain-readme-badge-facts` object.
@@ -266,8 +296,10 @@ The `--json` form emits the `kungfu-buildchain-readme-badge-facts` object.
266
296
  `--write` inserts or replaces only the marked block. KFD passed badges come
267
297
  from the repository's own verified release passport; unreleased repositories
268
298
  downgrade to explicit local declarations such as `declared`, `aligned`, or
269
- `planned`. See [`readme-badges.md`](readme-badges.md) for the marker contract
270
- and `[badges]` configuration.
299
+ `planned`. `buildchain badges bundle` is the focused trust-badge entrypoint: it
300
+ emits `kungfu-buildchain-badge-bundle-facts` and defaults to KFD-1, KFD-2,
301
+ KFD-3, and Release Passport. See [`readme-badges.md`](readme-badges.md) for the
302
+ marker contract and `[badges]` / `[badges.bundle]` configuration.
271
303
 
272
304
  Generate or check Homebrew tap projections from upstream release passports:
273
305
 
@@ -22,13 +22,20 @@ Use the public package export:
22
22
 
23
23
  ```js
24
24
  import {
25
+ collectBadgeBundleFacts,
25
26
  collectReadmeBadgeFacts,
27
+ renderBadgeBundleBlock,
26
28
  renderReadmeBadgeBlock,
29
+ checkBadgeBundleBlock,
27
30
  checkReadmeBadgeBlock,
31
+ updateBadgeBundleBlock,
28
32
  updateReadmeBadgeBlock,
29
- } from "@kungfu-tech/buildchain/readme-badges";
33
+ } from "@kungfu-tech/buildchain/badges";
30
34
  ```
31
35
 
36
+ `@kungfu-tech/buildchain/readme-badges` remains available for compatibility,
37
+ but new integrations should use `@kungfu-tech/buildchain/badges`.
38
+
32
39
  `collectReadmeBadgeFacts({ cwd })` returns a machine-readable object with
33
40
  contract `kungfu-buildchain-readme-badge-facts`. It collects repository
34
41
  identity, package name/version/license, configured platforms, configured
@@ -50,6 +57,13 @@ managed block.
50
57
 
51
58
  The Node API is the implementation source. The CLI delegates to it.
52
59
 
60
+ `collectBadgeBundleFacts({ cwd, claims })` is the trust-badge bundle API. It
61
+ uses the same repository facts, but returns contract
62
+ `kungfu-buildchain-badge-bundle-facts` and only renders the Buildchain trust
63
+ claims: `kfd-1`, `kfd-2`, `kfd-3`, and `release-passport`. Those four claims are
64
+ enabled by default. Callers can pass `claims: "kfd-1,release-passport"` or an
65
+ array to narrow the bundle without hand-writing badge Markdown.
66
+
53
67
  ## CLI
54
68
 
55
69
  Generate facts as JSON:
@@ -70,9 +84,23 @@ Insert or replace the block:
70
84
  buildchain badges readme --write
71
85
  ```
72
86
 
87
+ Generate only the Buildchain trust badge bundle:
88
+
89
+ ```bash
90
+ buildchain badges bundle --json
91
+ buildchain badges bundle --check
92
+ buildchain badges bundle --write
93
+ ```
94
+
95
+ Narrow the bundle to specific claims:
96
+
97
+ ```bash
98
+ buildchain badges bundle --claims kfd-1,release-passport --write
99
+ ```
100
+
73
101
  All commands accept `--cwd <dir>` and `--readme <path>`. Repositories can add
74
- `buildchain badges readme --check` to CI so badge drift is detected like any
75
- other generated release-facing surface.
102
+ `buildchain badges bundle --check` or `buildchain badges readme --check` to CI
103
+ so badge drift is detected like any other generated release-facing surface.
76
104
 
77
105
  ## Configuration
78
106
 
@@ -88,6 +116,9 @@ kfd_2 = "planned"
88
116
  kfd_3 = "aligned"
89
117
  platforms = ["macOS", "Linux", "Windows"]
90
118
  workflows = ["verify.yml", "build.yml"]
119
+
120
+ [badges.bundle]
121
+ claims = ["kfd-1", "kfd-2", "kfd-3", "release-passport"]
91
122
  ```
92
123
 
93
124
  `release_passport` may be a local path or URL. If omitted, Buildchain tries
@@ -154,6 +185,12 @@ Recommended CI gate:
154
185
  buildchain badges readme --check
155
186
  ```
156
187
 
188
+ or, when the repository only wants the Buildchain trust bundle:
189
+
190
+ ```bash
191
+ buildchain badges bundle --check
192
+ ```
193
+
157
194
  The check fails when:
158
195
 
159
196
  - the marker block is missing;
@@ -51,6 +51,9 @@ Additive passport sections:
51
51
  policy. It records real CI/release generation and publication times,
52
52
  reproducibility inputs, source revision or source-date-epoch, and whether
53
53
  timestamp fields participate in the release artifact digest.
54
+ - `buildFacts`: module/product build facts that bind Git source digests,
55
+ version sources, lifecycle invocations, platforms, outputs, product
56
+ artifacts, and verification results to the release.
54
57
  - `artifacts`: release assets and registry artifacts in one list, each pointing
55
58
  back to the evidence file that proves its digest.
56
59
 
@@ -97,6 +100,8 @@ buildchain collect github-release \
97
100
  --package-set-json package-set.json \
98
101
  --anchor-manifest-json libnode.release.json \
99
102
  --build-summary-json .buildchain/artifacts/build-summary.json \
103
+ --build-facts-json .buildchain/facts/native-core.json \
104
+ --build-facts-json .buildchain/facts/product.json \
100
105
  --platform-manifest-json .buildchain/artifacts/linux-x64/manifest.json \
101
106
  --platform-manifest-json .buildchain/artifacts/darwin-arm64/manifest.json \
102
107
  --platform-manifest-json .buildchain/artifacts/win32-x64/manifest.json \
@@ -111,7 +116,12 @@ buildchain collect github-release \
111
116
  dist-tag, registry, role, platform, and digest, so agents do not need to stitch
112
117
  npm facts back together from the lower-level evidence files.
113
118
  `buildSummary`, `platformArtifactManifests`, and `distTagPromotion` preserve the
114
- build and npm dist-tag evidence chain in the same passport.
119
+ build and npm dist-tag evidence chain in the same passport. `buildFacts[]`
120
+ records first-class module/product build facts, while
121
+ `evidence.buildFacts[]` gives agents compact paths, SHA-256 hashes, contracts,
122
+ ids, and digests for quick audit traversal. See
123
+ [`build-facts.md`](build-facts.md) for the fact collection and verification
124
+ contract.
115
125
 
116
126
  ### KFD-1 contract-world release gate
117
127
 
@@ -61,6 +61,7 @@ repository changes are patch".
61
61
 
62
62
  | Date | Action | Line | Faces | Class | Rationale | PR |
63
63
  | --- | --- | --- | --- | --- | --- | --- |
64
+ | 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. | |
64
65
  | 2026-07-06 | open-minor | `v2.8` | kfd-1-contract-world-release-gate, kfd-2-release-trust-passport-audit, kfd-3-collaboration-interface-trust-proof, publish-source-lock-enforcement, required-check-protection | additive | KFD release gates add KFD-1 self contract verification, KFD-2 public release trust claim audit, KFD-3 collaboration-interface trust proofs, publish-side source-lock enforcement for promote-only wrappers, and protected channel required checks repaired to bind GitHub Actions check runs instead of legacy commit status contexts. | |
65
66
  | 2026-07-04 | open-minor | `v2.5` | scheduled-integration-governance | additive | Scheduled integration governance adds scheduled feature-branch discovery, conflict-free integration, reporting, and agent-visible governance automation for dev-line maintenance. | |
66
67
  | 2026-07-03 | open-minor | `v2.4` | infra-contract-lifecycle | additive | Infra contract lifecycle adds the provider-neutral `infra-contract` CLI command family, project type, adapter capability contract, lifecycle evidence bundle, propagation evidence, CI evidence mode, and consumer-facing contract artifacts. | |
@@ -376,6 +376,14 @@ records this as `routing.contract =
376
376
  `viewerPathPrefix = "/"`, `artifactPathPrefix = "buildchain"`, and
377
377
  `directoryIndexResolution = true`.
378
378
 
379
+ When a surface uses an S3 object prefix, Buildchain also writes directory-index
380
+ alias objects during apply. The root `dist/buildchain/index.html` is copied to
381
+ the prefix keys `pr-29/buildchain` and `pr-29/buildchain/`, while nested indexes
382
+ such as `dist/buildchain/docs/index.html` are copied to `pr-29/buildchain/docs`
383
+ and `pr-29/buildchain/docs/`. This makes surface-host requests for `/` and
384
+ `/docs/` resolve to the surface's `index.html` files even when the CloudFront
385
+ origin is an S3 REST origin rather than an S3 website endpoint.
386
+
379
387
  It can also execute a previously saved deploy plan. In that mode Buildchain
380
388
  recomputes the local artifact hash before running AWS commands and fails closed
381
389
  if the artifact no longer matches the saved plan:
@@ -464,13 +472,17 @@ such as `dist/buildchain/docs/index.html` becoming `/docs/` on the buildchain
464
472
  preview host. If a surface has no nested HTML route, Buildchain records only
465
473
  the root smoke URL; absence of nested HTML is not a deployment failure. When a
466
474
  nested route is present, the check fails closed if a deploy reports success but
467
- that child page returns 403 or another unexpected status. Production additionally fails if a
468
- response is unreachable, returns an unexpected status, or still sends
469
- `x-robots-tag: noindex`. The health check also verifies that each surface
470
- binding recorded a deployment manifest pointer. The production release passport
471
- embeds the deploy plan, apply result, production preflight, and health check so
472
- a reviewer or agent can audit why the production site changed and whether every
473
- declared host and every existing nested route was actually covered.
475
+ that child page returns 403 or another unexpected status. Surface root checks
476
+ expect the apply result to have written directory-index alias objects, so a
477
+ multi-host preview root such as `https://buildchain-pr-29.preview.libkungfu.dev/`
478
+ must resolve to the surface `index.html`, not the bare prefix directory.
479
+ Production additionally fails if a response is unreachable, returns an
480
+ unexpected status, or still sends `x-robots-tag: noindex`. The health check also
481
+ verifies that each surface binding recorded a deployment manifest pointer. The
482
+ production release passport embeds the deploy plan, apply result, production
483
+ preflight, and health check so a reviewer or agent can audit why the production
484
+ site changed and whether every declared host and every existing nested route was
485
+ actually covered.
474
486
 
475
487
  ## Cleanup Plans
476
488
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "2.8.17",
3
+ "version": "2.9.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",
@@ -12,6 +12,8 @@
12
12
  },
13
13
  "exports": {
14
14
  ".": "./packages/core/index.js",
15
+ "./badges": "./packages/core/badges.js",
16
+ "./build-facts": "./packages/core/build-facts.js",
15
17
  "./core": "./packages/core/index.js",
16
18
  "./artifact-passport": "./packages/core/artifact-passport.js",
17
19
  "./buildchain-contract": "./packages/core/buildchain-contract.js",
@@ -12,10 +12,12 @@ Current shared surfaces:
12
12
  - toolkit observability logging through `@kungfu-tech/buildchain/logging`;
13
13
  - toolkit diagnostics and native profile collection through
14
14
  `@kungfu-tech/buildchain/diagnostics`;
15
+ - source/version/module/product build facts through
16
+ `@kungfu-tech/buildchain/build-facts`;
15
17
  - release passport creation and verification through
16
18
  `@kungfu-tech/buildchain/release-passport`.
17
- - managed README badge facts and marker blocks through
18
- `@kungfu-tech/buildchain/readme-badges`.
19
+ - managed KFD / Release Passport badge bundle facts and README marker blocks
20
+ through `@kungfu-tech/buildchain/badges`.
19
21
 
20
22
  ## Toolkit Imports
21
23
 
@@ -52,16 +54,30 @@ const { createBuildchainLogger } = await import("@kungfu-tech/buildchain/logging
52
54
  const { collectRunnerDiagnostics } = await import("@kungfu-tech/buildchain/diagnostics");
53
55
  ```
54
56
 
57
+ Build facts consumers can collect source-bound module/product facts before
58
+ publishing and pass those facts into the release passport:
59
+
60
+ ```js
61
+ import { collectModuleBuildFacts, writeBuildFacts } from "@kungfu-tech/buildchain/build-facts";
62
+
63
+ const fact = collectModuleBuildFacts({ moduleId: "native-core" });
64
+ writeBuildFacts({ fact, output: ".buildchain/facts/native-core.json" });
65
+ ```
66
+
55
67
  Web-surface validation stays in core because both local scripts and GitHub
56
68
  Actions need the same fail-closed interpretation of project, channel, deploy,
57
69
  retention, and staging security declarations.
58
70
 
59
- README badge consumers should import the public subpath and treat Markdown as a
60
- projection of the returned facts:
71
+ README badge consumers should import the public badge subpath and treat
72
+ Markdown as a projection of the returned facts:
61
73
 
62
74
  ```js
63
- import { collectReadmeBadgeFacts, renderReadmeBadgeBlock } from "@kungfu-tech/buildchain/readme-badges";
75
+ import { collectBadgeBundleFacts, renderBadgeBundleBlock } from "@kungfu-tech/buildchain/badges";
64
76
 
65
- const facts = await collectReadmeBadgeFacts({ cwd: process.cwd() });
66
- const markdown = renderReadmeBadgeBlock(facts);
77
+ const facts = await collectBadgeBundleFacts({ cwd: process.cwd() });
78
+ const markdown = renderBadgeBundleBlock(facts);
67
79
  ```
80
+
81
+ The older `@kungfu-tech/buildchain/readme-badges` subpath remains available for
82
+ callers that need the full README badge surface instead of the default
83
+ KFD-1 / KFD-2 / KFD-3 / Release Passport bundle.
@@ -0,0 +1,18 @@
1
+ export {
2
+ BADGE_BUNDLE_DEFAULT_CLAIMS,
3
+ BADGE_BUNDLE_FACTS_CONTRACT,
4
+ README_BADGE_BLOCK_END,
5
+ README_BADGE_BLOCK_START,
6
+ README_BADGE_FACTS_CONTRACT,
7
+ README_BADGE_HOSTED_BASE_URL,
8
+ checkBadgeBundleBlock,
9
+ checkReadmeBadgeBlock,
10
+ collectBadgeBundleFacts,
11
+ collectReadmeBadgeFacts,
12
+ createReadmeBadgeEndpointRegistry,
13
+ readReadme,
14
+ renderBadgeBundleBlock,
15
+ renderReadmeBadgeBlock,
16
+ updateBadgeBundleBlock,
17
+ updateReadmeBadgeBlock,
18
+ } from "./readme-badges.js";