@kungfu-tech/buildchain 4.0.1-alpha.4 → 4.0.1-alpha.41
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/actions/release-tail/README.md +8 -0
- package/architecture/ci-lane-change-budget.json +187 -0
- package/architecture/decisions/0002-next-development-transition.md +101 -0
- package/architecture/internal-capabilities.json +117 -8
- package/architecture/maintainability-policy.json +43 -25
- package/architecture/release-tail-contract-inventory.json +5 -2
- package/architecture/v3-core-mechanism-inventory.json +89 -0
- package/architecture/v4-adopter-delivery-parity.json +32 -5
- package/architecture/v4-capability-state-machine-manifest.json +73 -0
- package/architecture/v4-compatibility-facts-parity.json +77 -0
- package/architecture/v4-floating-consumer-policy.json +6 -0
- package/architecture/v4-next-development-parity.json +192 -0
- package/architecture/v4-publication-rehearsal-parity.json +84 -0
- package/architecture/v4-release-train-parity.json +1 -0
- package/architecture/v4-tail-reseal-parity.json +150 -0
- package/bin/buildchain.mjs +23 -2
- package/bin/internal/adopter-delivery-cli.mjs +70 -0
- package/bin/internal/command-registry.mjs +3 -0
- package/bin/internal/compatibility-facts-cli.mjs +101 -0
- package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +47 -0
- package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +47 -0
- package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +40 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/archive-template.json +19 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/bootstrap-positive.json +93 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/gate-positive.json +29 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/gate-unknown-selector.json +26 -0
- package/contracts/fixtures/v4-adopter-delivery-v1/offline-vectors.json +50 -0
- package/contracts/fixtures/v4-compatibility-facts-v1/shared.json +1129 -0
- package/contracts/fixtures/v4-floating-consumer-policy-v1/cases.json +7 -1
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/artifacts/product.bin +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/config/buildchain.toml +5 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/release-activation.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/documents/signed-channel.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/evidence/qualification.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/candidate.json +5 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/candidate/manifests/release-passport.json +1 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/capsule.json +707 -0
- package/contracts/fixtures/v4-publication-rehearsal-v1/offline-vectors.json +27 -0
- package/contracts/fixtures/v4-tail-reseal-v1/valid.json +229 -0
- package/contracts/next-development-request-v1.schema.json +66 -0
- package/contracts/next-development-transition-v1.schema.json +292 -0
- package/contracts/v4-adopter-delivery-v1.schema.json +81 -0
- package/contracts/v4-compatibility-facts-v1.schema.json +230 -0
- package/contracts/v4-floating-consumer-policy-receipt-v1.schema.json +4 -2
- package/contracts/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
- package/contracts/v4-tail-reseal-v1.schema.json +276 -0
- package/dist/site/agent-index.json +4 -0
- package/dist/site/artifact-schemas.json +8 -0
- package/dist/site/buildchain-contract.json +1393 -28
- package/dist/site/buildchain-site.json +477 -32
- package/dist/site/capability-registry.json +17 -14
- package/dist/site/cli-registry.json +159 -1
- package/dist/site/kfd-claims.json +455 -15
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +53 -7
- package/dist/site/node-api-registry.json +14008 -9602
- package/dist/site/page-registry.json +442 -21
- package/dist/site/public-surface-audit.json +440 -11
- package/dist/site/publication-authority-registry.json +44 -8
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +22 -0
- package/dist/site/schemas/release-tail-capabilities-v1.schema.json +199 -0
- package/dist/site/schemas/v4-adopter-delivery-v1.schema.json +81 -0
- package/dist/site/schemas/v4-compatibility-facts-v1.schema.json +230 -0
- package/dist/site/schemas/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
- package/dist/site/site-manifest.json +35 -11
- package/dist/site/workflow-registry.json +142 -8
- package/docs/MAP.md +7 -2
- package/docs/cli-reference.md +193 -0
- package/docs/cli.md +8 -0
- package/docs/dev-alpha-candidate-patrol.md +8 -0
- package/docs/dev-delivery-warrant.md +22 -1
- package/docs/next-development-transition.md +118 -0
- package/docs/node-api-reference.md +583 -288
- package/docs/release-candidate.md +7 -0
- package/docs/release-tail-provider-plane.md +30 -0
- package/docs/v4-adopter-delivery.md +133 -0
- package/docs/v4-compatibility-facts.md +91 -0
- package/docs/v4-publication-rehearsal.md +130 -0
- package/docs/v4-tail-reseal.md +73 -0
- package/docs/versioning.md +4 -3
- package/package.json +30 -6
- package/packages/core/adopter-delivery-passport.js +259 -0
- package/packages/core/adopter-delivery-vectors.js +158 -0
- package/packages/core/adopter-delivery-vectors.json +77 -0
- package/packages/core/buildchain-agent-manuals.js +3 -0
- package/packages/core/buildchain-compatibility-authority.js +336 -0
- package/packages/core/buildchain-compatibility-fact.js +394 -0
- package/packages/core/buildchain-compatibility-facts.json +217 -0
- package/packages/core/buildchain-compatibility-proof.js +566 -0
- package/packages/core/buildchain-config.js +84 -0
- package/packages/core/buildchain-contract.js +93 -141
- package/packages/core/buildchain-delivery-bootstrap.js +240 -0
- package/packages/core/buildchain-delivery-infrastructure.js +164 -0
- package/packages/core/buildchain-delivery-self-dogfood.js +395 -0
- package/packages/core/buildchain-publication-authority.js +1 -0
- package/packages/core/channel-candidate.js +8 -0
- package/packages/core/channel-promotion-baseline.js +55 -0
- package/packages/core/ci-lane-change-budget.js +247 -0
- package/packages/core/dev-alpha-candidate-selection.js +10 -2
- package/packages/core/dev-delivery-execution-transfer.js +21 -1
- package/packages/core/dev-delivery-native-proof.js +43 -27
- package/packages/core/dev-delivery-process-boundary.js +19 -6
- package/packages/core/dev-delivery-provider-heartbeat.js +18 -6
- package/packages/core/dev-delivery-warrant-settlement.js +234 -2
- package/packages/core/dev-delivery-warrant-state.js +46 -10
- package/packages/core/dev-delivery-warrant.js +16 -3
- package/packages/core/github-governance-authority.js +1 -0
- package/packages/core/index.js +5 -0
- package/packages/core/kungfu-temporal-fact.js +557 -0
- package/packages/core/legacy-kfd-adopter-driver.js +167 -0
- package/packages/core/next-development-candidate-reservation.js +186 -0
- package/packages/core/next-development-controller.js +728 -0
- package/packages/core/next-development-projection.js +287 -0
- package/packages/core/next-development-transition.js +738 -0
- package/packages/core/paper-agent-entry.js +11 -5
- package/packages/core/paper.js +16 -5
- package/packages/core/published-delivery-authority.js +266 -0
- package/packages/core/release-candidate-recovery.js +70 -15
- package/packages/core/release-candidate.js +2 -2
- package/packages/core/release-passport.js +36 -9
- package/packages/core/v4-adopter-delivery-parity.js +3 -3
- package/packages/core/v4-adopter-delivery.js +359 -0
- package/packages/core/v4-canonical-contracts.js +5 -0
- package/packages/core/v4-delivery-warrant-read-candidate.js +10 -3
- package/packages/core/v4-floating-consumer-evidence.js +18 -4
- package/packages/core/v4-floating-consumer-policy.js +143 -20
- package/packages/core/v4-floating-consumer-release-passport.js +35 -8
- package/packages/core/v4-publication-rehearsal-capsule.js +468 -0
- package/packages/core/v4-publication-rehearsal-provider-bindings.js +212 -0
- package/packages/core/v4-publication-rehearsal.js +481 -0
- package/packages/core/v4-tail-reseal-contract.js +26 -0
- package/packages/core/v4-tail-reseal-github.js +178 -0
- package/packages/core/v4-tail-reseal-receipt.js +225 -0
- package/packages/core/v4-tail-reseal.js +594 -0
- package/packages/core/workflow-yaml-contract.js +24 -2
- package/scripts/artifact-signing-controller-core.mjs +1 -1
- package/scripts/buildchain-cli-help.mjs +30 -0
- package/scripts/check-ci-lane-change-budget.mjs +100 -0
- package/scripts/check-inventory.mjs +14 -3
- package/scripts/check-project-cut-merge-queue-admission.mjs +87 -0
- package/scripts/check-v4-floating-consumer-policy-contract.mjs +23 -4
- package/scripts/dev-alpha-candidate-patrol.mjs +22 -1
- package/scripts/dev-delivery-source-proof-replay.mjs +153 -0
- package/scripts/dev-delivery-source-proof-reuse.mjs +13 -97
- package/scripts/dev-delivery-warrant-options.mjs +27 -11
- package/scripts/dev-delivery-warrant-store.mjs +10 -6
- package/scripts/dev-delivery-warrant.mjs +50 -6
- package/scripts/dev-pr-auto-merge.mjs +25 -11
- package/scripts/dev-pr-delivery-warrant.mjs +45 -0
- package/scripts/dev-pr-prequeue-guard.mjs +0 -18
- package/scripts/dev-qualification-patrol.mjs +9 -9
- package/scripts/dispatch-artifact-signing-authority.mjs +1 -1
- package/scripts/generate-channel-promotion-workflow.mjs +2 -2
- package/scripts/generate-next-development-guidance.mjs +49 -0
- package/scripts/generate-release-candidate-passport.mjs +152 -0
- package/scripts/generate-site-bundle.mjs +46 -3
- package/scripts/init-repo.mjs +22 -4
- package/scripts/next-development-self-dogfood-harness.mjs +460 -0
- package/scripts/next-development-self-dogfood.mjs +597 -0
- package/scripts/next-development-transition.mjs +47 -0
- package/scripts/project-cut-merge-queue-admission.mjs +394 -0
- package/scripts/promotion-channel-router.mjs +4 -4
- package/scripts/release-candidate-anchor-provenance.mjs +99 -0
- package/scripts/release-tail.mjs +51 -3
- package/scripts/resume-from-candidate-run.mjs +595 -65
- package/scripts/site-capability-metadata.mjs +29 -0
- package/scripts/stable-candidate-qualification.mjs +9 -10
- package/scripts/v4-consumer-policy.mjs +5 -5
- package/scripts/v4-publication-rehearsal-fixture.mjs +144 -0
- package/scripts/v4-tail-reseal-macos-rehearsal.mjs +134 -0
- package/scripts/v4-tail-reseal.mjs +416 -0
|
@@ -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
|
|
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
|
|
330
|
+
if (effectiveTerminalEvidenceRoot(candidate) !== identity.evidenceRoot) {
|
|
99
331
|
throw new Error("duplicate terminal event evidenceRoot drift");
|
|
100
332
|
}
|
|
101
333
|
const receipt = noopReceipt(
|
|
@@ -19,7 +19,10 @@ import {
|
|
|
19
19
|
normalizeNativeCommandContract,
|
|
20
20
|
validateActiveDevDeliveryWarrant,
|
|
21
21
|
} from "./dev-delivery-native-proof.js";
|
|
22
|
-
import {
|
|
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
|
-
|
|
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,
|
|
@@ -514,16 +517,26 @@ export const settleDevDeliveryTerminalEvent = createDevDeliveryTerminalSettler({
|
|
|
514
517
|
cancelQueued: cancelQueuedDevDeliveryCandidate,
|
|
515
518
|
terminalStates: TERMINAL_STATES,
|
|
516
519
|
});
|
|
520
|
+
export const reconcileDevDeliveryTerminalEvidence =
|
|
521
|
+
createDevDeliveryTerminalEvidenceReconciler({
|
|
522
|
+
normalizeQueue: normalizeDevDeliveryQueue,
|
|
523
|
+
transition,
|
|
524
|
+
});
|
|
517
525
|
export function observeDevDeliveryQueue(
|
|
518
526
|
queueInput,
|
|
519
|
-
{ now = new Date().toISOString() } = {},
|
|
527
|
+
{ now = new Date().toISOString(), allowLegacyV3Readback = false } = {},
|
|
520
528
|
) {
|
|
521
|
-
const queue = normalizeDevDeliveryQueue(queueInput
|
|
529
|
+
const queue = normalizeDevDeliveryQueue(queueInput, {
|
|
530
|
+
allowLegacyV3Readback,
|
|
531
|
+
});
|
|
522
532
|
const currentTime = timestamp(now, "now");
|
|
523
533
|
const states = {};
|
|
524
534
|
for (const candidate of queue.candidates)
|
|
525
535
|
states[candidate.status] = (states[candidate.status] || 0) + 1;
|
|
526
|
-
const queued = rankDevDeliveryCandidates(queue, {
|
|
536
|
+
const queued = rankDevDeliveryCandidates(queue, {
|
|
537
|
+
now: currentTime,
|
|
538
|
+
allowLegacyV3Readback,
|
|
539
|
+
});
|
|
527
540
|
return {
|
|
528
541
|
schema: "kungfu.buildchain.dev-delivery-queue-observation/v1",
|
|
529
542
|
repository: queue.repository,
|
|
@@ -116,6 +116,7 @@ const PROTECTED_AUTHORITY_PATHS = Object.freeze([
|
|
|
116
116
|
".github/CODEOWNERS",
|
|
117
117
|
".github/workflows/.publication-authority.yml",
|
|
118
118
|
".github/workflows/.release-candidate-promote.yml",
|
|
119
|
+
".github/workflows/buildchain-ref-promotion-recovery.yml",
|
|
119
120
|
".github/workflows/buildchain-ref-promotion.yml",
|
|
120
121
|
".github/workflows/github-governance-audit.yml",
|
|
121
122
|
".github/workflows/paper-release-sealed.yml",
|
package/packages/core/index.js
CHANGED
|
@@ -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,
|