@kungfu-tech/buildchain 4.0.1-alpha.2 → 4.0.1-alpha.21
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/decisions/0003-two-phase-delivery-warrant.md +152 -0
- package/architecture/internal-capabilities.json +211 -8
- package/architecture/maintainability-policy.json +113 -28
- package/architecture/release-tail-contract-inventory.json +5 -2
- package/architecture/v3-core-mechanism-inventory.json +91 -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-delivery-authority-parity.json +250 -0
- package/architecture/v4-delivery-warrant-shadow-fixtures.json +41 -9
- 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 +32 -3
- 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/dev-delivery-authority-v2.schema.json +662 -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 +5 -0
- package/dist/site/artifact-schemas.json +10 -0
- package/dist/site/buildchain-contract.json +1475 -27
- package/dist/site/buildchain-site.json +627 -31
- package/dist/site/capability-registry.json +17 -14
- package/dist/site/cli-registry.json +205 -3
- package/dist/site/kfd-claims.json +490 -16
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +52 -6
- package/dist/site/node-api-registry.json +14736 -8851
- package/dist/site/page-registry.json +593 -21
- package/dist/site/public-surface-audit.json +837 -48
- package/dist/site/publication-authority-registry.json +44 -8
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +24 -0
- package/dist/site/schemas/dev-delivery-authority-v2.schema.json +662 -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 +34 -10
- package/dist/site/workflow-registry.json +160 -10
- package/docs/MAP.md +8 -2
- package/docs/cli-reference.md +404 -13
- package/docs/cli.md +8 -0
- package/docs/dev-alpha-candidate-patrol.md +8 -0
- package/docs/dev-delivery-qualification-landing-adr.md +251 -0
- package/docs/dev-delivery-warrant.md +351 -38
- package/docs/next-development-transition.md +118 -0
- package/docs/node-api-reference.md +646 -293
- 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 +34 -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 +96 -143
- 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-authority-candidate.js +270 -0
- package/packages/core/dev-delivery-authority-evidence.js +146 -0
- package/packages/core/dev-delivery-authority-landing.js +461 -0
- package/packages/core/dev-delivery-authority-observation.js +48 -0
- package/packages/core/dev-delivery-authority-qualification.js +591 -0
- package/packages/core/dev-delivery-authority-settlement.js +213 -0
- package/packages/core/dev-delivery-authority-state.js +583 -0
- package/packages/core/dev-delivery-candidate-identity.js +13 -0
- package/packages/core/dev-delivery-contract-surface.js +76 -0
- package/packages/core/dev-delivery-execution-failure.js +133 -0
- package/packages/core/dev-delivery-execution-transfer.js +592 -0
- package/packages/core/dev-delivery-landing-admission-core.js +119 -0
- package/packages/core/dev-delivery-landing-readback.js +598 -0
- package/packages/core/dev-delivery-landing-terminal-evidence.js +271 -0
- package/packages/core/dev-delivery-landing-testing-port.js +6 -0
- package/packages/core/dev-delivery-native-execution.js +110 -0
- package/packages/core/dev-delivery-native-proof.js +562 -0
- package/packages/core/dev-delivery-process-boundary.js +563 -0
- package/packages/core/dev-delivery-provider-attempt.js +127 -0
- package/packages/core/dev-delivery-provider-heartbeat.js +382 -0
- package/packages/core/dev-delivery-warrant-cancellation.js +1 -0
- package/packages/core/dev-delivery-warrant-qualification.js +145 -0
- package/packages/core/dev-delivery-warrant-settlement.js +237 -36
- package/packages/core/dev-delivery-warrant-state.js +587 -0
- package/packages/core/dev-delivery-warrant.js +328 -370
- 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 +32 -5
- 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/buildchain-cli-help.mjs +41 -2
- package/scripts/check-ci-lane-change-budget.mjs +100 -0
- package/scripts/check-inventory.mjs +14 -3
- package/scripts/check-v4-floating-consumer-policy-contract.mjs +23 -4
- package/scripts/dev-alpha-candidate-patrol.mjs +22 -1
- package/scripts/dev-delivery-authority-command-adapters.mjs +206 -0
- package/scripts/dev-delivery-authority-provider.mjs +28 -0
- package/scripts/dev-delivery-authority.mjs +490 -0
- package/scripts/dev-delivery-native-run.mjs +177 -0
- package/scripts/dev-delivery-process-boundary.mjs +260 -0
- package/scripts/dev-delivery-proof.mjs +67 -2
- package/scripts/dev-delivery-provider-heartbeat.mjs +215 -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-two-phase-resume.mjs +345 -0
- package/scripts/dev-delivery-two-phase.mjs +573 -0
- package/scripts/dev-delivery-warrant-options.mjs +266 -0
- package/scripts/dev-delivery-warrant-store.mjs +231 -0
- package/scripts/dev-delivery-warrant.mjs +232 -194
- package/scripts/dev-pr-auto-merge.mjs +1 -1
- package/scripts/dev-pr-delivery-warrant.mjs +11 -0
- 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 +69 -4
- 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/npm-publish-transaction.mjs +2 -2
- 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/release-train-self-dogfood.mjs +94 -92
- package/scripts/resume-from-candidate-run.mjs +557 -30
- package/scripts/site-capability-metadata.mjs +41 -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
- package/templates/native-dev-delivery.yml +143 -0
|
@@ -0,0 +1,259 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ADOPTER_DELIVERY_GATE_RESULT_CONTRACT,
|
|
3
|
+
adopterDeliveryGateDigest,
|
|
4
|
+
} from "./adopter-delivery-gate.js";
|
|
5
|
+
|
|
6
|
+
export const ADOPTER_DELIVERY_PASSPORT_BINDING_CONTRACT =
|
|
7
|
+
"kungfu-buildchain-adopter-delivery-passport-binding";
|
|
8
|
+
|
|
9
|
+
const ROOT_PATTERN = /^sha256:[0-9a-f]{64}$/;
|
|
10
|
+
|
|
11
|
+
function issue(code, message, details = {}) {
|
|
12
|
+
return { code, message, details };
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function validateRootedJson(value, rootField, code, label) {
|
|
16
|
+
const root = value?.[rootField];
|
|
17
|
+
if (!ROOT_PATTERN.test(root ?? "")) {
|
|
18
|
+
return [issue(code, `${label} must be a canonical sha256 root`)];
|
|
19
|
+
}
|
|
20
|
+
try {
|
|
21
|
+
const preimage = structuredClone(value);
|
|
22
|
+
delete preimage[rootField];
|
|
23
|
+
return adopterDeliveryGateDigest(preimage) === root
|
|
24
|
+
? []
|
|
25
|
+
: [issue(code, `${label} does not match its exact JSON closure`)];
|
|
26
|
+
} catch {
|
|
27
|
+
return [issue(code, `${label} requires finite acyclic JSON`)];
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
function validateGateIdentity(result) {
|
|
32
|
+
const issues = [];
|
|
33
|
+
if (
|
|
34
|
+
result.schemaVersion !== 1 ||
|
|
35
|
+
result.contract !== ADOPTER_DELIVERY_GATE_RESULT_CONTRACT
|
|
36
|
+
) {
|
|
37
|
+
issues.push(
|
|
38
|
+
issue(
|
|
39
|
+
"adopterDelivery.gateResult.contract",
|
|
40
|
+
"adopter delivery gate result contract is unsupported",
|
|
41
|
+
),
|
|
42
|
+
);
|
|
43
|
+
}
|
|
44
|
+
if (
|
|
45
|
+
!result.project ||
|
|
46
|
+
!result.artifact ||
|
|
47
|
+
!result.protocol ||
|
|
48
|
+
!result.artifactProfile
|
|
49
|
+
) {
|
|
50
|
+
issues.push(
|
|
51
|
+
issue(
|
|
52
|
+
"adopterDelivery.gateResult.closure",
|
|
53
|
+
"gate result must retain project, artifact, protocol, and artifact-profile bindings",
|
|
54
|
+
),
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
if (!ROOT_PATTERN.test(result.artifact?.root ?? "")) {
|
|
58
|
+
issues.push(
|
|
59
|
+
issue(
|
|
60
|
+
"adopterDelivery.gateResult.artifact.root",
|
|
61
|
+
"delivery artifact root must be a canonical sha256 root",
|
|
62
|
+
),
|
|
63
|
+
);
|
|
64
|
+
}
|
|
65
|
+
if (result.qualifying !== false || result.selfCertified !== false) {
|
|
66
|
+
issues.push(
|
|
67
|
+
issue(
|
|
68
|
+
"adopterDelivery.gateResult.nonClaims",
|
|
69
|
+
"delivery evidence must remain non-qualifying and non-self-certifying",
|
|
70
|
+
),
|
|
71
|
+
);
|
|
72
|
+
}
|
|
73
|
+
return issues;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
function validatePassedGate(result) {
|
|
77
|
+
if (result.status !== "passed") {
|
|
78
|
+
return result.status === "failed"
|
|
79
|
+
? []
|
|
80
|
+
: [
|
|
81
|
+
issue(
|
|
82
|
+
"adopterDelivery.gateResult.status",
|
|
83
|
+
"gate status must be passed or failed",
|
|
84
|
+
),
|
|
85
|
+
];
|
|
86
|
+
}
|
|
87
|
+
const passed =
|
|
88
|
+
result.protocol?.loaded === true &&
|
|
89
|
+
ROOT_PATTERN.test(result.protocol?.reportRoot ?? "") &&
|
|
90
|
+
result.artifactProfile?.loaded === true &&
|
|
91
|
+
result.artifactProfile?.valid === true &&
|
|
92
|
+
result.semanticReport !== null &&
|
|
93
|
+
(result.issues?.length ?? -1) === 0;
|
|
94
|
+
return passed
|
|
95
|
+
? []
|
|
96
|
+
: [
|
|
97
|
+
issue(
|
|
98
|
+
"adopterDelivery.gateResult.status",
|
|
99
|
+
"a passed gate must retain successful exact driver and artifact-profile evidence",
|
|
100
|
+
),
|
|
101
|
+
];
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
export function validateAdopterDeliveryGateResult(result) {
|
|
105
|
+
if (!result || typeof result !== "object" || Array.isArray(result)) {
|
|
106
|
+
return {
|
|
107
|
+
valid: false,
|
|
108
|
+
passed: false,
|
|
109
|
+
issues: [
|
|
110
|
+
issue(
|
|
111
|
+
"adopterDelivery.gateResult",
|
|
112
|
+
"adopter delivery gate result must be an object",
|
|
113
|
+
),
|
|
114
|
+
],
|
|
115
|
+
};
|
|
116
|
+
}
|
|
117
|
+
const issues = [
|
|
118
|
+
...validateGateIdentity(result),
|
|
119
|
+
...validateRootedJson(
|
|
120
|
+
result,
|
|
121
|
+
"gateRoot",
|
|
122
|
+
"adopterDelivery.gateResult.gateRoot",
|
|
123
|
+
"adopter delivery gate root",
|
|
124
|
+
),
|
|
125
|
+
...validatePassedGate(result),
|
|
126
|
+
];
|
|
127
|
+
const valid = issues.length === 0;
|
|
128
|
+
return { valid, passed: valid && result.status === "passed", issues };
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
export function createAdopterDeliveryPassportBinding(gateResult) {
|
|
132
|
+
const normalized = structuredClone(gateResult);
|
|
133
|
+
const validation = validateAdopterDeliveryGateResult(normalized);
|
|
134
|
+
const binding = {
|
|
135
|
+
schemaVersion: 1,
|
|
136
|
+
contract: ADOPTER_DELIVERY_PASSPORT_BINDING_CONTRACT,
|
|
137
|
+
valid: validation.passed,
|
|
138
|
+
qualifying: false,
|
|
139
|
+
selfCertified: false,
|
|
140
|
+
gateResult: normalized,
|
|
141
|
+
validationIssues: validation.issues,
|
|
142
|
+
nonClaims: [
|
|
143
|
+
"A passing adopter delivery gate does not grant runtime permission or release authority.",
|
|
144
|
+
"The selected protocol driver retains semantic authority; Buildchain only binds its exact result into delivery evidence.",
|
|
145
|
+
],
|
|
146
|
+
};
|
|
147
|
+
binding.bindingRoot = adopterDeliveryGateDigest(binding);
|
|
148
|
+
return binding;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
export function normalizeAdopterDeliveryPassportBinding(value) {
|
|
152
|
+
if (!value) return undefined;
|
|
153
|
+
return value.contract === ADOPTER_DELIVERY_PASSPORT_BINDING_CONTRACT
|
|
154
|
+
? structuredClone(value)
|
|
155
|
+
: createAdopterDeliveryPassportBinding(value);
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export function validateAdopterDeliveryPassportBinding(
|
|
159
|
+
binding,
|
|
160
|
+
{ expectedProjectRepository = "" } = {},
|
|
161
|
+
) {
|
|
162
|
+
if (!binding || typeof binding !== "object" || Array.isArray(binding)) {
|
|
163
|
+
return [
|
|
164
|
+
issue(
|
|
165
|
+
"adopterDelivery.binding",
|
|
166
|
+
"adopter delivery passport binding must be an object",
|
|
167
|
+
),
|
|
168
|
+
];
|
|
169
|
+
}
|
|
170
|
+
const gateValidation = validateAdopterDeliveryGateResult(binding.gateResult);
|
|
171
|
+
const issues = [
|
|
172
|
+
...validateRootedJson(
|
|
173
|
+
binding,
|
|
174
|
+
"bindingRoot",
|
|
175
|
+
"adopterDelivery.binding.bindingRoot",
|
|
176
|
+
"adopter delivery binding root",
|
|
177
|
+
),
|
|
178
|
+
...gateValidation.issues,
|
|
179
|
+
];
|
|
180
|
+
if (
|
|
181
|
+
binding.schemaVersion !== 1 ||
|
|
182
|
+
binding.contract !== ADOPTER_DELIVERY_PASSPORT_BINDING_CONTRACT
|
|
183
|
+
) {
|
|
184
|
+
issues.push(
|
|
185
|
+
issue(
|
|
186
|
+
"adopterDelivery.binding.contract",
|
|
187
|
+
"adopter delivery passport binding contract is unsupported",
|
|
188
|
+
),
|
|
189
|
+
);
|
|
190
|
+
}
|
|
191
|
+
if (
|
|
192
|
+
binding.valid !== gateValidation.passed ||
|
|
193
|
+
binding.qualifying !== false ||
|
|
194
|
+
binding.selfCertified !== false
|
|
195
|
+
) {
|
|
196
|
+
issues.push(
|
|
197
|
+
issue(
|
|
198
|
+
"adopterDelivery.binding.status",
|
|
199
|
+
"binding status must preserve a passing non-authoritative gate result",
|
|
200
|
+
),
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
if (!gateValidation.passed) {
|
|
204
|
+
issues.push(
|
|
205
|
+
issue(
|
|
206
|
+
"adopterDelivery.status",
|
|
207
|
+
"release passport requires a passed adopter delivery gate",
|
|
208
|
+
),
|
|
209
|
+
);
|
|
210
|
+
}
|
|
211
|
+
if (
|
|
212
|
+
expectedProjectRepository &&
|
|
213
|
+
binding.gateResult?.project?.adopterId !== expectedProjectRepository
|
|
214
|
+
) {
|
|
215
|
+
issues.push(
|
|
216
|
+
issue(
|
|
217
|
+
"adopterDelivery.project",
|
|
218
|
+
"delivery project must match the release passport product repository",
|
|
219
|
+
),
|
|
220
|
+
);
|
|
221
|
+
}
|
|
222
|
+
return issues;
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
function sameJson(left, right) {
|
|
226
|
+
try {
|
|
227
|
+
return adopterDeliveryGateDigest(left) === adopterDeliveryGateDigest(right);
|
|
228
|
+
} catch {
|
|
229
|
+
return false;
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
|
|
233
|
+
export function validateAdopterDeliveryReleaseEvidence({
|
|
234
|
+
binding,
|
|
235
|
+
artifactBinding,
|
|
236
|
+
expectedProjectRepository = "",
|
|
237
|
+
} = {}) {
|
|
238
|
+
if (!binding && !artifactBinding) return [];
|
|
239
|
+
if (!binding) {
|
|
240
|
+
return [
|
|
241
|
+
issue(
|
|
242
|
+
"adopterDelivery.passport",
|
|
243
|
+
"artifact evidence cannot introduce delivery authority absent from the passport",
|
|
244
|
+
),
|
|
245
|
+
];
|
|
246
|
+
}
|
|
247
|
+
const issues = validateAdopterDeliveryPassportBinding(binding, {
|
|
248
|
+
expectedProjectRepository,
|
|
249
|
+
});
|
|
250
|
+
if (!artifactBinding || !sameJson(artifactBinding, binding)) {
|
|
251
|
+
issues.push(
|
|
252
|
+
issue(
|
|
253
|
+
"adopterDelivery.artifactEvidence",
|
|
254
|
+
"passport and artifact evidence must bind the same exact delivery result",
|
|
255
|
+
),
|
|
256
|
+
);
|
|
257
|
+
}
|
|
258
|
+
return issues;
|
|
259
|
+
}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
import vectorSuite from "./adopter-delivery-vectors.json" with { type: "json" };
|
|
2
|
+
|
|
3
|
+
import { adopterDeliveryGateDigest } from "./adopter-delivery-gate.js";
|
|
4
|
+
|
|
5
|
+
export const ADOPTER_DELIVERY_VECTOR_SUITE_CONTRACT =
|
|
6
|
+
"kungfu-buildchain-adopter-delivery-vectors/v1";
|
|
7
|
+
|
|
8
|
+
const ROOT_PATTERN = /^sha256:[0-9a-f]{64}$/;
|
|
9
|
+
const REQUIRED_CASES = new Map([
|
|
10
|
+
["golden-two-driver-offline-replay", "golden"],
|
|
11
|
+
["negative-driver-mismatch", "negative"],
|
|
12
|
+
["negative-category-conflict", "negative"],
|
|
13
|
+
["negative-evidence-substitution", "negative"],
|
|
14
|
+
["negative-stale-package-cut", "negative"],
|
|
15
|
+
["fault-driver-throw", "fault"],
|
|
16
|
+
]);
|
|
17
|
+
|
|
18
|
+
function freezeJson(value) {
|
|
19
|
+
if (value && typeof value === "object" && !Object.isFrozen(value)) {
|
|
20
|
+
Object.freeze(value);
|
|
21
|
+
for (const child of Object.values(value)) freezeJson(child);
|
|
22
|
+
}
|
|
23
|
+
return value;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
function issue(code, path, message) {
|
|
27
|
+
return { code, path, message };
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
function suiteDigest(suite) {
|
|
31
|
+
const preimage = structuredClone(suite);
|
|
32
|
+
delete preimage.suiteRoot;
|
|
33
|
+
return adopterDeliveryGateDigest(preimage);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
export function validateAdopterDeliveryVectorSuite(suite) {
|
|
37
|
+
const issues = [];
|
|
38
|
+
if (!suite || typeof suite !== "object" || Array.isArray(suite)) {
|
|
39
|
+
return {
|
|
40
|
+
valid: false,
|
|
41
|
+
issues: [
|
|
42
|
+
issue(
|
|
43
|
+
"adopter-delivery-vectors.invalid",
|
|
44
|
+
"/",
|
|
45
|
+
"Vector suite must be a JSON object.",
|
|
46
|
+
),
|
|
47
|
+
],
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
if (
|
|
51
|
+
suite.schemaVersion !== 1 ||
|
|
52
|
+
suite.contract !== ADOPTER_DELIVERY_VECTOR_SUITE_CONTRACT
|
|
53
|
+
) {
|
|
54
|
+
issues.push(
|
|
55
|
+
issue(
|
|
56
|
+
"adopter-delivery-vectors.contract",
|
|
57
|
+
"/contract",
|
|
58
|
+
"Vector suite contract is unsupported.",
|
|
59
|
+
),
|
|
60
|
+
);
|
|
61
|
+
}
|
|
62
|
+
if (!Array.isArray(suite.cases)) {
|
|
63
|
+
issues.push(
|
|
64
|
+
issue(
|
|
65
|
+
"adopter-delivery-vectors.cases",
|
|
66
|
+
"/cases",
|
|
67
|
+
"Vector suite cases must be an array.",
|
|
68
|
+
),
|
|
69
|
+
);
|
|
70
|
+
} else {
|
|
71
|
+
const seen = new Set();
|
|
72
|
+
for (const [index, entry] of suite.cases.entries()) {
|
|
73
|
+
if (!entry || typeof entry !== "object" || Array.isArray(entry)) {
|
|
74
|
+
issues.push(
|
|
75
|
+
issue(
|
|
76
|
+
"adopter-delivery-vectors.case",
|
|
77
|
+
`/cases/${index}`,
|
|
78
|
+
"Vector case must be an object.",
|
|
79
|
+
),
|
|
80
|
+
);
|
|
81
|
+
continue;
|
|
82
|
+
}
|
|
83
|
+
if (typeof entry.id !== "string" || seen.has(entry.id)) {
|
|
84
|
+
issues.push(
|
|
85
|
+
issue(
|
|
86
|
+
"adopter-delivery-vectors.case-id",
|
|
87
|
+
`/cases/${index}/id`,
|
|
88
|
+
"Vector case id must be non-empty and unique.",
|
|
89
|
+
),
|
|
90
|
+
);
|
|
91
|
+
}
|
|
92
|
+
seen.add(entry.id);
|
|
93
|
+
if (!entry.expected || typeof entry.expected !== "object") {
|
|
94
|
+
issues.push(
|
|
95
|
+
issue(
|
|
96
|
+
"adopter-delivery-vectors.expected",
|
|
97
|
+
`/cases/${index}/expected`,
|
|
98
|
+
"Vector case must declare its expected result.",
|
|
99
|
+
),
|
|
100
|
+
);
|
|
101
|
+
}
|
|
102
|
+
}
|
|
103
|
+
for (const [id, className] of REQUIRED_CASES) {
|
|
104
|
+
const entry = suite.cases.find((candidate) => candidate?.id === id);
|
|
105
|
+
if (!entry || entry.class !== className) {
|
|
106
|
+
issues.push(
|
|
107
|
+
issue(
|
|
108
|
+
"adopter-delivery-vectors.required-case",
|
|
109
|
+
"/cases",
|
|
110
|
+
`Required ${className} vector ${id} is missing.`,
|
|
111
|
+
),
|
|
112
|
+
);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
if (!ROOT_PATTERN.test(suite.suiteRoot ?? "")) {
|
|
117
|
+
issues.push(
|
|
118
|
+
issue(
|
|
119
|
+
"adopter-delivery-vectors.root",
|
|
120
|
+
"/suiteRoot",
|
|
121
|
+
"Vector suite root must be a canonical sha256 root.",
|
|
122
|
+
),
|
|
123
|
+
);
|
|
124
|
+
} else {
|
|
125
|
+
try {
|
|
126
|
+
if (suiteDigest(suite) !== suite.suiteRoot) {
|
|
127
|
+
issues.push(
|
|
128
|
+
issue(
|
|
129
|
+
"adopter-delivery-vectors.root",
|
|
130
|
+
"/suiteRoot",
|
|
131
|
+
"Vector suite root does not match the exact JSON closure.",
|
|
132
|
+
),
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
} catch {
|
|
136
|
+
issues.push(
|
|
137
|
+
issue(
|
|
138
|
+
"adopter-delivery-vectors.root",
|
|
139
|
+
"/suiteRoot",
|
|
140
|
+
"Vector suite must contain finite acyclic JSON.",
|
|
141
|
+
),
|
|
142
|
+
);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
return { valid: issues.length === 0, issues };
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
export const ADOPTER_DELIVERY_VECTOR_SUITE = freezeJson(
|
|
149
|
+
structuredClone(vectorSuite),
|
|
150
|
+
);
|
|
151
|
+
|
|
152
|
+
export function getAdopterDeliveryVector(id) {
|
|
153
|
+
const entry = ADOPTER_DELIVERY_VECTOR_SUITE.cases.find(
|
|
154
|
+
(candidate) => candidate.id === id,
|
|
155
|
+
);
|
|
156
|
+
if (!entry) throw new RangeError(`Unknown adopter delivery vector: ${id}`);
|
|
157
|
+
return structuredClone(entry);
|
|
158
|
+
}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schemaVersion": 1,
|
|
3
|
+
"contract": "kungfu-buildchain-adopter-delivery-vectors/v1",
|
|
4
|
+
"rootAlgorithm": "sha256-buildchain-canonical-json-v1",
|
|
5
|
+
"authorities": {
|
|
6
|
+
"kfdPackage": "@kungfu-tech/kfd@1.0.0-alpha.65",
|
|
7
|
+
"categoryProfileVectors": "@kungfu-tech/kfd/adopter-conformance/category-profile-vectors.json",
|
|
8
|
+
"categoryInstanceVectors": "@kungfu-tech/kfd/adopter-conformance/category-instance-vectors.json"
|
|
9
|
+
},
|
|
10
|
+
"cases": [
|
|
11
|
+
{
|
|
12
|
+
"id": "golden-two-driver-offline-replay",
|
|
13
|
+
"class": "golden",
|
|
14
|
+
"surface": "protocol-neutral-gate",
|
|
15
|
+
"operation": "evaluate identical exact requests with two isolated protocol drivers and replay each request offline",
|
|
16
|
+
"expected": {
|
|
17
|
+
"statuses": ["passed", "passed"],
|
|
18
|
+
"issueCodes": [],
|
|
19
|
+
"deterministicRoots": true,
|
|
20
|
+
"qualifying": false,
|
|
21
|
+
"selfCertified": false
|
|
22
|
+
}
|
|
23
|
+
},
|
|
24
|
+
{
|
|
25
|
+
"id": "negative-driver-mismatch",
|
|
26
|
+
"class": "negative",
|
|
27
|
+
"surface": "protocol-neutral-gate",
|
|
28
|
+
"operation": "select an exact protocol identity and version that are not registered",
|
|
29
|
+
"expected": {
|
|
30
|
+
"status": "failed",
|
|
31
|
+
"issueCodes": ["delivery-driver-unknown"]
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
{
|
|
35
|
+
"id": "negative-category-conflict",
|
|
36
|
+
"class": "negative",
|
|
37
|
+
"surface": "published-kfd-category-driver",
|
|
38
|
+
"operation": "append a duplicate published category profile to the exact KFD instance selection",
|
|
39
|
+
"expected": {
|
|
40
|
+
"status": "failed",
|
|
41
|
+
"issueCodes": ["acp-composition-invalid"]
|
|
42
|
+
}
|
|
43
|
+
},
|
|
44
|
+
{
|
|
45
|
+
"id": "negative-evidence-substitution",
|
|
46
|
+
"class": "negative",
|
|
47
|
+
"surface": "release-passport-binding",
|
|
48
|
+
"operation": "substitute the artifact root in artifact evidence after binding the passport",
|
|
49
|
+
"expected": {
|
|
50
|
+
"status": "failed",
|
|
51
|
+
"issueCodes": ["adopterDelivery.artifactEvidence"]
|
|
52
|
+
}
|
|
53
|
+
},
|
|
54
|
+
{
|
|
55
|
+
"id": "negative-stale-package-cut",
|
|
56
|
+
"class": "negative",
|
|
57
|
+
"surface": "published-kfd-category-driver",
|
|
58
|
+
"operation": "replace the KFD instance package version with an uninstalled stale cut",
|
|
59
|
+
"expected": {
|
|
60
|
+
"status": "failed",
|
|
61
|
+
"issueCodes": ["delivery-kfd-package-cut-mismatch"]
|
|
62
|
+
}
|
|
63
|
+
},
|
|
64
|
+
{
|
|
65
|
+
"id": "fault-driver-throw",
|
|
66
|
+
"class": "fault",
|
|
67
|
+
"surface": "protocol-neutral-gate",
|
|
68
|
+
"operation": "throw a private exception from the selected protocol driver",
|
|
69
|
+
"expected": {
|
|
70
|
+
"status": "failed",
|
|
71
|
+
"issueCodes": ["delivery-driver-error"],
|
|
72
|
+
"privateDetailRedacted": true
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
],
|
|
76
|
+
"suiteRoot": "sha256:c978707556406ffda4ef4192032332c01c2da1cebb6ad8c4f0edfc65d5cef0c7"
|
|
77
|
+
}
|
|
@@ -10,6 +10,7 @@ export const BUILDCHAIN_AGENT_MANUALS = Object.freeze([
|
|
|
10
10
|
{ id: "github-governance-authority", title: "GitHub governance authority", path: "docs/github-governance-authority.md", plane: "verify" },
|
|
11
11
|
{ id: "release-candidate", title: "Release Candidate Passport", path: "docs/release-candidate.md", plane: "verify" },
|
|
12
12
|
{ id: "release-train", title: "Release Train and Release Cut", path: "docs/release-train.md", plane: "verify" },
|
|
13
|
+
{ id: "next-development-transition", title: "Next-development transition", path: "docs/next-development-transition.md", plane: "verify" },
|
|
13
14
|
{ id: "release-propagation", title: "Release propagation", path: "docs/release-propagation.md", plane: "use" },
|
|
14
15
|
{ id: "readme-badges", title: "README badge blocks", path: "docs/readme-badges.md", plane: "use" },
|
|
15
16
|
{ id: "homebrew", title: "Homebrew distribution indexes", path: "docs/homebrew.md", plane: "use" },
|
|
@@ -29,10 +30,12 @@ export const BUILDCHAIN_AGENT_MANUALS = Object.freeze([
|
|
|
29
30
|
{ id: "kfd-agent-hub", title: "KFD Agent Hub Builder flow", path: "docs/kfd-agent-hub.md", plane: "use" },
|
|
30
31
|
{ id: "lifecycle-protocol", title: "Lifecycle protocol", path: "docs/lifecycle-protocol.md", plane: "use" },
|
|
31
32
|
{ id: "reusable-build-surface", title: "Reusable build surface", path: "docs/reusable-build-surface.md", plane: "use" },
|
|
33
|
+
{ id: "v4-adopter-delivery", title: "V4 public adopter delivery", path: "docs/v4-adopter-delivery.md", plane: "verify" },
|
|
32
34
|
{ id: "publish-transaction", title: "Publish transaction", path: "docs/publish-transaction.md", plane: "verify" },
|
|
33
35
|
{ id: "release-tail-contract", title: "Declarative release-tail contract", path: "docs/release-tail-contract.md", plane: "verify" },
|
|
34
36
|
{ id: "release-tail-provider-plane", title: "Declarative release-tail provider plane", path: "docs/release-tail-provider-plane.md", plane: "use" },
|
|
35
37
|
{ id: "release-governance", title: "Release governance", path: "docs/release-governance.md", plane: "why" },
|
|
38
|
+
{ id: "v4-compatibility-facts", title: "Buildchain v4 compatibility Facts", path: "docs/v4-compatibility-facts.md", plane: "verify" },
|
|
36
39
|
{ id: "release-flow", title: "Release flow", path: "docs/release-flow.md", plane: "verify" },
|
|
37
40
|
{ id: "runtime-train-validation", title: "Runtime train validation", path: "docs/runtime-train-validation.md", plane: "verify" },
|
|
38
41
|
{ id: "versioning", title: "Versioning", path: "docs/versioning.md", plane: "why" },
|