@kungfu-tech/buildchain 4.1.3 → 4.1.4

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 (199) hide show
  1. package/AGENTS.md +11 -13
  2. package/CONTRIBUTING.md +32 -9
  3. package/README.md +56 -140
  4. package/actions/release/promotion/ref/README.md +1 -1
  5. package/architecture/action-taxonomy.json +1 -1
  6. package/architecture/agent-change-map.md +32 -45
  7. package/architecture/build-orchestration.json +1 -1
  8. package/architecture/capability-state-machine-manifest.json +5 -5
  9. package/architecture/ci-lane-change-budget.json +92 -92
  10. package/architecture/code-layout.json +2 -12
  11. package/architecture/core-mechanisms.json +38 -39
  12. package/architecture/cross-platform-adopter-qualification.json +1 -1
  13. package/architecture/dev-delivery-orchestration.json +2 -2
  14. package/architecture/floating-consumer-policy.json +3 -3
  15. package/architecture/internal-capabilities.json +27 -28
  16. package/architecture/maintainability-debt.json +60 -94
  17. package/architecture/maintainability-policy.json +7 -13
  18. package/architecture/minimal-consumer-migration.json +43 -5014
  19. package/architecture/platform-stage-checkpoints.json +1 -1
  20. package/architecture/release-tail-contract.json +2 -2
  21. package/architecture/release-topology.json +31 -25
  22. package/architecture/stage-capsule-qualification.json +1 -1
  23. package/architecture/universal-workflow-bootstrap.json +60 -60
  24. package/architecture/universal-workflow-capability-policy.json +3 -3
  25. package/architecture/universal-workflow-fault-campaign.json +7 -7
  26. package/architecture/workflow-taxonomy.json +59 -60
  27. package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
  28. package/dist/site/buildchain-contract.json +138 -66
  29. package/dist/site/buildchain-site.json +257 -331
  30. package/dist/site/capability-registry.json +4 -4
  31. package/dist/site/cli-registry.json +6 -142
  32. package/dist/site/controller-registry.json +19 -19
  33. package/dist/site/kfd-claims.json +481 -529
  34. package/dist/site/kfd-upstream-aggregate.json +1 -1
  35. package/dist/site/manual-registry.json +22 -22
  36. package/dist/site/node-api-registry.json +82 -339
  37. package/dist/site/page-registry.json +229 -304
  38. package/dist/site/public-surface-audit.json +544 -754
  39. package/dist/site/publication-authority-registry.json +316 -316
  40. package/dist/site/publication-registry.json +1 -1
  41. package/dist/site/site-manifest.json +23 -23
  42. package/dist/site/workflow-registry.json +1071 -1027
  43. package/docs/MAP.md +28 -20
  44. package/docs/auditable-demo.md +17 -49
  45. package/docs/bootstrap-recovery.md +46 -37
  46. package/docs/cli-reference.md +2 -46
  47. package/docs/cli.md +97 -186
  48. package/docs/code-organization.md +7 -5
  49. package/docs/dev-alpha-candidate-patrol.md +19 -42
  50. package/docs/dev-delivery-orchestration.md +15 -11
  51. package/docs/dev-delivery-qualification-landing-adr.md +10 -9
  52. package/docs/dev-delivery-warrant.md +17 -16
  53. package/docs/dev-qualification-patrol.md +25 -20
  54. package/docs/getting-started.md +80 -139
  55. package/docs/github-artifact-attestation.md +31 -81
  56. package/docs/install.md +66 -30
  57. package/docs/lifecycle-protocol.md +19 -57
  58. package/docs/migration-inventory.md +17 -45
  59. package/docs/next-development-transition.md +13 -13
  60. package/docs/node-api-reference.md +122 -138
  61. package/docs/oci-publication.md +13 -10
  62. package/docs/publication-artifacts.md +128 -486
  63. package/docs/publication-authority.md +15 -45
  64. package/docs/publish-transaction.md +13 -11
  65. package/docs/release-candidate.md +126 -355
  66. package/docs/release-discussions.md +36 -67
  67. package/docs/release-flow.md +80 -339
  68. package/docs/release-governance.md +114 -962
  69. package/docs/release-promotion-request.md +45 -43
  70. package/docs/release-propagation.md +13 -27
  71. package/docs/release-tail-provider-plane.md +38 -65
  72. package/docs/reusable-build-surface.md +78 -196
  73. package/docs/runtime-train-validation.md +8 -6
  74. package/docs/stable-candidate-patrol.md +13 -66
  75. package/docs/v4-adopter-delivery.md +15 -15
  76. package/docs/v4-declarative-release-tail-migration.md +19 -17
  77. package/docs/v4-production-release.md +11 -6
  78. package/docs/v4-publication-rehearsal.md +12 -27
  79. package/docs/v4-stage-capsule.md +14 -20
  80. package/docs/v4-tail-reseal.md +34 -20
  81. package/docs/web-surface-deployments.md +26 -264
  82. package/docs/workflow-catalog.md +31 -31
  83. package/docs/workflow-path-migration.md +10 -4
  84. package/package.json +5 -4
  85. package/packages/core/adoption/buildchain-kfd-claims.js +7 -7
  86. package/packages/core/adoption/cli/output.mjs +1 -9
  87. package/packages/core/adoption/cli/product-gate.mjs +1 -15
  88. package/packages/core/adoption/cli/project.mjs +9 -10
  89. package/packages/core/adoption/cli/standards.mjs +1 -14
  90. package/packages/core/adoption/cli/support.mjs +0 -2
  91. package/packages/core/adoption/cli/surface-register.mjs +0 -2
  92. package/packages/core/adoption/commands/init-repo.mjs +77 -485
  93. package/packages/core/adoption/consumer-init.js +279 -0
  94. package/packages/core/adoption/qualification/admission.js +1 -1
  95. package/packages/core/build/cli/cache.mjs +0 -2
  96. package/packages/core/build/cli/facts.mjs +0 -3
  97. package/packages/core/build/cli/homebrew.mjs +0 -4
  98. package/packages/core/build/cli/lifecycle.mjs +0 -3
  99. package/packages/core/build/github-artifact-attestation.js +2 -2
  100. package/packages/core/build/platform-stage-checkpoints.js +1 -1
  101. package/packages/core/build/signing/dispatch.js +1 -1
  102. package/packages/core/consumer/buildchain-config.js +9 -0
  103. package/packages/core/consumer/contract/inspection.js +351 -9
  104. package/packages/core/consumer/contract/javascript-syntax.js +439 -0
  105. package/packages/core/consumer/contract/javascript-values.js +61 -0
  106. package/packages/core/consumer/contract/javascript.js +555 -0
  107. package/packages/core/consumer/contract/local-validation.js +84 -0
  108. package/packages/core/contracts/buildchain-contract.js +39 -8
  109. package/packages/core/contracts/cli/introspection.mjs +1 -9
  110. package/packages/core/contracts/public-surface-cli.js +0 -1
  111. package/packages/core/dev-delivery/dev-delivery-contract-surface.js +2 -2
  112. package/packages/core/governance/buildchain-publication-authority.js +24 -24
  113. package/packages/core/governance/cli/doctor.mjs +58 -42
  114. package/packages/core/governance/commands/architecture.mjs +6 -1
  115. package/packages/core/governance/commands/audit-publication-control-plane.mjs +1 -1
  116. package/packages/core/governance/commands/workflow-friction-report.mjs +1 -1
  117. package/packages/core/governance/github-governance-authority.js +2 -2
  118. package/packages/core/governance/publication/collection.js +1 -1
  119. package/packages/core/index.js +1 -3
  120. package/packages/core/observability/cli/candidate.mjs +0 -2
  121. package/packages/core/observability/cli/context.mjs +0 -5
  122. package/packages/core/observability/cli/diagnostics.mjs +0 -7
  123. package/packages/core/observability/cli/events.mjs +2 -10
  124. package/packages/core/paper/commands/paper-work-fleet-cli.mjs +1 -1
  125. package/packages/core/paper/commands/paper.mjs +33 -422
  126. package/packages/core/paper/consumer-status.js +72 -0
  127. package/packages/core/paper/operations/identity.js +0 -3
  128. package/packages/core/paper/operations/migration.js +460 -0
  129. package/packages/core/paper/operations/preflight-checks.js +8 -68
  130. package/packages/core/paper/operations/scaffold.js +16 -326
  131. package/packages/core/paper/operations/status.js +27 -53
  132. package/packages/core/paper/paper-agent-entry.js +36 -147
  133. package/packages/core/paper/paper-fleet.js +24 -39
  134. package/packages/core/paper/paper-repository.js +16 -0
  135. package/packages/core/paper/paper-runtime-channels.js +1 -1
  136. package/packages/core/paper/paper-scaffold-content.js +153 -162
  137. package/packages/core/paper/paper-work.js +3 -10
  138. package/packages/core/paper/paper.js +43 -5
  139. package/packages/core/providers/github/artifact-attestation.js +1 -1
  140. package/packages/core/providers/github/pipeline-context-artifacts.js +172 -0
  141. package/packages/core/publication/authority/control-plane.js +2 -2
  142. package/packages/core/publication/authority/seal.js +1 -1
  143. package/packages/core/publication/cli/dispatch.mjs +1 -12
  144. package/packages/core/publication/pipeline/actions.js +16 -9
  145. package/packages/core/publication/pipeline/apply.js +17 -9
  146. package/packages/core/publication/pipeline/context.js +29 -0
  147. package/packages/core/publication/pipeline/prepare.js +15 -6
  148. package/packages/core/publication/pipeline/recovery-materials.js +63 -1
  149. package/packages/core/publication/pipeline/recovery-prepare.js +21 -9
  150. package/packages/core/publication/pipeline/stable-entry.js +12 -7
  151. package/packages/core/publication/pipeline/stable-products.js +21 -19
  152. package/packages/core/publication/pipeline/version-actions.js +15 -6
  153. package/packages/core/publication/publication-rehearsal-projection.js +0 -9
  154. package/packages/core/release/cli/dispatch.mjs +1 -4
  155. package/packages/core/release/cli/inspection-handlers.mjs +1 -33
  156. package/packages/core/release/cli/release-handlers.mjs +2 -19
  157. package/packages/core/release/cli/verification-handlers.mjs +4 -25
  158. package/packages/core/release/next-development-projection.js +13 -13
  159. package/packages/core/release/passport/locations.js +13 -8
  160. package/packages/core/release/release-passport.js +70 -5
  161. package/packages/core/web/cli/badges.mjs +0 -4
  162. package/packages/core/web/publication-admission.js +1 -1
  163. package/packages/core/web/publication-capability.js +1 -1
  164. package/packages/core/web/readme-badges.js +1 -1
  165. package/packages/core/workflow/cli/main.mjs +1 -4
  166. package/packages/core/workflow/cli/process.mjs +1 -1
  167. package/packages/core/workflow/commands/buildchain-cli-help.mjs +2 -8
  168. package/packages/core/workflow/engine/conformance.js +1 -1
  169. package/packages/core/workflow/pipeline/build.js +21 -1
  170. package/packages/core/workflow/pipeline/delivery-observation.js +6 -2
  171. package/packages/core/workflow/workflow-taxonomy.mjs +61 -17
  172. package/scripts/check-code-layout.mjs +2 -0
  173. package/scripts/check-core-mechanism-inventory.mjs +29 -13
  174. package/scripts/check-floating-consumer-policy-contract.mjs +3 -3
  175. package/scripts/check-inventory.mjs +27 -27
  176. package/scripts/check-maintainability.mjs +28 -5
  177. package/scripts/check-public-dogfood-contract.mjs +3 -3
  178. package/scripts/check-release-topology.mjs +1 -1
  179. package/scripts/check-self-consumer-contract.mjs +7 -7
  180. package/scripts/check-universal-workflow-bootstrap.mjs +1 -1
  181. package/scripts/generate-channel-promotion-workflow.mjs +1 -1
  182. package/scripts/generate-minimal-consumer-contract.mjs +21 -1
  183. package/scripts/generate-site-bundle.mjs +2 -1
  184. package/scripts/generate-tail-reseal-fixture.mjs +3 -3
  185. package/scripts/inventory/promotion.mjs +1 -1
  186. package/scripts/next-development-self-dogfood-harness.mjs +1 -1
  187. package/scripts/next-development-self-dogfood.mjs +4 -4
  188. package/scripts/site-capability-metadata.mjs +2 -6
  189. package/scripts/source-metric-lineage.mjs +62 -7
  190. package/scripts/verify-golden-path.mjs +31 -35
  191. package/templates/native-dev-delivery.yml +1 -1
  192. package/templates/universal-buildchain-bootstrap.yml +1 -1
  193. package/packages/core/paper/operations/bootstrap.js +0 -75
  194. package/packages/core/paper/operations/plans.js +0 -213
  195. package/packages/core/paper/operations/provisioning.js +0 -113
  196. package/packages/core/paper/operations/scaffold-config.js +0 -77
  197. package/packages/core/paper/operations/scaffold-workflows.js +0 -116
  198. package/packages/core/paper/operations/workspace.js +0 -60
  199. package/packages/core/paper/paper-npm-bootstrap.js +0 -492
