@kungfu-tech/buildchain 2.12.4 → 2.12.5-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.
Files changed (33) hide show
  1. package/bin/buildchain.mjs +3 -0
  2. package/dist/site/agent-index.json +1 -0
  3. package/dist/site/artifact-schemas.json +1 -0
  4. package/dist/site/buildchain-contract.json +2008 -12
  5. package/dist/site/buildchain-site.json +74 -11
  6. package/dist/site/capability-registry.json +4 -3
  7. package/dist/site/controller-registry.json +1626 -0
  8. package/dist/site/kfd-claims.json +88 -74
  9. package/dist/site/kfd-upstream-aggregate.json +1 -1
  10. package/dist/site/manual-registry.json +18 -2
  11. package/dist/site/node-api-registry.json +20 -7
  12. package/dist/site/page-registry.json +58 -5
  13. package/dist/site/public-surface-audit.json +572 -102
  14. package/dist/site/publication-registry.json +4 -4
  15. package/dist/site/release-provenance.json +2 -0
  16. package/dist/site/site-manifest.json +15 -6
  17. package/dist/site/workflow-registry.json +534 -68
  18. package/docs/MAP.md +2 -1
  19. package/docs/controller-evidence.md +113 -0
  20. package/docs/release-passport.md +6 -0
  21. package/package.json +3 -1
  22. package/packages/core/buildchain-contract.js +62 -1
  23. package/packages/core/buildchain-kfd-claims.js +3 -0
  24. package/packages/core/controller-evidence.js +505 -0
  25. package/packages/core/index.js +17 -0
  26. package/packages/core/public-surface-audit.js +40 -3
  27. package/packages/core/release-candidate.js +26 -0
  28. package/packages/core/release-passport.js +19 -0
  29. package/scripts/check-inventory.mjs +4 -1
  30. package/scripts/controller-evidence.mjs +170 -0
  31. package/scripts/generate-channel-build-workflow.mjs +141 -2
  32. package/scripts/generate-release-candidate-passport.mjs +4 -0
  33. package/scripts/generate-site-bundle.mjs +11 -1
package/docs/MAP.md CHANGED
@@ -28,7 +28,7 @@ workflow, action, and Node API export also carries a `capabilityGroup`,
28
28
  | --- | --- | --- |
29
29
  | Getting Started | `capability-registry.json`, `product-mechanism.json` | [`install.md`](install.md), [`product-mechanism.md`](product-mechanism.md), [`cli.md`](cli.md) |
30
30
  | Release Passport and Trust | `release-model.json`, `artifact-schemas.json`, `kfd-claims.json` | [`release-passport.md`](release-passport.md), [`release-candidate.md`](release-candidate.md), [`publish-transaction.md`](publish-transaction.md), [`binary-distribution.md`](binary-distribution.md) |
31
- | Reusable Build and Lifecycle | `workflow-registry.json`, `release-model.json` | [`reusable-build-surface.md`](reusable-build-surface.md), [`shifu-gate-profiles.md`](shifu-gate-profiles.md), [`lifecycle-protocol.md`](lifecycle-protocol.md) |
31
+ | Reusable Build and Lifecycle | `workflow-registry.json`, `controller-registry.json`, `release-model.json` | [`reusable-build-surface.md`](reusable-build-surface.md), [`controller-evidence.md`](controller-evidence.md), [`shifu-gate-profiles.md`](shifu-gate-profiles.md), [`lifecycle-protocol.md`](lifecycle-protocol.md) |
32
32
  | KFD Trust and Surface Closure | `kfd-claims.json`, `public-surface-audit.json`, `cli-registry.json`, `node-api-registry.json` | [`kfd-support.md`](kfd-support.md), [`release-passport.md`](release-passport.md) |
33
33
  | Site Bundle, Web Surfaces, and Propagation | `buildchain-site.json`, `site-manifest.json`, `page-registry.json`, `release-model.json` | [`site-bundle-contract.md`](site-bundle-contract.md), [`web-surface-deployments.md`](web-surface-deployments.md), [`release-propagation.md`](release-propagation.md) |
34
34
  | Publication Artifacts | `publication-registry.json`, `workflow-registry.json`, `node-api-registry.json`, `manual-registry.json`, `kungfu-buildchain-publication-artifact-registry` | [`publication-artifacts.md`](publication-artifacts.md), [`reusable-build-surface.md`](reusable-build-surface.md) |
@@ -86,6 +86,7 @@ replace them.
86
86
  | 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 |
87
87
  | How do I detect, register, audit, witness, or query KFD-3 product surfaces? | [`kfd-support.md`](kfd-support.md) + [`cli.md`](cli.md) | verify/use | stable |
88
88
  | 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 |
