@kungfu-tech/buildchain 4.0.2-alpha.8 → 4.0.2

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 (157) hide show
  1. package/AGENTS.md +10 -1
  2. package/CONTRIBUTING.md +24 -0
  3. package/README.md +2 -2
  4. package/actions/promote-buildchain-ref/README.md +1 -1
  5. package/actions/v4-release-candidate-promote/README.md +28 -0
  6. package/architecture/agent-change-map.md +64 -7
  7. package/architecture/ci-lane-change-budget.json +366 -0
  8. package/architecture/internal-capabilities.json +53 -8
  9. package/architecture/maintainability-debt.json +147 -93
  10. package/architecture/maintainability-policy.json +32 -28
  11. package/architecture/release-tail-contract-inventory.json +6 -6
  12. package/architecture/v4-architecture-constitution.md +23 -20
  13. package/architecture/v4-cross-platform-adopter-qualification.json +1 -1
  14. package/architecture/v4-delivery-authority-parity.json +2 -2
  15. package/architecture/v4-delivery-warrant-shadow-bootstrap-plan.json +1 -1
  16. package/architecture/v4-floating-consumer-policy.json +2 -2
  17. package/architecture/v4-next-development-parity.json +5 -5
  18. package/architecture/v4-partial-mutation-recovery-qualification.json +4 -1
  19. package/architecture/v4-platform-stage-checkpoints.json +1 -1
  20. package/architecture/v4-provider-operation-journal-contract.json +5 -2
  21. package/architecture/v4-publication-facade-patches.json +64 -0
  22. package/architecture/v4-release-activation-shadow-domain.json +5 -2
  23. package/architecture/v4-release-topology.json +74 -39
  24. package/architecture/v4-rust-wasm-production-authority.json +58 -0
  25. package/architecture/v4-stable-publication-fence.json +5 -2
  26. package/architecture/v4-stage-capsule-qualification.json +2 -2
  27. package/architecture/v4-tail-reseal-parity.json +8 -6
  28. package/architecture/v4-universal-workflow-bootstrap.json +171 -0
  29. package/architecture/v4-universal-workflow-fault-campaign.json +72 -0
  30. package/architecture/v4-universal-workflow-train-admission.json +40 -0
  31. package/architecture/workflow-taxonomy.json +1451 -0
  32. package/bin/buildchain.mjs +7 -7
  33. package/contracts/buildchain-v2-residuals-v1.json +57 -48
  34. package/contracts/dev-delivery-authority-v2.schema.json +16 -2
  35. package/contracts/fixtures/v4-tail-reseal-v1/valid.json +1 -1
  36. package/contracts/v4-canonical-contracts-v1.schema.json +1 -0
  37. package/dist/site/buildchain-contract.json +93 -48
  38. package/dist/site/buildchain-site.json +222 -69
  39. package/dist/site/capability-registry.json +4 -4
  40. package/dist/site/controller-registry.json +50 -13
  41. package/dist/site/kfd-claims.json +2585 -1000
  42. package/dist/site/kfd-upstream-aggregate.json +1 -1
  43. package/dist/site/manual-registry.json +13 -13
  44. package/dist/site/node-api-registry.json +120 -115
  45. package/dist/site/page-registry.json +204 -51
  46. package/dist/site/public-surface-audit.json +3205 -1219
  47. package/dist/site/publication-authority-registry.json +1124 -362
  48. package/dist/site/publication-registry.json +4 -4
  49. package/dist/site/schemas/dev-delivery-authority-v2.schema.json +16 -2
  50. package/dist/site/site-manifest.json +17 -17
  51. package/dist/site/workflow-registry.json +5061 -1659
  52. package/docs/MAP.md +1 -0
  53. package/docs/auditable-demo.md +1 -1
  54. package/docs/cli.md +21 -8
  55. package/docs/dev-delivery-warrant.md +1 -1
  56. package/docs/engineering-housekeeper.md +3 -3
  57. package/docs/kfd-support.md +26 -2
  58. package/docs/next-development-transition.md +2 -2
  59. package/docs/node-api-reference.md +190 -190
  60. package/docs/publication-authority.md +2 -2
  61. package/docs/release-candidate.md +3 -3
  62. package/docs/release-flow.md +67 -19
  63. package/docs/release-governance.md +8 -8
  64. package/docs/release-passport.md +27 -2
  65. package/docs/reusable-build-surface.md +16 -0
  66. package/docs/v4-adopter-delivery.md +2 -2
  67. package/docs/v4-production-release.md +71 -8
  68. package/docs/v4-rust-wasm-production-authority.md +58 -0
  69. package/docs/v4-stage-capsule.md +2 -2
  70. package/docs/v4-tail-reseal.md +1 -1
  71. package/docs/workflow-catalog.md +154 -0
  72. package/docs/workflow-path-migration.md +109 -0
  73. package/package.json +10 -6
  74. package/packages/core/artifact-verification-envelope.js +5 -5
  75. package/packages/core/buildchain-contract.js +1 -1
  76. package/packages/core/buildchain-kfd-claims.js +2 -2
  77. package/packages/core/buildchain-publication-authority.js +42 -26
  78. package/packages/core/buildchain-v4-domain.wasm +0 -0
  79. package/packages/core/ci-lane-change-budget.js +14 -1
  80. package/packages/core/controller-evidence.js +4 -1
  81. package/packages/core/dev-delivery-candidate-identity.js +40 -6
  82. package/packages/core/dev-delivery-warrant-state.js +3 -4
  83. package/packages/core/dev-delivery-warrant.js +12 -2
  84. package/packages/core/github-governance-authority.js +4 -4
  85. package/packages/core/kfd-adopter-manifest.js +46 -47
  86. package/packages/core/next-development-projection.js +2 -2
  87. package/packages/core/paper-agent-entry.js +30 -4
  88. package/packages/core/paper-fleet.js +1 -1
  89. package/packages/core/paper-runtime-channels.js +348 -0
  90. package/packages/core/paper-scaffold-content.js +10 -0
  91. package/packages/core/paper.js +37 -71
  92. package/packages/core/release-line-dry-run.js +1 -1
  93. package/packages/core/release-passport-contract.js +5 -5
  94. package/packages/core/release-passport.js +5 -4
  95. package/packages/core/release-tail-provider-plane.js +68 -1048
  96. package/packages/core/v4-canonical-contracts.js +10 -75
  97. package/packages/core/v4-domain-wasm-artifact.js +7 -0
  98. package/packages/core/v4-domain-wasm.js +216 -0
  99. package/packages/core/v4-floating-consumer-evidence.js +1 -1
  100. package/packages/core/v4-floating-consumer-policy.js +1 -1
  101. package/packages/core/v4-partial-mutation-recovery-qualification.js +9 -386
  102. package/packages/core/v4-product-publication.js +19 -349
  103. package/packages/core/v4-protected-publication-source.js +19 -21
  104. package/packages/core/v4-provider-operation-journal.js +18 -487
  105. package/packages/core/v4-provider-readback-idempotency.js +12 -97
  106. package/packages/core/v4-release-activation-shadow.js +13 -500
  107. package/packages/core/v4-release-invocation.js +28 -389
  108. package/packages/core/v4-stable-publication-fence.js +13 -342
  109. package/packages/core/v4-universal-workflow-bootstrap.js +586 -0
  110. package/scripts/binary-publication-evidence.mjs +135 -0
  111. package/scripts/build-contract-core.mjs +1 -14
  112. package/scripts/build-v4-domain-wasm.mjs +189 -0
  113. package/scripts/check-action-bundles.mjs +12 -2
  114. package/scripts/check-ci-lane-change-budget.mjs +4 -1
  115. package/scripts/check-core-mechanism-inventory.mjs +4 -3
  116. package/scripts/check-inventory.mjs +35 -44
  117. package/scripts/check-maintainability.mjs +16 -113
  118. package/scripts/check-v4-floating-consumer-policy-contract.mjs +2 -2
  119. package/scripts/check-v4-public-dogfood-contract.mjs +22 -9
  120. package/scripts/check-v4-release-topology.mjs +90 -33
  121. package/scripts/check-v4-runtime-semantic-closure.mjs +4 -1
  122. package/scripts/check-v4-universal-workflow-bootstrap.mjs +266 -0
  123. package/scripts/check-workflow-taxonomy.mjs +6 -0
  124. package/scripts/copy-v4-domain-wasm.mjs +14 -0
  125. package/scripts/dev-delivery-authority-command-adapters.mjs +1 -1
  126. package/scripts/dev-delivery-authority.mjs +8 -8
  127. package/scripts/dev-delivery-source-proof-reuse.mjs +2 -1
  128. package/scripts/dev-delivery-warrant-options.mjs +14 -9
  129. package/scripts/dev-delivery-warrant-store.mjs +73 -7
  130. package/scripts/dev-delivery-warrant-transition.mjs +109 -0
  131. package/scripts/dev-delivery-warrant.mjs +76 -99
  132. package/scripts/dev-pr-auto-merge.mjs +15 -15
  133. package/scripts/generate-channel-build-workflow.mjs +7 -2
  134. package/scripts/generate-channel-promotion-workflow.mjs +7 -5
  135. package/scripts/generate-site-bundle.mjs +11 -11
  136. package/scripts/generate-v4-universal-workflow-facades.mjs +458 -0
  137. package/scripts/generate-workflow-taxonomy.mjs +25 -0
  138. package/scripts/github-output.mjs +31 -0
  139. package/scripts/maintainability-metrics.mjs +16 -5
  140. package/scripts/maintainability-public-surface.mjs +115 -0
  141. package/scripts/next-development-review.mjs +307 -0
  142. package/scripts/paper-work-fleet-cli.mjs +2 -0
  143. package/scripts/release-asset-client.mjs +91 -0
  144. package/scripts/release-candidate-resolver.mjs +9 -9
  145. package/scripts/source-verification-evidence.mjs +344 -0
  146. package/scripts/stable-candidate-qualification.mjs +1 -1
  147. package/scripts/universal-facade-maintainability.mjs +82 -0
  148. package/scripts/v4-product-publication-intent.mjs +13 -6
  149. package/scripts/v4-publication-settlement.mjs +211 -0
  150. package/scripts/v4-universal-workflow-backflow.mjs +212 -0
  151. package/scripts/v4-universal-workflow-engine.mjs +618 -0
  152. package/scripts/v4-universal-workflow-self-dogfood.mjs +205 -0
  153. package/scripts/verify-version-state-delta.mjs +173 -0
  154. package/scripts/workflow-taxonomy.mjs +507 -0
  155. package/templates/native-dev-delivery.yml +4 -7
  156. package/templates/universal-buildchain-bootstrap-recovery.yml +282 -0
  157. package/templates/universal-buildchain-bootstrap.yml +28 -0
