@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.
- package/README.md +9 -6
- package/actions/release-tail/README.md +8 -0
- package/actions/v4-release-candidate-promote/README.md +3 -0
- package/architecture/agent-change-map.md +1015 -0
- package/architecture/ci-lane-change-budget.json +256 -0
- package/architecture/decisions/0004-v4-declarative-release-tail.md +47 -0
- package/architecture/internal-capabilities.json +220 -15
- package/architecture/maintainability-debt.json +3229 -0
- package/architecture/maintainability-policy.json +489 -132
- package/architecture/release-tail-contract-inventory.json +5 -2
- package/architecture/v3-core-mechanism-inventory.json +4 -3
- package/architecture/v3-v4-capability-closure.md +59 -0
- package/architecture/v3-v4-live-capability-inventory.json +102404 -0
- package/architecture/v4-adopter-delivery-parity.json +32 -5
- package/architecture/v4-cross-platform-adopter-qualification.json +52 -0
- package/architecture/v4-delivery-warrant-shadow-fixtures.json +3 -3
- package/architecture/v4-floating-consumer-policy.json +6 -0
- package/architecture/v4-publication-rehearsal-parity.json +84 -0
- package/architecture/v4-runtime-semantic-closure.json +710 -0
- package/bin/buildchain.mjs +7 -1
- package/bin/internal/adopter-delivery-cli.mjs +70 -0
- package/bin/internal/command-registry.mjs +1 -0
- package/bin/internal/trust-release-release-handlers.mjs +5 -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-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 +1 -1
- package/contracts/v4-adopter-delivery-v1.schema.json +81 -0
- package/contracts/v4-floating-consumer-policy-receipt-v1.schema.json +4 -2
- package/contracts/v4-publication-qualification-v1.schema.json +51 -0
- package/contracts/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
- package/dist/site/agent-index.json +4 -0
- package/dist/site/artifact-schemas.json +8 -0
- package/dist/site/buildchain-contract.json +125 -34
- package/dist/site/buildchain-site.json +308 -33
- package/dist/site/capability-registry.json +13 -12
- package/dist/site/cli-registry.json +57 -2
- package/dist/site/controller-registry.json +41 -5
- package/dist/site/kfd-claims.json +438 -24
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +22 -7
- package/dist/site/node-api-registry.json +12843 -9314
- package/dist/site/page-registry.json +288 -21
- package/dist/site/public-surface-audit.json +281 -21
- package/dist/site/publication-authority-registry.json +66 -8
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +20 -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-publication-qualification-v1.schema.json +51 -0
- package/dist/site/schemas/v4-publication-rehearsal-capsule-v1.schema.json +233 -0
- package/dist/site/site-manifest.json +19 -11
- package/dist/site/workflow-registry.json +195 -17
- package/docs/MAP.md +4 -2
- package/docs/cli-reference.md +70 -2
- package/docs/cli.md +8 -0
- package/docs/dev-delivery-warrant.md +34 -10
- package/docs/node-api-reference.md +524 -279
- package/docs/publish-transaction.md +11 -4
- package/docs/release-candidate.md +7 -0
- package/docs/release-tail-provider-plane.md +30 -0
- package/docs/v4-adopter-delivery.md +152 -0
- package/docs/v4-declarative-release-tail-migration.md +43 -0
- package/docs/v4-publication-rehearsal.md +130 -0
- package/package.json +24 -4
- package/packages/core/adopter-delivery-passport.js +295 -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 +1 -0
- package/packages/core/buildchain-config.js +84 -0
- package/packages/core/buildchain-contract.js +31 -1
- 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 +2 -0
- package/packages/core/ci-lane-change-budget.js +247 -0
- package/packages/core/dev-delivery-native-proof.js +43 -27
- package/packages/core/dev-delivery-warrant-settlement.js +239 -3
- package/packages/core/dev-delivery-warrant-state.js +46 -10
- package/packages/core/dev-delivery-warrant.js +29 -7
- package/packages/core/github-governance-authority.js +5 -4
- package/packages/core/index.js +6 -0
- package/packages/core/legacy-kfd-adopter-driver.js +167 -0
- package/packages/core/paper-scaffold-content.js +401 -0
- package/packages/core/paper.js +12 -378
- package/packages/core/publication-control-plane-audit.js +135 -111
- package/packages/core/publication-rehearsal-projection.js +104 -0
- package/packages/core/publication-rehearsal-runtime.js +190 -0
- package/packages/core/published-delivery-authority.js +266 -0
- package/packages/core/release-candidate-recovery.js +71 -15
- package/packages/core/release-candidate.js +2 -2
- package/packages/core/release-passport.js +95 -170
- package/packages/core/v4-adopter-delivery-parity.js +3 -3
- package/packages/core/v4-adopter-delivery.js +359 -0
- package/packages/core/v4-cross-platform-adopter-qualification.js +343 -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 +139 -35
- package/packages/core/v4-floating-consumer-release-passport.js +154 -8
- package/packages/core/v4-publication-qualification.js +222 -0
- 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/workflow-yaml-contract.js +24 -2
- package/scripts/artifact-signing-controller-core.mjs +1 -1
- package/scripts/audit-publication-control-plane.mjs +17 -17
- package/scripts/buildchain-cli-help.mjs +13 -0
- package/scripts/check-ci-lane-change-budget.mjs +100 -0
- package/scripts/check-internal-architecture.mjs +23 -3
- package/scripts/check-inventory.mjs +24 -6
- package/scripts/check-maintainability.mjs +145 -4
- package/scripts/check-project-cut-merge-queue-admission.mjs +87 -0
- package/scripts/check-v3-v4-capability-inventory.mjs +574 -0
- package/scripts/check-v4-floating-consumer-policy-contract.mjs +30 -4
- package/scripts/check-v4-runtime-semantic-closure.mjs +266 -0
- 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-agent-change-map.mjs +118 -0
- package/scripts/generate-channel-promotion-workflow.mjs +2 -2
- package/scripts/generate-release-candidate-passport.mjs +177 -0
- package/scripts/generate-site-bundle.mjs +36 -0
- package/scripts/maintainability-domain-metrics.mjs +237 -0
- package/scripts/maintainability-governance.mjs +473 -0
- package/scripts/maintainability-metrics.mjs +28 -6
- package/scripts/project-cut-merge-queue-admission.mjs +394 -0
- package/scripts/promotion-channel-router.mjs +4 -4
- package/scripts/promotion-routing-evidence.mjs +35 -6
- package/scripts/release-candidate-anchor-provenance.mjs +99 -0
- package/scripts/release-candidate-resolver.mjs +44 -0
- package/scripts/release-line-policy.mjs +25 -15
- package/scripts/release-tail.mjs +68 -3
- package/scripts/resume-from-candidate-run.mjs +595 -65
- package/scripts/run-lifecycle-core.mjs +341 -376
- package/scripts/site-capability-metadata.mjs +21 -0
- package/scripts/stable-candidate-qualification.mjs +9 -10
- package/scripts/v3-v4-capability-catalog.mjs +439 -0
- package/scripts/v4-consumer-policy.mjs +4 -0
- package/scripts/v4-cross-platform-adopter-qualification.mjs +228 -0
- package/scripts/v4-declarative-promotion-admission.mjs +42 -0
- 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
|
-
|
|
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
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
"Warrant
|
|
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
|
-
|
|
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
|
|
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(
|
|
@@ -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 (
|
|
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 {
|
|
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,
|
|
@@ -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:
|
|
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, {
|
|
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-
|
|
500
|
-
|
|
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
|
},
|
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,
|
|
@@ -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,
|