@kungfu-tech/buildchain 3.0.9-alpha.8 → 4.0.0-alpha.0

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.
Files changed (255) hide show
  1. package/AGENTS.md +39 -0
  2. package/README.md +17 -13
  3. package/actions/promote-buildchain-ref/README.md +0 -10
  4. package/actions/release-tail/README.md +6 -10
  5. package/architecture/internal-capabilities.json +502 -0
  6. package/architecture/maintainability-baseline.json +59 -0
  7. package/architecture/maintainability-policy.json +1384 -0
  8. package/architecture/release-tail-contract-inventory.json +587 -0
  9. package/architecture/v3-core-mechanism-inventory.json +1043 -0
  10. package/architecture/v3-core-mechanism-inventory.md +67 -0
  11. package/architecture/v4-adopter-delivery-parity.json +47 -0
  12. package/architecture/v4-architecture-constitution.md +210 -0
  13. package/architecture/v4-bootstrap-authority.json +56 -0
  14. package/architecture/v4-canonical-contract-fixtures.json +105 -0
  15. package/architecture/v4-capability-state-machine-manifest.json +480 -0
  16. package/architecture/v4-capability-state-machine-manifest.schema.json +202 -0
  17. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.json +830 -0
  18. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.md +223 -0
  19. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.schema.json +318 -0
  20. package/architecture/v4-delivery-warrant-shadow-fixtures.json +227 -0
  21. package/architecture/v4-delivery-warrant-shadow-fixtures.schema.json +67 -0
  22. package/architecture/v4-exception-ledger.json +5 -0
  23. package/architecture/v4-exception-ledger.schema.json +56 -0
  24. package/architecture/v4-partial-mutation-recovery-qualification.json +65 -0
  25. package/architecture/v4-platform-stage-checkpoints.json +97 -0
  26. package/architecture/v4-provider-operation-journal-contract.json +113 -0
  27. package/architecture/v4-release-activation-shadow-domain.json +61 -0
  28. package/architecture/v4-release-train-parity.json +68 -0
  29. package/architecture/v4-rust-libnode-bridge-evaluation.json +107 -0
  30. package/architecture/v4-rust-libnode-bridge-spike.md +85 -0
  31. package/architecture/v4-stable-publication-fence.json +66 -0
  32. package/architecture/v4-stage-capsule-contract.json +90 -0
  33. package/architecture/v4-stage-capsule-qualification.json +99 -0
  34. package/architecture/v4-stage-capsule-resume-planner.json +52 -0
  35. package/architecture/v4-stage-capsule-store-contract.json +72 -0
  36. package/bin/buildchain.mjs +15 -6
  37. package/contracts/auditable-demo-scenario-v1.schema.json +1 -1
  38. package/contracts/buildchain-v2-residuals-v1.json +2 -2
  39. package/contracts/fixtures/v4-delivery-warrant-trace-v1/golden.json +158 -0
  40. package/contracts/fixtures/v4-delivery-warrant-trace-v1/property.json +380 -0
  41. package/contracts/fixtures/v4-delivery-warrant-trace-v1/replay.json +163 -0
  42. package/contracts/fixtures/v4-partial-mutation-recovery-v1/shared.json +155 -0
  43. package/contracts/fixtures/v4-provider-operation-journal-v1/shared.json +457 -0
  44. package/contracts/fixtures/v4-provider-readback-idempotency-v1/shared.json +682 -0
  45. package/contracts/fixtures/v4-release-activation-shadow-v1/shared.json +53 -0
  46. package/contracts/fixtures/v4-stable-publication-fence-v1/shared.json +56 -0
  47. package/contracts/fixtures/v4-stage-capsule-resume-v1/late-platform-failure.json +176 -0
  48. package/contracts/fixtures/v4-stage-capsule-store-v1/shared.json +132 -0
  49. package/contracts/fixtures/v4-stage-capsule-v1/shared.json +111 -0
  50. package/contracts/v4-canonical-contracts-v1.schema.json +182 -0
  51. package/contracts/v4-delivery-warrant-semantic-diff-report-v1.schema.json +284 -0
  52. package/contracts/v4-delivery-warrant-trace-v1.schema.json +215 -0
  53. package/contracts/v4-host-contract-v1.schema.json +135 -0
  54. package/contracts/v4-partial-mutation-recovery-v1.schema.json +168 -0
  55. package/contracts/v4-provider-operation-journal-v1.schema.json +381 -0
  56. package/contracts/v4-release-activation-shadow-v1.schema.json +186 -0
  57. package/contracts/v4-stable-publication-fence-v1.schema.json +125 -0
  58. package/contracts/v4-stage-capsule-resume-v1.schema.json +225 -0
  59. package/contracts/v4-stage-capsule-store-v1.schema.json +154 -0
  60. package/contracts/v4-stage-capsule-v1.schema.json +178 -0
  61. package/crates/buildchain-v4-bridge/Cargo.lock +213 -0
  62. package/crates/buildchain-v4-bridge/Cargo.toml +12 -0
  63. package/crates/buildchain-v4-bridge/src/main.rs +495 -0
  64. package/dist/site/agent-index.json +0 -3
  65. package/dist/site/artifact-schemas.json +0 -6
  66. package/dist/site/buildchain-contract.json +103 -397
  67. package/dist/site/buildchain-site.json +302 -270
  68. package/dist/site/capability-registry.json +9 -11
  69. package/dist/site/cli-registry.json +8 -30
  70. package/dist/site/controller-registry.json +48 -8
  71. package/dist/site/kfd-claims.json +129 -142
  72. package/dist/site/kfd-upstream-aggregate.json +9 -9
  73. package/dist/site/manual-registry.json +18 -49
  74. package/dist/site/node-api-registry.json +1882 -4118
  75. package/dist/site/page-registry.json +278 -230
  76. package/dist/site/public-surface-audit.json +87 -185
  77. package/dist/site/publication-authority-registry.json +11 -1
  78. package/dist/site/publication-registry.json +4 -4
  79. package/dist/site/release-provenance.json +3 -7
  80. package/dist/site/schemas/kfd-support-projection-v1.schema.json +106 -0
  81. package/dist/site/site-manifest.json +22 -38
  82. package/dist/site/workflow-registry.json +80 -35
  83. package/docs/MAP.md +8 -4
  84. package/docs/auditable-demo.md +2 -2
  85. package/docs/aws-us-elastic-runner-burst-plane.md +7 -59
  86. package/docs/cli-reference.md +15 -92
  87. package/docs/cli.md +14 -14
  88. package/docs/dev-alpha-candidate-patrol.md +3 -11
  89. package/docs/dev-delivery-warrant.md +28 -100
  90. package/docs/engineering-housekeeper.md +12 -4
  91. package/docs/getting-started.md +1 -1
  92. package/docs/install.md +5 -5
  93. package/docs/kfd-support.md +2 -7
  94. package/docs/lifecycle-protocol.md +2 -4
  95. package/docs/node-api-reference.md +414 -523
  96. package/docs/release-flow.md +31 -31
  97. package/docs/release-governance.md +16 -28
  98. package/docs/release-passport.md +2 -15
  99. package/docs/release-tail-contract.md +13 -6
  100. package/docs/release-tail-provider-plane.md +13 -19
  101. package/docs/release-train.md +4 -4
  102. package/docs/reusable-build-surface.md +14 -27
  103. package/docs/site-bundle-contract.md +1 -5
  104. package/docs/stable-candidate-patrol.md +7 -7
  105. package/docs/v4-canonical-contracts.md +92 -0
  106. package/docs/v4-delivery-warrant-read-candidate.md +73 -0
  107. package/docs/v4-delivery-warrant-semantic-diff.md +75 -0
  108. package/docs/v4-production-release.md +63 -0
  109. package/docs/v4-stage-capsule.md +193 -0
  110. package/docs/versioning.md +3 -3
  111. package/package.json +19 -17
  112. package/packages/core/adopter-delivery-gate.js +576 -0
  113. package/packages/core/adopter-delivery-json.js +66 -0
  114. package/packages/core/artifact-signing.js +0 -61
  115. package/packages/core/artifact-verification-envelope.js +5 -5
  116. package/packages/core/build-facts.js +12 -4
  117. package/packages/core/buildchain-agent-manuals.js +0 -2
  118. package/packages/core/buildchain-config.js +4 -69
  119. package/packages/core/buildchain-contract.js +232 -46
  120. package/packages/core/buildchain-kfd-claims.js +1 -1
  121. package/packages/core/channel-candidate.js +0 -8
  122. package/packages/core/channel-promotion-baseline.js +0 -52
  123. package/packages/core/controller-evidence.js +3 -4
  124. package/packages/core/dev-alpha-candidate-selection.js +2 -10
  125. package/packages/core/dev-delivery-warrant-cancellation.js +0 -1
  126. package/packages/core/dev-delivery-warrant-settlement.js +1 -5
  127. package/packages/core/dev-delivery-warrant.js +12 -52
  128. package/packages/core/diagnostics.js +3 -8
  129. package/packages/core/github-governance-authority.js +3 -1
  130. package/packages/core/kfd-adopter-category-driver.js +167 -0
  131. package/packages/core/kfd-adopter-manifest.js +47 -46
  132. package/packages/core/kfd-gate.js +15 -45
  133. package/packages/core/paper-agent-entry.js +7 -16
  134. package/packages/core/paper-fleet.js +2 -2
  135. package/packages/core/paper-repository.js +2 -3
  136. package/packages/core/paper-scaffold-content.js +2 -23
  137. package/packages/core/paper.js +11 -43
  138. package/packages/core/publication-reproducibility.js +4 -4
  139. package/packages/core/release-line-bootstrap.js +21 -8
  140. package/packages/core/release-passport-contract.js +5 -5
  141. package/packages/core/release-passport.js +20 -131
  142. package/packages/core/self-dogfood-version.js +48 -35
  143. package/packages/core/spawn-command.js +232 -8
  144. package/packages/core/v4-adopter-delivery-parity.js +219 -0
  145. package/packages/core/v4-canonical-contracts.js +284 -0
  146. package/packages/core/v4-delivery-warrant-fixture-runner.js +371 -0
  147. package/packages/core/v4-delivery-warrant-read-candidate.js +279 -0
  148. package/packages/core/v4-delivery-warrant-semantic-diff-gate.js +352 -0
  149. package/packages/core/v4-delivery-warrant-shadow-adapter.js +447 -0
  150. package/packages/core/v4-partial-mutation-recovery-qualification.js +395 -0
  151. package/packages/core/v4-platform-stage-checkpoints.js +471 -0
  152. package/packages/core/v4-provider-operation-journal.js +531 -0
  153. package/packages/core/v4-provider-readback-idempotency.js +394 -0
  154. package/packages/core/v4-release-activation-shadow.js +519 -0
  155. package/packages/core/v4-stable-publication-fence.js +357 -0
  156. package/packages/core/v4-stage-capsule-local-store.js +426 -0
  157. package/packages/core/v4-stage-capsule-qualification-campaign.js +512 -0
  158. package/packages/core/v4-stage-capsule-qualification.js +456 -0
  159. package/packages/core/v4-stage-capsule-resume-planner.js +397 -0
  160. package/packages/core/v4-stage-capsule-store.js +401 -0
  161. package/packages/core/v4-stage-capsule.js +319 -0
  162. package/scripts/assemble-self-publication-admission.mjs +1 -1
  163. package/scripts/audit-publication-control-plane.mjs +5 -5
  164. package/scripts/auditable-demo-bundle-verification.mjs +3 -2
  165. package/scripts/auditable-demo-platform.mjs +2 -2
  166. package/scripts/auditable-demo-renditions.mjs +1 -1
  167. package/scripts/auditable-demo.mjs +2 -2
  168. package/scripts/aws-macos-jit-controller-core.mjs +13 -346
  169. package/scripts/aws-macos-jit-controller-runtime.mjs +2 -210
  170. package/scripts/aws-macos-jit-controller.mjs +37 -275
  171. package/scripts/aws-macos-jit-core.mjs +3 -41
  172. package/scripts/aws-macos-jit.mjs +0 -12
  173. package/scripts/aws-windows-jit-campaign.mjs +2 -2
  174. package/scripts/aws-windows-jit-controller-core.mjs +1 -1
  175. package/scripts/aws-windows-jit-controller.mjs +3 -3
  176. package/scripts/build-contract-core.mjs +3 -8
  177. package/scripts/build-standalone-binary.mjs +3 -14
  178. package/scripts/buildchain-channel-router.mjs +4 -0
  179. package/scripts/buildchain-cli-help.mjs +7 -13
  180. package/scripts/buildchain-contract-lock.mjs +0 -6
  181. package/scripts/check-action-bundles.mjs +3 -4
  182. package/scripts/check-internal-architecture.mjs +7 -6
  183. package/scripts/check-inventory.mjs +30 -25
  184. package/scripts/check-v4-public-dogfood-contract.mjs +270 -0
  185. package/scripts/create-release-bundle.mjs +8 -4
  186. package/scripts/dev-alpha-candidate-patrol.mjs +1 -22
  187. package/scripts/dev-delivery-proof.mjs +2 -54
  188. package/scripts/dev-delivery-warrant.mjs +59 -77
  189. package/scripts/dev-pr-auto-merge.mjs +4 -30
  190. package/scripts/dev-pr-delivery-warrant.mjs +0 -55
  191. package/scripts/dispatch-artifact-signing-authority.mjs +7 -4
  192. package/scripts/generate-buildchain-kfd-witnesses.mjs +94 -88
  193. package/scripts/generate-channel-build-workflow.mjs +54 -24
  194. package/scripts/generate-channel-promotion-workflow.mjs +15 -6
  195. package/scripts/generate-site-bundle.mjs +5 -21
  196. package/scripts/git-fetch-process-tree.mjs +34 -1
  197. package/scripts/init-repo.mjs +64 -159
  198. package/scripts/inspect-artifact-signing-requests.mjs +0 -6
  199. package/scripts/locked-source-checkout.mjs +3 -4
  200. package/scripts/maintainability-metrics.mjs +8 -2
  201. package/scripts/npm-publish-dry-run.mjs +2 -2
  202. package/scripts/npm-publish-transaction.mjs +2 -2
  203. package/scripts/publication-commit-evidence.mjs +23 -69
  204. package/scripts/release-candidate-resolver.mjs +11 -17
  205. package/scripts/release-tail.mjs +3 -49
  206. package/scripts/resume-from-candidate-run.mjs +9 -123
  207. package/scripts/run-lifecycle-core.mjs +12 -13
  208. package/scripts/seal-artifact-signing-requests.mjs +17 -21
  209. package/scripts/site-capability-metadata.mjs +2 -7
  210. package/scripts/stable-candidate-qualification.mjs +10 -10
  211. package/scripts/v4-architecture.mjs +12 -2
  212. package/scripts/v4-bridge-bootstrap.mjs +141 -0
  213. package/scripts/v4-bridge-evidence.mjs +141 -0
  214. package/scripts/v4-host-adapter.mjs +182 -0
  215. package/scripts/v4-platform-stage-checkpoint-rehearsal.mjs +207 -0
  216. package/scripts/v4-stage-capsule-qualification.mjs +528 -0
  217. package/scripts/v4-stage-capsule-resume-rehearsal.mjs +57 -0
  218. package/scripts/v4-warrant-shadow-plan.mjs +601 -0
  219. package/scripts/verify-golden-path.mjs +5 -5
  220. package/scripts/web-surface-cloudfront-rewrite.mjs +15 -15
  221. package/scripts/web-surface-core.mjs +2 -8
  222. package/scripts/workflow-call-contract.mjs +5 -184
  223. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-perspective.json +0 -16
  224. package/contracts/fixtures/kfd-adopter-release-v1/kfd-4-replay.json +0 -57
  225. package/contracts/fixtures/next-development-transition-v1/anchored-manual-waiting.json +0 -47
  226. package/contracts/fixtures/next-development-transition-v1/semver-auto-planned.json +0 -47
  227. package/contracts/fixtures/next-development-transition-v1/version-model-cases.json +0 -40
  228. package/contracts/next-development-request-v1.schema.json +0 -66
  229. package/contracts/next-development-transition-v1.schema.json +0 -292
  230. package/contracts/publication-rehearsal-capsule-v1.schema.json +0 -173
  231. package/dist/site/schemas/publication-rehearsal-capsule-v1.schema.json +0 -269
  232. package/dist/site/schemas/release-tail-capabilities-v1.schema.json +0 -353
  233. package/dist/site/schemas/release-tail-provider-bindings-v1.schema.json +0 -94
  234. package/docs/next-development-transition.md +0 -119
  235. package/docs/publication-rehearsal.md +0 -94
  236. package/packages/core/buildchain-compatibility-proof.js +0 -631
  237. package/packages/core/dev-delivery-native-proof.js +0 -333
  238. package/packages/core/dev-delivery-warrant-shadow.js +0 -502
  239. package/packages/core/next-development-candidate-reservation.js +0 -186
  240. package/packages/core/next-development-controller.js +0 -726
  241. package/packages/core/next-development-projection.js +0 -288
  242. package/packages/core/next-development-transition.js +0 -738
  243. package/packages/core/publication-rehearsal-projection.js +0 -173
  244. package/packages/core/publication-rehearsal-runtime.js +0 -921
  245. package/scripts/aws-macos-jit-instance-rehydrate.mjs +0 -260
  246. package/scripts/aws-macos-jit-source-rebind.mjs +0 -724
  247. package/scripts/dev-delivery-native-run.mjs +0 -187
  248. package/scripts/dev-delivery-two-phase.mjs +0 -598
  249. package/scripts/generate-next-development-guidance.mjs +0 -49
  250. package/scripts/materialize-self-release-candidate-version.mjs +0 -137
  251. package/scripts/next-development-self-dogfood-harness.mjs +0 -409
  252. package/scripts/next-development-self-dogfood.mjs +0 -532
  253. package/scripts/next-development-transition.mjs +0 -47
  254. package/scripts/release-candidate-tail-reseal.mjs +0 -426
  255. package/templates/native-dev-delivery.yml +0 -82
