@kungfu-tech/buildchain 2.10.4 → 2.10.5

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 (37) hide show
  1. package/README.md +16 -1
  2. package/bin/buildchain.mjs +299 -16
  3. package/dist/site/buildchain-contract.json +7 -7
  4. package/dist/site/buildchain-site.json +42 -37
  5. package/dist/site/capability-registry.json +2 -2
  6. package/dist/site/cli-registry.json +164 -8
  7. package/dist/site/kfd-claims.json +190 -19
  8. package/dist/site/manual-registry.json +10 -10
  9. package/dist/site/node-api-registry.json +24 -11
  10. package/dist/site/page-registry.json +27 -22
  11. package/dist/site/public-surface-audit.json +334 -126
  12. package/dist/site/release-provenance.json +2 -1
  13. package/dist/site/site-manifest.json +14 -14
  14. package/dist/site/workflow-registry.json +4 -1
  15. package/docs/MAP.md +2 -2
  16. package/docs/cli.md +48 -14
  17. package/docs/install.md +1 -1
  18. package/docs/kfd-support.md +80 -21
  19. package/docs/lifecycle-protocol.md +7 -2
  20. package/docs/publish-transaction.md +1 -1
  21. package/docs/readme-badges.md +2 -2
  22. package/docs/release-passport.md +1 -1
  23. package/docs/reusable-build-surface.md +7 -7
  24. package/docs/web-surface-deployments.md +33 -4
  25. package/package.json +3 -2
  26. package/packages/core/buildchain-config.js +10 -5
  27. package/packages/core/buildchain-layout.js +157 -0
  28. package/packages/core/index.js +34 -0
  29. package/packages/core/kfd.js +273 -0
  30. package/packages/core/kfd3-surface-register.js +25 -17
  31. package/packages/core/public-surface-audit.js +14 -7
  32. package/scripts/buildchain-contract-lock.mjs +6 -2
  33. package/scripts/check-inventory.mjs +5 -4
  34. package/scripts/generate-site-bundle.mjs +20 -3
  35. package/scripts/init-repo.mjs +2 -1
  36. package/scripts/web-surface-production-release-pr.mjs +209 -36
  37. package/scripts/web-surface-release-pr-review.mjs +2 -1
package/README.md CHANGED
@@ -171,10 +171,25 @@ npx @kungfu-tech/buildchain validate --require-version-state
171
171
  npx @kungfu-tech/buildchain release --dry-run --target-ref alpha/v2/v2.2