89
+ | How do reusable workflows bind controller intent, source/runtime identity, outcomes, and receipt evidence? | [`controller-evidence.md`](controller-evidence.md) | verify/use | draft |
89
90
  | How do I propagate finalized upstream releases to downstream package/site PRs? | [`release-propagation.md`](release-propagation.md) | use | preview |
90
91
  | How do paper or report repositories publish PDFs, metadata, source bundles, site-consumable manifests, npm packages, and GitHub Releases? | [`publication-artifacts.md`](publication-artifacts.md) | use | stable |
91
92
  | 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 |
@@ -0,0 +1,113 @@
1
+ ---
2
+ status: draft
3
+ period: ongoing
4
+ theme: buildchain-controller-evidence
5
+ doc_type: analysis
6
+ source_level: local-files
7
+ confidence: high
8
+ sensitivity: public
9
+ evidence_grade: B
10
+ review_state: unreviewed
11
+ last_reviewed: 2026-07-14
12
+ ai_provenance:
13
+ model_family: GPT-5
14
+ product: Codex
15
+ generated_at: 2026-07-14
16
+ boundary: Based on repository source and tests; no claim about unobserved downstream runs.
17
+ ---
18
+
19
+ # Controller Evidence
20
+
21
+ Buildchain controller evidence records what a reusable workflow intended to do
22
+ and what it actually completed. It is a project-independent envelope around
23
+ Buildchain orchestration; it does not replace a consumer project's own policy,
24
+ Gate registry, or domain receipts.
25
+
26
+ The machine-readable entrypoint is
27
+ `dist/site/controller-registry.json`. The Node API is exported as
28
+ `@kungfu-tech/buildchain/controller-evidence`.
29
+
30
+ ## Public controller inventory
31
+
32
+ The first versioned inventory contains:
33
+
34
+ - source check;
35
+ - lifecycle build and channel routing;
36
+ - the Shifu Gate profile envelope;
37
+ - web-surface build/deploy orchestration;
38
+ - publication artifact and paper release;
39
+ - release-candidate promotion;
40
+ - release propagation.
41
+
42
+ Patrol and repository-maintenance workflows are not controllers. A controller
43
+ descriptor declares its workflow, version, input classifications, expected
44
+ stages, capabilities, evidence kinds, and a deterministic descriptor digest.
45
+
46
+ ## Plan contract
47
+
48
+ A `buildchain.controller-evidence/v1` plan binds:
49
+
50
+ - the controller id, version, workflow path, and descriptor digest;
51
+ - the exact consumer repository and 40-character source SHA;
52
+ - the requested Buildchain ref, exact runtime SHA, and runtime contract digest;
53
+ - normalized inputs;
54
+ - expected stages, capabilities, and evidence kinds.
55
+
56
+ Inputs use one of four policies:
57
+
58
+ - `included` for safe scalar values;
59
+ - `digest-only` for commands, structured values, runner selection, paths, role
60
+ identifiers, registries, mirrors, and other environment-shaped values;
61
+ - `redacted` for workflow secrets and token/private-key shaped fields;
62
+ - `unsupported` for a declared input that must fail closed when provided.
63
+
64
+ Redacted inputs carry no value, digest, or presence bit. Included path-like
65
+ inputs reject absolute runner paths. Undeclared inputs fail plan creation.
66
+
67
+ ## Receipt and aggregation
68
+
69
+ A receipt binds back to the plan digest and repeats the source and runtime
70
+ identities. Every declared stage is recorded as `passed`, `failed`, `skipped`,
71
+ `cancelled`, or `missing`; the receipt status is `passed`, `failed`, `skipped`,
72
+ or `partial`. Evidence is represented by kind and SHA-256 digest, with an
73
+ optional artifact name.
74
+
75
+ Reusable workflows expose these outputs:
76
+
77
+ - `controller-plan-artifact`, `controller-plan-json`, and
78
+ `controller-plan-digest`;
79
+ - `controller-receipt-artifact`, `controller-receipt-json`,
80
+ `controller-receipt-digest`, and `controller-receipt-status`.
81
+
82
+ Final aggregation uses `always()`. A required missing stage, required missing
83
+ evidence, invalid digest, source/runtime mismatch, or missing receipt cannot be
84
+ reported as qualifying green. `aggregateControllerReceipts()` reports an
85
+ explicit `receipt-missing` status when a plan has no receipt.
86
+
87
+ ## Shifu boundary
88
+
89
+ The Shifu profile controller is an envelope only. Its controller receipt
90
+ references the digest and status of `buildchain.shifu-gate-aggregate/v1`; it
91
+ does not copy project Gate identifiers, Gate semantics, registry contents, or
92
+ per-Gate results into Buildchain's generic controller contract.
93
+
94
+ ## Release Passport references
95
+
96
+ Release-candidate and final Release Passport documents may carry compact
97
+ `controllerReceipts[]` references. Each reference contains the controller id,
98
+ plan and receipt digests, source and runtime SHAs, status, and artifact name.
99
+ The passport validates those identities; it never invents a controller receipt
100
+ from a successful job conclusion.
101
+
102
+ The PR-stage lifecycle build creates its qualifying receipt before the
103
+ release-candidate passport. Promotion validates that passport and preserves the
104
+ same references in the final Release Passport, closing the build-to-publish
105
+ evidence chain.
106
+
107
+ ## Train validation
108
+
109
+ An unreleased contract should be tested through a temporary Buildchain train
110
+ ref and an exact downstream consumer source SHA. The downstream run should
111
+ retain the plan artifact, receipt artifact, workflow outputs, and Release
112
+ Passport or release-candidate reference. Promote to an official alpha or stable
113
+ channel only after those identities and digests agree.
@@ -8,6 +8,12 @@ promotion PRs, exact tags, GitHub Releases, npm Trusted Publishing, and
8
8
  machine-readable evidence. A project can keep its existing build system and use
