@kungfu-tech/buildchain 4.0.1-alpha.5 → 4.0.1-alpha.55

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 (159) hide show
  1. package/README.md +9 -6
  2. package/actions/release-tail/README.md +8 -0
  3. package/actions/v4-release-candidate-promote/README.md +3 -0
  4. package/architecture/agent-change-map.md +1015 -0
  5. package/architecture/ci-lane-change-budget.json +256 -0
  6. package/architecture/decisions/0004-v4-declarative-release-tail.md +47 -0
  7. package/architecture/internal-capabilities.json +220 -15
  8. package/architecture/maintainability-debt.json +3229 -0
  9. package/architecture/maintainability-policy.json +489 -132
  10. package/architecture/release-tail-contract-inventory.json +5 -2
  11. package/architecture/v3-core-mechanism-inventory.json +4 -3
  12. package/architecture/v3-v4-capability-closure.md +59 -0
  13. package/architecture/v3-v4-live-capability-inventory.json +102404 -0
  14. package/architecture/v4-adopter-delivery-parity.json +32 -5
  15. package/architecture/v4-cross-platform-adopter-qualification.json +52 -0
  16. package/architecture/v4-delivery-warrant-shadow-fixtures.json +3 -3
  17. package/architecture/v4-floating-consumer-policy.json +6 -0
  18. package/architecture/v4-publication-rehearsal-parity.json +84 -0
  19. package/architecture/v4-runtime-semantic-closure.json +710 -0
  20. package/bin/buildchain.mjs +7 -1
  21. package/bin/internal/adopter-delivery-cli.mjs +70 -0
  22. package/bin/internal/command-registry.mjs +1 -0
  23. package/bin/internal/trust-release-release-handlers.mjs +5 -0
  24. package/contracts/fixtures/v4-adopter-delivery-v1/archive-template.json +19 -0
  25. package/contracts/fixtures/v4-adopter-delivery-v1/bootstrap-positive.json +93 -0
  26. package/contracts/fixtures/v4-adopter-delivery-v1/gate-positive.json +29 -0
  27. package/contracts/fixtures/v4-adopter-delivery-v1/gate-unknown-selector.json +26 -0
  28. package/contracts/fixtures/v4-adopter-delivery-v1/offline-vectors.json +50 -0
  29. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/artifacts/product.bin +1 -0
  30. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/config/buildchain.toml +5 -0
  31. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/release-activation.json +1 -0
  32. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/signed-channel.json +1 -0
  33. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/evidence/qualification.json +1 -0
  34. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/candidate.json +5 -0
  35. package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/release-passport.json +1 -0
  36. package/contracts/fixtures/v4-publication-rehearsal-v1/capsule.json +707 -0
  37. package/contracts/fixtures/v4-publication-rehearsal-v1/offline-vectors.json +27 -0
  38. package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
  39. package/contracts/v4-adopter-delivery-v1.schema.json +81 -0
  40. package/contracts/v4-floating-consumer-policy-receipt-v1.schema.json +4 -2
  41. package/contracts/v4-publication-qualification-v1.schema.json +51 -0
  42. package/contracts/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
  43. package/dist/site/agent-index.json +4 -0
  44. package/dist/site/artifact-schemas.json +8 -0
  45. package/dist/site/buildchain-contract.json +125 -34
  46. package/dist/site/buildchain-site.json +308 -33
  47. package/dist/site/capability-registry.json +13 -12
  48. package/dist/site/cli-registry.json +57 -2
  49. package/dist/site/controller-registry.json +41 -5
  50. package/dist/site/kfd-claims.json +438 -24
  51. package/dist/site/kfd-upstream-aggregate.json +1 -1
  52. package/dist/site/manual-registry.json +22 -7
  53. package/dist/site/node-api-registry.json +12843 -9314
  54. package/dist/site/page-registry.json +288 -21
  55. package/dist/site/public-surface-audit.json +281 -21
  56. package/dist/site/publication-authority-registry.json +66 -8
  57. package/dist/site/publication-registry.json +4 -4
  58. package/dist/site/release-provenance.json +20 -0
  59. package/dist/site/schemas/release-tail-capabilities-v1.schema.json +199 -0
  60. package/dist/site/schemas/v4-adopter-delivery-v1.schema.json +81 -0
  61. package/dist/site/schemas/v4-publication-qualification-v1.schema.json +51 -0
  62. package/dist/site/schemas/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
  63. package/dist/site/site-manifest.json +19 -11
  64. package/dist/site/workflow-registry.json +195 -17
  65. package/docs/MAP.md +4 -2
  66. package/docs/cli-reference.md +70 -2
  67. package/docs/cli.md +8 -0
  68. package/docs/dev-delivery-warrant.md +34 -10
  69. package/docs/node-api-reference.md +524 -279
  70. package/docs/publish-transaction.md +11 -4
  71. package/docs/release-candidate.md +7 -0
  72. package/docs/release-tail-provider-plane.md +30 -0
  73. package/docs/v4-adopter-delivery.md +152 -0
  74. package/docs/v4-declarative-release-tail-migration.md +43 -0
  75. package/docs/v4-publication-rehearsal.md +130 -0
  76. package/package.json +24 -4
  77. package/packages/core/adopter-delivery-passport.js +295 -0
  78. package/packages/core/adopter-delivery-vectors.js +158 -0
  79. package/packages/core/adopter-delivery-vectors.json +77 -0
  80. package/packages/core/buildchain-agent-manuals.js +1 -0
  81. package/packages/core/buildchain-config.js +84 -0
  82. package/packages/core/buildchain-contract.js +31 -1
  83. package/packages/core/buildchain-delivery-bootstrap.js +240 -0
  84. package/packages/core/buildchain-delivery-infrastructure.js +164 -0
  85. package/packages/core/buildchain-delivery-self-dogfood.js +395 -0
  86. package/packages/core/buildchain-publication-authority.js +2 -0
  87. package/packages/core/ci-lane-change-budget.js +247 -0
  88. package/packages/core/dev-delivery-native-proof.js +43 -27
  89. package/packages/core/dev-delivery-warrant-settlement.js +239 -3
  90. package/packages/core/dev-delivery-warrant-state.js +46 -10
  91. package/packages/core/dev-delivery-warrant.js +29 -7
  92. package/packages/core/github-governance-authority.js +5 -4
  93. package/packages/core/index.js +6 -0
  94. package/packages/core/legacy-kfd-adopter-driver.js +167 -0
  95. package/packages/core/paper-scaffold-content.js +401 -0
  96. package/packages/core/paper.js +12 -378
  97. package/packages/core/publication-control-plane-audit.js +135 -111
  98. package/packages/core/publication-rehearsal-projection.js +104 -0
  99. package/packages/core/publication-rehearsal-runtime.js +190 -0
  100. package/packages/core/published-delivery-authority.js +266 -0
  101. package/packages/core/release-candidate-recovery.js +71 -15
  102. package/packages/core/release-candidate.js +2 -2
  103. package/packages/core/release-passport.js +95 -170
  104. package/packages/core/v4-adopter-delivery-parity.js +3 -3
  105. package/packages/core/v4-adopter-delivery.js +359 -0
  106. package/packages/core/v4-cross-platform-adopter-qualification.js +343 -0
  107. package/packages/core/v4-delivery-warrant-read-candidate.js +10 -3
  108. package/packages/core/v4-floating-consumer-evidence.js +18 -4
  109. package/packages/core/v4-floating-consumer-policy.js +139 -35
  110. package/packages/core/v4-floating-consumer-release-passport.js +154 -8
  111. package/packages/core/v4-publication-qualification.js +222 -0
  112. package/packages/core/v4-publication-rehearsal-capsule.js +468 -0
  113. package/packages/core/v4-publication-rehearsal-provider-bindings.js +212 -0
  114. package/packages/core/v4-publication-rehearsal.js +481 -0
  115. package/packages/core/workflow-yaml-contract.js +24 -2
  116. package/scripts/artifact-signing-controller-core.mjs +1 -1
  117. package/scripts/audit-publication-control-plane.mjs +17 -17
  118. package/scripts/buildchain-cli-help.mjs +13 -0
  119. package/scripts/check-ci-lane-change-budget.mjs +100 -0
  120. package/scripts/check-internal-architecture.mjs +23 -3
  121. package/scripts/check-inventory.mjs +24 -6
  122. package/scripts/check-maintainability.mjs +145 -4
  123. package/scripts/check-project-cut-merge-queue-admission.mjs +87 -0
  124. package/scripts/check-v3-v4-capability-inventory.mjs +574 -0
  125. package/scripts/check-v4-floating-consumer-policy-contract.mjs +30 -4
  126. package/scripts/check-v4-runtime-semantic-closure.mjs +266 -0
  127. package/scripts/dev-delivery-source-proof-replay.mjs +153 -0
  128. package/scripts/dev-delivery-source-proof-reuse.mjs +13 -97
  129. package/scripts/dev-delivery-warrant-options.mjs +27 -11
  130. package/scripts/dev-delivery-warrant-store.mjs +10 -6
  131. package/scripts/dev-delivery-warrant.mjs +50 -6
  132. package/scripts/dev-pr-auto-merge.mjs +25 -11
  133. package/scripts/dev-pr-delivery-warrant.mjs +45 -0
  134. package/scripts/dev-pr-prequeue-guard.mjs +0 -18
  135. package/scripts/dev-qualification-patrol.mjs +9 -9
  136. package/scripts/dispatch-artifact-signing-authority.mjs +1 -1
  137. package/scripts/generate-agent-change-map.mjs +118 -0
  138. package/scripts/generate-channel-promotion-workflow.mjs +2 -2
  139. package/scripts/generate-release-candidate-passport.mjs +177 -0
  140. package/scripts/generate-site-bundle.mjs +36 -0
  141. package/scripts/maintainability-domain-metrics.mjs +237 -0
  142. package/scripts/maintainability-governance.mjs +473 -0
  143. package/scripts/maintainability-metrics.mjs +28 -6
  144. package/scripts/project-cut-merge-queue-admission.mjs +394 -0
  145. package/scripts/promotion-channel-router.mjs +4 -4
  146. package/scripts/promotion-routing-evidence.mjs +35 -6
  147. package/scripts/release-candidate-anchor-provenance.mjs +99 -0
  148. package/scripts/release-candidate-resolver.mjs +44 -0
  149. package/scripts/release-line-policy.mjs +25 -15
  150. package/scripts/release-tail.mjs +68 -3
  151. package/scripts/resume-from-candidate-run.mjs +595 -65
  152. package/scripts/run-lifecycle-core.mjs +341 -376
  153. package/scripts/site-capability-metadata.mjs +21 -0
  154. package/scripts/stable-candidate-qualification.mjs +9 -10
  155. package/scripts/v3-v4-capability-catalog.mjs +439 -0
  156. package/scripts/v4-consumer-policy.mjs +4 -0
  157. package/scripts/v4-cross-platform-adopter-qualification.mjs +228 -0
  158. package/scripts/v4-declarative-promotion-admission.mjs +42 -0
  159. package/scripts/v4-publication-rehearsal-fixture.mjs +144 -0
