@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.
- package/bin/buildchain.mjs +3 -0
- package/dist/site/agent-index.json +1 -0
- package/dist/site/artifact-schemas.json +1 -0
- package/dist/site/buildchain-contract.json +2008 -12
- package/dist/site/buildchain-site.json +74 -11
- package/dist/site/capability-registry.json +4 -3
- package/dist/site/controller-registry.json +1626 -0
- package/dist/site/kfd-claims.json +88 -74
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +18 -2
- package/dist/site/node-api-registry.json +20 -7
- package/dist/site/page-registry.json +58 -5
- package/dist/site/public-surface-audit.json +572 -102
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +2 -0
- package/dist/site/site-manifest.json +15 -6
- package/dist/site/workflow-registry.json +534 -68
- package/docs/MAP.md +2 -1
- package/docs/controller-evidence.md +113 -0
- package/docs/release-passport.md +6 -0
- package/package.json +3 -1
- package/packages/core/buildchain-contract.js +62 -1
- package/packages/core/buildchain-kfd-claims.js +3 -0
- package/packages/core/controller-evidence.js +505 -0
- package/packages/core/index.js +17 -0
- package/packages/core/public-surface-audit.js +40 -3
- package/packages/core/release-candidate.js +26 -0
- package/packages/core/release-passport.js +19 -0
- package/scripts/check-inventory.mjs +4 -1
- package/scripts/controller-evidence.mjs +170 -0
- package/scripts/generate-channel-build-workflow.mjs +141 -2
- package/scripts/generate-release-candidate-passport.mjs +4 -0
- 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.
|
package/docs/release-passport.md
CHANGED
|
@@ -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.
|
|
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({
|
|
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",
|