9
9
  Buildchain to make the release record auditable.
10
10
 
11
+ Release-candidate and final passports may also include compact
12
+ `controllerReceipts[]` references. These bind a real reusable-workflow receipt
13
+ to its plan digest, consumer source SHA, and exact Buildchain runtime SHA; they
14
+ do not infer execution evidence from a green job. See
15
+ [`controller-evidence.md`](controller-evidence.md).
16
+
11
17
  ## Contract
12
18
 
13
19
  The release passport surface is a welded contract. Additive fields are allowed;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kungfu-tech/buildchain",
3
- "version": "2.12.4",
3
+ "version": "2.12.5-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",
@@ -17,6 +17,7 @@
17
17
  "./core": "./packages/core/index.js",
18
18
  "./artifact-passport": "./packages/core/artifact-passport.js",
19
19
  "./buildchain-contract": "./packages/core/buildchain-contract.js",
20
+ "./controller-evidence": "./packages/core/controller-evidence.js",
20
21
  "./diagnostics": "./packages/core/diagnostics.js",
21
22
  "./homebrew": "./packages/core/homebrew.js",
22
23
  "./issue-reporting": "./packages/core/issue-reporting.js",
@@ -45,6 +46,7 @@
45
46
  "./site/node-api-registry.json": "./dist/site/node-api-registry.json",
46
47
  "./site/kfd-claims.json": "./dist/site/kfd-claims.json",
47
48
  "./site/workflow-registry.json": "./dist/site/workflow-registry.json",
49
+ "./site/controller-registry.json": "./dist/site/controller-registry.json",
48
50
  "./site/public-surface-audit.json": "./dist/site/public-surface-audit.json",
49
51
  "./site/kfd-upstream-aggregate.json": "./dist/site/kfd-upstream-aggregate.json",
50
52
  "./site/release-model.json": "./dist/site/release-model.json",
@@ -1,6 +1,8 @@
1
1
  import crypto from "node:crypto";
2
2
  import fs from "node:fs";
3
3
  import path from "node:path";
4
+ import { createControllerRegistry } from "./controller-evidence.js";
5
+ import { enumerateWorkflowInputs } from "./public-surface-audit.js";
4
6
 
5
7
  export const BUILDCHAIN_RUNTIME_CONTRACT_WORLD = "kungfu-buildchain-runtime-contract-world";
6
8
  export const BUILDCHAIN_CONTRACT_LOCK = "kungfu-buildchain-contract-lock";
@@ -70,9 +72,31 @@ function majorLineFromPackageVersion(version = "") {
70
72
  return match ? `v${match[1]}` : "v2";
71
73
  }
72
74
 