@@ -0,0 +1,394 @@
1
+ import {
2
+ V4ContractFault,
3
+ v4ContentRoot,
4
+ validateV4Clock,
5
+ validateV4Root,
6
+ } from "./v4-canonical-contracts.js";
7
+ import {
8
+ V4_PROVIDER_OPERATION_OBSERVATION_CONTRACT,
9
+ v4ProviderOperationJournalStateRoot,
10
+ v4ProviderOperationEntryRoot,
11
+ validateV4ProviderOperationEntry,
12
+ } from "./v4-provider-operation-journal.js";
13
+
14
+ export const V4_PROVIDER_READBACK_SAMPLE_CONTRACT =
15
+ "buildchain-v4-provider-readback-sample/v1";
16
+ export const V4_PROVIDER_READBACK_FOLD_CONTRACT =
17
+ "buildchain-v4-provider-readback-fold/v1";
18
+
19
+ const PROVIDERS = Object.freeze({
20
+ github: {
21
+ schema: "buildchain-v4-github-release-readback/v1",
22
+ subject: "assetSubjectRoot",
23
+ target: "assetTargetRoot",
24
+ statuses: {
25
+ 200: "already-applied",
26
+ 202: "eventually-visible",
27
+ 404: "not-found",
28
+ },
29
+ conflict: 409,
30
+ },
31
+ npm: {
32
+ schema: "buildchain-v4-npm-publication-readback/v1",
33
+ subject: "packageSubjectRoot",
34
+ target: "versionTargetRoot",
35
+ statuses: {
36
+ published: "already-applied",
37
+ processing: "eventually-visible",
38
+ "not-found": "not-found",
39
+ },
40
+ conflict: "conflict",
41
+ },
42
+ oci: {
43
+ schema: "buildchain-v4-oci-manifest-readback/v1",
44
+ subject: "repositorySubjectRoot",
45
+ target: "manifestTargetRoot",
46
+ statuses: {
47
+ 200: "already-applied",
48
+ 202: "eventually-visible",
49
+ 404: "not-found",
50
+ },
51
+ conflict: 409,
52
+ },
53
+ });
54
+
55
+ function fault(code, path, message) {
56
+ throw new V4ContractFault(code, path, message);
57
+ }
58
+
59
+ function exactKeys(value, keys, path) {
60
+ if (!value || typeof value !== "object" || Array.isArray(value))
61
+ fault("malformed-provider-readback", path, `${path} must be an object`);
62
+ const actual = Object.keys(value).sort();
63
+ const expected = [...keys].sort();
64
+ if (
65
+ actual.length !== expected.length ||
66
+ actual.some((key, index) => key !== expected[index])
67
+ )
68
+ fault(
69
+ "malformed-provider-readback",
70
+ path,
71
+ `${path} keys are not canonical`,
72
+ );
73
+ }
74
+
75
+ function validateContext(context) {
76
+ exactKeys(
77
+ context,
78
+ ["operationRoot", "attemptRoot", "subjectRoot", "expectedTargetRoot"],
79
+ "$/context",
80
+ );
81
+ for (const key of Object.keys(context))
82
+ validateV4Root(context[key], `$/context/${key}`);
83
+ }
84
+
85
+ function sampleRoot(sample) {
86
+ const { sampleRoot: _sampleRoot, ...payload } = sample;
87
+ return v4ContentRoot("provider-readback-sample", payload);
88
+ }
89
+
90
+ function validateSample(sample, path = "$/samples") {
91
+ exactKeys(
92
+ sample,
93
+ [
94
+ "schema",
95
+ "operationRoot",
96
+ "attemptRoot",
97
+ "state",
98
+ "observedTargetRoot",
99
+ "evidenceRoots",
100
+ "sampleRoot",
101
+ ],
102
+ path,
103
+ );
104
+ if (sample.schema !== V4_PROVIDER_READBACK_SAMPLE_CONTRACT)
105
+ fault(
106
+ "unsupported-provider-readback-version",
107
+ `${path}/schema`,
108
+ "unsupported provider readback sample schema",
109
+ );
110
+ if (
111
+ !["not-found", "eventually-visible", "already-applied"].includes(
112
+ sample.state,
113
+ )
114
+ )
115
+ fault(
116
+ "malformed-provider-readback",
117
+ `${path}/state`,
118
+ "provider readback state is unsupported",
119
+ );
120
+ for (const key of ["operationRoot", "attemptRoot", "sampleRoot"])
121
+ validateV4Root(sample[key], `${path}/${key}`);
122
+ if (sample.observedTargetRoot !== null)
123
+ validateV4Root(sample.observedTargetRoot, `${path}/observedTargetRoot`);
124
+ if (
125
+ !Array.isArray(sample.evidenceRoots) ||
126
+ sample.evidenceRoots.length === 0 ||
127
+ sample.evidenceRoots.some(
128
+ (root, index) => (
129
+ validateV4Root(root, `${path}/evidenceRoots/${index}`),
130
+ false
131
+ ),
132
+ )
133
+ )
134
+ fault(
135
+ "malformed-provider-readback",
136
+ `${path}/evidenceRoots`,
137
+ "evidenceRoots must not be empty",
138
+ );
139
+ const sortedEvidence = [...new Set(sample.evidenceRoots)].sort();
140
+ if (JSON.stringify(sortedEvidence) !== JSON.stringify(sample.evidenceRoots))
141
+ fault(
142
+ "malformed-provider-readback",
143
+ `${path}/evidenceRoots`,
144
+ "evidenceRoots must be unique and byte-sorted",
145
+ );
146
+ if (
147
+ (sample.state === "already-applied") !==
148
+ (sample.observedTargetRoot !== null)
149
+ )
150
+ fault(
151
+ "malformed-provider-readback",
152
+ `${path}/observedTargetRoot`,
153
+ "only already-applied readback may carry an observed target root",
154
+ );
155
+ if (sample.sampleRoot !== sampleRoot(sample))
156
+ fault(
157
+ "provider-readback-root-mismatch",
158
+ `${path}/sampleRoot`,
159
+ "sampleRoot does not bind the provider-neutral readback",
160
+ );
161
+ return sample;
162
+ }
163
+
164
+ function adaptProviderReadback(provider, response, context) {
165
+ const descriptor = PROVIDERS[provider];
166
+ if (!descriptor)
167
+ fault(
168
+ "unsupported-provider-readback-version",
169
+ "$/provider",
170
+ "provider readback adapter is unsupported",
171
+ );
172
+ validateContext(context);
173
+ exactKeys(
174
+ response,
175
+ ["schema", "status", descriptor.subject, descriptor.target, "evidenceRoot"],
176
+ "$/response",
177
+ );
178
+ if (response.schema !== descriptor.schema)
179
+ fault(
180
+ "unsupported-provider-readback-version",
181
+ "$/response/schema",
182
+ "provider response schema does not match its adapter",
183
+ );
184
+ validateV4Root(
185
+ response[descriptor.subject],
186
+ `$/response/${descriptor.subject}`,
187
+ );
188
+ validateV4Root(response.evidenceRoot, "$/response/evidenceRoot");
189
+ if (response[descriptor.target] !== null)
190
+ validateV4Root(
191
+ response[descriptor.target],
192
+ `$/response/${descriptor.target}`,
193
+ );
194
+ if (response[descriptor.subject] !== context.subjectRoot)
195
+ fault(
196
+ "provider-readback-root-mismatch",
197
+ `$/response/${descriptor.subject}`,
198
+ "provider response subject does not bind the operation subject",
199
+ );
200
+ if (response.status === descriptor.conflict)
201
+ fault(
202
+ "conflicting-provider-readback",
203
+ "$/response/status",
204
+ "provider reported a conflicting target",
205
+ );
206
+ const state = descriptor.statuses[response.status];
207
+ if (!state)
208
+ fault(
209
+ "malformed-provider-readback",
210
+ "$/response/status",
211
+ "provider response status is unsupported",
212
+ );
213
+ const observedTargetRoot = response[descriptor.target];
214
+ if (state === "already-applied") {
215
+ if (observedTargetRoot !== context.expectedTargetRoot)
216
+ fault(
217
+ "provider-readback-root-mismatch",
218
+ `$/response/${descriptor.target}`,
219
+ "successful provider response does not bind the expected target",
220
+ );
221
+ } else if (observedTargetRoot !== null) {
222
+ fault(
223
+ "conflicting-provider-readback",
224
+ `$/response/${descriptor.target}`,
225
+ "non-success provider response carries an ambiguous target",
226
+ );
227
+ }
228
+ const sample = {
229
+ schema: V4_PROVIDER_READBACK_SAMPLE_CONTRACT,
230
+ operationRoot: context.operationRoot,
231
+ attemptRoot: context.attemptRoot,
232
+ state,
233
+ observedTargetRoot,
234
+ evidenceRoots: [response.evidenceRoot],
235
+ sampleRoot:
236
+ "sha256:0000000000000000000000000000000000000000000000000000000000000000",
237
+ };
238
+ sample.sampleRoot = sampleRoot(sample);
239
+ return validateSample(sample);
240
+ }
241
+
242
+ export function adaptV4GitHubReleaseReadback(response, context) {
243
+ return adaptProviderReadback("github", response, context);
244
+ }
245
+
246
+ export function adaptV4NpmPublicationReadback(response, context) {
247
+ return adaptProviderReadback("npm", response, context);
248
+ }
249
+
250
+ export function adaptV4OciManifestReadback(response, context) {
251
+ return adaptProviderReadback("oci", response, context);
252
+ }
253
+
254
+ export function foldV4ProviderReadbackSamples(samples, coordinates) {
255
+ exactKeys(
256
+ coordinates,
257
+ [
258
+ "sequence",
259
+ "priorEntryRoot",
260
+ "operationRoot",
261
+ "attemptRoot",
262
+ "observedAt",
263
+ ],
264
+ "$/coordinates",
265
+ );
266
+ if (!Number.isSafeInteger(coordinates.sequence) || coordinates.sequence < 0)
267
+ fault(
268
+ "malformed-provider-readback",
269
+ "$/coordinates/sequence",
270
+ "readback sequence must be a non-negative safe integer",
271
+ );
272
+ for (const key of ["priorEntryRoot", "operationRoot", "attemptRoot"])
273
+ validateV4Root(coordinates[key], `$/coordinates/${key}`);
274
+ validateV4Clock(coordinates.observedAt, "$/coordinates/observedAt");
275
+ if (!Array.isArray(samples) || samples.length === 0)
276
+ fault(
277
+ "malformed-provider-readback",
278
+ "$/samples",
279
+ "at least one rooted provider readback sample is required",
280
+ );
281
+ const unique = new Map();
282
+ for (const [index, sample] of samples.entries()) {
283
+ validateSample(sample, `$/samples/${index}`);
284
+ if (
285
+ sample.operationRoot !== coordinates.operationRoot ||
286
+ sample.attemptRoot !== coordinates.attemptRoot
287
+ )
288
+ fault(
289
+ "provider-readback-coordinate-mismatch",
290
+ `$/samples/${index}`,
291
+ "provider readback sample does not bind the journal coordinates",
292
+ );
293
+ unique.set(sample.sampleRoot, sample);
294
+ }
295
+ const folded = [...unique.values()].sort((left, right) =>
296
+ left.sampleRoot.localeCompare(right.sampleRoot),
297
+ );
298
+ const states = new Set(folded.map((sample) => sample.state));
299
+ if (states.has("already-applied") && states.size !== 1)
300
+ fault(
301
+ "conflicting-provider-readback",
302
+ "$/samples",
303
+ "successful and unresolved readbacks cannot describe one attempt",
304
+ );
305
+ const targets = new Set(
306
+ folded.map((sample) => sample.observedTargetRoot).filter(Boolean),
307
+ );
308
+ if (targets.size > 1)
309
+ fault(
310
+ "conflicting-provider-readback",
311
+ "$/samples",
312
+ "provider readbacks disagree about the observed target",
313
+ );
314
+ const classification = states.has("already-applied")
315
+ ? "already-applied"
316
+ : states.has("eventually-visible")
317
+ ? "eventually-visible"
318
+ : "not-found";
319
+ const readbackRoots = folded.map((sample) => sample.sampleRoot);
320
+ const observation = {
321
+ kind: "observation",
322
+ schema: V4_PROVIDER_OPERATION_OBSERVATION_CONTRACT,
323
+ sequence: coordinates.sequence,
324
+ priorEntryRoot: coordinates.priorEntryRoot,
325
+ operationRoot: coordinates.operationRoot,
326
+ attemptRoot: coordinates.attemptRoot,
327
+ observedAt: coordinates.observedAt,
328
+ status: classification === "already-applied" ? "succeeded" : "unknown",
329
+ evidenceRoots: readbackRoots,
330
+ entryRoot:
331
+ "sha256:0000000000000000000000000000000000000000000000000000000000000000",
332
+ };
333
+ observation.entryRoot = v4ProviderOperationEntryRoot(observation);
334
+ validateV4ProviderOperationEntry(observation);
335
+ const projection = {
336
+ schema: V4_PROVIDER_READBACK_FOLD_CONTRACT,
337
+ classification,
338
+ readbackRoots,
339
+ observation,
340
+ projectionRoot:
341
+ "sha256:0000000000000000000000000000000000000000000000000000000000000000",
342
+ };
343
+ const { projectionRoot: _projectionRoot, ...payload } = projection;
344
+ projection.projectionRoot = v4ContentRoot("provider-readback-fold", payload);
345
+ return projection;
346
+ }
347
+
348
+ const ADAPTERS = Object.freeze({
349
+ github: adaptV4GitHubReleaseReadback,
350
+ npm: adaptV4NpmPublicationReadback,
351
+ oci: adaptV4OciManifestReadback,
352
+ });
353
+
354
+ export function projectV4ProviderReadbackFixtures(fixtures) {
355
+ const projectCase = (fixture) => {
356
+ const samples = fixture.readbacks.map(({ provider, response }) =>
357
+ ADAPTERS[provider](response, fixtures.context),
358
+ );
359
+ if (JSON.stringify(samples) !== JSON.stringify(fixture.neutralSamples))
360
+ fault(
361
+ "provider-readback-fixture-mismatch",
362
+ "$/neutralSamples",
363
+ "provider adapters did not produce the retained neutral samples",
364
+ );
365
+ const projection = foldV4ProviderReadbackSamples(
366
+ samples,
367
+ fixtures.coordinates,
368
+ );
369
+ return {
370
+ id: fixture.id,
371
+ ...projection,
372
+ journalStateRoot: v4ProviderOperationJournalStateRoot([
373
+ ...fixtures.journalPrefix,
374
+ projection.observation,
375
+ ]),
376
+ };
377
+ };
378
+ const validCases = fixtures.validCases.map(projectCase);
379
+ const invalidCases = fixtures.invalidCases.map((fixture) => {
380
+ try {
381
+ projectCase(fixture);
382
+ } catch (error) {
383
+ if (error instanceof V4ContractFault)
384
+ return { id: fixture.id, fault: error.code };
385
+ throw error;
386
+ }
387
+ fault(
388
+ "malformed-provider-readback",
389
+ "$/invalidCases",
390
+ `fixture ${fixture.id} unexpectedly passed`,
391
+ );
392
+ });
393
+ return { validCases, invalidCases };
394
+ }