@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
|
@@ -7,8 +7,18 @@ import {
|
|
|
7
7
|
normalizeBuildchainRef,
|
|
8
8
|
parseBuildchainRefIdentity,
|
|
9
9
|
} from "./buildchain-channel-identity.js";
|
|
10
|
+
import {
|
|
11
|
+
createHistoricalBuildchainCompatibilityFacts,
|
|
12
|
+
createHistoricalBuildchainCompatibilityProofs,
|
|
13
|
+
} from "./buildchain-compatibility-fact.js";
|
|
14
|
+
import {
|
|
15
|
+
assertBuildchainCompatibilityProjection,
|
|
16
|
+
createBuildchainCompatibilityProofRegistry,
|
|
17
|
+
} from "./buildchain-compatibility-authority.js";
|
|
18
|
+
import { evaluateBuildchainContractLock as evaluateFactBackedBuildchainContractLock } from "./buildchain-compatibility-proof.js";
|
|
10
19
|
import { createControllerRegistry } from "./controller-evidence.js";
|
|
11
20
|
import { enumerateWorkflowInputs } from "./public-surface-audit.js";
|
|
21
|
+
import { devDeliveryWorkflowContractSurface } from "./dev-delivery-contract-surface.js";
|
|
12
22
|
|
|
13
23
|
export {
|
|
14
24
|
BUILDCHAIN_CHANNELS,
|
|
@@ -17,11 +27,47 @@ export {
|
|
|
17
27
|
parseBuildchainRefIdentity,
|
|
18
28
|
};
|
|
19
29
|
|
|
30
|
+
export {
|
|
31
|
+
BUILDCHAIN_COMPATIBILITY_FACT_REGISTRY_SCHEMA,
|
|
32
|
+
BUILDCHAIN_COMPATIBILITY_FACT_SCHEMA,
|
|
33
|
+
BUILDCHAIN_COMPATIBILITY_PROOF_REGISTRY_SCHEMA,
|
|
34
|
+
BUILDCHAIN_COMPATIBILITY_PROOF_SCHEMA,
|
|
35
|
+
BUILDCHAIN_COMPATIBILITY_RELEASE_EVIDENCE_SCHEMA,
|
|
36
|
+
createBuildchainCompatibilityFact,
|
|
37
|
+
createBuildchainCompatibilityFactRegistry,
|
|
38
|
+
createBuildchainCompatibilityProof,
|
|
39
|
+
createHistoricalBuildchainCompatibilityFacts,
|
|
40
|
+
createHistoricalBuildchainCompatibilityProofs,
|
|
41
|
+
verifyBuildchainCompatibilityFact,
|
|
42
|
+
verifyBuildchainCompatibilityFactRegistry,
|
|
43
|
+
verifyBuildchainCompatibilityProof,
|
|
44
|
+
} from "./buildchain-compatibility-fact.js";
|
|
45
|
+
export {
|
|
46
|
+
assertBuildchainCompatibilityProjection,
|
|
47
|
+
createBuildchainCompatibilityPathQuery,
|
|
48
|
+
createBuildchainCompatibilityProofRegistry,
|
|
49
|
+
createBuildchainCompatibilityReleaseEvidence,
|
|
50
|
+
resolveBuildchainCompatibilityProof,
|
|
51
|
+
verifyBuildchainCompatibilityPath,
|
|
52
|
+
} from "./buildchain-compatibility-authority.js";
|
|
53
|
+
export {
|
|
54
|
+
BUILDCHAIN_COMPATIBILITY_VERIFICATION_RECEIPT_SCHEMA,
|
|
55
|
+
BUILDCHAIN_LEGACY_COMPATIBILITY_VERIFICATION_RECEIPT_SCHEMA,
|
|
56
|
+
createBuildchainCompatibilityVerificationReceipt,
|
|
57
|
+
verifyBuildchainCompatibilityVerificationReceipt,
|
|
58
|
+
} from "./buildchain-compatibility-proof.js";
|
|
59
|
+
|
|
20
60
|
export const BUILDCHAIN_RUNTIME_CONTRACT_WORLD = "kungfu-buildchain-runtime-contract-world";
|
|
21
61
|
export const BUILDCHAIN_CONTRACT_LOCK = "kungfu-buildchain-contract-lock";
|
|
22
62
|
|
|
23
63
|
const DEFAULT_POLICY = "major-compatible";
|
|
24
|
-
|
|
64
|
+
|
|
65
|
+
function compatibilityAuthority() {
|
|
66
|
+
return {
|
|
67
|
+
compatibilityFacts: createHistoricalBuildchainCompatibilityFacts(),
|
|
68
|
+
compatibilityProofs: createHistoricalBuildchainCompatibilityProofs(),
|
|
69
|
+
};
|
|
70
|
+
}
|
|
25
71
|
|
|
26
72
|
function optionalString(value) {
|
|
27
73
|
return value === undefined || value === null ? "" : String(value);
|
|
@@ -125,8 +171,7 @@ export function createBuildchainContractWorld({
|
|
|
125
171
|
packageJson = undefined,
|
|
126
172
|
controllerRegistry = undefined,
|
|
127
173
|
} = {}) {
|
|
128
|
-
const pkg = packageJson || readJson(path.join(root, "package.json"), {});
|
|
129
|
-
const majorLine = majorLineFromPackageVersion(pkg.version);
|
|
174
|
+
const pkg = packageJson || readJson(path.join(root, "package.json"), {}), majorLine = majorLineFromPackageVersion(pkg.version);
|
|
130
175
|
const workflowDescriptors = controllerRegistry ? [] : enumerateWorkflowInputs({ root });
|
|
131
176
|
const controllerWorkflowIds = new Set([
|
|
132
177
|
"check",
|
|
@@ -217,6 +262,7 @@ export function createBuildchainContractWorld({
|
|
|
217
262
|
"alpha and stable channel selections use separate consumer contract locks by default",
|
|
218
263
|
],
|
|
219
264
|
}),
|
|
265
|
+
surface(root, devDeliveryWorkflowContractSurface(pkg, majorLine)),
|
|
220
266
|
surface(root, {
|
|
221
267
|
id: "release-candidate-promote",
|
|
222
268
|
kind: "workflow",
|
|
@@ -795,26 +841,60 @@ export function createBuildchainContractWorld({
|
|
|
795
841
|
version: pkg.version || "",
|
|
796
842
|
repository: pkg.repository?.url || pkg.repository || "https://github.com/kungfu-systems/buildchain",
|
|
797
843
|
},
|
|
798
|
-
majorLine,
|
|
799
|
-
|
|
844
|
+
majorLine, compatibilityPolicy: DEFAULT_POLICY,
|
|
845
|
+
...compatibilityAuthority(),
|
|
800
846
|
surfaces,
|
|
801
847
|
};
|
|
802
848
|
return finalizeBuildchainContractWorld(base);
|
|
803
849
|
}
|
|
804
850
|
|
|
805
851
|
export function finalizeBuildchainContractWorld(contractWorld) {
|
|
852
|
+
if (!Array.isArray(contractWorld?.compatibilityFacts) || !Array.isArray(contractWorld?.compatibilityProofs)) {
|
|
853
|
+
throw new Error("contract world requires compatibility Facts and their proof projection");
|
|
854
|
+
}
|
|
855
|
+
const sourceSurfaces = (contractWorld.surfaces || []).map((entry) => ({ ...entry }));
|
|
856
|
+
const proofRegistry = createBuildchainCompatibilityProofRegistry({
|
|
857
|
+
proofs: contractWorld.compatibilityProofs,
|
|
858
|
+
surfaces: sourceSurfaces,
|
|
859
|
+
majorLine: contractWorld.majorLine,
|
|
860
|
+
});
|
|
861
|
+
if (JSON.stringify(contractWorld.compatibilityFacts) !== JSON.stringify(proofRegistry.facts)) {
|
|
862
|
+
throw new Error("contract world compatibility Facts drift from the verified registry");
|
|
863
|
+
}
|
|
806
864
|
const world = {
|
|
807
865
|
...contractWorld,
|
|
808
|
-
|
|
866
|
+
compatibilityFacts: proofRegistry.facts,
|
|
867
|
+
compatibilityFactRegistryRoot: proofRegistry.factRegistryRoot,
|
|
868
|
+
compatibilityFactCutRoot: proofRegistry.factCutRoot,
|
|
869
|
+
compatibilityProofs: proofRegistry.proofs,
|
|
870
|
+
compatibilityProofRegistryRoot: proofRegistry.registryRoot,
|
|
871
|
+
surfaces: sourceSurfaces.map((entry) => {
|
|
872
|
+
const surfaceEntry = { ...entry };
|
|
873
|
+
delete surfaceEntry.compatibleBreakingDigests;
|
|
874
|
+
delete surfaceEntry.compatibilityProofRoots;
|
|
875
|
+
delete surfaceEntry.compatibilityFactRoots;
|
|
876
|
+
const projection = proofRegistry.projections[entry.id] || [];
|
|
877
|
+
if (projection.length > 0) {
|
|
878
|
+
surfaceEntry.compatibleBreakingDigests = projection.map((item) => item.breakingDigest);
|
|
879
|
+
surfaceEntry.compatibilityProofRoots = projection.map((item) => item.proofRoot);
|
|
880
|
+
surfaceEntry.compatibilityFactRoots = projection.map((item) => item.factRoot);
|
|
881
|
+
}
|
|
882
|
+
return surfaceEntry;
|
|
883
|
+
}),
|
|
809
884
|
};
|
|
810
885
|
const compatibilityModel = {
|
|
811
886
|
schemaVersion: world.schemaVersion,
|
|
812
887
|
contract: world.contract,
|
|
813
888
|
majorLine: world.majorLine,
|
|
889
|
+
compatibilityFactRegistryRoot: world.compatibilityFactRegistryRoot,
|
|
890
|
+
compatibilityFactCutRoot: world.compatibilityFactCutRoot,
|
|
891
|
+
compatibilityProofRegistryRoot: world.compatibilityProofRegistryRoot,
|
|
814
892
|
surfaces: world.surfaces.map((entry) => ({
|
|
815
893
|
id: entry.id,
|
|
816
894
|
kind: entry.kind,
|
|
817
895
|
breakingDigest: entry.breakingDigest,
|
|
896
|
+
compatibilityProofRoots: entry.compatibilityProofRoots || [],
|
|
897
|
+
compatibilityFactRoots: entry.compatibilityFactRoots || [],
|
|
818
898
|
})),
|
|
819
899
|
};
|
|
820
900
|
const digestModel = {
|
|
@@ -846,6 +926,9 @@ export function createBuildchainContractLock({
|
|
|
846
926
|
contract: contractWorld.contract,
|
|
847
927
|
contractDigest: contractWorld.contractDigest,
|
|
848
928
|
compatibilityDigest: contractWorld.compatibilityDigest,
|
|
929
|
+
compatibilityFactRegistryRoot: contractWorld.compatibilityFactRegistryRoot,
|
|
930
|
+
compatibilityFactCutRoot: contractWorld.compatibilityFactCutRoot,
|
|
931
|
+
compatibilityProofRegistryRoot: contractWorld.compatibilityProofRegistryRoot,
|
|
849
932
|
majorLine: contractWorld.majorLine,
|
|
850
933
|
compatibilityPolicy,
|
|
851
934
|
acceptedAt,
|
|
@@ -853,6 +936,8 @@ export function createBuildchainContractLock({
|
|
|
853
936
|
id: entry.id,
|
|
854
937
|
kind: entry.kind,
|
|
855
938
|
breakingDigest: entry.breakingDigest,
|
|
939
|
+
compatibilityProofRoots: entry.compatibilityProofRoots || [],
|
|
940
|
+
compatibilityFactRoots: entry.compatibilityFactRoots || [],
|
|
856
941
|
})),
|
|
857
942
|
},
|
|
858
943
|
};
|
|
@@ -889,143 +974,8 @@ export function readBuildchainContractLock(filePath) {
|
|
|
889
974
|
return value;
|
|
890
975
|
}
|
|
891
976
|
|
|
892
|
-
function
|
|
893
|
-
return
|
|
894
|
-
}
|
|
895
|
-
|
|
896
|
-
function evaluateChannelBinding({
|
|
897
|
-
lock,
|
|
898
|
-
workflowShellRef,
|
|
899
|
-
runtimeRef,
|
|
900
|
-
expectedChannel,
|
|
901
|
-
expectedMajor,
|
|
902
|
-
allowOpaqueRuntime,
|
|
903
|
-
}) {
|
|
904
|
-
if (!workflowShellRef && !expectedChannel && !expectedMajor) return null;
|
|
905
|
-
return evaluateBuildchainChannelBinding({
|
|
906
|
-
workflowShellRef,
|
|
907
|
-
runtimeRef,
|
|
908
|
-
lockRef: lock?.buildchain?.ref || "",
|
|
909
|
-
lockMajorLine: lock?.buildchain?.majorLine || "",
|
|
910
|
-
expectedChannel,
|
|
911
|
-
expectedMajor,
|
|
912
|
-
allowOpaqueRuntime,
|
|
913
|
-
});
|
|
914
|
-
}
|
|
915
|
-
|
|
916
|
-
export function evaluateBuildchainContractLock({
|
|
917
|
-
lock,
|
|
918
|
-
current,
|
|
919
|
-
runtimeRef = "",
|
|
920
|
-
runtimeSha = "",
|
|
921
|
-
runtimeClass = "",
|
|
922
|
-
compatibilityPolicy = "",
|
|
923
|
-
workflowShellRef = "",
|
|
924
|
-
expectedChannel = "",
|
|
925
|
-
expectedMajor = "",
|
|
926
|
-
allowOpaqueRuntime = false,
|
|
927
|
-
} = {}) {
|
|
928
|
-
if (!current || current.contract !== BUILDCHAIN_RUNTIME_CONTRACT_WORLD) {
|
|
929
|
-
throw new Error("current must be a Buildchain runtime contract world");
|
|
930
|
-
}
|
|
931
|
-
const binding = evaluateChannelBinding({
|
|
932
|
-
lock,
|
|
933
|
-
workflowShellRef,
|
|
934
|
-
runtimeRef,
|
|
935
|
-
expectedChannel,
|
|
936
|
-
expectedMajor,
|
|
937
|
-
allowOpaqueRuntime,
|
|
938
|
-
});
|
|
939
|
-
if (binding?.ok === false) {
|
|
940
|
-
return {
|
|
941
|
-
ok: false,
|
|
942
|
-
status: binding.status,
|
|
943
|
-
drift: false,
|
|
944
|
-
compatible: false,
|
|
945
|
-
issueRecommended: false,
|
|
946
|
-
reasons: binding.reasons,
|
|
947
|
-
channelBinding: binding,
|
|
948
|
-
};
|
|
949
|
-
}
|
|
950
|
-
const floatingRuntime = FLOATING_CLASSES.has(runtimeClass);
|
|
951
|
-
if (!floatingRuntime) {
|
|
952
|
-
return {
|
|
953
|
-
ok: true,
|
|
954
|
-
status: "non-floating-runtime",
|
|
955
|
-
drift: false,
|
|
956
|
-
compatible: true,
|
|
957
|
-
issueRecommended: false,
|
|
958
|
-
reason: `runtime class ${runtimeClass || "unknown"} is not a stable floating ref`,
|
|
959
|
-
};
|
|
960
|
-
}
|
|
961
|
-
if (!lock) {
|
|
962
|
-
return {
|
|
963
|
-
ok: true,
|
|
964
|
-
status: "missing-lock",
|
|
965
|
-
drift: false,
|
|
966
|
-
compatible: true,
|
|
967
|
-
issueRecommended: false,
|
|
968
|
-
reason: "consumer repository has no Buildchain contract lock",
|
|
969
|
-
};
|
|
970
|
-
}
|
|
971
|
-
const accepted = lock.buildchain || {};
|
|
972
|
-
const policy = compatibilityPolicy || accepted.compatibilityPolicy || DEFAULT_POLICY;
|
|
973
|
-
const shaDrift = !!accepted.resolvedSha && !!runtimeSha && accepted.resolvedSha !== runtimeSha;
|
|
974
|
-
const contractDrift = !!accepted.contractDigest && accepted.contractDigest !== current.contractDigest;
|
|
975
|
-
if (!shaDrift && !contractDrift) {
|
|
976
|
-
return {
|
|
977
|
-
ok: true,
|
|
978
|
-
status: "unchanged",
|
|
979
|
-
drift: false,
|
|
980
|
-
compatible: true,
|
|
981
|
-
issueRecommended: false,
|
|
982
|
-
policy,
|
|
983
|
-
accepted,
|
|
984
|
-
current: contractSummary(current, runtimeRef, runtimeSha),
|
|
985
|
-
};
|
|
986
|
-
}
|
|
987
|
-
const reasons = [];
|
|
988
|
-
if (accepted.contract !== current.contract) {
|
|
989
|
-
reasons.push(`contract changed from ${accepted.contract || "(unknown)"} to ${current.contract}`);
|
|
990
|
-
}
|
|
991
|
-
if (accepted.majorLine && accepted.majorLine !== current.majorLine) {
|
|
992
|
-
reasons.push(`major line changed from ${accepted.majorLine} to ${current.majorLine}`);
|
|
993
|
-
}
|
|
994
|
-
if (policy === "exact" && accepted.contractDigest !== current.contractDigest) {
|
|
995
|
-
reasons.push("exact policy requires the contract digest to remain unchanged");
|
|
996
|
-
}
|
|
997
|
-
if (!["major-compatible", "allow-additive", "exact"].includes(policy)) {
|
|
998
|
-
reasons.push(`unsupported compatibility policy: ${policy}`);
|
|
999
|
-
}
|
|
1000
|
-
const currentSurfaces = surfaceMap(current.surfaces);
|
|
1001
|
-
for (const oldSurface of accepted.surfaces || []) {
|
|
1002
|
-
const nextSurface = currentSurfaces.get(oldSurface.id);
|
|
1003
|
-
if (!nextSurface) {
|
|
1004
|
-
reasons.push(`surface removed: ${oldSurface.id}`);
|
|
1005
|
-
continue;
|
|
1006
|
-
}
|
|
1007
|
-
const compatibleBreakingDigests = new Set(nextSurface.compatibleBreakingDigests || []);
|
|
1008
|
-
if (
|
|
1009
|
-
nextSurface.breakingDigest !== oldSurface.breakingDigest
|
|
1010
|
-
&& !compatibleBreakingDigests.has(oldSurface.breakingDigest)
|
|
1011
|
-
) {
|
|
1012
|
-
reasons.push(`surface breaking digest changed: ${oldSurface.id}`);
|
|
1013
|
-
}
|
|
1014
|
-
}
|
|
1015
|
-
const compatible = reasons.length === 0;
|
|
1016
|
-
return {
|
|
1017
|
-
ok: compatible,
|
|
1018
|
-
status: compatible ? "compatible-drift" : "breaking-drift",
|
|
1019
|
-
drift: shaDrift || contractDrift,
|
|
1020
|
-
shaDrift,
|
|
1021
|
-
contractDrift,
|
|
1022
|
-
compatible,
|
|
1023
|
-
issueRecommended: true,
|
|
1024
|
-
policy,
|
|
1025
|
-
reasons,
|
|
1026
|
-
accepted,
|
|
1027
|
-
current: contractSummary(current, runtimeRef, runtimeSha),
|
|
1028
|
-
};
|
|
977
|
+
export function evaluateBuildchainContractLock(options = {}) {
|
|
978
|
+
return evaluateFactBackedBuildchainContractLock(options);
|
|
1029
979
|
}
|
|
1030
980
|
|
|
1031
981
|
export function contractSummary(contractWorld, runtimeRef = "", runtimeSha = "") {
|
|
@@ -1035,6 +985,9 @@ export function contractSummary(contractWorld, runtimeRef = "", runtimeSha = "")
|
|
|
1035
985
|
contract: contractWorld.contract,
|
|
1036
986
|
contractDigest: contractWorld.contractDigest,
|
|
1037
987
|
compatibilityDigest: contractWorld.compatibilityDigest,
|
|
988
|
+
compatibilityFactRegistryRoot: contractWorld.compatibilityFactRegistryRoot,
|
|
989
|
+
compatibilityFactCutRoot: contractWorld.compatibilityFactCutRoot,
|
|
990
|
+
compatibilityProofRegistryRoot: contractWorld.compatibilityProofRegistryRoot,
|
|
1038
991
|
majorLine: contractWorld.majorLine,
|
|
1039
992
|
surfaceCount: Array.isArray(contractWorld.surfaces) ? contractWorld.surfaces.length : 0,
|
|
1040
993
|
};
|
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
import { adopterDeliveryGateDigest } from "./adopter-delivery-gate.js";
|
|
2
|
+
import { validateAdopterDeliveryGateResult } from "./adopter-delivery-passport.js";
|
|
3
|
+
|
|
4
|
+
export const BUILDCHAIN_DELIVERY_BOOTSTRAP_CONTRACT =
|
|
5
|
+
"kungfu-buildchain-delivery-infrastructure-bootstrap/v1";
|
|
6
|
+
|
|
7
|
+
const ROOT_PATTERN = /^sha256:[0-9a-f]{64}$/;
|
|
8
|
+
const SHA_PATTERN = /^[0-9a-f]{40}$/;
|
|
9
|
+
const SEMVER_PATTERN =
|
|
10
|
+
/^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-([0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*))?(?:\+[0-9A-Za-z-]+(?:\.[0-9A-Za-z-]+)*)?$/;
|
|
11
|
+
|
|
12
|
+
function issue(code, message) {
|
|
13
|
+
return { code, message };
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
function exactRoot(value) {
|
|
17
|
+
return ROOT_PATTERN.test(value ?? "");
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
function exactCut(cut) {
|
|
21
|
+
return (
|
|
22
|
+
cut &&
|
|
23
|
+
typeof cut === "object" &&
|
|
24
|
+
typeof cut.version === "string" &&
|
|
25
|
+
SHA_PATTERN.test(cut.sourceCommit ?? "") &&
|
|
26
|
+
exactRoot(cut.packageRoot) &&
|
|
27
|
+
exactRoot(cut.gateRoot) &&
|
|
28
|
+
typeof cut.protocol?.id === "string" &&
|
|
29
|
+
typeof cut.protocol?.version === "string" &&
|
|
30
|
+
exactRoot(cut.protocol?.root) &&
|
|
31
|
+
typeof cut.profile?.id === "string" &&
|
|
32
|
+
typeof cut.profile?.version === "string" &&
|
|
33
|
+
exactRoot(cut.profile?.root)
|
|
34
|
+
);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
function parseSemver(value) {
|
|
38
|
+
const match = SEMVER_PATTERN.exec(value ?? "");
|
|
39
|
+
if (!match) return null;
|
|
40
|
+
return {
|
|
41
|
+
core: match.slice(1, 4).map(Number),
|
|
42
|
+
prerelease: match[4] ? match[4].split(".") : [],
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
function compareIdentifier(left, right) {
|
|
47
|
+
const leftNumber = /^\d+$/.test(left) ? Number(left) : null;
|
|
48
|
+
const rightNumber = /^\d+$/.test(right) ? Number(right) : null;
|
|
49
|
+
if (leftNumber !== null && rightNumber !== null) {
|
|
50
|
+
return Math.sign(leftNumber - rightNumber);
|
|
51
|
+
}
|
|
52
|
+
if (leftNumber !== null) return -1;
|
|
53
|
+
if (rightNumber !== null) return 1;
|
|
54
|
+
return left === right ? 0 : left < right ? -1 : 1;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
function compareSemver(leftValue, rightValue) {
|
|
58
|
+
const left = parseSemver(leftValue);
|
|
59
|
+
const right = parseSemver(rightValue);
|
|
60
|
+
if (!left || !right) return null;
|
|
61
|
+
for (let index = 0; index < left.core.length; index += 1) {
|
|
62
|
+
if (left.core[index] !== right.core[index]) {
|
|
63
|
+
return Math.sign(left.core[index] - right.core[index]);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
if (left.prerelease.length === 0 || right.prerelease.length === 0) {
|
|
67
|
+
if (left.prerelease.length === right.prerelease.length) return 0;
|
|
68
|
+
return left.prerelease.length === 0 ? 1 : -1;
|
|
69
|
+
}
|
|
70
|
+
const width = Math.max(left.prerelease.length, right.prerelease.length);
|
|
71
|
+
for (let index = 0; index < width; index += 1) {
|
|
72
|
+
if (left.prerelease[index] === undefined) return -1;
|
|
73
|
+
if (right.prerelease[index] === undefined) return 1;
|
|
74
|
+
const comparison = compareIdentifier(
|
|
75
|
+
left.prerelease[index],
|
|
76
|
+
right.prerelease[index],
|
|
77
|
+
);
|
|
78
|
+
if (comparison !== 0) return comparison;
|
|
79
|
+
}
|
|
80
|
+
return 0;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function sameProtocol(left, right) {
|
|
84
|
+
return (
|
|
85
|
+
left?.id === right?.id &&
|
|
86
|
+
left?.version === right?.version &&
|
|
87
|
+
left?.root === right?.root
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
|
|
91
|
+
function validTransition(transition, authority, candidate) {
|
|
92
|
+
if (!transition || typeof transition !== "object") return false;
|
|
93
|
+
const body = structuredClone(transition);
|
|
94
|
+
const transitionRoot = body.transitionRoot;
|
|
95
|
+
delete body.transitionRoot;
|
|
96
|
+
return (
|
|
97
|
+
exactRoot(transitionRoot) &&
|
|
98
|
+
adopterDeliveryGateDigest(body) === transitionRoot &&
|
|
99
|
+
body.fromGateRoot === authority.gateRoot &&
|
|
100
|
+
body.toGateRoot === candidate.gateRoot &&
|
|
101
|
+
body.fromProtocolRoot === authority.protocol.root &&
|
|
102
|
+
body.toProtocolRoot === candidate.protocol.root &&
|
|
103
|
+
body.fromProfileRoot === authority.profile.root &&
|
|
104
|
+
body.toProfileRoot === candidate.profile.root &&
|
|
105
|
+
exactRoot(body.compatibilityProofRoot) &&
|
|
106
|
+
exactRoot(body.independentReviewRoot)
|
|
107
|
+
);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
function validateWarrant(warrant, candidate) {
|
|
111
|
+
return (
|
|
112
|
+
warrant &&
|
|
113
|
+
typeof warrant === "object" &&
|
|
114
|
+
warrant.outcome === "merged" &&
|
|
115
|
+
warrant.sourceHead === candidate.sourceCommit &&
|
|
116
|
+
exactRoot(warrant.sourceProofRoot) &&
|
|
117
|
+
exactRoot(warrant.nativeProofRoot) &&
|
|
118
|
+
exactRoot(warrant.integrationProofRoot)
|
|
119
|
+
);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
export function qualifyBuildchainDeliveryInfrastructureBootstrap({
|
|
123
|
+
authority,
|
|
124
|
+
candidate,
|
|
125
|
+
gateResult,
|
|
126
|
+
warrant,
|
|
127
|
+
transitionEvidence,
|
|
128
|
+
} = {}) {
|
|
129
|
+
const issues = [];
|
|
130
|
+
if (!exactCut(authority)) {
|
|
131
|
+
issues.push(
|
|
132
|
+
issue("bootstrap.authority.cut", "N-1 authority cut is incomplete"),
|
|
133
|
+
);
|
|
134
|
+
}
|
|
135
|
+
if (!exactCut(candidate)) {
|
|
136
|
+
issues.push(
|
|
137
|
+
issue("bootstrap.candidate.cut", "candidate cut is incomplete"),
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
if (authority?.protected !== true || authority?.published !== true) {
|
|
141
|
+
issues.push(
|
|
142
|
+
issue(
|
|
143
|
+
"bootstrap.authority.release",
|
|
144
|
+
"N-1 authority must be both protected and publicly released",
|
|
145
|
+
),
|
|
146
|
+
);
|
|
147
|
+
}
|
|
148
|
+
if (candidate?.authorityVersion !== authority?.version) {
|
|
149
|
+
issues.push(
|
|
150
|
+
issue(
|
|
151
|
+
"bootstrap.authority.stale",
|
|
152
|
+
"candidate must name the exact N-1 authority version",
|
|
153
|
+
),
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
const versionOrder = compareSemver(authority?.version, candidate?.version);
|
|
157
|
+
if (versionOrder === null || versionOrder >= 0) {
|
|
158
|
+
issues.push(
|
|
159
|
+
issue(
|
|
160
|
+
"bootstrap.authority.order",
|
|
161
|
+
"N-1 authority version must precede the candidate version",
|
|
162
|
+
),
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
if (
|
|
166
|
+
authority?.sourceCommit === candidate?.sourceCommit ||
|
|
167
|
+
authority?.packageRoot === candidate?.packageRoot
|
|
168
|
+
) {
|
|
169
|
+
issues.push(
|
|
170
|
+
issue(
|
|
171
|
+
"bootstrap.self-authorization",
|
|
172
|
+
"candidate source or package cannot serve as its own N-1 authority",
|
|
173
|
+
),
|
|
174
|
+
);
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
const gateValidation = validateAdopterDeliveryGateResult(gateResult);
|
|
178
|
+
if (!gateValidation.passed) {
|
|
179
|
+
issues.push(
|
|
180
|
+
issue(
|
|
181
|
+
"bootstrap.gate.failed",
|
|
182
|
+
"candidate must retain a passed public adopter delivery gate result",
|
|
183
|
+
),
|
|
184
|
+
);
|
|
185
|
+
}
|
|
186
|
+
if (
|
|
187
|
+
gateResult?.artifact?.root !== candidate?.packageRoot ||
|
|
188
|
+
gateResult?.project?.adopterId !== "kungfu-systems/buildchain"
|
|
189
|
+
) {
|
|
190
|
+
issues.push(
|
|
191
|
+
issue(
|
|
192
|
+
"bootstrap.gate.candidate",
|
|
193
|
+
"gate result must bind the exact Buildchain candidate package",
|
|
194
|
+
),
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
if (!validateWarrant(warrant, candidate)) {
|
|
198
|
+
issues.push(
|
|
199
|
+
issue(
|
|
200
|
+
"bootstrap.warrant",
|
|
201
|
+
"merged Delivery Warrant evidence must bind the candidate source",
|
|
202
|
+
),
|
|
203
|
+
);
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
const transitionRequired =
|
|
207
|
+
!sameProtocol(authority?.protocol, candidate?.protocol) ||
|
|
208
|
+
!sameProtocol(authority?.profile, candidate?.profile) ||
|
|
209
|
+
authority?.gateRoot !== candidate?.gateRoot;
|
|
210
|
+
if (
|
|
211
|
+
transitionRequired &&
|
|
212
|
+
!validTransition(transitionEvidence, authority, candidate)
|
|
213
|
+
) {
|
|
214
|
+
issues.push(
|
|
215
|
+
issue(
|
|
216
|
+
"bootstrap.transition",
|
|
217
|
+
"gate, protocol, or profile changes require exact independent transition evidence",
|
|
218
|
+
),
|
|
219
|
+
);
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
const result = {
|
|
223
|
+
schemaVersion: 1,
|
|
224
|
+
contract: BUILDCHAIN_DELIVERY_BOOTSTRAP_CONTRACT,
|
|
225
|
+
status: issues.length === 0 ? "passed" : "failed",
|
|
226
|
+
authority: structuredClone(authority ?? null),
|
|
227
|
+
candidate: structuredClone(candidate ?? null),
|
|
228
|
+
gateResultRoot: gateResult?.gateRoot ?? null,
|
|
229
|
+
warrant: structuredClone(warrant ?? null),
|
|
230
|
+
transitionRequired,
|
|
231
|
+
transitionEvidenceRoot: transitionEvidence?.transitionRoot ?? null,
|
|
232
|
+
issues,
|
|
233
|
+
qualifying: false,
|
|
234
|
+
selfCertified: false,
|
|
235
|
+
releaseAuthorized: false,
|
|
236
|
+
finalAuthority: "protected-n-minus-one-plus-exact-delivery-evidence",
|
|
237
|
+
};
|
|
238
|
+
result.bootstrapRoot = adopterDeliveryGateDigest(result);
|
|
239
|
+
return result;
|
|
240
|
+
}
|