@kungfu-tech/buildchain 4.0.1-alpha.4 → 4.0.1-alpha.6
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/decisions/0002-next-development-transition.md +101 -0
- package/architecture/internal-capabilities.json +117 -8
- package/architecture/maintainability-policy.json +38 -20
- 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-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-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 +462 -27
- package/dist/site/capability-registry.json +17 -14
- package/dist/site/cli-registry.json +159 -1
- package/dist/site/kfd-claims.json +429 -15
- package/dist/site/kfd-upstream-aggregate.json +1 -1
- package/dist/site/manual-registry.json +52 -6
- package/dist/site/node-api-registry.json +13972 -9697
- package/dist/site/page-registry.json +428 -17
- package/dist/site/public-surface-audit.json +429 -11
- package/dist/site/publication-authority-registry.json +22 -4
- package/dist/site/publication-registry.json +4 -4
- package/dist/site/release-provenance.json +21 -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 +121 -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/next-development-transition.md +118 -0
- package/docs/node-api-reference.md +448 -168
- 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 +29 -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/channel-candidate.js +8 -0
- package/packages/core/channel-promotion-baseline.js +55 -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-process-boundary.js +19 -6
- package/packages/core/dev-delivery-provider-heartbeat.js +18 -6
- 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-passport.js +26 -8
- 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-floating-consumer-policy.js +29 -9
- 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/scripts/buildchain-cli-help.mjs +30 -0
- package/scripts/check-inventory.mjs +14 -3
- 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/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/release-tail.mjs +51 -3
- package/scripts/resume-from-candidate-run.mjs +545 -15
- package/scripts/site-capability-metadata.mjs +28 -0
- package/scripts/v4-consumer-policy.mjs +1 -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
|
@@ -0,0 +1,336 @@
|
|
|
1
|
+
import {
|
|
2
|
+
devDeliveryContentRoot as contentRoot,
|
|
3
|
+
devDeliveryExactRoot as exactRoot,
|
|
4
|
+
devDeliveryExactSha as exactSha,
|
|
5
|
+
devDeliveryText as text,
|
|
6
|
+
} from "./dev-delivery-common.js";
|
|
7
|
+
import {
|
|
8
|
+
BUILDCHAIN_COMPATIBILITY_PROOF_REGISTRY_SCHEMA,
|
|
9
|
+
BUILDCHAIN_COMPATIBILITY_RELEASE_EVIDENCE_SCHEMA,
|
|
10
|
+
createBuildchainCompatibilityFactRegistry,
|
|
11
|
+
createHistoricalBuildchainCompatibilityProofs,
|
|
12
|
+
verifyBuildchainCompatibilityProof,
|
|
13
|
+
} from "./buildchain-compatibility-fact.js";
|
|
14
|
+
import {
|
|
15
|
+
KUNGFU_TEMPORAL_PATH_QUERY_SCHEMA,
|
|
16
|
+
verifyKungfuTemporalPath,
|
|
17
|
+
} from "./kungfu-temporal-fact.js";
|
|
18
|
+
|
|
19
|
+
const COMPATIBILITY_OPERATION = "accept-contract-lock";
|
|
20
|
+
const COMPATIBILITY_DIRECTION = "source-to-target";
|
|
21
|
+
|
|
22
|
+
function exactText(value, label) {
|
|
23
|
+
const normalized = text(value);
|
|
24
|
+
if (!normalized) throw new Error(`${label} must not be empty`);
|
|
25
|
+
return normalized;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function factInputFromProof(proof) {
|
|
29
|
+
return {
|
|
30
|
+
proofId: proof.proofId,
|
|
31
|
+
surfaceId: proof.source.surfaceId,
|
|
32
|
+
surfaceKind: proof.source.surfaceKind,
|
|
33
|
+
sourceBreakingDigest: proof.source.breakingDigest,
|
|
34
|
+
targetBreakingDigest: proof.target.breakingDigest,
|
|
35
|
+
scope: proof.scope,
|
|
36
|
+
evidence: proof.evidence,
|
|
37
|
+
authority: proof.authority,
|
|
38
|
+
cut: proof.cut,
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
function projectionForSurface({ proofs, factByProofRoot, surface }) {
|
|
43
|
+
const matching = proofs.filter(
|
|
44
|
+
(proof) =>
|
|
45
|
+
proof.target.surfaceId === surface.id &&
|
|
46
|
+
proof.target.surfaceKind === surface.kind &&
|
|
47
|
+
proof.target.breakingDigest === surface.breakingDigest &&
|
|
48
|
+
proof.operation === COMPATIBILITY_OPERATION,
|
|
49
|
+
);
|
|
50
|
+
const bySource = new Map();
|
|
51
|
+
for (const proof of matching) {
|
|
52
|
+
const sourceDigest = proof.source.breakingDigest;
|
|
53
|
+
if (bySource.has(sourceDigest))
|
|
54
|
+
throw new Error(
|
|
55
|
+
`ambiguous compatibility proof for ${surface.id} ${sourceDigest}`,
|
|
56
|
+
);
|
|
57
|
+
bySource.set(sourceDigest, proof);
|
|
58
|
+
}
|
|
59
|
+
return [...bySource.values()]
|
|
60
|
+
.sort((left, right) =>
|
|
61
|
+
left.source.breakingDigest.localeCompare(right.source.breakingDigest),
|
|
62
|
+
)
|
|
63
|
+
.map((proof) => ({
|
|
64
|
+
breakingDigest: proof.source.breakingDigest,
|
|
65
|
+
proofRoot: proof.proofRoot,
|
|
66
|
+
factRoot: factByProofRoot.get(proof.proofRoot)?.factRoot || "",
|
|
67
|
+
}));
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
export function createBuildchainCompatibilityProofRegistry({
|
|
71
|
+
proofs = createHistoricalBuildchainCompatibilityProofs(),
|
|
72
|
+
surfaces = [],
|
|
73
|
+
majorLine = "",
|
|
74
|
+
} = {}) {
|
|
75
|
+
const verifiedProofs = proofs
|
|
76
|
+
.map((proof) => {
|
|
77
|
+
const verification = verifyBuildchainCompatibilityProof(proof);
|
|
78
|
+
if (!verification.ok)
|
|
79
|
+
throw new Error(
|
|
80
|
+
`invalid compatibility proof: ${verification.reason}${verification.error ? `: ${verification.error}` : ""}`,
|
|
81
|
+
);
|
|
82
|
+
return verification.proof;
|
|
83
|
+
})
|
|
84
|
+
.sort((left, right) => left.proofRoot.localeCompare(right.proofRoot));
|
|
85
|
+
const factRegistry = createBuildchainCompatibilityFactRegistry({
|
|
86
|
+
factInputs: verifiedProofs.map(factInputFromProof),
|
|
87
|
+
});
|
|
88
|
+
const factByProofRoot = new Map(
|
|
89
|
+
factRegistry.facts.map((fact) => [fact.proof.proofRoot, fact]),
|
|
90
|
+
);
|
|
91
|
+
const projections = Object.fromEntries(
|
|
92
|
+
[...surfaces]
|
|
93
|
+
.sort((left, right) => left.id.localeCompare(right.id))
|
|
94
|
+
.map((surface) => [
|
|
95
|
+
surface.id,
|
|
96
|
+
projectionForSurface({
|
|
97
|
+
proofs: verifiedProofs,
|
|
98
|
+
factByProofRoot,
|
|
99
|
+
surface,
|
|
100
|
+
}),
|
|
101
|
+
])
|
|
102
|
+
.filter(([, entries]) => entries.length > 0),
|
|
103
|
+
);
|
|
104
|
+
const identity = {
|
|
105
|
+
schema: BUILDCHAIN_COMPATIBILITY_PROOF_REGISTRY_SCHEMA,
|
|
106
|
+
proofRoots: verifiedProofs.map((proof) => proof.proofRoot),
|
|
107
|
+
};
|
|
108
|
+
return {
|
|
109
|
+
...identity,
|
|
110
|
+
proofs: verifiedProofs,
|
|
111
|
+
facts: factRegistry.facts,
|
|
112
|
+
factRegistry,
|
|
113
|
+
factRegistryRoot: factRegistry.registryRoot,
|
|
114
|
+
factCutRoot: factRegistry.currentCutRoot,
|
|
115
|
+
projections,
|
|
116
|
+
registryRoot: contentRoot(identity),
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export function assertBuildchainCompatibilityProjection(contractWorld) {
|
|
121
|
+
if (
|
|
122
|
+
!Array.isArray(contractWorld?.compatibilityFacts) ||
|
|
123
|
+
!Array.isArray(contractWorld?.compatibilityProofs)
|
|
124
|
+
) {
|
|
125
|
+
throw new Error(
|
|
126
|
+
"compatibility Facts and their proof projection are required",
|
|
127
|
+
);
|
|
128
|
+
}
|
|
129
|
+
const registry = createBuildchainCompatibilityProofRegistry({
|
|
130
|
+
proofs: contractWorld.compatibilityProofs,
|
|
131
|
+
surfaces: contractWorld.surfaces || [],
|
|
132
|
+
majorLine: contractWorld.majorLine,
|
|
133
|
+
});
|
|
134
|
+
if (contractWorld.compatibilityProofRegistryRoot !== registry.registryRoot) {
|
|
135
|
+
throw new Error("compatibility proof registry root mismatch");
|
|
136
|
+
}
|
|
137
|
+
if (
|
|
138
|
+
contractWorld.compatibilityFactRegistryRoot !== registry.factRegistryRoot
|
|
139
|
+
) {
|
|
140
|
+
throw new Error("compatibility Fact registry root mismatch");
|
|
141
|
+
}
|
|
142
|
+
if (contractWorld.compatibilityFactCutRoot !== registry.factCutRoot) {
|
|
143
|
+
throw new Error("compatibility Fact Cut root mismatch");
|
|
144
|
+
}
|
|
145
|
+
if (
|
|
146
|
+
JSON.stringify(contractWorld.compatibilityFacts) !==
|
|
147
|
+
JSON.stringify(registry.facts)
|
|
148
|
+
) {
|
|
149
|
+
throw new Error("compatibility Facts drift from the verified registry");
|
|
150
|
+
}
|
|
151
|
+
for (const surface of contractWorld.surfaces || []) {
|
|
152
|
+
const expected = registry.projections[surface.id] || [];
|
|
153
|
+
const expectedDigests = expected.map((entry) => entry.breakingDigest);
|
|
154
|
+
const expectedRoots = expected.map((entry) => entry.proofRoot);
|
|
155
|
+
const expectedFactRoots = expected.map((entry) => entry.factRoot);
|
|
156
|
+
const actualDigests = surface.compatibleBreakingDigests || [];
|
|
157
|
+
const actualRoots = surface.compatibilityProofRoots || [];
|
|
158
|
+
const actualFactRoots = surface.compatibilityFactRoots || [];
|
|
159
|
+
if (JSON.stringify(actualDigests) !== JSON.stringify(expectedDigests)) {
|
|
160
|
+
throw new Error(
|
|
161
|
+
`compatibleBreakingDigests projection mismatch for ${surface.id}`,
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
if (JSON.stringify(actualRoots) !== JSON.stringify(expectedRoots)) {
|
|
165
|
+
throw new Error(
|
|
166
|
+
`compatibilityProofRoots projection mismatch for ${surface.id}`,
|
|
167
|
+
);
|
|
168
|
+
}
|
|
169
|
+
if (JSON.stringify(actualFactRoots) !== JSON.stringify(expectedFactRoots)) {
|
|
170
|
+
throw new Error(
|
|
171
|
+
`compatibilityFactRoots projection mismatch for ${surface.id}`,
|
|
172
|
+
);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
return {
|
|
176
|
+
ok: true,
|
|
177
|
+
reason: "exact-Fact-backed-projection",
|
|
178
|
+
registryRoot: registry.registryRoot,
|
|
179
|
+
factRegistryRoot: registry.factRegistryRoot,
|
|
180
|
+
factCutRoot: registry.factCutRoot,
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
|
|
184
|
+
export function verifyBuildchainCompatibilityPath({ registry, query } = {}) {
|
|
185
|
+
if (!registry?.temporalBundle)
|
|
186
|
+
throw new Error("compatibility Fact registry is required");
|
|
187
|
+
return verifyKungfuTemporalPath(registry.temporalBundle, query);
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
export function createBuildchainCompatibilityPathQuery({
|
|
191
|
+
registry,
|
|
192
|
+
queryId,
|
|
193
|
+
sourceRoot,
|
|
194
|
+
targetRoot,
|
|
195
|
+
relationPathRoots,
|
|
196
|
+
maxDepth = 1,
|
|
197
|
+
} = {}) {
|
|
198
|
+
if (!registry?.temporalBundle || registry.predicateRoots?.length !== 1) {
|
|
199
|
+
throw new Error(
|
|
200
|
+
"one exact compatibility Fact registry predicate is required",
|
|
201
|
+
);
|
|
202
|
+
}
|
|
203
|
+
const predicateRoot = registry.predicateRoots[0];
|
|
204
|
+
const predicate = registry.temporalBundle.predicates.find(
|
|
205
|
+
(entry) => entry.root === predicateRoot,
|
|
206
|
+
)?.record;
|
|
207
|
+
return {
|
|
208
|
+
schema: KUNGFU_TEMPORAL_PATH_QUERY_SCHEMA,
|
|
209
|
+
queryId: exactText(queryId, "queryId"),
|
|
210
|
+
operation: COMPATIBILITY_OPERATION,
|
|
211
|
+
predicateRoot,
|
|
212
|
+
sourceRoot: exactRoot(sourceRoot, "sourceRoot"),
|
|
213
|
+
targetRoot: exactRoot(targetRoot, "targetRoot"),
|
|
214
|
+
cutRoot: exactRoot(registry.currentCutRoot, "currentCutRoot"),
|
|
215
|
+
relationPathRoots: (relationPathRoots || []).map((entry) =>
|
|
216
|
+
exactRoot(entry, "relationPathRoot"),
|
|
217
|
+
),
|
|
218
|
+
requiredAuthorityRoot: exactRoot(
|
|
219
|
+
predicate?.authorityRoot,
|
|
220
|
+
"requiredAuthorityRoot",
|
|
221
|
+
),
|
|
222
|
+
maxDepth,
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
export function resolveBuildchainCompatibilityProof({
|
|
227
|
+
registry,
|
|
228
|
+
surface,
|
|
229
|
+
sourceBreakingDigest,
|
|
230
|
+
majorLine,
|
|
231
|
+
} = {}) {
|
|
232
|
+
const candidates = (registry?.proofs || []).filter(
|
|
233
|
+
(proof) =>
|
|
234
|
+
proof.source.surfaceId === surface.id &&
|
|
235
|
+
proof.source.surfaceKind === surface.kind &&
|
|
236
|
+
proof.source.breakingDigest === sourceBreakingDigest &&
|
|
237
|
+
proof.target.breakingDigest === surface.breakingDigest &&
|
|
238
|
+
proof.operation === COMPATIBILITY_OPERATION,
|
|
239
|
+
);
|
|
240
|
+
if (candidates.length === 0)
|
|
241
|
+
return { ok: false, reason: "compatibility-proof-missing" };
|
|
242
|
+
if (candidates.length > 1)
|
|
243
|
+
return { ok: false, reason: "ambiguous-compatibility-proof" };
|
|
244
|
+
const verification = verifyBuildchainCompatibilityProof(candidates[0]);
|
|
245
|
+
if (!verification.ok) return verification;
|
|
246
|
+
const projection = registry.projections?.[surface.id] || [];
|
|
247
|
+
if (
|
|
248
|
+
!projection.some(
|
|
249
|
+
(entry) =>
|
|
250
|
+
entry.breakingDigest === sourceBreakingDigest &&
|
|
251
|
+
entry.proofRoot === verification.proofRoot,
|
|
252
|
+
)
|
|
253
|
+
) {
|
|
254
|
+
return { ok: false, reason: "compatibility-proof-projection-missing" };
|
|
255
|
+
}
|
|
256
|
+
const fact = registry.factRegistry?.facts.find(
|
|
257
|
+
(entry) => entry.proof.proofRoot === verification.proofRoot,
|
|
258
|
+
);
|
|
259
|
+
if (!fact) return { ok: false, reason: "compatibility-fact-missing" };
|
|
260
|
+
const query = createBuildchainCompatibilityPathQuery({
|
|
261
|
+
registry: registry.factRegistry,
|
|
262
|
+
queryId: `buildchain:compatibility:${surface.id}:${sourceBreakingDigest}:${surface.breakingDigest}`,
|
|
263
|
+
sourceRoot: fact.sourceRoot,
|
|
264
|
+
targetRoot: fact.targetRoot,
|
|
265
|
+
relationPathRoots: [fact.factRoot],
|
|
266
|
+
maxDepth: 1,
|
|
267
|
+
});
|
|
268
|
+
const pathReceipt = verifyBuildchainCompatibilityPath({
|
|
269
|
+
registry: registry.factRegistry,
|
|
270
|
+
query,
|
|
271
|
+
});
|
|
272
|
+
if (pathReceipt.record.status !== "accepted") {
|
|
273
|
+
return {
|
|
274
|
+
ok: false,
|
|
275
|
+
reason: pathReceipt.record.failureCode,
|
|
276
|
+
pathReceipt,
|
|
277
|
+
pathReceiptRoot: pathReceipt.root,
|
|
278
|
+
};
|
|
279
|
+
}
|
|
280
|
+
return {
|
|
281
|
+
ok: true,
|
|
282
|
+
reason: "Fact-backed-compatible-relation",
|
|
283
|
+
proof: verification.proof,
|
|
284
|
+
proofRoot: verification.proofRoot,
|
|
285
|
+
fact,
|
|
286
|
+
factRoot: fact.factRoot,
|
|
287
|
+
pathReceipt,
|
|
288
|
+
pathReceiptRoot: pathReceipt.root,
|
|
289
|
+
};
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
export function createBuildchainCompatibilityReleaseEvidence({
|
|
293
|
+
contractWorld,
|
|
294
|
+
release,
|
|
295
|
+
decisions = [],
|
|
296
|
+
} = {}) {
|
|
297
|
+
const projection = assertBuildchainCompatibilityProjection(contractWorld);
|
|
298
|
+
const normalizedRelease = {
|
|
299
|
+
sourceSha: exactSha(release?.sourceSha, "release.sourceSha"),
|
|
300
|
+
tag: exactText(release?.tag, "release.tag"),
|
|
301
|
+
channel: exactText(release?.channel, "release.channel"),
|
|
302
|
+
};
|
|
303
|
+
const rootSet = (field) =>
|
|
304
|
+
[...new Set(decisions.map((entry) => entry[field]).filter(Boolean))]
|
|
305
|
+
.map((entry) => exactRoot(entry, field))
|
|
306
|
+
.sort();
|
|
307
|
+
const compatibility = {
|
|
308
|
+
operation: COMPATIBILITY_OPERATION,
|
|
309
|
+
direction: COMPATIBILITY_DIRECTION,
|
|
310
|
+
authority: "Fact-registry-only",
|
|
311
|
+
grantsReleaseAuthority: false,
|
|
312
|
+
contractDigest: exactRoot(
|
|
313
|
+
contractWorld.contractDigest,
|
|
314
|
+
"contractWorld.contractDigest",
|
|
315
|
+
),
|
|
316
|
+
compatibilityDigest: exactRoot(
|
|
317
|
+
contractWorld.compatibilityDigest,
|
|
318
|
+
"contractWorld.compatibilityDigest",
|
|
319
|
+
),
|
|
320
|
+
factRegistryRoot: projection.factRegistryRoot,
|
|
321
|
+
factCutRoot: projection.factCutRoot,
|
|
322
|
+
proofRegistryRoot: projection.registryRoot,
|
|
323
|
+
usedFactRoots: rootSet("factRoot"),
|
|
324
|
+
usedProofRoots: rootSet("proofRoot"),
|
|
325
|
+
pathReceiptRoots: rootSet("pathReceiptRoot"),
|
|
326
|
+
};
|
|
327
|
+
const body = {
|
|
328
|
+
schemaVersion: 1,
|
|
329
|
+
contract: BUILDCHAIN_COMPATIBILITY_RELEASE_EVIDENCE_SCHEMA,
|
|
330
|
+
id: "buildchain-compatibility-facts",
|
|
331
|
+
kind: "compatibility-fact-lineage",
|
|
332
|
+
release: normalizedRelease,
|
|
333
|
+
compatibility,
|
|
334
|
+
};
|
|
335
|
+
return { ...body, evidenceRoot: contentRoot(body) };
|
|
336
|
+
}
|