@@ -43,7 +43,39 @@ export const DEV_DELIVERY_QUALIFICATION_RECEIPT_SCHEMA =
43
43
  export const NATIVE_PROOF_BASE_DELTA_SCHEMA =
44
44
  "kungfu.buildchain.native-proof-base-delta/v1";
45
45
  const NATIVE_QUALIFICATION_ROOT_SEMANTICS = "semantic-native-identity-v1";
46
- export function validateActiveDevDeliveryWarrant(queue) {
46
+
47
+ function normalizeQualifiedWarrant(warrant, candidate, allowLegacyV3Readback) {
48
+ const qualifiedV3Readback =
49
+ allowLegacyV3Readback &&
50
+ !warrant.nativeCommandContract &&
51
+ !candidate.nativeCommandContract &&
52
+ !warrant.nativeExecutionReceiptRoot &&
53
+ !warrant.qualificationReceiptRoot;
54
+ warrant.nativeProofRoot = exactRoot(
55
+ warrant.nativeProofRoot,
56
+ "Warrant nativeProofRoot",
57
+ );
58
+ warrant.nativeProofReuseRoot = exactRoot(
59
+ warrant.nativeProofReuseRoot,
60
+ "Warrant nativeProofReuseRoot",
61
+ );
62
+ if (!qualifiedV3Readback) {
63
+ warrant.nativeExecutionReceiptRoot = exactRoot(
64
+ warrant.nativeExecutionReceiptRoot,
65
+ "Warrant nativeExecutionReceiptRoot",
66
+ );
67
+ warrant.qualificationReceiptRoot = exactRoot(
68
+ warrant.qualificationReceiptRoot,
69
+ "Warrant qualificationReceiptRoot",
70
+ );
71
+ }
72
+ warrant.qualifiedAt = timestamp(warrant.qualifiedAt, "Warrant qualifiedAt");
73
+ }
74
+
75
+ export function validateActiveDevDeliveryWarrant(
76
+ queue,
77
+ { allowLegacyV3Readback = false } = {},
78
+ ) {
47
79
  const warrant = queue.activeWarrant;
48
80
  if (warrant.schema !== "kungfu.buildchain.dev-delivery-warrant/v1")
49
81
  throw new Error("active Warrant schema is unsupported");
@@ -68,24 +100,17 @@ export function validateActiveDevDeliveryWarrant(queue) {
68
100
  const phase = historicalPhaseLess ? "legacy-active" : warrant.phase;
69
101
  if (!["legacy-active", "provisional", "qualified"].includes(phase))
70
102
  throw new Error("active Warrant phase is unsupported");
71
- if (warrant.phase === "qualified") {
72
- warrant.nativeProofRoot = exactRoot(
73
- warrant.nativeProofRoot,
74
- "Warrant nativeProofRoot",
75
- );
76
- warrant.nativeProofReuseRoot = exactRoot(
77
- warrant.nativeProofReuseRoot,
78
- "Warrant nativeProofReuseRoot",
79
- );
80
- warrant.nativeExecutionReceiptRoot = exactRoot(
81
- warrant.nativeExecutionReceiptRoot,
82
- "Warrant nativeExecutionReceiptRoot",
83
- );
84
- warrant.qualificationReceiptRoot = exactRoot(
85
- warrant.qualificationReceiptRoot,
86
- "Warrant qualificationReceiptRoot",
103
+ const active = queue.candidates.filter((candidate) =>
104
+ ["selected", "proving", "waiting", "blocked", "qualified"].includes(
105
+ candidate.status,
106
+ ),
107
+ );
108
+ if (active.length !== 1 || active[0].candidateId !== warrant.candidateId)
109
+ throw new Error(
110
+ "exactly one active candidate must match the active Warrant",
87
111
  );
88
- warrant.qualifiedAt = timestamp(warrant.qualifiedAt, "Warrant qualifiedAt");
112
+ if (warrant.phase === "qualified") {
113
+ normalizeQualifiedWarrant(warrant, active[0], allowLegacyV3Readback);
89
114
  } else if (
90
115
  warrant.phase === "provisional" &&
91
116
  (warrant.nativeProofRoot ||
@@ -98,15 +123,6 @@ export function validateActiveDevDeliveryWarrant(queue) {
98
123
  "provisional Warrant cannot carry qualified native evidence",
99
124
  );
100
125
  }
101
- const active = queue.candidates.filter((candidate) =>
102
- ["selected", "proving", "waiting", "blocked", "qualified"].includes(
103
- candidate.status,
104
- ),
105
- );
106
- if (active.length !== 1 || active[0].candidateId !== warrant.candidateId)
107
- throw new Error(
108
- "exactly one active candidate must match the active Warrant",
109
- );
110
126
  if (
111
127
  historicalPhaseLess &&
112
128
  (active[0].environmentRoot ||
@@ -1,13 +1,18 @@
1
1
  import {
2
+ devDeliveryClone as clone,
2
3
  devDeliveryContentRoot,
3
4
  devDeliveryExactRoot as exactRoot,
4
5
  devDeliveryExactSha as exactSha,
5
6
  devDeliveryPositiveInteger as positiveInteger,
6
7
  devDeliveryText as text,
8
+ devDeliveryTimestamp as timestamp,
7
9
  } from "./dev-delivery-common.js";
10
+ import { verifyIntegrationDeliveryProof } from "./dev-delivery-proof.js";
8
11
 
9
12
  export const DEV_DELIVERY_SETTLEMENT_RECEIPT_SCHEMA =
10
13
  "kungfu.buildchain.dev-delivery-settlement-receipt/v1";
14
+ export const DEV_DELIVERY_TERMINAL_EVIDENCE_CORRECTION_SCHEMA =
15
+ "kungfu.buildchain.dev-delivery-terminal-evidence-correction/v1";
11
16
 
12
17
  const PROVIDER_FAILURE_FIELDS = [
13
18
  "transferRoot",
@@ -16,6 +21,233 @@ const PROVIDER_FAILURE_FIELDS = [
16
21
  "sealJobId",
17
22
  ];
18
23
 
24
+ function correctionBody(input) {
25
+ const body = clone(input || {});
26
+ delete body.correctionRoot;
27
+ return body;
28
+ }
29
+
30
+ export function normalizeTerminalEvidenceCorrection(
31
+ input,
32
+ { candidate, repository, protectedBase } = {},
33
+ ) {
34
+ const correction = correctionBody(input);
35
+ if (correction.schema !== DEV_DELIVERY_TERMINAL_EVIDENCE_CORRECTION_SCHEMA) {
36
+ throw new Error("unsupported terminal evidence correction schema");
37
+ }
38
+ correction.candidateId = exactRoot(
39
+ correction.candidateId,
40
+ "terminal evidence correction candidateId",
41
+ );
42
+ correction.pullRequestNumber = positiveInteger(
43
+ correction.pullRequestNumber,
44
+ "terminal evidence correction pullRequestNumber",
45
+ );
46
+ correction.sourceHead = exactSha(
47
+ correction.sourceHead,
48
+ "terminal evidence correction sourceHead",
49
+ );
50
+ correction.outcome = text(correction.outcome);
51
+ correction.priorEvidenceRoot = exactRoot(
52
+ correction.priorEvidenceRoot,
53
+ "terminal evidence correction priorEvidenceRoot",
54
+ );
55
+ correction.correctedAt = timestamp(
56
+ correction.correctedAt,
57
+ "terminal evidence correction correctedAt",
58
+ );
59
+ correction.reason = text(correction.reason);
60
+ if (!correction.reason) {
61
+ throw new Error("terminal evidence correction reason is required");
62
+ }
63
+ const verification = verifyIntegrationDeliveryProof(
64
+ correction.integrationProof,
65
+ );
66
+ if (!verification.ok) {
67
+ throw new Error(
68
+ `terminal evidence correction requires an exact integration proof: ${verification.reason}`,
69
+ );
70
+ }
71
+ if (
72
+ correction.integrationProof.currentBase !==
73
+ correction.integrationProof.mergeGroupHead ||
74
+ correction.integrationProof.replayTree !==
75
+ correction.integrationProof.mergeGroupTree
76
+ ) {
77
+ throw new Error(
78
+ "terminal evidence correction requires exact merge-group commit and tree continuity",
79
+ );
80
+ }
81
+ if (candidate) {
82
+ const checks = {
83
+ candidateId: correction.candidateId === candidate.candidateId,
84
+ pullRequestNumber:
85
+ correction.pullRequestNumber === candidate.pullRequestNumber,
86
+ sourceHead: correction.sourceHead === candidate.sourceHead,
87
+ outcome:
88
+ correction.outcome === candidate.status &&
89
+ correction.outcome === candidate.terminal?.outcome,
90
+ priorEvidenceRoot:
91
+ correction.priorEvidenceRoot === candidate.terminal?.evidenceRoot,
92
+ repository: correction.integrationProof.repository === repository,
93
+ protectedBase:
94
+ correction.integrationProof.protectedBase === protectedBase,
95
+ sourceProofRoot:
96
+ correction.integrationProof.sourceProofRoot ===
97
+ candidate.sourceProofRoot,
98
+ warrantCandidateId:
99
+ correction.integrationProof.warrantCandidateId ===
100
+ candidate.candidateId,
101
+ warrantFencingToken:
102
+ correction.integrationProof.warrantFencingToken ===
103
+ candidate.terminal?.fencingToken,
104
+ warrantGeneration:
105
+ correction.integrationProof.warrantGeneration ===
106
+ candidate.terminal?.leaseGeneration,
107
+ };
108
+ const failed = Object.entries(checks)
109
+ .filter(([, matches]) => !matches)
110
+ .map(([field]) => field);
111
+ if (failed.length > 0) {
112
+ throw new Error(
113
+ `terminal evidence correction identity drift: ${failed.join(", ")}`,
114
+ );
115
+ }
116
+ }
117
+ const correctionRoot = devDeliveryContentRoot(correction);
118
+ if (input?.correctionRoot && input.correctionRoot !== correctionRoot) {
119
+ throw new Error("terminal evidence correction root drift");
120
+ }
121
+ return { ...correction, correctionRoot };
122
+ }
123
+
124
+ export function effectiveTerminalEvidenceRoot(candidate) {
125
+ return (
126
+ candidate?.terminal?.integrationEvidenceCorrection?.integrationProof
127
+ ?.proofRoot ||
128
+ candidate?.terminal?.evidenceRoot ||
129
+ ""
130
+ );
131
+ }
132
+
133
+ export function createTerminalEvidenceCorrection(
134
+ candidate,
135
+ input,
136
+ { repository, protectedBase, now } = {},
137
+ ) {
138
+ return normalizeTerminalEvidenceCorrection(
139
+ {
140
+ schema: DEV_DELIVERY_TERMINAL_EVIDENCE_CORRECTION_SCHEMA,
141
+ candidateId: candidate?.candidateId,
142
+ pullRequestNumber: candidate?.pullRequestNumber,
143
+ sourceHead: candidate?.sourceHead,
144
+ outcome: candidate?.status,
145
+ priorEvidenceRoot: input?.expectedPriorEvidenceRoot,
146
+ integrationProof: input?.integrationProof,
147
+ correctedAt: now,
148
+ reason: input?.reason,
149
+ },
150
+ { candidate, repository, protectedBase },
151
+ );
152
+ }
153
+
154
+ export function createDevDeliveryTerminalEvidenceReconciler({
155
+ normalizeQueue,
156
+ transition,
157
+ }) {
158
+ return function reconcileDevDeliveryTerminalEvidence(
159
+ queueInput,
160
+ input,
161
+ { now = new Date().toISOString() } = {},
162
+ ) {
163
+ const before = normalizeQueue(queueInput);
164
+ const candidate = before.candidates.find(
165
+ (entry) =>
166
+ entry.candidateId === exactRoot(input?.candidateId, "candidateId"),
167
+ );
168
+ if (!candidate)
169
+ throw new Error("terminal evidence candidate does not exist");
170
+ if (candidate.status !== "merged") {
171
+ throw new Error(
172
+ "integration evidence correction requires a merged candidate",
173
+ );
174
+ }
175
+ const existing = candidate.terminal?.integrationEvidenceCorrection;
176
+ const correction = createTerminalEvidenceCorrection(candidate, input, {
177
+ repository: before.repository,
178
+ protectedBase: before.protectedBase,
179
+ now: existing?.correctedAt || timestamp(now, "now"),
180
+ });
181
+ if (existing) {
182
+ if (existing.correctionRoot !== correction.correctionRoot) {
183
+ throw new Error(
184
+ "terminal evidence correction already exists with different evidence",
185
+ );
186
+ }
187
+ const receipt = {
188
+ schema: DEV_DELIVERY_SETTLEMENT_RECEIPT_SCHEMA,
189
+ action: "duplicate-terminal-evidence-correction-noop",
190
+ applicable: true,
191
+ repository: before.repository,
192
+ protectedBase: before.protectedBase,
193
+ candidateId: candidate.candidateId,
194
+ pullRequestNumber: candidate.pullRequestNumber,
195
+ sourceHead: candidate.sourceHead,
196
+ outcome: candidate.status,
197
+ priorEvidenceRoot: candidate.terminal.evidenceRoot,
198
+ evidenceRoot: correction.integrationProof.proofRoot,
199
+ correctionRoot: correction.correctionRoot,
200
+ expectedOldStateRoot: before.stateRoot,
201
+ nextStateRoot: before.stateRoot,
202
+ nextAction:
203
+ "Retain the exact verified integration evidence correction.",
204
+ };
205
+ return {
206
+ queue: before,
207
+ receipt,
208
+ receiptRoot: devDeliveryContentRoot(receipt),
209
+ };
210
+ }
211
+ const transaction = transition(
212
+ before,
213
+ (queue) => {
214
+ const mutable = queue.candidates.find(
215
+ (entry) => entry.candidateId === candidate.candidateId,
216
+ );
217
+ mutable.terminal = {
218
+ ...mutable.terminal,
219
+ integrationEvidenceCorrection: correction,
220
+ };
221
+ return { candidate: mutable };
222
+ },
223
+ correction.correctedAt,
224
+ );
225
+ const receipt = {
226
+ schema: DEV_DELIVERY_SETTLEMENT_RECEIPT_SCHEMA,
227
+ action: "terminal-evidence-corrected",
228
+ applicable: true,
229
+ repository: transaction.after.repository,
230
+ protectedBase: transaction.after.protectedBase,
231
+ candidateId: candidate.candidateId,
232
+ pullRequestNumber: candidate.pullRequestNumber,
233
+ sourceHead: candidate.sourceHead,
234
+ outcome: candidate.status,
235
+ priorEvidenceRoot: candidate.terminal.evidenceRoot,
236
+ evidenceRoot: correction.integrationProof.proofRoot,
237
+ correctionRoot: correction.correctionRoot,
238
+ expectedOldStateRoot: transaction.expectedOldStateRoot,
239
+ nextStateRoot: transaction.after.stateRoot,
240
+ nextAction:
241
+ "Read back the corrected terminal candidate and repeat settlement idempotently.",
242
+ };
243
+ return {
244
+ queue: transaction.after,
245
+ receipt,
246
+ receiptRoot: devDeliveryContentRoot(receipt),
247
+ };
248
+ };
249
+ }
250
+
19
251
  export function normalizeProviderFailureAuthorityBinding(
20
252
  input = {},
21
253
  { required = false } = {},
@@ -56,7 +288,7 @@ function noopReceipt(queue, identity, candidate, action, details = {}) {
56
288
  outcome: identity.outcome,
57
289
  candidateId: candidate?.candidateId || null,
58
290
  evidenceRoot:
59
- candidate?.terminal?.evidenceRoot || identity.evidenceRoot || null,
291
+ effectiveTerminalEvidenceRoot(candidate) || identity.evidenceRoot || null,
60
292
  expectedOldStateRoot: queue.stateRoot,
61
293
  nextStateRoot: queue.stateRoot,
62
294
  nextAction: "No fenced delivery state remains for this terminal event.",
@@ -95,7 +327,7 @@ function settleTerminalCandidate(queue, identity, candidate) {
95
327
  "duplicate terminal event provider failure authority drift",
96
328
  );
97
329
  }
98
- if (candidate.terminal?.evidenceRoot !== identity.evidenceRoot) {
330
+ if (effectiveTerminalEvidenceRoot(candidate) !== identity.evidenceRoot) {
99
331
  throw new Error("duplicate terminal event evidenceRoot drift");
100
332
  }
101
333
  const receipt = noopReceipt(
@@ -103,6 +335,7 @@ function settleTerminalCandidate(queue, identity, candidate) {
103
335
  identity,
104
336
  candidate,
105
337
  "duplicate-terminal-event-noop",
338
+ { successorWake: candidate.terminal?.successorWake || null },
106
339
  );
107
340
  return { queue, receipt, receiptRoot: devDeliveryContentRoot(receipt) };
108
341
  }
@@ -207,7 +440,10 @@ export function createDevDeliveryTerminalSettler({
207
440
  throw new Error("stale fencing token");
208
441
  if (leaseGeneration !== queue.activeWarrant.generation)
209
442
  throw new Error("stale lease generation");
210
- if (identity.outcome === "dequeued") {
443
+ if (
444
+ identity.outcome === "dequeued" &&
445
+ queue.activeWarrant.phase === "provisional"
446
+ ) {
211
447
  return retainDequeuedWarrant(
212
448
  queue,
213
449
  identity,
@@ -19,7 +19,10 @@ import {
19
19
  normalizeNativeCommandContract,
20
20
  validateActiveDevDeliveryWarrant,
21
21
  } from "./dev-delivery-native-proof.js";
22
- import { normalizeProviderFailureAuthorityBinding } from "./dev-delivery-warrant-settlement.js";
22
+ import {
23
+ normalizeProviderFailureAuthorityBinding,
24
+ normalizeTerminalEvidenceCorrection,
25
+ } from "./dev-delivery-warrant-settlement.js";
23
26
  import {
24
27
  compareReleaseBlockerPriority,
25
28
  normalizeReleaseBlockerPriorityClaim,
@@ -51,8 +54,8 @@ export const TERMINAL_STATES = new Set([
51
54
  "terminal-failure",
52
55
  "dequeued",
53
56
  "cancelled",
57
+ "superseded",
54
58
  ]);
55
-
56
59
  export function issueDevDeliveryWarrant(
57
60
  queue,
58
61
  before,
@@ -158,6 +161,21 @@ function normalizePolicy(policy = {}) {
158
161
  emergencyPolicy: text(policy.emergencyPolicy || "reviewed-explicit-only"),
159
162
  };
160
163
  }
164
+
165
+ function lacksLiveNativeProof(candidate, status, allowLegacyV3Readback) {
166
+ const { environmentRoot, nativeCommandContract } = candidate;
167
+ const native =
168
+ candidate.deliveryClass !== "non-native-fast" ||
169
+ environmentRoot ||
170
+ nativeCommandContract;
171
+ return (
172
+ native &&
173
+ (!environmentRoot ||
174
+ (!nativeCommandContract && allowLegacyV3Readback !== true)) &&
175
+ !TERMINAL_STATES.has(status)
176
+ );
177
+ }
178
+
161
179
  function normalizeCandidate(input, expected) {
162
180
  const identity = createDevDeliveryCandidateIdentity(
163
181
  input,
@@ -229,8 +247,18 @@ function normalizeCandidate(input, expected) {
229
247
  "provider failure authority can exist only on terminal-failure state",
230
248
  );
231
249
  }
232
- if (failureAuthority) {
250
+ if (failureAuthority)
233
251
  candidate.terminal = { ...candidate.terminal, ...failureAuthority };
252
+ if (candidate.terminal.integrationEvidenceCorrection) {
253
+ candidate.terminal.integrationEvidenceCorrection =
254
+ normalizeTerminalEvidenceCorrection(
255
+ candidate.terminal.integrationEvidenceCorrection,
256
+ {
257
+ candidate,
258
+ repository: expected.repository,
259
+ protectedBase: expected.protectedBase,
260
+ },
261
+ );
234
262
  }
235
263
  }
236
264
  if (Object.hasOwn(input, "affectedPaths")) {
@@ -246,9 +274,7 @@ function normalizeCandidate(input, expected) {
246
274
  "candidate shardEvidenceRoots",
247
275
  );
248
276
  }
249
- const { environmentRoot: env, nativeCommandContract: cmd } = candidate;
250
- const native = candidate.deliveryClass !== "non-native-fast" || env || cmd;
251
- if (native && (!env || !cmd) && !TERMINAL_STATES.has(status))
277
+ if (lacksLiveNativeProof(candidate, status, expected.allowLegacyV3Readback))
252
278
  throw new Error("live native candidate requires exact native proof");
253
279
  if (Object.hasOwn(input, "releaseBlockerPriority"))
254
280
  candidate.releaseBlockerPriority = normalizeReleaseBlockerPriorityClaim(
@@ -318,13 +344,21 @@ export function normalizeDevDeliveryQueue(input, expected = {}) {
318
344
  "queue fencingCounter",
319
345
  );
320
346
  queue.policy = normalizePolicy(queue.policy);
347
+ const allowLegacyV3Readback =
348
+ expected.allowLegacyV3Readback === true &&
349
+ !(queue.candidates || []).some(
350
+ (candidate) => candidate?.nativeCommandContract,
351
+ ) &&
352
+ !queue.activeWarrant?.nativeCommandContract &&
353
+ !queue.activeWarrant?.nativeExecutionReceiptRoot &&
354
+ !queue.activeWarrant?.qualificationReceiptRoot;
321
355
  queue.candidates = (queue.candidates || []).map((candidate) =>
322
- normalizeCandidate(candidate, queue),
356
+ normalizeCandidate(candidate, { ...queue, allowLegacyV3Readback }),
323
357
  );
324
358
  validateDevDeliveryCandidateChain(queue.candidates, TERMINAL_STATES);
325
359
  queue.updatedAt = timestamp(queue.updatedAt, "queue updatedAt");
326
360
  if (queue.activeWarrant) {
327
- validateActiveDevDeliveryWarrant(queue);
361
+ validateActiveDevDeliveryWarrant(queue, { allowLegacyV3Readback });
328
362
  } else if (
329
363
  queue.candidates.some((candidate) =>
330
364
  ["selected", "proving", "waiting", "blocked", "qualified"].includes(
@@ -544,9 +578,11 @@ function effectivePriority(candidate, policy, now) {
544
578
  }
545
579
  export function rankDevDeliveryCandidates(
546
580
  queueInput,
547
- { now = new Date().toISOString() } = {},
581
+ { now = new Date().toISOString(), allowLegacyV3Readback = false } = {},
548
582
  ) {
549
- const queue = normalizeDevDeliveryQueue(queueInput);
583
+ const queue = normalizeDevDeliveryQueue(queueInput, {
584
+ allowLegacyV3Readback,
585
+ });
550
586
  const currentTime = timestamp(now, "now");
551
587
  return queue.candidates
552
588
  .filter((candidate) => candidate.status === "queued")
@@ -11,7 +11,9 @@ import {
11
11
  createCancelQueuedDevDeliveryCandidate,
12
12
  } from "./dev-delivery-warrant-cancellation.js";
13
13
  import {
14
+ createDevDeliveryTerminalEvidenceReconciler,
14
15
  DEV_DELIVERY_SETTLEMENT_RECEIPT_SCHEMA,
16
+ DEV_DELIVERY_TERMINAL_EVIDENCE_CORRECTION_SCHEMA,
15
17
  createDevDeliveryTerminalSettler,
16
18
  normalizeProviderFailureAuthorityBinding,
17
19
  } from "./dev-delivery-warrant-settlement.js";
@@ -91,6 +93,7 @@ export {
91
93
  };
92
94
  export { DEV_DELIVERY_CANCELLATION_RECEIPT_SCHEMA };
93
95
  export { DEV_DELIVERY_SETTLEMENT_RECEIPT_SCHEMA };
96
+ export { DEV_DELIVERY_TERMINAL_EVIDENCE_CORRECTION_SCHEMA };
94
97
 
95
98
  export function selectDevDeliveryWarrant(
96
99
  queueInput,
@@ -437,6 +440,10 @@ export function closeDevDeliveryWarrant(
437
440
  ...(failureAuthority || {}),
438
441
  };
439
442
  queue.activeWarrant = null;
443
+ candidate.terminal.successorWake = createDevDeliverySuccessorWake(
444
+ queue,
445
+ currentTime,
446
+ );
440
447
  return { candidate, active };
441
448
  },
442
449
  currentTime,
@@ -453,10 +460,7 @@ export function closeDevDeliveryWarrant(
453
460
  ...(failureAuthority || {}),
454
461
  expectedOldStateRoot: transaction.expectedOldStateRoot,
455
462
  nextStateRoot: transaction.after.stateRoot,
456
- successorWake: createDevDeliverySuccessorWake(
457
- transaction.after,
458
- currentTime,
459
- ),
463
+ successorWake: transaction.result.candidate.terminal.successorWake,
460
464
  nextAction: "Select the next queued candidate, if any.",
461
465
  };
462
466
  return {
@@ -514,16 +518,26 @@ export const settleDevDeliveryTerminalEvent = createDevDeliveryTerminalSettler({
514
518
  cancelQueued: cancelQueuedDevDeliveryCandidate,
515
519
  terminalStates: TERMINAL_STATES,
516
520
  });
521
+ export const reconcileDevDeliveryTerminalEvidence =
522
+ createDevDeliveryTerminalEvidenceReconciler({
523
+ normalizeQueue: normalizeDevDeliveryQueue,
524
+ transition,
525
+ });
517
526
  export function observeDevDeliveryQueue(
518
527
  queueInput,
519
- { now = new Date().toISOString() } = {},
528
+ { now = new Date().toISOString(), allowLegacyV3Readback = false } = {},
520
529
  ) {
521
- const queue = normalizeDevDeliveryQueue(queueInput);
530
+ const queue = normalizeDevDeliveryQueue(queueInput, {
531
+ allowLegacyV3Readback,
532
+ });
522
533
  const currentTime = timestamp(now, "now");
523
534
  const states = {};
524
535
  for (const candidate of queue.candidates)
525
536
  states[candidate.status] = (states[candidate.status] || 0) + 1;
526
- const queued = rankDevDeliveryCandidates(queue, { now: currentTime });
537
+ const queued = rankDevDeliveryCandidates(queue, {
538
+ now: currentTime,
539
+ allowLegacyV3Readback,
540
+ });
527
541
  return {
528
542
  schema: "kungfu.buildchain.dev-delivery-queue-observation/v1",
529
543
  repository: queue.repository,
@@ -538,6 +552,14 @@ export function observeDevDeliveryQueue(
538
552
  ) || null
539
553
  : null,
540
554
  states,
555
+ pendingSuccessorWakes: queue.candidates
556
+ .filter((candidate) => candidate.terminal?.successorWake)
557
+ .map((candidate) => ({
558
+ pullRequestNumber: candidate.pullRequestNumber,
559
+ sourceHead: candidate.sourceHead,
560
+ outcome: candidate.status,
561
+ successorWake: candidate.terminal.successorWake,
562
+ })),
541
563
  queued: queued.map((entry, index) => ({
542
564
  position: index + 1,
543
565
  candidateId: entry.candidate.candidateId,
@@ -110,12 +110,15 @@ const PUBLIC_REPOSITORY_TARGETS = Object.freeze({
110
110
  "site-libkungfu-dev": [
111
111
  target("main", [check("web-surface / Record web-surface controller receipt")], false),
112
112
  ],
113
+ taolu: ["dev", "alpha", "release"].map((family) => target(`${family}/v1/v1.0`,
114
+ [check("build / Summarize build contract"), check("stage-capsule / Reconcile exact three-platform evidence")], false)),
113
115
  });
114
116
  const PUBLIC_REPOSITORIES = Object.freeze(Object.keys(PUBLIC_REPOSITORY_TARGETS).sort());
115
117
  const PROTECTED_AUTHORITY_PATHS = Object.freeze([
116
118
  ".github/CODEOWNERS",
117
119
  ".github/workflows/.publication-authority.yml",
118
120
  ".github/workflows/.release-candidate-promote.yml",
121
+ ".github/workflows/buildchain-ref-promotion-recovery.yml",
119
122
  ".github/workflows/buildchain-ref-promotion.yml",
120
123
  ".github/workflows/github-governance-audit.yml",
121
124
  ".github/workflows/paper-release-sealed.yml",
@@ -496,10 +499,8 @@ export function createBuildchainGithubGovernanceAuthority() {
496
499
  privateRepositoryPolicy: "excluded-from-managed-zone",
497
500
  unknownRepositoryPolicy: "non-authoritative-until-explicit-admission",
498
501
  baseline: {
499
- observedOn: "2026-07-30",
500
- repositoryCount: 16,
501
- publicCount: 16,
502
- privateCount: 0,
502
+ observedOn: "2026-08-28", repositoryCount: 17,
503
+ publicCount: 17, privateCount: 0,
503
504
  authoritativePublicTargetCount: Object.values(PUBLIC_REPOSITORY_TARGETS)
504
505
  .reduce((count, targets) => count + targets.length, 0),
505
506
  },
@@ -139,6 +139,11 @@ export {
139
139
  normalizeCandidateTimelineEvent,
140
140
  } from "./candidate-timeline.js";
141
141
 
142
+ export {
143
+ CI_LANE_CHANGE_BUDGET_CONTRACT,
144
+ evaluateCiLaneChangeBudget,
145
+ } from "./ci-lane-change-budget.js";
146
+
142
147
  export {
143
148
  CHANNEL_CANDIDATE_DECISION_SCHEMA,
144
149
  channelCandidateSourceLockRef,
@@ -641,6 +646,7 @@ export {
641
646
  export * from "./release-propagation.js";
642
647
  export * from "./v4-floating-consumer-policy.js";
643
648
  export * from "./v4-runtime-ref-resume-authority.js";
649
+ export * from "./v4-publication-qualification.js";
644
650
 
645
651
  export {
646
652
  RELEASE_ACTIVATION_CONTRACT,