@@ -113,16 +113,21 @@ async function inspectEntryRun(listed, plan, source, host) {
113
113
  const { run, jobs } = await host.runs.read(listed.id, listed.run_attempt);
114
114
  const consumer = await pipelineEntryRun(run, plan, source, host);
115
115
  if (!consumer) return null;
116
+ const productJobs = jobs.filter((job) =>
117
+ /(?:^| \/ )Build product \([^)]+\)$/u.test(job.name),
118
+ );
119
+ const check = await pipelineEntryCheck(run, host);
120
+ // Controller-only PR notifications are not new product qualifications. A
121
+ // failed controller must not displace an earlier actual build. Conversely,
122
+ // any admitted native receipt or product job (even cancelled/skipped setup)
123
+ // keeps the execution in scope and must qualify its original full evidence.
116
124
  if (
117
- !jobs.some(
118
- (job) =>
119
- job.conclusion !== "skipped" &&
120
- /(?:^| \/ )Build product \([^)]+\)$/u.test(job.name),
121
- ) &&
122
- run.conclusion === "success"
125
+ !check &&
126
+ (!productJobs.length ||
127
+ (run.conclusion === "success" &&
128
+ productJobs.every((job) => job.conclusion === "skipped")))
123
129
  )
124
130
  return null;
125
- const check = await pipelineEntryCheck(run, host);
126
131
  if (!check)
