@kungfu-tech/buildchain 2.2.1-alpha.0 → 2.2.1-alpha.1

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.
@@ -0,0 +1,274 @@
1
+ #!/usr/bin/env node
2
+ import fs from "node:fs";
3
+ import path from "node:path";
4
+ import { pathToFileURL } from "node:url";
5
+
6
+ const SITE_BUNDLE_CONTRACT = "kungfu-buildchain-site-bundle";
7
+ const root = path.resolve(import.meta.dirname, "..");
8
+ const outputDir = path.join(root, "dist", "site");
9
+
10
+ function readJson(rel) {
11
+ return JSON.parse(fs.readFileSync(path.join(root, rel), "utf8"));
12
+ }
13
+
14
+ function writeJson(filePath, value) {
15
+ fs.mkdirSync(path.dirname(filePath), { recursive: true });
16
+ fs.writeFileSync(filePath, `${JSON.stringify(value, null, 2)}\n`);
17
+ }
18
+
19
+ function stableJson(value) {
20
+ return `${JSON.stringify(value, null, 2)}\n`;
21
+ }
22
+
23
+ function existingJson(filePath) {
24
+ return fs.existsSync(filePath) ? fs.readFileSync(filePath, "utf8") : "";
25
+ }
26
+
27
+ function docEntry(id, title, pathName, plane) {
28
+ return {
29
+ id,
30
+ title,
31
+ path: pathName,
32
+ plane,
33
+ exists: fs.existsSync(path.join(root, pathName)),
34
+ };
35
+ }
36
+
37
+ function buildSiteBundle() {
38
+ const packageJson = readJson("package.json");
39
+ const inventory = readJson("tests/buildchain-inventory.json");
40
+ const docs = [
41
+ docEntry("install", "Install and verify Buildchain", "docs/install.md", "use"),
42
+ docEntry("release-passport", "Release Passport protocol", "docs/release-passport.md", "verify"),
43
+ docEntry("binary-distribution", "Binary distribution contract", "docs/binary-distribution.md", "verify"),
44
+ docEntry("toolkit-observability", "Toolkit observability", "docs/toolkit-observability.md", "use"),
45
+ docEntry("site-bundle-contract", "Site bundle contract", "docs/site-bundle-contract.md", "use"),
46
+ docEntry("product-mechanism", "Product mechanism", "docs/product-mechanism.md", "why"),
47
+ docEntry("cli", "CLI and npm package", "docs/cli.md", "use"),
48
+ docEntry("lifecycle-protocol", "Lifecycle protocol", "docs/lifecycle-protocol.md", "use"),
49
+ docEntry("reusable-build-surface", "Reusable build surface", "docs/reusable-build-surface.md", "use"),
50
+ docEntry("publish-transaction", "Publish transaction", "docs/publish-transaction.md", "verify"),
51
+ docEntry("release-governance", "Release governance", "docs/release-governance.md", "why"),
52
+ docEntry("release-flow", "Release flow", "docs/release-flow.md", "verify"),
53
+ docEntry("versioning", "Versioning", "docs/versioning.md", "why"),
54
+ docEntry("web-surface-deployments", "Web surface deployments", "docs/web-surface-deployments.md", "use"),
55
+ ];
56
+
57
+ const cliRegistry = {
58
+ schemaVersion: 1,
59
+ contract: "kungfu-buildchain-cli-registry",
60
+ binary: "buildchain",
61
+ npmPackage: packageJson.name,
62
+ commands: [
63
+ { id: "version", usage: "buildchain version", purpose: "Print the package or embedded binary version." },
64
+ { id: "init", usage: "buildchain init [--type package|native|web-surface|anchored-package]", purpose: "Bootstrap a repository with Buildchain configuration and caller workflow files." },
65
+ { id: "validate", usage: "buildchain validate [--require-version-state]", purpose: "Validate buildchain.toml and declared lifecycle surfaces." },
66
+ { id: "doctor", usage: "buildchain doctor [--json]", purpose: "Report local integration readiness." },
67
+ { id: "lifecycle", usage: "buildchain lifecycle run <stage>", purpose: "Run configured lifecycle commands and write deterministic artifact manifests." },
68
+ { id: "release-dry-run", usage: "buildchain release --dry-run --target-ref <ref>", purpose: "Explain what a channel merge would publish before the PR is merged." },
69
+ { id: "collect-github-release", usage: "buildchain collect github-release --tag <tag>", purpose: "Collect release assets into a release passport." },
70
+ { id: "verify-release-passport", usage: "buildchain verify release-passport <file-or-url>", purpose: "Fail closed unless a release passport and its evidence are complete." },
71
+ { id: "logging", usage: "buildchain log|mark|span|verify observability-log", purpose: "Emit timestamped build events, summarize logs, and enforce required phases." },
72
+ { id: "npm-dry-run", usage: "buildchain npm dry-run --json", purpose: "Verify npm publish shape before a release transaction." },
73
+ ],
74
+ };
75
+
76
+ const workflowRegistry = {
77
+ schemaVersion: 1,
78
+ contract: "kungfu-buildchain-workflow-registry",
79
+ workflows: [
80
+ { id: "build", path: ".github/workflows/.build.yml", surface: "reusable-build", status: "active" },
81
+ { id: "web-surface", path: ".github/workflows/.web-surface.yml", surface: "site-app-deployment", status: "active" },
82
+ { id: "buildchain-ref-promotion", path: ".github/workflows/buildchain-ref-promotion.yml", surface: "release-governance", status: "active" },
83
+ { id: "binary-distribution", path: ".github/workflows/binary-distribution.yml", surface: "release-passport", status: "active" },
84
+ ],
85
+ actions: [
86
+ { id: "validate-config", path: "actions/validate-config", status: "active" },
87
+ { id: "run-lifecycle", path: "actions/run-lifecycle", status: "active" },
88
+ { id: "promote-buildchain-ref", path: "actions/promote-buildchain-ref", status: "active" },
89
+ ],
90
+ };
91
+
92
+ const releaseModel = {
93
+ schemaVersion: 1,
94
+ contract: "kungfu-buildchain-release-model",
95
+ exactTags: "v-prefixed exact tags are immutable release records.",
96
+ floatingTags: "vX, vX.Y, and vX.Y-alpha are channel pointers updated by Buildchain transactions.",
97
+ channelBranches: ["dev/vX/vX.Y", "alpha/vX/vX.Y", "release/vX/vX.Y", "publish-gate/major"],
98
+ releasePassport: {
99
+ entrypoint: "buildchain.release.json",
100
+ bundle: "buildchain-release-bundle.tar.gz",
101
+ contract: "kungfu-buildchain-release-passport",
102
+ },
103
+ npm: {
104
+ package: packageJson.name,
105
+ command: packageJson.bin?.buildchain || "",
106
+ versionSource: "package.json#version",
107
+ alphaDistTag: "alpha",
108
+ stableDistTag: "latest",
109
+ },
110
+ };
111
+
112
+ const artifactSchemas = {
113
+ schemaVersion: 1,
114
+ contract: "kungfu-buildchain-artifact-schema-index",
115
+ releasePassport: [
116
+ "buildchain.release.json",
117
+ "artifact-evidence.json",
118
+ "product-mechanism.json",
119
+ "impact.json",
120
+ "agent-index.json",
121
+ "check-report.json",
122
+ "llms.txt",
123
+ "buildchain-release-bundle.json",
124
+ "buildchain-release-bundle.tar.gz",
125
+ ],
126
+ site: [
127
+ "buildchain-site.json",
128
+ "site-manifest.json",
129
+ "cli-registry.json",
130
+ "workflow-registry.json",
131
+ "release-model.json",
132
+ "artifact-schemas.json",
133
+ "product-mechanism.json",
134
+ "release-provenance.json",
135
+ "agent-index.json",
136
+ ],
137
+ };
138
+
139
+ const productMechanism = {
140
+ schemaVersion: 1,
141
+ contract: "kungfu-buildchain-product-mechanism",
142
+ name: "Buildchain",
143
+ formalName: "Buildchain by Kungfu",
144
+ category: "Buildchain Release Passport",
145
+ purpose: "A mature product release record for artifacts that users or agents depend on.",
146
+ executionSubstrate: "GitHub Actions, protected refs, exact tags, GitHub Releases, npm Trusted Publishing, and machine-readable evidence.",
147
+ notA: [
148
+ "a replacement CI/CD platform",
149
+ "a binary-only release tool",
150
+ "a workflow file collection as the product boundary",
151
+ ],
152
+ proofCases: [
153
+ "multi-platform CLI archives",
154
+ "npm package publication",
155
+ "native and multi-artifact release passports",
156
+ "site facts consumed by buildchain.libkungfu.dev",
157
+ ],
158
+ };
159
+
160
+ const releaseProvenance = {
161
+ schemaVersion: 1,
162
+ contract: "kungfu-buildchain-release-provenance",
163
+ package: {
164
+ name: packageJson.name,
165
+ versionSource: "package.json#version",
166
+ bin: packageJson.bin,
167
+ exports: packageJson.exports,
168
+ },
169
+ repository: packageJson.repository,
170
+ packageManager: packageJson.packageManager,
171
+ inventoryRelease: inventory.release,
172
+ stableRefs: inventory.stableRefs,
173
+ };
174
+
175
+ const siteManifest = {
176
+ schemaVersion: 1,
177
+ contract: "kungfu-buildchain-site-manifest",
178
+ product: {
179
+ name: "Buildchain",
180
+ formalName: "Buildchain by Kungfu",
181
+ category: "Buildchain Release Passport",
182
+ },
183
+ package: {
184
+ name: packageJson.name,
185
+ versionSource: "package.json#version",
186
+ },
187
+ entrypoint: "buildchain-site.json",
188
+ docs,
189
+ facts: [
190
+ "cli-registry.json",
191
+ "workflow-registry.json",
192
+ "release-model.json",
193
+ "artifact-schemas.json",
194
+ "product-mechanism.json",
195
+ "release-provenance.json",
196
+ "agent-index.json",
197
+ ],
198
+ };
199
+
200
+ const agentIndex = {
201
+ schemaVersion: 1,
202
+ contract: "kungfu-buildchain-site-agent-index",
203
+ readOrder: [
204
+ "site-manifest.json",
205
+ "product-mechanism.json",
206
+ "release-model.json",
207
+ "cli-registry.json",
208
+ "workflow-registry.json",
209
+ "artifact-schemas.json",
210
+ ],
211
+ instruction: "Use this bundle as the package-owned fact source for Buildchain pages. Do not infer current release mechanics from prose alone.",
212
+ };
213
+
214
+ const siteBundle = {
215
+ schemaVersion: 1,
216
+ contract: SITE_BUNDLE_CONTRACT,
217
+ product: siteManifest.product,
218
+ package: siteManifest.package,
219
+ sourceOfTruth: "npm package @kungfu-tech/buildchain/dist/site",
220
+ humanFirst: true,
221
+ agentFirst: true,
222
+ entrypoints: siteManifest.facts.concat(["site-manifest.json"]),
223
+ docs,
224
+ releaseModel,
225
+ };
226
+
227
+ return {
228
+ "buildchain-site.json": siteBundle,
229
+ "site-manifest.json": siteManifest,
230
+ "cli-registry.json": cliRegistry,
231
+ "workflow-registry.json": workflowRegistry,
232
+ "release-model.json": releaseModel,
233
+ "artifact-schemas.json": artifactSchemas,
234
+ "product-mechanism.json": productMechanism,
235
+ "release-provenance.json": releaseProvenance,
236
+ "agent-index.json": agentIndex,
237
+ };
238
+ }
239
+
240
+ export function writeSiteBundle({ check = false } = {}) {
241
+ const files = buildSiteBundle();
242
+ const mismatches = [];
243
+ for (const [name, value] of Object.entries(files)) {
244
+ const filePath = path.join(outputDir, name);
245
+ const next = stableJson(value);
246
+ if (check) {
247
+ if (existingJson(filePath) !== next) {
248
+ mismatches.push(path.relative(root, filePath));
249
+ }
250
+ } else {
251
+ writeJson(filePath, value);
252
+ }
253
+ }
254
+ if (mismatches.length > 0) {
255
+ throw new Error(`site bundle is stale: ${mismatches.join(", ")}`);
256
+ }
257
+ return {
258
+ schemaVersion: 1,
259
+ contract: "kungfu-buildchain-site-bundle-generation",
260
+ outputDir: path.relative(root, outputDir),
261
+ files: Object.keys(files).sort(),
262
+ check,
263
+ };
264
+ }
265
+
266
+ if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
267
+ try {
268
+ const result = writeSiteBundle({ check: process.argv.includes("--check") });
269
+ process.stdout.write(`${JSON.stringify(result, null, 2)}\n`);
270
+ } catch (error) {
271
+ console.error(`buildchain site bundle: ${error.message}`);
272
+ process.exitCode = 1;
273
+ }
274
+ }