@kungfu-tech/buildchain 4.0.1-alpha.9 → 4.0.2-alpha.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (99) hide show
  1. package/README.md +9 -6
  2. package/actions/v4-release-candidate-promote/README.md +3 -0
  3. package/architecture/agent-change-map.md +1017 -0
  4. package/architecture/ci-lane-change-budget.json +70 -1
  5. package/architecture/decisions/0004-v4-declarative-release-tail.md +47 -0
  6. package/architecture/internal-capabilities.json +159 -11
  7. package/architecture/maintainability-debt.json +3229 -0
  8. package/architecture/maintainability-policy.json +480 -129
  9. package/architecture/v3-core-mechanism-inventory.json +6 -3
  10. package/architecture/v3-v4-capability-closure.md +59 -0
  11. package/architecture/v3-v4-live-capability-inventory.json +102404 -0
  12. package/architecture/v4-cross-platform-adopter-qualification.json +52 -0
  13. package/architecture/v4-delivery-warrant-shadow-fixtures.json +3 -3
  14. package/architecture/v4-runtime-semantic-closure.json +710 -0
  15. package/bin/internal/trust-release-release-handlers.mjs +5 -0
  16. package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
  17. package/contracts/v4-publication-qualification-v1.schema.json +51 -0
  18. package/dist/site/agent-index.json +1 -0
  19. package/dist/site/artifact-schemas.json +2 -0
  20. package/dist/site/buildchain-contract.json +123 -32
  21. package/dist/site/buildchain-site.json +96 -28
  22. package/dist/site/capability-registry.json +6 -6
  23. package/dist/site/cli-registry.json +5 -2
  24. package/dist/site/controller-registry.json +41 -5
  25. package/dist/site/kfd-claims.json +172 -23
  26. package/dist/site/kfd-upstream-aggregate.json +1 -1
  27. package/dist/site/manual-registry.json +6 -6
  28. package/dist/site/node-api-registry.json +1474 -215
  29. package/dist/site/page-registry.json +85 -17
  30. package/dist/site/public-surface-audit.json +91 -21
  31. package/dist/site/publication-authority-registry.json +28 -1
  32. package/dist/site/publication-registry.json +4 -4
  33. package/dist/site/release-provenance.json +5 -0
  34. package/dist/site/schemas/v4-publication-qualification-v1.schema.json +51 -0
  35. package/dist/site/site-manifest.json +10 -10
  36. package/dist/site/workflow-registry.json +94 -18
  37. package/docs/MAP.md +1 -1
  38. package/docs/cli-reference.md +4 -4
  39. package/docs/dev-delivery-warrant.md +33 -9
  40. package/docs/node-api-reference.md +291 -206
  41. package/docs/publish-transaction.md +11 -4
  42. package/docs/release-candidate.md +7 -0
  43. package/docs/v4-adopter-delivery.md +23 -4
  44. package/docs/v4-declarative-release-tail-migration.md +43 -0
  45. package/package.json +8 -3
  46. package/packages/core/adopter-delivery-passport.js +36 -0
  47. package/packages/core/buildchain-contract.js +31 -1
  48. package/packages/core/buildchain-publication-authority.js +1 -0
  49. package/packages/core/dev-delivery-warrant-legacy-recovery.js +246 -0
  50. package/packages/core/dev-delivery-warrant-settlement.js +239 -3
  51. package/packages/core/dev-delivery-warrant-state.js +15 -2
  52. package/packages/core/dev-delivery-warrant.js +21 -4
  53. package/packages/core/github-governance-authority.js +4 -4
  54. package/packages/core/index.js +1 -0
  55. package/packages/core/paper-scaffold-content.js +401 -0
  56. package/packages/core/paper.js +12 -378
  57. package/packages/core/publication-control-plane-audit.js +135 -111
  58. package/packages/core/publication-rehearsal-projection.js +104 -0
  59. package/packages/core/publication-rehearsal-runtime.js +190 -0
  60. package/packages/core/release-candidate-recovery.js +6 -5
  61. package/packages/core/release-passport.js +82 -184
  62. package/packages/core/v4-cross-platform-adopter-qualification.js +343 -0
  63. package/packages/core/v4-floating-consumer-policy.js +3 -2
  64. package/packages/core/v4-floating-consumer-release-passport.js +134 -15
  65. package/packages/core/v4-publication-qualification.js +222 -0
  66. package/scripts/artifact-signing-controller-core.mjs +1 -1
  67. package/scripts/audit-publication-control-plane.mjs +17 -17
  68. package/scripts/buildchain-cli-help.mjs +3 -0
  69. package/scripts/check-internal-architecture.mjs +23 -3
  70. package/scripts/check-inventory.mjs +23 -5
  71. package/scripts/check-maintainability.mjs +145 -4
  72. package/scripts/check-project-cut-merge-queue-admission.mjs +87 -0
  73. package/scripts/check-v3-v4-capability-inventory.mjs +574 -0
  74. package/scripts/check-v4-floating-consumer-policy-contract.mjs +10 -3
  75. package/scripts/check-v4-runtime-semantic-closure.mjs +266 -0
  76. package/scripts/dev-delivery-warrant-options.mjs +42 -15
  77. package/scripts/dev-delivery-warrant.mjs +59 -6
  78. package/scripts/dev-pr-auto-merge.mjs +25 -11
  79. package/scripts/dev-pr-delivery-warrant.mjs +44 -0
  80. package/scripts/dev-pr-prequeue-guard.mjs +0 -18
  81. package/scripts/dispatch-artifact-signing-authority.mjs +1 -1
  82. package/scripts/generate-agent-change-map.mjs +118 -0
  83. package/scripts/generate-release-candidate-passport.mjs +26 -1
  84. package/scripts/generate-site-bundle.mjs +6 -0
  85. package/scripts/maintainability-domain-metrics.mjs +237 -0
  86. package/scripts/maintainability-governance.mjs +473 -0
  87. package/scripts/maintainability-metrics.mjs +28 -6
  88. package/scripts/project-cut-merge-queue-admission.mjs +394 -0
  89. package/scripts/promotion-routing-evidence.mjs +35 -6
  90. package/scripts/release-candidate-resolver.mjs +44 -0
  91. package/scripts/release-line-policy.mjs +25 -15
  92. package/scripts/release-tail.mjs +19 -2
  93. package/scripts/resume-from-candidate-run.mjs +106 -103
  94. package/scripts/run-lifecycle-core.mjs +341 -376
  95. package/scripts/site-capability-metadata.mjs +4 -0
  96. package/scripts/stable-candidate-qualification.mjs +9 -10
  97. package/scripts/v3-v4-capability-catalog.mjs +439 -0
  98. package/scripts/v4-cross-platform-adopter-qualification.mjs +228 -0
  99. package/scripts/v4-declarative-promotion-admission.mjs +42 -0