172
172
  ```
173
173
 
174
- Buildchain supports package and non-package projects through `buildchain.toml`.
174
+ Buildchain supports package and non-package projects through
175
+ `.buildchain/buildchain.toml`. Legacy root `buildchain.toml` files remain
176
+ readable, but new consumers should keep Buildchain-owned files under
177
+ `.buildchain/`:
178
+
179
+ ```text
180
+ .buildchain/buildchain.toml
181
+ .buildchain/contract-lock.json
182
+ .buildchain/kfd/kfd-3-surfaces.json
183
+ .buildchain/release-passport/buildchain.release.json
184
+ ```
185
+
175
186
  Lifecycle commands can call pnpm, npm, yarn, pip, Conan, CMake, Make, custom
176
187
  scripts, or any other command that can run in the repository checkout.
177
188
 
189
+ The KFD entrypoint is `buildchain kfd`. Buildchain currently provides concrete
190
+ KFD-1 contract-world, KFD-2 trust-claim, and KFD-3 collaboration-surface
191
+ workflows; KFD-4 is exposed as schema-only until a verification protocol exists.
192
+
178
193
  Buildchain's active GitHub Action surface is deliberately small:
179
194
 
180
195
  - `actions/validate-config`
@@ -64,6 +64,15 @@ import {
64
64
  writeBuildFacts,
65
65
  writeKungfuBuildInfoProjection,
66
66
  } from "../packages/core/build-facts.js";
67
+ import {
68
+ collectKfdStatus,
69
+ kfd1,
70
+ kfd2,
71
+ layout as buildchainLayout,
72
+ listKfdSchemas,
73
+ normalizeKfdStandardId,
74
+ readKfdSchema,
75
+ } from "../packages/core/kfd.js";
67
76
  import {
68
77
  auditKfd3Surfaces,
69
78
  createKfd3SurfaceWitness,
@@ -147,15 +156,30 @@ function usage() {
147
156
  [--module-fact <file>]... [--artifact <path>]...
148
157
  [--output <file>] [--json]
149
158
  buildchain facts verify [--cwd <dir>] --fact <file> [--json]
150
- buildchain kfd-3 detect [--cwd <dir>] [--kind <kind>]... [--artifact <path>] [--json]
151
- buildchain kfd-3 register <node-api|python-api|cli|binary|documentation|site-bundle>
159
+ buildchain kfd ...
160
+ buildchain kfd status [--cwd <dir>] [--json]
161
+ buildchain kfd migrate-layout [--cwd <dir>] [--write] [--force] [--json]
162
+ buildchain kfd schema list [--standard kfd-1|kfd-2|kfd-3|kfd-4] [--json]
163
+ buildchain kfd schema show <kfd-1|kfd-2|kfd-3|kfd-4> [--schema <name>] [--json]
164
+ buildchain kfd 1 schema [--schema <name>] [--json]
165
+ buildchain kfd 1 witness [--cwd <dir>] [--source-sha <sha>] [--output <file>] [--json]
166
+ buildchain kfd 1 gate --witness-json <file-or-json>... [--cwd <dir>] [--artifact-root <dir>]
167
+ [--output <file>] [--json]
168
+ buildchain kfd 1 verify --gate-json <file-or-json> [--json]
169
+ buildchain kfd 2 schema [--schema <name>] [--json]
170
+ buildchain kfd 2 taxonomy --entry-json <file-or-json>... [--kind residualRisk|downgradeReason] [--json]
171
+ buildchain kfd 2 claims [--cwd <dir>] [--output-dir <dir>] [--json]
172
+ buildchain kfd 3 ...
173
+ buildchain kfd 3 detect [--cwd <dir>] [--kind <kind>]... [--artifact <path>] [--json]
174
+ buildchain kfd 3 register <node-api|python-api|cli|binary|documentation|site-bundle>
152
175
  [--cwd <dir>] [--registry <path>] [--artifact <path>]
153
176
  [--product <name>] [--json]
154
- buildchain kfd-3 audit [--cwd <dir>] [--registry <path>] [--artifact <path>] [--json]
155
- buildchain kfd-3 witness [--cwd <dir>] [--registry <path>] [--kind prebuild|artifact]
177
+ buildchain kfd 3 audit [--cwd <dir>] [--registry <path>] [--artifact <path>] [--json]
178
+ buildchain kfd 3 witness [--cwd <dir>] [--registry <path>] [--kind prebuild|artifact]
156
179
  [--source-sha <sha>] [--artifact <path>] [--output <file>] [--json]
157
- buildchain kfd-3 query [<product>] [--cwd <dir>] [--registry <path>]
180
+ buildchain kfd 3 query [<product>] [--cwd <dir>] [--registry <path>]
158
181
  [--passport <file-or-url>] [--artifact <path>] [--json]
182
+ buildchain kfd 4 schema [--schema <name>] [--json]
159
183
  buildchain sample process-tree [--interval-ms <n>] [--label <name>]
160
184
  [--output <jsonl>] [--summary-output <json>]
161
185
  [--requested-parallelism <n>] [--json]
@@ -195,7 +219,11 @@ Examples:
195
219
  buildchain infra-contract --mode propagation-apply --propagation-plan <plan.json> --dry-run true
196
220
  buildchain infra-contract --mode evidence-bundle --artifact <artifact.json> --propagation-result <result.json>
197
221
  buildchain release-propagation plan --graph graph.json --upstream-release release.json --json
198
- buildchain kfd-3 query buildchain --json
222
+ buildchain kfd status --json
223
+ buildchain kfd schema list --json
224
+ buildchain kfd 1 witness --json
225
+ buildchain kfd 2 claims --json
226
+ buildchain kfd 3 query buildchain --json
199
227
  `;
200
228
  }
201
229
 
@@ -335,6 +363,25 @@ function writeJsonFile(filePath, value) {
335
363
  return filePath;
336
364
  }
337
365
 
