@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,531 @@
1
+ import {
2
+ V4ContractFault,
3
+ v4ContentRoot,
4
+ validateV4Clock,
5
+ validateV4Root,
6
+ } from "./v4-canonical-contracts.js";
7
+
8
+ export const V4_PROVIDER_OPERATION_IDENTITY_CONTRACT =
9
+ "buildchain-v4-provider-operation-identity/v1";
10
+ export const V4_PROVIDER_OPERATION_INTENT_CONTRACT =
11
+ "buildchain-v4-provider-operation-intent/v1";
12
+ export const V4_PROVIDER_OPERATION_ATTEMPT_CONTRACT =
13
+ "buildchain-v4-provider-operation-attempt/v1";
14
+ export const V4_PROVIDER_OPERATION_OBSERVATION_CONTRACT =
15
+ "buildchain-v4-provider-operation-observation/v1";
16
+ export const V4_PROVIDER_OPERATION_CONFIRMATION_CONTRACT =
17
+ "buildchain-v4-provider-operation-confirmation/v1";
18
+ export const V4_PROVIDER_OPERATION_RECONCILIATION_CONTRACT =
19
+ "buildchain-v4-provider-operation-reconciliation/v1";
20
+ export const V4_PROVIDER_OPERATION_JOURNAL_STATE_CONTRACT =
21
+ "buildchain-v4-provider-operation-journal-state/v1";
22
+
23
+ const TOKEN = /^[a-z][a-z0-9]*(?:-[a-z0-9]+)*$/u;
24
+ const CAPABILITY = /^[a-z][a-z0-9]*(?:[.-][a-z0-9]+)*$/u;
25
+ const ENTRY = Object.freeze({
26
+ intent: {
27
+ schema: V4_PROVIDER_OPERATION_INTENT_CONTRACT,
28
+ domain: "provider-operation-intent",
29
+ keys: [
30
+ "kind",
31
+ "schema",
32
+ "sequence",
33
+ "priorEntryRoot",
34
+ "operation",
35
+ "operationRoot",
36
+ "declaredAt",
37
+ "inputRoot",
38
+ "entryRoot",
39
+ ],
40
+ },
41
+ attempt: {
42
+ schema: V4_PROVIDER_OPERATION_ATTEMPT_CONTRACT,
43
+ domain: "provider-operation-attempt",
44
+ keys: [
45
+ "kind",
46
+ "schema",
47
+ "sequence",
48
+ "priorEntryRoot",
49
+ "operationRoot",
50
+ "attemptOrdinal",
51
+ "attemptedAt",
52
+ "effectRoot",
53
+ "entryRoot",
54
+ ],
55
+ },
56
+ observation: {
57
+ schema: V4_PROVIDER_OPERATION_OBSERVATION_CONTRACT,
58
+ domain: "provider-operation-observation",
59
+ keys: [
60
+ "kind",
61
+ "schema",
62
+ "sequence",
63
+ "priorEntryRoot",
64
+ "operationRoot",
65
+ "attemptRoot",
66
+ "observedAt",
67
+ "status",
68
+ "evidenceRoots",
69
+ "entryRoot",
70
+ ],
71
+ },
72
+ confirmation: {
73
+ schema: V4_PROVIDER_OPERATION_CONFIRMATION_CONTRACT,
74
+ domain: "provider-operation-confirmation",
75
+ keys: [
76
+ "kind",
77
+ "schema",
78
+ "sequence",
79
+ "priorEntryRoot",
80
+ "operationRoot",
81
+ "observationRoot",
82
+ "authorityRoot",
83
+ "confirmedAt",
84
+ "outcome",
85
+ "entryRoot",
86
+ ],
87
+ },
88
+ reconciliation: {
89
+ schema: V4_PROVIDER_OPERATION_RECONCILIATION_CONTRACT,
90
+ domain: "provider-operation-reconciliation",
91
+ keys: [
92
+ "kind",
93
+ "schema",
94
+ "sequence",
95
+ "priorEntryRoot",
96
+ "operationRoot",
97
+ "observationRoot",
98
+ "authorityRoot",
99
+ "reconciledAt",
100
+ "disposition",
101
+ "entryRoot",
102
+ ],
103
+ },
104
+ });
105
+
106
+ function fault(code, path, message) {
107
+ throw new V4ContractFault(code, path, message);
108
+ }
109
+
110
+ function exactKeys(value, keys, path) {
111
+ if (!value || typeof value !== "object" || Array.isArray(value))
112
+ fault(
113
+ "invalid-provider-operation-shape",
114
+ path,
115
+ `${path} must be an object`,
116
+ );
117
+ const actual = Object.keys(value).sort();
118
+ const expected = [...keys].sort();
119
+ if (
120
+ actual.length !== expected.length ||
121
+ actual.some((key, index) => key !== expected[index])
122
+ )
123
+ fault(
124
+ "invalid-provider-operation-shape",
125
+ path,
126
+ `${path} keys are not canonical`,
127
+ );
128
+ }
129
+
130
+ function validateToken(value, path) {
131
+ if (typeof value !== "string" || !TOKEN.test(value))
132
+ fault(
133
+ "invalid-provider-operation-token",
134
+ path,
135
+ `${path} must be an ASCII token`,
136
+ );
137
+ }
138
+
139
+ function validateCounter(value, path, minimum = 0) {
140
+ if (!Number.isSafeInteger(value) || value < minimum)
141
+ fault(
142
+ "invalid-provider-operation-counter",
143
+ path,
144
+ `${path} must be a safe integer greater than or equal to ${minimum}`,
145
+ );
146
+ }
147
+
148
+ function validateRootList(value, path) {
149
+ if (!Array.isArray(value) || value.length === 0)
150
+ fault(
151
+ "invalid-provider-operation-evidence",
152
+ path,
153
+ `${path} must contain at least one rooted observation`,
154
+ );
155
+ let prior = null;
156
+ for (const [index, root] of value.entries()) {
157
+ validateV4Root(root, `${path}/${index}`);
158
+ if (prior !== null && root <= prior)
159
+ fault(
160
+ "invalid-provider-operation-evidence",
161
+ `${path}/${index}`,
162
+ `${path} must be unique and byte-sorted`,
163
+ );
164
+ prior = root;
165
+ }
166
+ }
167
+
168
+ export function validateV4ProviderOperationIdentity(value) {
169
+ exactKeys(
170
+ value,
171
+ [
172
+ "schema",
173
+ "transactionRoot",
174
+ "capabilityId",
175
+ "subjectRoot",
176
+ "targetRoot",
177
+ "authorityRoot",
178
+ "policyRoot",
179
+ ],
180
+ "$/operation",
181
+ );
182
+ if (value.schema !== V4_PROVIDER_OPERATION_IDENTITY_CONTRACT)
183
+ fault(
184
+ "unsupported-provider-operation-version",
185
+ "$/operation/schema",
186
+ "unsupported provider operation identity schema",
187
+ );
188
+ if (
189
+ typeof value.capabilityId !== "string" ||
190
+ !CAPABILITY.test(value.capabilityId)
191
+ )
192
+ fault(
193
+ "invalid-provider-operation-token",
194
+ "$/operation/capabilityId",
195
+ "capabilityId must be an ASCII dotted token",
196
+ );
197
+ for (const name of [
198
+ "transactionRoot",
199
+ "subjectRoot",
200
+ "targetRoot",
201
+ "authorityRoot",
202
+ "policyRoot",
203
+ ])
204
+ validateV4Root(value[name], `$/operation/${name}`);
205
+ return value;
206
+ }
207
+
208
+ export function v4ProviderOperationRoot(identity) {
209
+ validateV4ProviderOperationIdentity(identity);
210
+ return v4ContentRoot("provider-operation-identity", identity);
211
+ }
212
+
213
+ function entryPayload(entry) {
214
+ const { entryRoot: _entryRoot, ...payload } = entry;
215
+ return payload;
216
+ }
217
+
218
+ export function v4ProviderOperationEntryRoot(entry) {
219
+ const descriptor = ENTRY[entry?.kind];
220
+ if (!descriptor)
221
+ fault(
222
+ "invalid-provider-operation-shape",
223
+ "$/kind",
224
+ "provider operation entry kind is unsupported",
225
+ );
226
+ return v4ContentRoot(descriptor.domain, entryPayload(entry));
227
+ }
228
+
229
+ export function validateV4ProviderOperationEntry(entry) {
230
+ const descriptor = ENTRY[entry?.kind];
231
+ if (!descriptor)
232
+ fault(
233
+ "invalid-provider-operation-shape",
234
+ "$/kind",
235
+ "provider operation entry kind is unsupported",
236
+ );
237
+ exactKeys(entry, descriptor.keys, "$");
238
+ if (entry.schema !== descriptor.schema)
239
+ fault(
240
+ "unsupported-provider-operation-version",
241
+ "$/schema",
242
+ "provider operation entry schema does not match its kind",
243
+ );
244
+ validateCounter(entry.sequence, "$/sequence");
245
+ if (entry.priorEntryRoot !== null)
246
+ validateV4Root(entry.priorEntryRoot, "$/priorEntryRoot");
247
+ validateV4Root(entry.operationRoot, "$/operationRoot");
248
+ validateV4Root(entry.entryRoot, "$/entryRoot");
249
+ if (entry.kind === "intent") {
250
+ validateV4ProviderOperationIdentity(entry.operation);
251
+ validateV4Clock(entry.declaredAt, "$/declaredAt");
252
+ validateV4Root(entry.inputRoot, "$/inputRoot");
253
+ if (entry.operationRoot !== v4ProviderOperationRoot(entry.operation))
254
+ fault(
255
+ "provider-operation-root-mismatch",
256
+ "$/operationRoot",
257
+ "operationRoot does not bind the logical provider operation",
258
+ );
259
+ } else if (entry.kind === "attempt") {
260
+ validateCounter(entry.attemptOrdinal, "$/attemptOrdinal", 1);
261
+ validateV4Clock(entry.attemptedAt, "$/attemptedAt");
262
+ validateV4Root(entry.effectRoot, "$/effectRoot");
263
+ } else if (entry.kind === "observation") {
264
+ validateV4Root(entry.attemptRoot, "$/attemptRoot");
265
+ validateV4Clock(entry.observedAt, "$/observedAt");
266
+ if (!["succeeded", "failed", "unknown"].includes(entry.status))
267
+ fault(
268
+ "invalid-provider-operation-observation",
269
+ "$/status",
270
+ "provider operation observation status is unsupported",
271
+ );
272
+ validateRootList(entry.evidenceRoots, "$/evidenceRoots");
273
+ } else if (entry.kind === "confirmation") {
274
+ validateV4Root(entry.observationRoot, "$/observationRoot");
275
+ validateV4Root(entry.authorityRoot, "$/authorityRoot");
276
+ validateV4Clock(entry.confirmedAt, "$/confirmedAt");
277
+ if (!["confirmed", "rejected"].includes(entry.outcome))
278
+ fault(
279
+ "invalid-provider-operation-confirmation",
280
+ "$/outcome",
281
+ "provider operation confirmation outcome is unsupported",
282
+ );
283
+ } else {
284
+ validateV4Root(entry.observationRoot, "$/observationRoot");
285
+ validateV4Root(entry.authorityRoot, "$/authorityRoot");
286
+ validateV4Clock(entry.reconciledAt, "$/reconciledAt");
287
+ if (!["retry", "confirm", "terminal"].includes(entry.disposition))
288
+ fault(
289
+ "invalid-provider-operation-reconciliation",
290
+ "$/disposition",
291
+ "provider operation reconciliation disposition is unsupported",
292
+ );
293
+ }
294
+ if (entry.entryRoot !== v4ProviderOperationEntryRoot(entry))
295
+ fault(
296
+ "provider-operation-entry-root-mismatch",
297
+ "$/entryRoot",
298
+ "entryRoot does not bind the canonical provider operation entry",
299
+ );
300
+ return entry;
301
+ }
302
+
303
+ function transitionFault(entry, phase) {
304
+ fault(
305
+ "impossible-provider-operation-transition",
306
+ `$/entries/${entry.sequence}/kind`,
307
+ `${entry.kind} cannot follow provider operation phase ${phase}`,
308
+ );
309
+ }
310
+
311
+ function assertJournalCoordinates(context, entry, index) {
312
+ validateV4ProviderOperationEntry(entry);
313
+ if (entry.sequence !== index)
314
+ fault(
315
+ "provider-operation-sequence-conflict",
316
+ `$/entries/${index}/sequence`,
317
+ "provider operation sequence must be contiguous and zero-based",
318
+ );
319
+ const expectedPrior = context?.state.lastEntryRoot ?? null;
320
+ if (entry.priorEntryRoot !== expectedPrior)
321
+ fault(
322
+ "provider-operation-causal-link-mismatch",
323
+ `$/entries/${index}/priorEntryRoot`,
324
+ "priorEntryRoot does not bind the append-only predecessor",
325
+ );
326
+ }
327
+
328
+ function initializeJournal(entry) {
329
+ if (entry.kind !== "intent") transitionFault(entry, "empty");
330
+ return {
331
+ authorityRoot: entry.operation.authorityRoot,
332
+ lastObservationStatus: null,
333
+ state: {
334
+ schema: V4_PROVIDER_OPERATION_JOURNAL_STATE_CONTRACT,
335
+ operationRoot: entry.operationRoot,
336
+ phase: "intended",
337
+ entryCount: 1,
338
+ attemptCount: 0,
339
+ lastEntryRoot: entry.entryRoot,
340
+ activeAttemptRoot: null,
341
+ lastObservationRoot: null,
342
+ confirmationRoot: null,
343
+ reconciliationRoot: null,
344
+ },
345
+ };
346
+ }
347
+
348
+ function applyAttempt(context, entry, index) {
349
+ const { state } = context;
350
+ if (!["intended", "retryable"].includes(state.phase))
351
+ transitionFault(entry, state.phase);
352
+ if (entry.attemptOrdinal !== state.attemptCount + 1)
353
+ fault(
354
+ "provider-operation-attempt-conflict",
355
+ `$/entries/${index}/attemptOrdinal`,
356
+ "attemptOrdinal must append exactly one logical retry attempt",
357
+ );
358
+ state.phase = "attempting";
359
+ state.attemptCount += 1;
360
+ state.activeAttemptRoot = entry.entryRoot;
361
+ state.lastObservationRoot = null;
362
+ context.lastObservationStatus = null;
363
+ }
364
+
365
+ function applyObservation(context, entry, index) {
366
+ const { state } = context;
367
+ if (state.phase !== "attempting") transitionFault(entry, state.phase);
368
+ if (entry.attemptRoot !== state.activeAttemptRoot)
369
+ fault(
370
+ "provider-operation-causal-link-mismatch",
371
+ `$/entries/${index}/attemptRoot`,
372
+ "observation must bind the active rooted attempt",
373
+ );
374
+ state.phase = "observed";
375
+ state.lastObservationRoot = entry.entryRoot;
376
+ context.lastObservationStatus = entry.status;
377
+ }
378
+
379
+ function applyReconciliation(context, entry, index) {
380
+ const { state } = context;
381
+ if (entry.authorityRoot !== context.authorityRoot)
382
+ fault(
383
+ "provider-operation-authority-escalation",
384
+ `$/entries/${index}/authorityRoot`,
385
+ "reconciliation cannot change the declared authority root",
386
+ );
387
+ if (state.phase !== "observed") transitionFault(entry, state.phase);
388
+ if (entry.observationRoot !== state.lastObservationRoot)
389
+ fault(
390
+ "provider-operation-causal-link-mismatch",
391
+ `$/entries/${index}/observationRoot`,
392
+ "reconciliation must bind the latest rooted observation",
393
+ );
394
+ if (
395
+ (entry.disposition === "retry" &&
396
+ context.lastObservationStatus === "succeeded") ||
397
+ (entry.disposition === "confirm" &&
398
+ context.lastObservationStatus !== "succeeded")
399
+ )
400
+ fault(
401
+ "invalid-provider-operation-reconciliation",
402
+ `$/entries/${index}/disposition`,
403
+ "reconciliation disposition conflicts with the rooted observation",
404
+ );
405
+ state.phase =
406
+ entry.disposition === "retry"
407
+ ? "retryable"
408
+ : entry.disposition === "confirm"
409
+ ? "confirmable"
410
+ : "terminal";
411
+ state.reconciliationRoot = entry.entryRoot;
412
+ }
413
+
414
+ function applyConfirmation(context, entry, index) {
415
+ const { state } = context;
416
+ if (entry.authorityRoot !== context.authorityRoot)
417
+ fault(
418
+ "provider-operation-authority-escalation",
419
+ `$/entries/${index}/authorityRoot`,
420
+ "confirmation cannot change the declared authority root",
421
+ );
422
+ if (["confirmed", "rejected"].includes(state.phase))
423
+ fault(
424
+ "conflicting-provider-operation-confirmation",
425
+ `$/entries/${index}`,
426
+ "a terminal provider operation cannot receive another confirmation",
427
+ );
428
+ if (
429
+ !["observed", "confirmable"].includes(state.phase) ||
430
+ context.lastObservationStatus !== "succeeded" ||
431
+ entry.observationRoot !== state.lastObservationRoot
432
+ )
433
+ fault(
434
+ "confirmation-without-rooted-observation",
435
+ `$/entries/${index}/observationRoot`,
436
+ "confirmation requires the latest successful rooted observation",
437
+ );
438
+ state.phase = entry.outcome;
439
+ state.confirmationRoot = entry.entryRoot;
440
+ }
441
+
442
+ function applyJournalEntry(context, entry, index) {
443
+ if (entry.operationRoot !== context.state.operationRoot)
444
+ fault(
445
+ "provider-operation-identity-drift",
446
+ `$/entries/${index}/operationRoot`,
447
+ "retry records must preserve logical operation identity",
448
+ );
449
+ if (entry.kind === "intent") transitionFault(entry, context.state.phase);
450
+ if (entry.kind === "attempt") applyAttempt(context, entry, index);
451
+ else if (entry.kind === "observation")
452
+ applyObservation(context, entry, index);
453
+ else if (entry.kind === "reconciliation")
454
+ applyReconciliation(context, entry, index);
455
+ else applyConfirmation(context, entry, index);
456
+ context.state.entryCount += 1;
457
+ context.state.lastEntryRoot = entry.entryRoot;
458
+ }
459
+
460
+ export function foldV4ProviderOperationJournal(entries) {
461
+ if (!Array.isArray(entries) || entries.length === 0)
462
+ fault(
463
+ "invalid-provider-operation-journal",
464
+ "$/entries",
465
+ "provider operation journal must contain an intent",
466
+ );
467
+ let context = null;
468
+ for (const [index, entry] of entries.entries()) {
469
+ assertJournalCoordinates(context, entry, index);
470
+ if (index === 0) context = initializeJournal(entry);
471
+ else applyJournalEntry(context, entry, index);
472
+ }
473
+ return context.state;
474
+ }
475
+
476
+ export function v4ProviderOperationJournalRoot(entries) {
477
+ foldV4ProviderOperationJournal(entries);
478
+ return v4ContentRoot("provider-operation-journal", entries);
479
+ }
480
+
481
+ export function v4ProviderOperationJournalStateRoot(entries) {
482
+ return v4ContentRoot(
483
+ "provider-operation-journal-state",
484
+ foldV4ProviderOperationJournal(entries),
485
+ );
486
+ }
487
+
488
+ export function projectV4ProviderOperationFixtures(fixtures) {
489
+ exactKeys(
490
+ fixtures,
491
+ ["schemaVersion", "contract", "validCases", "invalidCases"],
492
+ "$",
493
+ );
494
+ if (
495
+ fixtures.schemaVersion !== 1 ||
496
+ fixtures.contract !==
497
+ "buildchain-v4-provider-operation-journal-fixtures/v1" ||
498
+ !Array.isArray(fixtures.validCases) ||
499
+ !Array.isArray(fixtures.invalidCases)
500
+ )
501
+ fault(
502
+ "unsupported-provider-operation-version",
503
+ "$/schemaVersion",
504
+ "unsupported provider operation fixture contract",
505
+ );
506
+ const validCases = fixtures.validCases.map(({ id, entries }) => {
507
+ const state = foldV4ProviderOperationJournal(entries);
508
+ return {
509
+ id,
510
+ operationRoot: state.operationRoot,
511
+ entryRoots: entries.map((entry) => entry.entryRoot),
512
+ journalRoot: v4ProviderOperationJournalRoot(entries),
513
+ state,
514
+ stateRoot: v4ProviderOperationJournalStateRoot(entries),
515
+ };
516
+ });
517
+ const invalidCases = fixtures.invalidCases.map(({ id, entries }) => {
518
+ try {
519
+ foldV4ProviderOperationJournal(entries);
520
+ } catch (error) {
521
+ if (error instanceof V4ContractFault) return { id, fault: error.code };
522
+ throw error;
523
+ }
524
+ fault(
525
+ "invalid-provider-operation-fixture",
526
+ "$/invalidCases",
527
+ `fixture ${id} unexpectedly passed`,
528
+ );
529
+ });
530
+ return { validCases, invalidCases };
531
+ }