@@ -1,9 +1,5 @@
1
- import {
2
- V4ContractFault,
3
- v4ContentRoot,
4
- validateV4Clock,
5
- validateV4Root,
6
- } from "./v4-canonical-contracts.js";
1
+ import { V4ContractFault } from "./v4-canonical-contracts.js";
2
+ import { V4DomainWasmFault, invokeV4DomainWasm } from "./v4-domain-wasm.js";
7
3
 
8
4
  export const V4_PROVIDER_OPERATION_IDENTITY_CONTRACT =
9
5
  "buildchain-v4-provider-operation-identity/v1";
@@ -20,512 +16,47 @@ export const V4_PROVIDER_OPERATION_RECONCILIATION_CONTRACT =
20
16
  export const V4_PROVIDER_OPERATION_JOURNAL_STATE_CONTRACT =
21
17
  "buildchain-v4-provider-operation-journal-state/v1";
22
18
 
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;
19
+ function invoke(operation, payload) {
20
+ try {
21
+ return invokeV4DomainWasm(operation, payload);
22
+ } catch (error) {
23
+ if (error instanceof V4DomainWasmFault) {
24
+ throw new V4ContractFault(error.code, error.path, error.message);
25
+ }
26
+ throw error;
165
27
  }
166
28
  }
167
29
 