@@ -1,3 +1,11 @@
1
+ import fs from "node:fs";
2
+ import path from "node:path";
3
+ import {
4
+ gitResult,
5
+ gitValue,
6
+ normalizeRepository,
7
+ sha256Text,
8
+ } from "./paper-repository.js";
1
9
  function jsonText(value) {
2
10
  return `${JSON.stringify(value, null, 2)}\n`;
3
11
  }
@@ -161,3 +169,396 @@ Replace this section with the reviewed paper content.
161
169
  \\end{document}
162
170
  `;
163
171
  }
172
+ function planPaperScaffold(
173
+ runtime,
174
+ {
175
+ cwd = process.cwd(),
176
+ buildchainRoot = process.cwd(),
177
+ buildchainVersion = "",
178
+ buildchainRef = "v3",
179
+ buildchainSha = "",
180
+ name = path.basename(path.resolve(cwd)),
181
+ title = "",
182
+ packageName = "",
183
+ repository = "",
184
+ version = "0.1.0-alpha.0",
185
+ siteBaseUrl = "",
186
+ } = {},
187
+ ) {
188
+ const resolvedCwd = path.resolve(cwd);
189
+ const normalizedName = String(name || "").trim();
190
+ if (!normalizedName) throw new Error("paper scaffold requires --name");
191
+ const normalizedPackage = runtime.normalizePackageName(packageName);
192
+ const normalizedRepository = normalizeRepository(repository);
193
+ if (!normalizedRepository) {
194
+ throw new Error("paper scaffold requires --repository <owner/repo>");
195
+ }
196
+ const normalizedVersion = String(version || "")
197
+ .trim()
198
+ .replace(/^v/, "");
199
+ if (!/^\d+\.\d+\.\d+(?:-[0-9A-Za-z.-]+)?$/.test(normalizedVersion)) {
200
+ throw new Error("paper scaffold --version must be semver");
201
+ }
202
+ const runtimeIdentity = runtime.buildchainPackageIdentity(
203
+ buildchainRoot,
204
+ buildchainVersion,
205
+ );
206
+ const runtimeSha =
207
+ buildchainSha ||
208
+ runtime.resolvePaperRuntimeGitSha(buildchainRoot, runtimeIdentity.version);
209
+ if (!runtime.GIT_SHA_PATTERN.test(runtimeSha)) {
210
+ throw new Error(
211
+ "paper scaffold cannot resolve the exact Buildchain runtime SHA; pass buildchainSha or use a published Buildchain package with npm gitHead provenance",
212
+ );
213
+ }
214
+ const files = runtime.scaffoldFiles({
215
+ buildchainRoot,
216
+ buildchainVersion: runtimeIdentity.version,
217
+ buildchainRef,
218
+ buildchainSha: runtimeSha,
219
+ cwd: resolvedCwd,
220
+ name: normalizedName,
221
+ title: title || normalizedName,
222
+ packageName: normalizedPackage,
223
+ repository: normalizedRepository,
224
+ version: normalizedVersion,
225
+ siteBaseUrl,
226
+ });
227
+ const changes = [...files.entries()].map(([relativePath, content]) => {
228
+ const filePath = path.resolve(resolvedCwd, relativePath);
229
+ const exists = fs.existsSync(filePath);
230
+ if (!exists) {
231
+ return {
232
+ path: relativePath,
233
+ action: "create",
234
+ sha256: sha256Text(content),
235
+ content,
236
+ };
237
+ }
238
+ if (!fs.statSync(filePath).isFile()) {
239
+ return {
240
+ path: relativePath,
241
+ action: "conflict",
242
+ reason: "path-exists-and-is-not-a-file",
243
+ sha256: sha256Text(content),
244
+ content,
245
+ };
246
+ }
247
+ const current = fs.readFileSync(filePath, "utf8");
248
+ return current === content
249
+ ? {
250
+ path: relativePath,
251
+ action: "unchanged",
252
+ sha256: sha256Text(content),
253
+ content,
254
+ }
255
+ : {
256
+ path: relativePath,
257
+ action: "conflict",
258
+ reason: "existing-content-differs",
259
+ currentSha256: sha256Text(current),
260
+ sha256: sha256Text(content),
261
+ content,
262
+ };
263
+ });
264
+ const publicChanges = changes.map(({ content: _content, ...entry }) => entry);
265
+ const conflicts = publicChanges.filter(
266
+ (entry) => entry.action === "conflict",
267
+ );
268
+ const result = {
269
+ schemaVersion: 1,
270
+ contract: runtime.PAPER_SCAFFOLD_CONTRACT,
271
+ ok: conflicts.length === 0,
272
+ cwd: resolvedCwd,
273
+ dryRun: true,
274
+ identity: {
275
+ project: normalizedName,
276
+ title: title || normalizedName,
277
+ package: normalizedPackage,
278
+ repository: normalizedRepository,
279
+ version: normalizedVersion,
280
+ },
281
+ buildchain: {
282
+ version: runtimeIdentity.version,
283
+ ref: runtimeSha,
284
+ resolvedSha: runtimeSha,
285
+ },
286
+ summary: {
287
+ create: publicChanges.filter((entry) => entry.action === "create").length,
288
+ unchanged: publicChanges.filter((entry) => entry.action === "unchanged")
289
+ .length,
290
+ conflict: conflicts.length,
291
+ },
292
+ changes: publicChanges,
293
+ conflicts,
294
+ nextActions:
295
+ conflicts.length > 0
296
+ ? [
297
+ {
298
+ id: "resolve-scaffold-conflicts",
299
+ command: "",
300
+ description:
301
+ "Resolve the listed semantic conflicts; scaffold never overwrites them.",
302
+ },
303
+ ]
304
+ : [
305
+ {
306
+ id: "write-scaffold",
307
+ command: "buildchain paper scaffold --write <same arguments>",
308
+ description:
309
+ "Write only missing files after the conflict-free plan is reviewed.",
310
+ },
311
+ ],
312
+ };
313
+ Object.defineProperty(result, "_plannedFiles", {
314
+ value: changes,
315
+ enumerable: false,
316
+ });
317
+ return result;
318
+ }
319
+
320
+ function writePaperScaffold(runtime, plan) {
321
+ if (!plan || plan.contract !== runtime.PAPER_SCAFFOLD_CONTRACT) {
322
+ throw new Error("paper scaffold plan contract mismatch");
323
+ }
324
+ if (!plan.ok || plan.conflicts.length > 0) {
325
+ return {
326
+ ...plan,
327
+ dryRun: false,
328
+ written: [],
329
+ ok: false,
330
+ errorCode: "paper-scaffold-conflict",
331
+ };
332
+ }
333
+ const resolvedCwd = path.resolve(plan.cwd);
334
+ const creates = plan._plannedFiles.filter(
335
+ (entry) => entry.action === "create",
336
+ );
337
+ for (const entry of creates) {
338
+ const target = path.resolve(resolvedCwd, entry.path);
339
+ if (fs.existsSync(target)) {
340
+ const current = fs.statSync(target).isFile()
341
+ ? fs.readFileSync(target, "utf8")
342
+ : undefined;
343
+ if (current !== entry.content) {
344
+ throw new Error(
345
+ `paper scaffold race detected at ${entry.path}; no file was overwritten`,
346
+ );
347
+ }
348
+ continue;
349
+ }
350
+ }
351
+ const written = [];
352
+ for (const entry of creates) {
353
+ const target = path.resolve(resolvedCwd, entry.path);
354
+ if (fs.existsSync(target)) continue;
355
+ fs.mkdirSync(path.dirname(target), { recursive: true });
356
+ fs.writeFileSync(target, entry.content, { flag: "wx" });
357
+ written.push(entry.path);
358
+ }
359
+ return {
360
+ ...plan,
361
+ ok: true,
362
+ dryRun: false,
363
+ written,
364
+ idempotent: written.length === 0,
365
+ nextActions: [
366
+ {
367
+ id: "paper-preflight",
368
+ command: `buildchain paper preflight --cwd ${JSON.stringify(resolvedCwd)} --json`,
369
+ description:
370
+ "Verify the generated repository before any external mutation.",
371
+ },
372
+ ],
373
+ };
374
+ }
375
+
376
+ function planPaperMigration(
377
+ runtime,
378
+ {
379
+ cwd = process.cwd(),
380
+ buildchainRoot = process.cwd(),
381
+ buildchainVersion = "",
382
+ buildchainSha = "",
383
+ } = {},
384
+ ) {
385
+ const resolvedCwd = path.resolve(cwd);
386
+ const repositoryRoot = gitValue(resolvedCwd, [
387
+ "rev-parse",
388
+ "--show-toplevel",
389
+ ]);
390
+ const repositoryPrefix = gitValue(resolvedCwd, [
391
+ "rev-parse",
392
+ "--show-prefix",
393
+ ]).replace(/\/+$/u, "");
394
+ if (!repositoryRoot || repositoryPrefix) {
395
+ throw new Error("paper migration must target the exact repository root");
396
+ }
397
+ const source = {
398
+ head: gitValue(resolvedCwd, ["rev-parse", "HEAD"]),
399
+ clean: gitResult(resolvedCwd, ["status", "--porcelain"]).stdout === "",
400
+ };
401
+ if (!runtime.GIT_SHA_PATTERN.test(source.head)) {
402
+ throw new Error("paper migration requires a committed Git source");
403
+ }
404
+ const plannedFiles = [
405
+ ...runtime.migrationFiles({
406
+ cwd: resolvedCwd,
407
+ buildchainRoot,
408
+ buildchainVersion,
409
+ buildchainSha,
410
+ }),
411
+ ].map(([relativePath, content]) => {
412
+ const target = path.resolve(resolvedCwd, relativePath);
413
+ if (fs.existsSync(target) && !fs.statSync(target).isFile()) {
414
+ return {
415
+ path: relativePath,
416
+ action: "conflict",
417
+ currentSha256: "",
418
+ sha256: sha256Text(content),
419
+ content,
420
+ };
421
+ }
422
+ const current = fs.existsSync(target)
423
+ ? fs.readFileSync(target, "utf8")
424
+ : undefined;
425
+ return {
426
+ path: relativePath,
427
+ action:
428
+ current === undefined
429
+ ? "create"
430
+ : current === content
431
+ ? "unchanged"
432
+ : "update",
433
+ currentSha256: current === undefined ? "" : sha256Text(current),
434
+ sha256: sha256Text(content),
435
+ content,
436
+ };
437
+ });
438
+ const changes = plannedFiles.map(({ content: _content, ...entry }) => entry);
439
+ const conflicts = changes.filter((entry) => entry.action === "conflict");
440
+ const ok = source.clean && conflicts.length === 0;
441
+ const result = {
442
+ schemaVersion: 1,
443
+ contract: runtime.PAPER_MIGRATION_CONTRACT,
444
+ ok,
445
+ cwd: resolvedCwd,
446
+ dryRun: true,
447
+ source,
448
+ summary: {
449
+ create: changes.filter((entry) => entry.action === "create").length,
450
+ update: changes.filter((entry) => entry.action === "update").length,
451
+ unchanged: changes.filter((entry) => entry.action === "unchanged").length,
452
+ conflict: conflicts.length,
453
+ },
454
+ changes,
455
+ conflicts,
456
+ nextActions: !source.clean
457
+ ? [
458
+ {
459
+ id: "commit-source",
460
+ command: "git status --short",
461
+ description:
462
+ "Migration only rewrites Buildchain-owned control files from a clean committed source.",
463
+ },
464
+ ]
465
+ : conflicts.length > 0
466
+ ? [
467
+ {
468
+ id: "resolve-migration-conflicts",
469
+ command: "",
470
+ description:
471
+ "Resolve non-file targets; migration never replaces a directory or special path.",
472
+ },
473
+ ]
474
+ : [
475
+ {
476
+ id: "write-migration",
477
+ command: "buildchain paper migrate --write --json",
478
+ description:
479
+ "Write the reviewed Buildchain-owned control files without changing paper content or publication configuration.",
480
+ },
481
+ {
482
+ id: "refresh-pnpm-lock",
483
+ command: "pnpm install --lockfile-only",
484
+ description:
485
+ "Bind the exact Buildchain semantic dependency into pnpm-lock.yaml after the reviewed package update.",
486
+ },
487
+ ],
488
+ };
489
+ Object.defineProperty(result, "_plannedFiles", {
490
+ value: plannedFiles,
491
+ enumerable: false,
492
+ });
493
+ return result;
494
+ }
495
+
496
+ function writePaperMigration(runtime, plan) {
497
+ if (!plan || plan.contract !== runtime.PAPER_MIGRATION_CONTRACT) {
498
+ throw new Error("paper migration plan contract mismatch");
499
+ }
500
+ if (!plan.ok) {
501
+ return {
502
+ ...plan,
503
+ dryRun: false,
504
+ written: [],
505
+ updated: [],
506
+ ok: false,
507
+ errorCode: "paper-migration-blocked",
508
+ };
509
+ }
510
+ const written = [];
511
+ const updated = [];
512
+ for (const entry of plan._plannedFiles) {
513
+ if (entry.action === "unchanged") continue;
514
+ const target = path.resolve(plan.cwd, entry.path);
515
+ const exists = fs.existsSync(target);
516
+ const current =
517
+ exists && fs.statSync(target).isFile()
518
+ ? fs.readFileSync(target, "utf8")
519
+ : undefined;
520
+ const currentSha256 = current === undefined ? "" : sha256Text(current);
521
+ if (
522
+ (entry.action === "create" && exists) ||
523
+ (entry.action === "update" && currentSha256 !== entry.currentSha256)
524
+ ) {
525
+ throw new Error(
526
+ `paper migration race detected at ${entry.path}; no stale plan was applied`,
527
+ );
528
+ }
529
+ }
530
+ for (const entry of plan._plannedFiles) {
531
+ if (entry.action === "unchanged") continue;
532
+ const target = path.resolve(plan.cwd, entry.path);
533
+ fs.mkdirSync(path.dirname(target), { recursive: true });
534
+ fs.writeFileSync(target, entry.content, {
535
+ flag: entry.action === "create" ? "wx" : "w",
536
+ });
537
+ (entry.action === "create" ? written : updated).push(entry.path);
538
+ }
539
+ return {
540
+ ...plan,
541
+ ok: true,
542
+ dryRun: false,
543
+ written,
544
+ updated,
545
+ idempotent: written.length === 0 && updated.length === 0,
546
+ nextActions: [
547
+ {
548
+ id: "paper-preflight",
549
+ command: `buildchain paper preflight --cwd ${JSON.stringify(plan.cwd)} --offline --json`,
550
+ description:
551
+ "Verify the migrated repository before any external mutation.",
552
+ },
553
+ ],
554
+ };
555
+ }
556
+
557
+ export function createPaperScaffoldOperations(runtime) {
558
+ return {
559
+ planPaperMigration: (options) => planPaperMigration(runtime, options),
560
+ planPaperScaffold: (options) => planPaperScaffold(runtime, options),
561
+ writePaperMigration: (plan) => writePaperMigration(runtime, plan),
562
+ writePaperScaffold: (plan) => writePaperScaffold(runtime, plan),
563
+ };
564
+ }