73
- export function createBuildchainContractWorld({ root = process.cwd(), packageJson = undefined } = {}) {
75
+ export function createBuildchainContractWorld({
76
+ root = process.cwd(),
77
+ packageJson = undefined,
78
+ controllerRegistry = undefined,
79
+ } = {}) {
74
80
  const pkg = packageJson || readJson(path.join(root, "package.json"), {});
75
81
  const majorLine = majorLineFromPackageVersion(pkg.version);
82
+ const workflowDescriptors = controllerRegistry ? [] : enumerateWorkflowInputs({ root });
83
+ const controllerWorkflowIds = new Set([
84
+ "check",
85
+ ".build",
86
+ "build",
87
+ ".gate-profile",
88
+ ".web-surface",
89
+ "publication-artifact",
90
+ "paper-release",
91
+ "release-candidate-promote",
92
+ "release-propagation",
93
+ ]);
94
+ const hasCompleteControllerSource = [...controllerWorkflowIds]
95
+ .every((id) => workflowDescriptors.some((workflow) => workflow.id === id));
96
+ const resolvedControllerRegistry = controllerRegistry
97
+ || (hasCompleteControllerSource
98
+ ? createControllerRegistry({ workflows: workflowDescriptors })
99
+ : readJson(path.join(root, "dist/site/controller-registry.json"), { controllers: [] }));
76
100
  const surfaces = [
77
101
  surface(root, {
78
102
  id: "reusable-build",
@@ -476,6 +500,43 @@ export function createBuildchainContractWorld({ root = process.cwd(), packageJso
476
500
  ],
477
501
  }),
478
502
  ];
503
+ for (const descriptor of resolvedControllerRegistry.controllers) {
504
+ surfaces.push(surface(root, {
505
+ id: `controller:${descriptor.id}`,
506
+ kind: "controller",
507
+ path: descriptor.workflow.path,
508
+ requiredInputs: [],
509
+ requiredOutputs: [
510
+ "controller-plan-json",
511
+ "controller-plan-digest",
512
+ "controller-receipt-json",
513
+ "controller-receipt-digest",
514
+ "controller-receipt-status",
515
+ ],
516
+ breakingDefaults: {
517
+ evidenceContract: "buildchain.controller-evidence/v1",
518
+ descriptorVersion: descriptor.version,
519
+ workflowPath: descriptor.workflow.path,
520
+ requiredStages: descriptor.expected.stages.filter((stage) => stage.required).map((stage) => stage.id),
521
+ capabilities: descriptor.expected.capabilities,
522
+ evidenceRequirements: descriptor.expected.evidence,
523
+ inputClassificationPolicy: "buildchain-controller-input-policy/v1",
524
+ },
525
+ optionalInputs: Object.keys(descriptor.inputs),
526
+ controllerDescriptor: {
527
+ contract: descriptor.contract,
528
+ digest: descriptor.digest,
529
+ registryDigest: resolvedControllerRegistry.digest,
530
+ inputClassifications: descriptor.inputs,
531
+ },
532
+ guarantees: [
533
+ "plans bind exact consumer source SHA, exact Buildchain runtime SHA, and the runtime contract digest",
534
+ "receipts bind the plan digest and preserve pass, fail, skip, and partial stage outcomes",
535
+ "redacted input values are never serialized and digest-only input values are never emitted in plaintext",
536
+ "missing receipts are non-qualifying and must not be represented as a successful controller run",
537
+ ],
538
+ }));
539
+ }
479
540
  const base = {
480
541
  schemaVersion: 1,
481
542
  contract: BUILDCHAIN_RUNTIME_CONTRACT_WORLD,
@@ -15,6 +15,7 @@ export const BUILDCHAIN_AGENT_MANUALS = Object.freeze([
15
15
  { id: "map", title: "Buildchain documentation map", path: "docs/MAP.md", plane: "use" },
16
16
  { id: "install", title: "Install and verify Buildchain", path: "docs/install.md", plane: "use" },
17
17
  { id: "release-passport", title: "Release Passport protocol", path: "docs/release-passport.md", plane: "verify" },
18
+ { id: "controller-evidence", title: "Controller evidence contract", path: "docs/controller-evidence.md", plane: "verify" },
18
19
  { id: "release-candidate", title: "Release Candidate Passport", path: "docs/release-candidate.md", plane: "verify" },
19
20
  { id: "release-propagation", title: "Release propagation", path: "docs/release-propagation.md", plane: "use" },
20
21
  { id: "readme-badges", title: "README badge blocks", path: "docs/readme-badges.md", plane: "use" },
@@ -50,6 +51,7 @@ const SITE_CONTRACT_FILES = Object.freeze([
50
51
  "dist/site/manual-registry.json",
51
52
  "dist/site/node-api-registry.json",
52
53
  "dist/site/workflow-registry.json",
54
+ "dist/site/controller-registry.json",
53
55
  "dist/site/public-surface-audit.json",
54
56
  "dist/site/release-model.json",
55
57
  "dist/site/artifact-schemas.json",
@@ -65,6 +67,7 @@ const SCHEMA_AND_STANDARD_FILES = Object.freeze([
65
67
  "packages/core/kfd-gate.js",
66
68
  "packages/core/release-passport.js",
67
69
  "packages/core/buildchain-contract.js",
70
+ "packages/core/controller-evidence.js",
68
71
  "packages/core/buildchain-kfd-claims.js",
69
72
  "packages/core/kfd3-surface-register.js",
70
73
  "packages/core/public-surface-audit.js",