168
30
  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}`);
31
+ invoke("provider-operation-identity-validate", value);
205
32
  return value;
206
33
  }
207
34
 
208
35
  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;
36
+ return invoke("provider-operation-identity-root", identity).root;
216
37
  }
217
38
 
218
39
  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));
40
+ return invoke("provider-operation-entry-root", entry).root;
227
41
  }
228
42
 
229
43
  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
- );
44
+ invoke("provider-operation-entry-validate", entry);
300
45
  return entry;
301
46
  }
302
47
 
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
48
  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;
49
+ return invoke("provider-operation-journal", entries).state;
474
50
  }
475
51
 
476
52
  export function v4ProviderOperationJournalRoot(entries) {
477
- foldV4ProviderOperationJournal(entries);
478
- return v4ContentRoot("provider-operation-journal", entries);
53
+ return invoke("provider-operation-journal", entries).journalRoot;
479
54
  }
480
55
 
481
56
  export function v4ProviderOperationJournalStateRoot(entries) {
482
- return v4ContentRoot(
483
- "provider-operation-journal-state",
484
- foldV4ProviderOperationJournal(entries),
485
- );
57
+ return invoke("provider-operation-journal", entries).stateRoot;
486
58
  }
487
59
 
488
60
  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 };
61
+ return invoke("provider-operation-fixtures", fixtures);
531
62
  }
@@ -1,15 +1,10 @@
1
1
  import {
2
2
  V4ContractFault,
3
3
  v4ContentRoot,
4
- validateV4Clock,
5
4
  validateV4Root,
6
5
  } 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";
6
+ import { v4ProviderOperationJournalStateRoot } from "./v4-provider-operation-journal.js";
7
+ import { V4DomainWasmFault, invokeV4DomainWasm } from "./v4-domain-wasm.js";
13
8
 
14
9
  export const V4_PROVIDER_READBACK_SAMPLE_CONTRACT =
15
10
  "buildchain-v4-provider-readback-sample/v1";
@@ -252,97 +247,17 @@ export function adaptV4OciManifestReadback(response, context) {
252
247
  }
253
248
 
254
249
  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);
250
+ try {
251
+ return invokeV4DomainWasm("provider-readback-fold", {
252
+ samples,
253
+ coordinates,
254
+ });
255
+ } catch (error) {
256
+ if (error instanceof V4DomainWasmFault) {
257
+ throw new V4ContractFault(error.code, error.path, error.message);
258
+ }
259
+ throw error;
294
260
  }
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
261
  }
347
262
 
348
263
  const ADAPTERS = Object.freeze({