366
+ function readJsonInput(value, { cwd = process.cwd(), label = "json" } = {}) {
367
+ const input = String(value || "").trim();
368
+ if (!input) {
369
+ throw new Error(`${label} is required`);
370
+ }
371
+ const filePath = path.isAbsolute(input) ? input : path.join(cwd, input);
372
+ if (fs.existsSync(filePath)) {
373
+ return JSON.parse(fs.readFileSync(filePath, "utf8"));
374
+ }
375
+ return JSON.parse(input);
376
+ }
377
+
378
+ function readRepeatedJsonInputs(args, name, { cwd = process.cwd(), label = name } = {}) {
379
+ return readRepeatedFlag(args, name).map((value, index) => readJsonInput(value, {
380
+ cwd,
381
+ label: `${label}[${index}]`,
382
+ }));
383
+ }
384
+
338
385
  async function runReadmeBadgesCli(args = []) {
339
386
  const [subcommand = "", surface = "", ...badgeArgs] = args;
340
387
  if (!["readme", "bundle"].includes(subcommand) || (surface && surface.startsWith("--") === false)) {
@@ -477,11 +524,11 @@ function kfd3Kinds(args = []) {
477
524
  async function runKfd3Cli(args = []) {
478
525
  const [subcommand = "", maybeKindOrProduct = "", ...rest] = args;
479
526
  if (!["detect", "register", "audit", "witness", "query"].includes(subcommand)) {
480
- throw new Error("usage: buildchain kfd-3 <detect|register|audit|witness|query> ...");
527
+ throw new Error("usage: buildchain kfd 3 <detect|register|audit|witness|query> ...");
481
528
  }
482
529
  const effectiveArgs = maybeKindOrProduct && maybeKindOrProduct.startsWith("--") ? [maybeKindOrProduct, ...rest] : rest;
483
530
  const cwd = path.resolve(readFlag(effectiveArgs, "cwd", process.cwd()));
484
- const registryPath = readFlag(effectiveArgs, "registry", "buildchain.kfd3.json");
531
+ const registryPath = readFlag(effectiveArgs, "registry", "");
485
532
  const artifactPath = readFlag(effectiveArgs, "artifact", "");
486
533
  const json = readBooleanFlag(effectiveArgs, "json");
487
534
 
@@ -490,7 +537,7 @@ async function runKfd3Cli(args = []) {
490
537
  if (json) {
491
538
  printJson(result);
492
539
  } else {
493
- process.stdout.write(`kfd-3 detect: ${result.summary.surfaceCount} surfaces\n`);
540
+ process.stdout.write(`kfd 3 detect: ${result.summary.surfaceCount} surfaces\n`);
494
541
  for (const entry of result.surfaces) {
495
542
  process.stdout.write(`- ${entry.kind}: ${entry.id} (${entry.detectionMethod})\n`);
496
543
  }
@@ -501,7 +548,7 @@ async function runKfd3Cli(args = []) {
501
548
  if (subcommand === "register") {
502
549
  const registerKind = maybeKindOrProduct && !maybeKindOrProduct.startsWith("--") ? maybeKindOrProduct : "";
503
550
  if (!registerKind) {
504
- throw new Error("usage: buildchain kfd-3 register <node-api|python-api|cli|binary|documentation|site-bundle>");
551
+ throw new Error("usage: buildchain kfd 3 register <node-api|python-api|cli|binary|documentation|site-bundle>");
505
552
  }
506
553
  const result = registerKfd3Surfaces({
507
554
  cwd,
@@ -515,7 +562,7 @@ async function runKfd3Cli(args = []) {
515
562
  if (json) {
516
563
  printJson(result);
517
564
  } else {
518
- process.stdout.write(`kfd-3 register: ${result.registeredCount} ${registerKind} surfaces -> ${registryPath}\n`);
565
+ process.stdout.write(`kfd 3 register: ${result.registeredCount} ${registerKind} surfaces -> ${registryPath}\n`);
519
566
  }
520
567
  return;
521
568
  }
@@ -525,7 +572,7 @@ async function runKfd3Cli(args = []) {
525
572
  if (json) {
526
573
  printJson(report);
527
574
  } else {
528
- process.stdout.write(`kfd-3 audit: ${report.status}\n`);
575
+ process.stdout.write(`kfd 3 audit: ${report.status}\n`);
529
576
  process.stdout.write(`detected=${report.summary.detected} declared=${report.summary.declared} enforced=${report.summary.enforced}\n`);
530
577
  for (const issue of report.issues) {
531
578
  process.stdout.write(`- ${issue.level}: ${issue.code}: ${issue.surfaceId}\n`);
@@ -552,7 +599,7 @@ async function runKfd3Cli(args = []) {
552
599
  if (json || !output) {
553
600
  printJson(witness);
554
601
  } else {
555
- process.stdout.write(`kfd-3 witness: wrote ${output}\n`);
602
+ process.stdout.write(`kfd 3 witness: wrote ${output}\n`);
556
603
  }
557
604
  return;
558
605
  }
@@ -568,7 +615,7 @@ async function runKfd3Cli(args = []) {
568
615
  if (json) {
569
616
  printJson(result);
570
617
  } else {
571
- process.stdout.write(`kfd-3 query: ${result.product} (${result.status || result.kfd?.kfd3 || "unknown"})\n`);
618
+ process.stdout.write(`kfd 3 query: ${result.product} (${result.status || result.kfd?.kfd3 || "unknown"})\n`);
572
619
  process.stdout.write(`capabilities: ${result.capabilities?.length || 0}\n`);
573
620
  for (const entry of result.capabilities || []) {
574
621
  process.stdout.write(`- ${entry.kind}: ${entry.id} [${entry.state || "declared"}]\n`);
@@ -576,6 +623,242 @@ async function runKfd3Cli(args = []) {
576
623
  }
577
624
  }
578
625
 
626
+ function printKfdSchemaOrJson({ result, json }) {
627
+ if (json) {
628
+ printJson(result);
629
+ } else {
630
+ process.stdout.write(JSON.stringify(result.schema, null, 2));
631
+ process.stdout.write("\n");
632
+ }
633
+ }
634
+
635
+ function runKfd1Cli(args = []) {
636
+ const [rawAction = "schema", ...rest] = args;
637
+ const action = rawAction || "schema";
638
+ const cwd = path.resolve(readFlag(rest, "cwd", process.cwd()));
639
+ const json = readBooleanFlag(rest, "json");
640
+ if (action === "schema") {
641
+ printKfdSchemaOrJson({
642
+ result: readKfdSchema({ standard: "kfd-1", schema: readFlag(rest, "schema", "") }),
643
+ json,
644
+ });
645
+ return;
646
+ }
647
+ if (action === "witness") {
648
+ const witness = kfd1.createBuildchainWitness({
649
+ root: cwd,
650
+ sourceSha: readFlag(rest, "source-sha", process.env.GITHUB_SHA || ""),
651
+ });
652
+ const output = readFlag(rest, "output", "");
653
+ if (output) {
654
+ writeJsonFile(path.resolve(cwd, output), witness);
655
+ }
656
+ if (json || !output) {
657
+ printJson(witness);
658
+ } else {
659
+ process.stdout.write(`kfd 1 witness: wrote ${output}\n`);
660
+ }
661
+ return;
662
+ }
663
+ if (action === "gate") {
664
+ const witnesses = readRepeatedJsonInputs(rest, "witness-json", { cwd, label: "kfd-1 witness" });
665
+ if (witnesses.length === 0) {
666
+ throw new Error("buildchain kfd 1 gate requires at least one --witness-json");
667
+ }
668
+ const gate = kfd1.createReleaseGateEvidence({
669
+ cwd,
670
+ artifactRoot: readFlag(rest, "artifact-root", ""),
671
+ witnesses,
672
+ });
673
+ const output = readFlag(rest, "output", "");
674
+ if (output) {
675
+ writeJsonFile(path.resolve(cwd, output), gate);
676
+ }
677
+ if (json || !output) {
678
+ printJson(gate);
679
+ } else {
680
+ process.stdout.write(`kfd 1 gate: wrote ${output}\n`);
681
+ }
682
+ return;
683
+ }
684
+ if (action === "verify") {
685
+ const gate = readJsonInput(readFlag(rest, "gate-json", ""), { cwd, label: "kfd-1 gate" });
686
+ const issues = kfd1.validateReleaseGateEvidence(gate);
687
+ const result = {
688
+ schemaVersion: 1,
689
+ contract: "kungfu-buildchain-kfd-1-verify-result",
690
+ ok: issues.length === 0,
691
+ issues,
692
+ };
693
+ if (json) {
694
+ printJson(result);
695
+ } else {
696
+ process.stdout.write(`kfd 1 verify: ${result.ok ? "ok" : "failed"}\n`);
697
+ for (const issue of issues) {
698
+ process.stdout.write(`- ${issue.level || "error"}: ${issue.code || "kfd-1"}: ${issue.message || issue}\n`);
699
+ }
700
+ }
701
+ if (!result.ok) {
702
+ process.exitCode = 1;
703
+ }
704
+ return;
705
+ }
706
+ throw new Error("usage: buildchain kfd 1 <schema|witness|gate|verify> ...");
707
+ }
708
+
709
+ function runKfd2Cli(args = []) {
710
+ const [rawAction = "schema", ...rest] = args;
711
+ const action = rawAction || "schema";
712
+ const cwd = path.resolve(readFlag(rest, "cwd", process.cwd()));
713
+ const json = readBooleanFlag(rest, "json");
714
+ if (action === "schema") {
715
+ printKfdSchemaOrJson({
716
+ result: readKfdSchema({ standard: "kfd-2", schema: readFlag(rest, "schema", "") }),
717
+ json,
718
+ });
719
+ return;
720
+ }
721
+ if (action === "taxonomy") {
722
+ const kind = readFlag(rest, "kind", "residualRisk");
723
+ const entries = readRepeatedJsonInputs(rest, "entry-json", { cwd, label: "kfd-2 taxonomy entry" });
724
+ const result = {
725
+ schemaVersion: 1,
726
+ contract: "kungfu-buildchain-kfd-2-taxonomy-validation",
727
+ ok: true,
728
+ kind,
729
+ entries: kfd2.validateTaxonomyEntries({ entries, kind }),
730
+ };
731
+ if (json) {
732
+ printJson(result);
733
+ } else {
734
+ process.stdout.write(`kfd 2 taxonomy: ${result.entries.length} ${kind} entries ok\n`);
735
+ }
736
+ return;
737
+ }
738
+ if (action === "claims") {
739
+ const claims = kfd2.createBuildchainClaims({ root: cwd });
740
+ const outputDir = readFlag(rest, "output-dir", "");
741
+ if (outputDir) {
742
+ for (const claim of claims) {
743
+ const slug = String(claim.id || "claim").replace(/[^a-z0-9._-]+/gi, "-");
744
+ writeJsonFile(path.resolve(cwd, outputDir, `${slug}.json`), claim);
745
+ }
746
+ }
747
+ const result = {
748
+ schemaVersion: 1,
749
+ contract: "kungfu-buildchain-kfd-2-claims",
750
+ count: claims.length,
751
+ claims,
752
+ };
753
+ if (json || !outputDir) {
754
+ printJson(result);
755
+ } else {
756
+ process.stdout.write(`kfd 2 claims: wrote ${claims.length} claims to ${outputDir}\n`);
757
+ }
758
+ return;
759
+ }
760
+ throw new Error("usage: buildchain kfd 2 <schema|taxonomy|claims> ...");
761
+ }
762
+
763
+ async function runKfdCli(args = []) {
764
+ const [subcommand = "", maybeStandardOrAction = "", ...rest] = args;
765
+ if (!subcommand) {
766
+ throw new Error("usage: buildchain kfd <status|migrate-layout|schema|1|2|3|4> ...");
767
+ }
768
+
769
+ if (subcommand === "status") {
770
+ const effectiveArgs = maybeStandardOrAction && maybeStandardOrAction.startsWith("--") ? [maybeStandardOrAction, ...rest] : rest;
771
+ const cwd = path.resolve(readFlag(effectiveArgs, "cwd", process.cwd()));
772
+ const result = collectKfdStatus({ cwd });
773
+ if (readBooleanFlag(effectiveArgs, "json")) {
774
+ printJson(result);
775
+ } else {
776
+ process.stdout.write(`kfd status: layout=${result.layout.status}\n`);
777
+ for (const [standard, capabilities] of Object.entries(result.support)) {
778
+ process.stdout.write(`- ${standard}: ${capabilities.join(", ")}\n`);
779
+ }
780
+ }
781
+ return;
782
+ }
783
+
784
+ if (subcommand === "migrate-layout") {
785
+ const effectiveArgs = maybeStandardOrAction && maybeStandardOrAction.startsWith("--") ? [maybeStandardOrAction, ...rest] : rest;
786
+ const cwd = path.resolve(readFlag(effectiveArgs, "cwd", process.cwd()));
787
+ const result = buildchainLayout.migrate({
788
+ cwd,
789
+ write: readBooleanFlag(effectiveArgs, "write"),
790
+ force: readBooleanFlag(effectiveArgs, "force"),
791
+ });
792
+ if (readBooleanFlag(effectiveArgs, "json")) {
793
+ printJson(result);
794
+ } else {
795
+ process.stdout.write(`kfd migrate-layout: ${result.status}${result.write ? " (write)" : " (dry-run)"}\n`);
796
+ for (const move of result.moves) {
797
+ process.stdout.write(`- ${move.from} -> ${move.to}\n`);
798
+ }
799
+ }
800
+ return;
801
+ }
802
+
803
+ if (subcommand === "schema") {
804
+ const [schemaCommand = "", maybeStandard = "", ...schemaRest] = [maybeStandardOrAction, ...rest];
805
+ const effectiveArgs = maybeStandard && maybeStandard.startsWith("--") ? [maybeStandard, ...schemaRest] : schemaRest;
806
+ const json = readBooleanFlag(effectiveArgs, "json");
807
+ if (schemaCommand === "list") {
808
+ const result = listKfdSchemas({ standard: readFlag(effectiveArgs, "standard", "") });
809
+ if (json) {
810
+ printJson(result);
811
+ } else {
812
+ process.stdout.write(`kfd schema list: ${result.schemas.length} schemas\n`);
813
+ for (const entry of result.schemas) {
814
+ process.stdout.write(`- ${entry.standard}:${entry.name} ${entry.schemaId || entry.schemaPath}\n`);
815
+ }
816
+ }
817
+ return;
818
+ }
819
+ if (schemaCommand === "show") {
820
+ const standard = maybeStandard && !maybeStandard.startsWith("--") ? maybeStandard : readFlag(effectiveArgs, "standard", "");
821
+ if (!standard) {
822
+ throw new Error("usage: buildchain kfd schema show <kfd-1|kfd-2|kfd-3|kfd-4> [--schema <name>]");
823
+ }
824
+ const result = readKfdSchema({ standard, schema: readFlag(effectiveArgs, "schema", "") });
825
+ if (json) {
826
+ printJson(result);
827
+ } else {
828
+ process.stdout.write(JSON.stringify(result.schema, null, 2));
829
+ process.stdout.write("\n");
830
+ }
831
+ return;
832
+ }
833
+ throw new Error("usage: buildchain kfd schema <list|show> ...");
834
+ }
835
+
836
+ const standard = normalizeKfdStandardId(subcommand);
837
+ if (standard === "kfd-1") {
838
+ runKfd1Cli([maybeStandardOrAction, ...rest]);
839
+ return;
840
+ }
841
+ if (standard === "kfd-2") {
842
+ runKfd2Cli([maybeStandardOrAction, ...rest]);
843
+ return;
844
+ }
845
+ if (standard === "kfd-3") {
846
+ await runKfd3Cli([maybeStandardOrAction, ...rest]);
847
+ return;
848
+ }
849
+ if (standard === "kfd-4") {
850
+ const action = maybeStandardOrAction || "schema";
851
+ if (action === "schema") {
852
+ const schemaArgs = rest;
853
+ const json = readBooleanFlag(schemaArgs, "json");
854
+ printKfdSchemaOrJson({ result: readKfdSchema({ standard, schema: readFlag(schemaArgs, "schema", "") }), json });
855
+ return;
856
+ }
857
+ throw new Error("KFD-4 is currently schema-only in Buildchain; use: buildchain kfd 4 schema");
858
+ }
859
+ throw new Error("usage: buildchain kfd <status|migrate-layout|schema|1|2|3|4> ...");
860
+ }
861
+
579
862
  async function runBuildFactsCli(args = []) {
580
863
  const [subcommand = "", ...factArgs] = args;
581
864
  const cwd = path.resolve(readFlag(factArgs, "cwd", process.cwd()));
@@ -940,8 +1223,8 @@ async function main(argv = process.argv.slice(2)) {
940
1223
  return;
941
1224
  }
942
1225
 
943
- if (command === "kfd-3") {
944
- await runKfd3Cli(args);
1226
+ if (command === "kfd") {
1227
+ await runKfdCli(args);
945
1228
  return;
946
1229
  }
947
1230
 
@@ -4,7 +4,7 @@
4
4
  "product": {
5
5
  "name": "Buildchain",
6
6
  "package": "@kungfu-tech/buildchain",
7
- "version": "2.10.4",
7
+ "version": "2.10.5",
8
8
  "repository": "https://github.com/kungfu-systems/buildchain"
9
9
  },
10
10
  "majorLine": "v2",
@@ -92,7 +92,7 @@
92
92
  "GitHub Release passport and evidence publication is delegated to promote-buildchain-ref after the semver release transaction completes"
93
93
  ],
94
94
  "breakingDigest": "sha256:403d2fcdb0c5eabe749e89102defad69745f70a1556707bec7831fcc2e9fa8f8",
95
- "auditDigest": "sha256:377c48c5991c0bc8c0d7874596c2ecb83f8fd61837c8cbc37439058d1f97e71f"
95
+ "auditDigest": "sha256:b3e96fe1d01793481dcf507373b7856a9b29451d168b18cd0f149517cb61ffde"
96
96
  },
97
97
  {
98
98
  "contractVersion": 1,
@@ -134,7 +134,7 @@
134
134
  "breaking contract drift fails closed before rendering, deployment, or release publication"
135
135
  ],
136
136
  "breakingDigest": "sha256:82ee63cb336e40d832dfff4a1c5e6cbfa221a4fc8b2359990033bc931bffc43a",
137
- "auditDigest": "sha256:c7ccd61dcad7420276d5c13549ccbbd7f9afee30eab28ff09fe3d59b2a3f638f"
137
+ "auditDigest": "sha256:ae85fb8353b26d804f9856b971c9c77bd19bbbf6286f35e015284ebce31c818a"
138
138
  },
139
139
  {
140
140
  "contractVersion": 1,
@@ -344,7 +344,7 @@
344
344
  "README badge block checks and writes are generated from machine-readable repository facts"
345
345
  ],
346
346
  "breakingDigest": "sha256:90a73892b2d6c214048448d5f45df75639bdf7b7e8fefd9c596e04b087407bcc",
347
- "auditDigest": "sha256:1bdab893fbb6af1d1d0b840e3583fafb874522c2dde1ae39f393f3fa97b1ef72"
347
+ "auditDigest": "sha256:e7d8cea1254cd2a5acb2c217ae986cc349fd7117147a819fbc17d8dac7ed0755"
348
348
  },
349
349
  {
350
350
  "contractVersion": 1,
@@ -434,7 +434,7 @@
434
434
  "manual entries carry source file digests so downstream sites and agents can detect stale hand-written documentation"
435
435
  ],
436
436
  "breakingDigest": "sha256:7d0d2819e3a3e72989d9c57b5efe9d0bc0a79bc0f2c82a0c7b9d6c5a211a91f2",
437
- "auditDigest": "sha256:e48299d248fbea70481f03d7d3ce200e59ac0d8667cfb78b34307821cfe220d2"
437
+ "auditDigest": "sha256:e6e30455ad08e8e979bea81065523e3082ca837470a979adc874bfa623740ef1"
438
438
  },
439
439
  {
440
440
  "contractVersion": 1,
@@ -456,9 +456,9 @@
456
456
  "agents can discover supported Node APIs without importing internal file paths"
457
457
  ],
458
458
  "breakingDigest": "sha256:48f925608d3e2131d90936b07dc2a30341204cae3e6e785c0f77d61ad755c945",
459
- "auditDigest": "sha256:2f9d529de163b590729dd01cda95eff0ebaed8152fab6502a26bfa32984b7d8a"
459
+ "auditDigest": "sha256:1d012a0a8f04a4c91abb0a6546103031584247fff028c4066e491ace8afab49d"
460
460
  }
461
461
  ],
462
462
  "compatibilityDigest": "sha256:967df7e854fdf582294ddfb6403eff25c00db9518a24051e7d47cbd75527c785",
463
- "contractDigest": "sha256:657034ebc39315b3450cd4c4356af2529b6a2ad03d0df680ec6010f3396df52d"
463
+ "contractDigest": "sha256:515f9d76f67aa18c607f96ecdd608cda561929ea3ae3c887609fe28d0f05c25f"
464
464
  }