127
132
  return {
128
133
  status: "missing",
@@ -17,7 +17,6 @@ function assertPublishedPlan(stablePlan, source, values) {
17
17
  const { plan, qualification: qualified, release } = values;
18
18
  verifyPipelinePublicationPlan(plan);
19
19
  if (
20
- plan.evidenceVersion !== 1 ||
21
20
  plan.channel !== "alpha" ||
22
21
  plan.version !== stablePlan.candidateVersion ||
23
22
  plan.tag !== source.candidate.tag ||
@@ -32,17 +31,6 @@ function assertPublishedPlan(stablePlan, source, values) {
32
31
  throw new Error(
33
32
  "Published product evidence differs from the exact Alpha contract or source",
34
33
  );
35
- if (
36
- plan.publisher.repository !== "kungfu-systems/buildchain" ||
37
- plan.publisher.workflow !==
38
- ".github/workflows/.release-pipeline-products.yml" ||
39
- plan.publisher.job !== "apply" ||
40
- !/^[0-9a-f]{40}$/u.test(plan.publisher.workflowSha || "") ||
41
- plan.runtime.repository !== "kungfu-systems/buildchain"
42
- )
43
- throw new Error(
44
- "Published product evidence requires the central publisher",
45
- );
46
34
  const issued = Date.parse(qualified.qualification?.issuedAt);
47
35
  if (
48
36
  !Number.isFinite(issued) ||
@@ -200,7 +188,11 @@ function completionTime(jobs, qualified, candidate) {
200
188
  return new Date(Math.max(...values)).toISOString();
201
189
  }
202
190
 
203
- function verifyPublishedDocuments(values, bundle, directory, host, execute) {
191
+ export function verifyPublishedDocuments(
192
+ values,
193
+ bundle,
194
+ { directory, token, execute },
195
+ ) {
204
196
  const {
205
197
  plan,
206
198
  qualification: qualified,
@@ -208,6 +200,18 @@ function verifyPublishedDocuments(values, bundle, directory, host, execute) {
208
200
  release,
209
201
  invocation,
210
202
  } = values;
203
+ if (
204
+ plan.evidenceVersion !== 1 ||
205
+ plan.publisher.repository !== "kungfu-systems/buildchain" ||
206
+ plan.publisher.workflow !==
207
+ ".github/workflows/.release-pipeline-products.yml" ||
208
+ plan.publisher.job !== "apply" ||
209
+ !/^[0-9a-f]{40}$/u.test(plan.publisher.workflowSha || "") ||
210
+ plan.runtime.repository !== "kungfu-systems/buildchain"
211
+ )
212
+ throw new Error(
213
+ "Published product evidence requires the central publisher",
214
+ );
211
215
  const materialization = release.versionMaterialization;
212
216
  const signing = verifyPipelineSigning({
213
217
  plan,
@@ -218,7 +222,7 @@ function verifyPublishedDocuments(values, bundle, directory, host, execute) {
218
222
  bundle,
219
223
  ),
220
224
  directory: path.join(directory, "signature"),
221
- token: host.token,
225
+ token,
222
226
  // Historical evidence is checked at issue time. It never supplies fresh
223
227
  // Stable publisher admission or extends the original receipt's lifetime.
224
228
  evaluatedAt: qualified.qualification.issuedAt,
@@ -274,13 +278,11 @@ export async function readPipelineStableProducts(
274
278
  path.join(fs.realpathSync(os.tmpdir()), "buildchain-stable-products-"),
275
279
  );
276
280
  try {
277
- const signing = verifyPublishedDocuments(
278
- evidence.values,
279
- evidence.bundle,
281
+ const signing = verifyPublishedDocuments(evidence.values, evidence.bundle, {
280
282
  directory,
281
- host,
283
+ token: host.token,
282
284
  execute,
283
- );
285
+ });
284
286
  await reobservePublicationBuild(qualified.build, qualified.source, host);
285
287
  const signer = await signingRun(plan, qualified, host);
286
288
  const completedAt = completionTime(
@@ -6,14 +6,18 @@ import { buildPipelineVersionMaterial } from "./version-build.js";
6
6
  import { qualifyPipelineVersionContext } from "./version-context.js";
7
7
  import { preparePipelinePublication } from "./prepare.js";
8
8
  import { settlePipelinePublication } from "./settle.js";
9
+ import {
10
+ readPipelineContext,
11
+ writePipelineContext,
12
+ } from "../../providers/github/pipeline-context-artifacts.js";
9
13
 
10
- const contextInput = (core) =>
11
- JSON.parse(core.getInput("context", { required: true }));
14
+ const contextInput = (core, env) =>
15
+ readPipelineContext(core.getInput("context", { required: true }), env);
12
16
  const directory = (env) =>
13
17
  path.join(env.GITHUB_WORKSPACE, ".buildchain/version-material");
14
18
 
15
19
  export async function buildPipelineVersionAction(core, env) {
16
- const context = contextInput(core);
20
+ const context = await contextInput(core, env);
17
21
  if (
18
22
  context.schema !== "buildchain.pipeline-version-context/v1" ||
19
23
  context.runId !== Number(env.GITHUB_RUN_ID) ||
@@ -36,7 +40,7 @@ export async function buildPipelineVersionAction(core, env) {
36
40
  }
37
41
 
38
42
  export async function materializePipelinePublicationAction(core, env) {
39
- const context = contextInput(core);
43
+ const context = await contextInput(core, env);
40
44
  const operation = core.getInput("operation", { required: true });
41
45
  let result = { operation, context };
42
46
  if (operation === "regenerate") {
@@ -58,7 +62,12 @@ export async function materializePipelinePublicationAction(core, env) {
58
62
  }
59
63
  core.setOutput("operation", result.operation);
60
64
  core.setOutput("stable-wait", result.wait ? JSON.stringify(result.wait) : "");
61
- core.setOutput("context", JSON.stringify(result.context || {}));
65
+ core.setOutput(
66
+ "context",
67
+ operation === "regenerate"
68
+ ? await writePipelineContext(result.context || {}, env)
69
+ : core.getInput("context", { required: true }),
70
+ );
62
71
  core.setOutput(
63
72
  "matrix",
64
73
  JSON.stringify({ include: result.context?.platforms || [] }),
@@ -66,7 +75,7 @@ export async function materializePipelinePublicationAction(core, env) {
66
75
  }
67
76
 
68
77
  export async function materializePipelineDevelopmentAction(core, env) {
69
- const context = contextInput(core);
78
+ const context = await contextInput(core, env);
70
79
  if (context.preparation.purpose !== "development")
71
80
  throw new Error(
72
81
  "Development materialization received a different version purpose",
@@ -9,8 +9,6 @@ export const PUBLICATION_REHEARSAL_AGENT_SECTION_START =
9
9
  "<!-- buildchain:publication-rehearsal:start -->";
10
10
  export const PUBLICATION_REHEARSAL_AGENT_SECTION_END =
11
11
  "<!-- buildchain:publication-rehearsal:end -->";
12
- export const PUBLICATION_REHEARSAL_WORKFLOW_PATH =
13
- ".github/workflows/publication-rehearsal.yml";
14
12
 
15
13
  export function publicationRehearsalToml() {
16
14
  return `[publication_rehearsal]\ncontract = ${JSON.stringify(PUBLICATION_REHEARSAL_CAPSULE_CONTRACT)}\nadr = ${JSON.stringify(RELEASE_LOCAL_CONSTRUCTIBILITY_ADR)}\ninvariant = ${JSON.stringify(RELEASE_LOCAL_CONSTRUCTIBILITY_INVARIANT)}\ncommand = ${JSON.stringify(PUBLICATION_REHEARSAL_COMMAND)}\ncapsule = ".buildchain/publication-rehearsal/capsule.json"\ncandidate_root = ".buildchain/publication-rehearsal/candidate"\nstate = ".buildchain/publication-rehearsal/state.json"\nevidence = ".buildchain/publication-rehearsal/evidence.json"\n`;
@@ -95,10 +93,3 @@ export function mergePublicationRehearsalAgentInstructions(current = "") {
95
93
  end + PUBLICATION_REHEARSAL_AGENT_SECTION_END.length,
96
94
  )}`;
97
95
  }
98
-
99
- export function publicationRehearsalWorkflow(buildchainRef) {
100
- const ref = String(buildchainRef || "").trim();
101
- if (!/^v4(?:-alpha)?$/u.test(ref))
102
- throw new Error("publication rehearsal workflow requires a floating public entry");
103
- return `name: Publication Rehearsal\n\non:\n workflow_dispatch:\n inputs:\n capsule-path:\n description: "Source-bound v4 publication rehearsal capsule"\n required: true\n default: ".buildchain/publication-rehearsal/capsule.json"\n candidate-root:\n description: "Repository-relative candidate root"\n required: true\n default: ".buildchain/publication-rehearsal/candidate"\n\npermissions:\n contents: read\n\njobs:\n rehearsal:\n uses: kungfu-systems/buildchain/.github/workflows/public-release-tail.yml@${ref}\n with:\n rehearsal-capsule-path: \${{ inputs.capsule-path }}\n candidate-root: \${{ inputs.candidate-root }}\n rehearsal-mode: simulate\n state-path: ".buildchain/publication-rehearsal/state.json"\n rehearsal-evidence-path: ".buildchain/publication-rehearsal/evidence.json"\n`;
104
- }
@@ -1,10 +1,7 @@
1
1
  import { runReleasePropagationCli } from "../commands/release-propagation.mjs";
2
2
  import { runReleaseTailCli } from "../commands/release-tail.mjs";
3
3
  import { runTailResealCli } from "../commands/tail-reseal.mjs";
4
- import {
5
- TRUST_RELEASE_COMMANDS,
6
- dispatchTrustReleaseCommand,
7
- } from "./trust-release.mjs";
4
+ import { dispatchTrustReleaseCommand } from "./trust-release.mjs";
8
5
  import { packageVersion } from "../../contracts/cli/context.mjs";
9
6
  import { runScript } from "../../workflow/cli/process.mjs";
10
7
 
@@ -1,44 +1,12 @@
1
- import fs from "node:fs";
2
- import path from "node:path";
3
- import { spawnSync } from "node:child_process";
4
- import { verifyInfraContractEvidenceBundle } from "../../providers/commands/infra-contract-core.mjs";
5
- import { verifyBuildchainLogEvents } from "../../observability/logging.js";
6
- import {
7
- explainReleaseLineDryRun,
8
- formatReleaseLineDryRun,
9
- } from "../release-line-dry-run.js";
10
- import {
11
- planReleaseLineBootstrap,
12
- writeReleaseLineBootstrapVersionState,
13
- } from "../release-line-bootstrap.js";
14
- import { collectGitHubReleasePassport } from "../passport/collection.js";
15
- import { explainReleasePassport, verifyReleasePassport } from "../release-passport.js";
16
- import {
17
- createPublicationAdmission,
18
- createRunnerProvenance,
19
- verifyPublicationAdmission,
20
- } from "../../publication/publication-authority.js";
21
- import {
22
- createGitHubArtifactAttestationPolicy,
23
- createGitHubArtifactAttestationVerificationPlan,
24
- verifyGitHubArtifactAttestationEvidence,
25
- } from "../../build/github-artifact-attestation.js";
1
+ import { explainReleasePassport } from "../release-passport.js";
26
2
  import {
27
3
  explainArtifactPassport,
28
4
  verifyArtifactPassport,
29
5
  } from "../../build/artifact-passport.js";
30
6
  import {
31
- projectArtifactVerificationEnvelopeToKfx,
32
- verifyArtifactVerificationEnvelope,
33
- } from "../../build/artifact-verification-envelope.js";
34
- import {
35
- artifactEnvelopeOptions,
36
7
  printJson,
37
8
  readBooleanFlag,
38
9
  readFlag,
39
- readJsonInput,
40
- readRepeatedFlag,
41
- writeJsonFile,
42
10
  } from "../../contracts/cli/options.mjs";
43
11
 
44
12
  async function handleAuditCommand({ args, runScript, packageVersion }) {
@@ -1,8 +1,4 @@
1
- import fs from "node:fs";
2
1
  import path from "node:path";
3
- import { spawnSync } from "node:child_process";
4
- import { verifyInfraContractEvidenceBundle } from "../../providers/commands/infra-contract-core.mjs";
5
- import { verifyBuildchainLogEvents } from "../../observability/logging.js";
6
2
  import {
7
3
  explainReleaseLineDryRun,
8
4
  formatReleaseLineDryRun,
@@ -12,25 +8,12 @@ import {
12
8
  writeReleaseLineBootstrapVersionState,
13
9
  } from "../release-line-bootstrap.js";
14
10
  import { collectGitHubReleasePassport } from "../passport/collection.js";
15
- import { explainReleasePassport, verifyReleasePassport } from "../release-passport.js";
16
11
  import {
17
12
  createPublicationAdmission,
18
13
  createRunnerProvenance,
19
- verifyPublicationAdmission,
20
14
  } from "../../publication/publication-authority.js";
21
- import {
22
- createGitHubArtifactAttestationPolicy,
23
- createGitHubArtifactAttestationVerificationPlan,
24
- verifyGitHubArtifactAttestationEvidence,
25
- } from "../../build/github-artifact-attestation.js";
26
- import {
27
- explainArtifactPassport,
28
- verifyArtifactPassport,
29
- } from "../../build/artifact-passport.js";
30
- import {
31
- projectArtifactVerificationEnvelopeToKfx,
32
- verifyArtifactVerificationEnvelope,
33
- } from "../../build/artifact-verification-envelope.js";
15
+ import { createGitHubArtifactAttestationPolicy } from "../../build/github-artifact-attestation.js";
16
+ import { projectArtifactVerificationEnvelopeToKfx } from "../../build/artifact-verification-envelope.js";
34
17
  import {
35
18
  artifactEnvelopeOptions,
36
19
  printJson,
@@ -3,34 +3,14 @@ import path from "node:path";
3
3
  import { spawnSync } from "node:child_process";
4
4
  import { verifyInfraContractEvidenceBundle } from "../../providers/commands/infra-contract-core.mjs";
5
5
  import { verifyBuildchainLogEvents } from "../../observability/logging.js";
6
+ import { verifyReleasePassport } from "../release-passport.js";
7
+ import { verifyPublicationAdmission } from "../../publication/publication-authority.js";
6
8
  import {
7
- explainReleaseLineDryRun,
8
- formatReleaseLineDryRun,
9
- } from "../release-line-dry-run.js";
10
- import {
11
- planReleaseLineBootstrap,
12
- writeReleaseLineBootstrapVersionState,
13
- } from "../release-line-bootstrap.js";
14
- import { collectGitHubReleasePassport } from "../passport/collection.js";
15
- import { explainReleasePassport, verifyReleasePassport } from "../release-passport.js";
16
- import {
17
- createPublicationAdmission,
18
- createRunnerProvenance,
19
- verifyPublicationAdmission,
20
- } from "../../publication/publication-authority.js";
21
- import {
22
- createGitHubArtifactAttestationPolicy,
23
9
  createGitHubArtifactAttestationVerificationPlan,
24
10
  verifyGitHubArtifactAttestationEvidence,
25
11
  } from "../../build/github-artifact-attestation.js";
26
- import {
27
- explainArtifactPassport,
28
- verifyArtifactPassport,
29
- } from "../../build/artifact-passport.js";
30
- import {
31
- projectArtifactVerificationEnvelopeToKfx,
32
- verifyArtifactVerificationEnvelope,
33
- } from "../../build/artifact-verification-envelope.js";
12
+ import { verifyArtifactPassport } from "../../build/artifact-passport.js";
13
+ import { verifyArtifactVerificationEnvelope } from "../../build/artifact-verification-envelope.js";
34
14
  import {
35
15
  artifactEnvelopeOptions,
36
16
  printJson,
@@ -38,7 +18,6 @@ import {
38
18
  readFlag,
39
19
  readJsonInput,
40
20
  readRepeatedFlag,
41
- writeJsonFile,
42
21
  } from "../../contracts/cli/options.mjs";
43
22
 
44
23
  async function verifyGitHubArtifactAttestationCommand({
@@ -266,19 +266,19 @@ invalid.
266
266
 
267
267
  ## Public self-dogfood and adoption
268
268
 
269
- \`.github/workflows/self-build-public-consumer-dogfood.yml\` remains the exact thin
270
- consumer of the public \`public-build-stage-capsule-canary.yml@v4-alpha\` contract. Its
271
- declared \`lifecycle.verify\` runs \`pnpm run check\`, so the same public path
272
- executes pure recovery tests that inject a transient durable-state write
273
- failure, restore the adapter operation on a fresh runner, supersede stale work
274
- when protected Dev moves, preserve \`pr-pending\` during protected-PR delay, and
275
- prove both legal version models. No caller-local qualification job, action,
276
- or private self-dogfood route is added.
277
-
278
- The existing dual-channel self-consumer separately retains exact hosted
279
- \`build.yml@v4-alpha\` and \`build.yml@v4\` runtime evidence. Consumers adopt
280
- the proved contract through the floating v4 coordinates; exact resolved SHAs
281
- remain audit evidence and never become durable selectors.
269
+ \`.github/workflows/buildchain.yml\` calls the published
270
+ \`public-ops-pipeline.yml@v4\` entry. Products declare their verification commands
271
+ in schema-2 TOML, including the full repository check on each required platform.
272
+ Next-development preparation, independent review, protected merge and settlement
273
+ remain runtime responsibilities.
274
+
275
+ \`.github/workflows/buildchain-recover.yml\` calls
276
+ \`public-ops-recover.yml@v4\` with one exact attempt and an optional temporary
277
+ repaired runtime. It preserves completed publication evidence while continuing
278
+ unfinished follow-ups. Both callers use the same generated bytes as external
279
+ consumers. Tool-maintained locks and retained receipts bind exact runtime SHAs.
280
+ Earlier Stage Capsule and channel-build proofs retain their historical source
281
+ identities; they do not define additional current consumer entrypoints.
282
282
 
283
283
  ## Local adapter
284
284
 
@@ -1,29 +1,32 @@
1
1
  import path from "node:path";
2
2
  import fs from "node:fs";
3
- import { readJsonFile } from "./files.js";
4
3
  import https from "node:https";
5
4
  import http from "node:http";
6
5
  import { nonEmptyString } from "./identity.js";
7
- export async function resolveSiblingJson(basePath, relativePath) {
6
+ export async function resolveSiblingJson(basePath, relativePath, options) {
8
7
  if (!basePath || !relativePath) {
9
8
  return undefined;
10
9
  }
11
10
  if (/^https?:\/\//.test(relativePath)) {
12
- return readJsonFromLocation(relativePath);
11
+ return readJsonFromLocation(relativePath, 0, options);
13
12
  }
14
13
  if (/^https?:\/\//.test(basePath)) {
15
- return readJsonFromLocation(new URL(relativePath, basePath).toString());
14
+ return readJsonFromLocation(
15
+ new URL(relativePath, basePath).toString(),
16
+ 0,
17
+ options,
18
+ );
16
19
  }
17
20
  const candidate = path.resolve(path.dirname(basePath), relativePath);
18
21
  if (!fs.existsSync(candidate)) {
19
22
  return undefined;
20
23
  }
21
- return readJsonFile(candidate);
24
+ return readJsonFromLocation(candidate, 0, options);
22
25
  }
23
26
  export async function readJsonFromLocation(
24
27
  location,
25
28
  redirectCount = 0,
26
- { timeoutMs = 15_000 } = {},
29
+ { timeoutMs = 15_000, raw = false } = {},
27
30
  ) {
28
31
  const input = nonEmptyString(location, "location");
29
32
  if (!Number.isInteger(timeoutMs) || timeoutMs <= 0) {
@@ -47,6 +50,7 @@ export async function readJsonFromLocation(
47
50
  response.resume();
48
51
  readJsonFromLocation(nextLocation, redirectCount + 1, {
49
52
  timeoutMs,
53
+ raw,
50
54
  }).then(resolve, reject);
51
55
  return;
52
56
  }
@@ -64,7 +68,7 @@ export async function readJsonFromLocation(
64
68
  });
65
69
  response.on("end", () => {
66
70
  try {
67
- resolve(JSON.parse(body));
71
+ resolve(raw ? body : JSON.parse(body));
68
72
  } catch (error) {
69
73
  reject(error);
70
74
  }
@@ -78,5 +82,6 @@ export async function readJsonFromLocation(
78
82
  request.on("error", reject);
79
83
  });
80
84
  }
81
- return readJsonFile(input);
85
+ const bytes = fs.readFileSync(input, "utf8");
86
+ return raw ? bytes : JSON.parse(bytes);
82
87
  }
@@ -1,3 +1,7 @@
1
+ import fs from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { verifyPublishedDocuments } from "../publication/pipeline/stable-products.js";
1
5
  import { resolveReleasePassportVerificationInputs } from "./release-passport-contract.js";
2
6
  import { nowIso } from "./passport/identity.js";
3
7
  import {
@@ -5,6 +9,56 @@ import {
5
9
  resolveSiblingJson,
6
10
  } from "./passport/locations.js";
7
11
  import { createReleaseCheckReport } from "./passport/report.js";
12
+
13
+ async function verifyPipelinePassport(location, release, checkedAt, execute) {
14
+ const directory = fs.mkdtempSync(
15
+ path.join(fs.realpathSync(os.tmpdir()), "buildchain-passport-"),
16
+ );
17
+ const report = {
18
+ schemaVersion: 1,
19
+ contract: "kungfu-buildchain-release-check-report",
20
+ checkedAt,
21
+ verificationScope: "signed-release-metadata",
22
+ artifactBytesVerified: false,
23
+ providerStateVerified: false,
24
+ completeness: { artifactCount: 0 },
25
+ issues: [],
26
+ };
27
+ try {
28
+ const values = { release };
29
+ for (const name of ["plan", "qualification", "capsules", "invocation"])
30
+ values[name] = await resolveSiblingJson(
31
+ location,
32
+ `buildchain.${name}.json`,
33
+ );
34
+ const bundle = await resolveSiblingJson(
35
+ location,
36
+ "buildchain.attestation.json",
37
+ { raw: true },
38
+ );
39
+ verifyPublishedDocuments(values, bundle, {
40
+ directory,
41
+ token: process.env.GH_TOKEN || process.env.GITHUB_TOKEN,
42
+ execute,
43
+ });
44
+ report.completeness.artifactCount = values.qualification.artifacts.length;
45
+ report.source = release.source;
46
+ report.release = release.release;
47
+ } catch {
48
+ report.issues.push({
49
+ level: "error",
50
+ code: "pipeline.evidence",
51
+ message:
52
+ "Signed release metadata verification failed. Supply all five unchanged companion files and GitHub CLI with attestation verification support.",
53
+ });
54
+ } finally {
55
+ fs.rmSync(directory, { recursive: true, force: true });
56
+ }
57
+ report.ok = report.issues.length === 0;
58
+ report.trust = report.ok ? "pass" : "fail";
59
+ return report;
60
+ }
61
+
8
62
  export async function verifyReleasePassport({
9
63
  passportLocation,
10
64
  artifactEvidenceLocation = "",
@@ -17,7 +71,16 @@ export async function verifyReleasePassport({
17
71
  kfdAdopterManifestGateLocation = "",
18
72
  kfdSupportEvidenceLocation = "",
19
73
  checkedAt = nowIso(),
74
+ execute,
20
75
  } = {}) {
76
+ const passport = await readJsonFromLocation(passportLocation);
77
+ if (passport?.schema === "kungfu.buildchain.release-passport/v4")
78
+ return verifyPipelinePassport(
79
+ passportLocation,
80
+ passport,
81
+ checkedAt,
82
+ execute,
83
+ );
21
84
  const evidence = await resolveReleasePassportVerificationInputs({
22
85
  passportLocation,
23
86
  locations: {
@@ -34,10 +97,7 @@ export async function verifyReleasePassport({
34
97
  readJson: readJsonFromLocation,
35
98
  resolveSibling: resolveSiblingJson,
36
99
  });
37
- return createReleaseCheckReport({
38
- ...evidence,
39
- checkedAt,
40
- });
100
+ return createReleaseCheckReport({ ...evidence, checkedAt });
41
101
  }
42
102
  export async function explainReleasePassport({
43
103
  passportLocation,
@@ -46,7 +106,9 @@ export async function explainReleasePassport({
46
106
  const report = await verifyReleasePassport({ passportLocation });
47
107
  const passport = await readJsonFromLocation(passportLocation);
48
108
  const nextAction = report.ok
49
- ? "install-or-upgrade-after-policy-review"
109
+ ? report.verificationScope === "signed-release-metadata"
110
+ ? "verify-artifact-bytes-and-review-policy"
111
+ : "install-or-upgrade-after-policy-review"
50
112
  : "block-release-and-report-verification-failure";
51
113
  return {
52
114
  schemaVersion: 1,
@@ -54,6 +116,9 @@ export async function explainReleasePassport({
54
116
  audience: forAudience,
55
117
  release: passport.release,
56
118
  trust: report.trust,
119
+ verificationScope: report.verificationScope,
120
+ artifactBytesVerified: report.artifactBytesVerified,
121
+ providerStateVerified: report.providerStateVerified,
57
122
  complete: report.ok,
58
123
  artifactCount: report.completeness.artifactCount,
59
124
  runnerPolicy: passport.runnerPolicy,
@@ -13,10 +13,6 @@ import {
13
13
  printJson,
14
14
  readBooleanFlag,
15
15
  readFlag,
16
- readJsonInput,
17
- readRepeatedFlag,
18
- readRepeatedJsonInputs,
19
- writeJsonFile,
20
16
  } from "../../contracts/cli/options.mjs";
21
17
 
22
18
  export async function runReadmeBadgesCli(args = []) {
@@ -56,7 +56,7 @@ export function assembleWebPublicationAdmission({
56
56
  "managed web-surface publication requires an ephemeral GitHub-hosted Actions runner",
57
57
  );
58
58
  }
59
- const workflowPath = ".github/workflows/public-release-web.yml";
59
+ const workflowPath = ".github/workflows/.release-web.yml";
60
60
  const publisherWorkflowPath = workflowPath;
61
61
  const controlPlaneAudit = createPublicationControlPlaneAudit({
62
62
  repository,
@@ -36,7 +36,7 @@ export function verifyWebPublicationCapability(request, now = Date.now()) {
36
36
  }
37
37
  const roleArn = required(request, "roleArn");
38
38
  const exact = {
39
- workflowPath: ".github/workflows/public-release-web.yml",
39
+ workflowPath: ".github/workflows/.release-web.yml",
40
40
  repository: required(request, "repository"),
41
41
  sourceSha: required(request, "sourceSha").toLowerCase(),
42
42
  runtimeSha: required(request, "runtimeSha").toLowerCase(),
@@ -457,7 +457,7 @@ function normalizePackageRepository(repository) {
457
457
  function discoverWorkflowFacts({ cwd, repository, badgeConfig = {} }) {
458
458
  const workflowDir = path.join(cwd, ".github", "workflows");
459
459
  const configured = normalizeStringArray(badgeConfig.workflows);
460
- const defaults = ["verify.yml", "build.yml", "buildchain-ref-promotion.yml"];
460
+ const defaults = ["verify.yml", ".build-candidate.yml", "buildchain-ref-promotion.yml"];
461
461
  const names = configured.length > 0 ? configured : defaults;
462
462
  if (!fs.existsSync(workflowDir)) {
463
463
  return [];
@@ -1,10 +1,7 @@
1
1
  import { initializeCliRuntime } from "../../contracts/cli/context.mjs";
2
2
  import { BUILDCHAIN_USAGE } from "../commands/buildchain-cli-help.mjs";
3
3
  import { formatCliHelp } from "../../contracts/cli-reference.js";
4
- import {
5
- TRUST_RELEASE_COMMANDS,
6
- dispatchTrustReleaseCommand,
7
- } from "../../release/cli/trust-release.mjs";
4
+ import { TRUST_RELEASE_COMMANDS } from "../../release/cli/trust-release.mjs";
8
5
  import { dispatchRegisteredCommand } from "../../contracts/command-registry.mjs";
9
6
  import { handleAdopterDeliveryCommand } from "../../adoption/cli/dispatch.mjs";
10
7
  import { handleKfdCommand } from "../../adoption/cli/kfd.mjs";
@@ -1,4 +1,4 @@
1
- import { spawn, spawnSync } from "node:child_process";
1
+ import { spawnSync } from "node:child_process";
2
2
  import path from "node:path";
3
3
  import { root } from "../../contracts/cli/context.mjs";
4
4
 
@@ -20,7 +20,7 @@ export const BUILDCHAIN_USAGE = `Usage:
20
20
  [--cold-fallback-status not-run|passed|failed]
21
21
  [--output <file>] [--json]
22
22
  buildchain candidate timeline --input <file-or-json> [--output <file>] [--json]
23
- buildchain init [--cwd <dir>] [--type package|native|web-surface|infra-contract|publication-artifact|anchored-package] [--force]
23
+ buildchain init [--cwd <dir>] [--type npm|binary|paper|package|native|publication-artifact|anchored-package] [--force]
24
24
  [--package-manager pnpm|npm|yarn] [--runner-preset <preset>]
25
25
  [--artifact-name <name>]
26
26
  buildchain validate [--cwd <dir>] [--require-version-state]
@@ -253,7 +253,7 @@ export const BUILDCHAIN_USAGE = `Usage:
253
253
  [--output <file>] [--promote]
254
254
  [--no-toolchain-pull]
255
255
  [--allow-unpinned-toolchain] [--json]
256
- buildchain paper scaffold --package <name> --repository <owner/repo> [--write] [--json]
256
+ buildchain paper scaffold --repository <owner/repo> [--package <name>] [--write] [--json]
257
257
  buildchain paper migrate [--cwd <dir>] [--write] [--json]
258
258
  buildchain paper work start <topic> [--cwd <dir>] [--branch <branch>] [--execute] [--json]
259
259
  buildchain paper work submit [--cwd <dir>] [--title <title>] [--body <body>] [--execute] [--json]
@@ -261,13 +261,7 @@ export const BUILDCHAIN_USAGE = `Usage:
261
261
  buildchain paper fleet update [--root <dir>] [--write] [--json]
262
262
  buildchain paper agent verify [--cwd <dir>] [--offline] [--json]
263
263
  buildchain paper preflight [--cwd <dir>] [--offline] [--json]
264
- buildchain paper bootstrap npm [--cwd <dir>] [--execute]
265
- [--confirm-public-package <name>] [--json]
266
- buildchain paper build [--cwd <dir>] [--execute] [--json]
267
- buildchain paper alpha [--cwd <dir>] [--source-ref <ref>] [--target-ref <ref>]
268
- [--execute] [--json]
269
264
  buildchain paper status [--cwd <dir>] [--json]
270
- buildchain paper resume [--cwd <dir>] [--runtime-ref <ref>] [--execute] [--json]
271
265
  buildchain release-propagation <plan|write-lock|work|entry|pickup> ...
272
266
  buildchain badges readme [--cwd <dir>] [--readme <path>] [--check] [--write] [--json]
273
267
  buildchain badges bundle [--cwd <dir>] [--readme <path>] [--claims <csv>] [--check] [--write] [--json]
@@ -52,7 +52,7 @@ export function executeBootstrapConformance(
52
52
  const source = fs.readFileSync(path.join(runtimeRoot, relative), "utf8");
53
53
  if (
54
54
  relative !== architecture.bootstrap.publicWorkflow &&
55
- !/(?:\.\/)?\.github\/workflows\/public-ops-bootstrap\.yml/u.test(source)
55
+ !/(?:\.\/)?\.github\/workflows\/\.ops-bootstrap\.yml/u.test(source)
56
56
  )
57
57
  fail(`candidate Bootstrap facade is not governed: ${relative}`);
58
58
  }