@cynodia/axiom-server 0.14.0-alpha.2 → 0.14.0-alpha.4

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 (40) hide show
  1. package/conformance/live/aggregate-reset.json +1 -1
  2. package/conformance/live/dependency-commit-no-change.json +1 -1
  3. package/conformance/live/f2-state-ref-refused.json +1 -1
  4. package/conformance/live/initial-result.json +1 -1
  5. package/conformance/live/insert-on-filter-entry.json +1 -1
  6. package/conformance/live/limit-boundary.json +1 -1
  7. package/conformance/live/manifest.json +1 -1
  8. package/conformance/live/not-live-capable.json +1 -1
  9. package/conformance/live/provider-only-sequence.json +1 -1
  10. package/conformance/live/provider-record-remove.json +1 -1
  11. package/conformance/live/remove-on-filter-exit.json +1 -1
  12. package/conformance/live/update-with-move.json +1 -1
  13. package/conformance/live/update-without-move.json +1 -1
  14. package/conformance/workflow/manifest.json +1 -1
  15. package/conformance/workflow/workflow-action-on-error.json +1 -1
  16. package/conformance/workflow/workflow-action-retry.json +1 -1
  17. package/conformance/workflow/workflow-action-success.json +1 -1
  18. package/conformance/workflow/workflow-action-terminal-failure.json +1 -1
  19. package/conformance/workflow/workflow-branch-false.json +1 -1
  20. package/conformance/workflow/workflow-branch-true.json +1 -1
  21. package/conformance/workflow/workflow-cancel-waiting.json +1 -1
  22. package/conformance/workflow/workflow-event-match.json +1 -1
  23. package/conformance/workflow/workflow-event-nonmatch.json +1 -1
  24. package/conformance/workflow/workflow-event-timeout.json +1 -1
  25. package/conformance/workflow/workflow-start-complete.json +1 -1
  26. package/conformance/workflow/workflow-start-idempotency.json +1 -1
  27. package/conformance/workflow/workflow-timer.json +1 -1
  28. package/dist/authority-identity.js +13 -3
  29. package/dist/server.js +30 -3
  30. package/dist/workflows.js +55 -7
  31. package/package.json +3 -3
  32. package/schema/protocol.v1.schema.json +1 -1
  33. package/schema/server-ir.v1.schema.json +1 -1
  34. package/schema/server-ir.v2.schema.json +1 -1
  35. package/schema/server-ir.v3.schema.json +1 -1
  36. package/schema/server-ir.v4.schema.json +1 -1
  37. package/schema/server-ir.v5.schema.json +1 -1
  38. package/schema/server-ir.v6.schema.json +1 -1
  39. package/schema/server-ir.v7.schema.json +1 -1
  40. package/schema/server-ir.v8.schema.json +1 -1
@@ -10,7 +10,7 @@
10
10
  "contract": "axiom.server.v6",
11
11
  "id": "live-query-conformance",
12
12
  "name": "Live Query Conformance",
13
- "version": "0.14.0-alpha.2",
13
+ "version": "0.14.0-alpha.4",
14
14
  "entities": [
15
15
  {
16
16
  "id": "entity_order",
@@ -10,7 +10,7 @@
10
10
  "contract": "axiom.server.v6",
11
11
  "id": "live-query-conformance",
12
12
  "name": "Live Query Conformance",
13
- "version": "0.14.0-alpha.2",
13
+ "version": "0.14.0-alpha.4",
14
14
  "entities": [
15
15
  {
16
16
  "id": "entity_order",
@@ -11,7 +11,7 @@
11
11
  "contract": "axiom.server.v6",
12
12
  "id": "live-query-conformance",
13
13
  "name": "Live Query Conformance",
14
- "version": "0.14.0-alpha.2",
14
+ "version": "0.14.0-alpha.4",
15
15
  "entities": [
16
16
  {
17
17
  "id": "entity_order",
@@ -9,7 +9,7 @@
9
9
  "contract": "axiom.server.v6",
10
10
  "id": "live-query-conformance",
11
11
  "name": "Live Query Conformance",
12
- "version": "0.14.0-alpha.2",
12
+ "version": "0.14.0-alpha.4",
13
13
  "entities": [
14
14
  {
15
15
  "id": "entity_order",
@@ -10,7 +10,7 @@
10
10
  "contract": "axiom.server.v6",
11
11
  "id": "live-query-conformance",
12
12
  "name": "Live Query Conformance",
13
- "version": "0.14.0-alpha.2",
13
+ "version": "0.14.0-alpha.4",
14
14
  "entities": [
15
15
  {
16
16
  "id": "entity_order",
@@ -9,7 +9,7 @@
9
9
  "contract": "axiom.server.v6",
10
10
  "id": "live-query-conformance",
11
11
  "name": "Live Query Conformance",
12
- "version": "0.14.0-alpha.2",
12
+ "version": "0.14.0-alpha.4",
13
13
  "entities": [
14
14
  {
15
15
  "id": "entity_order",
@@ -2,7 +2,7 @@
2
2
  "conformance": "axiom.conformance.v7",
3
3
  "baseContract": "axiom.server.v7",
4
4
  "protocol": "axiom.protocol.v1",
5
- "release": "0.14.0-alpha.2",
5
+ "release": "0.14.0-alpha.4",
6
6
  "description": "Portable live-query conformance fixtures (spec13 §152, §194). Each file carries a compiled axiom.server.v7 Server IR, a dataset of provider rows, the live query to open, its required initial result, and a script of committed mutations each paired with the live message that must follow (canonical update / whole reset / none). The runner also checks the primary invariant: folding the delivered stream must equal a fresh one-shot execution of the same QueryDef. Running one needs only a DataProvider and the semantics in docs/LIVE_QUERIES.md.",
7
7
  "fixtures": [
8
8
  {
@@ -10,7 +10,7 @@
10
10
  "contract": "axiom.server.v6",
11
11
  "id": "live-query-conformance",
12
12
  "name": "Live Query Conformance",
13
- "version": "0.14.0-alpha.2",
13
+ "version": "0.14.0-alpha.4",
14
14
  "entities": [
15
15
  {
16
16
  "id": "entity_order",
@@ -12,7 +12,7 @@
12
12
  "contract": "axiom.server.v6",
13
13
  "id": "live-query-conformance",
14
14
  "name": "Live Query Conformance",
15
- "version": "0.14.0-alpha.2",
15
+ "version": "0.14.0-alpha.4",
16
16
  "entities": [
17
17
  {
18
18
  "id": "entity_order",
@@ -9,7 +9,7 @@
9
9
  "contract": "axiom.server.v6",
10
10
  "id": "live-query-conformance",
11
11
  "name": "Live Query Conformance",
12
- "version": "0.14.0-alpha.2",
12
+ "version": "0.14.0-alpha.4",
13
13
  "entities": [
14
14
  {
15
15
  "id": "entity_order",
@@ -10,7 +10,7 @@
10
10
  "contract": "axiom.server.v6",
11
11
  "id": "live-query-conformance",
12
12
  "name": "Live Query Conformance",
13
- "version": "0.14.0-alpha.2",
13
+ "version": "0.14.0-alpha.4",
14
14
  "entities": [
15
15
  {
16
16
  "id": "entity_order",
@@ -10,7 +10,7 @@
10
10
  "contract": "axiom.server.v6",
11
11
  "id": "live-query-conformance",
12
12
  "name": "Live Query Conformance",
13
- "version": "0.14.0-alpha.2",
13
+ "version": "0.14.0-alpha.4",
14
14
  "entities": [
15
15
  {
16
16
  "id": "entity_order",
@@ -9,7 +9,7 @@
9
9
  "contract": "axiom.server.v6",
10
10
  "id": "live-query-conformance",
11
11
  "name": "Live Query Conformance",
12
- "version": "0.14.0-alpha.2",
12
+ "version": "0.14.0-alpha.4",
13
13
  "entities": [
14
14
  {
15
15
  "id": "entity_order",
@@ -2,7 +2,7 @@
2
2
  "conformance": "axiom.conformance.v8",
3
3
  "baseContract": "axiom.server.v8",
4
4
  "protocol": "axiom.protocol.v1",
5
- "release": "0.14.0-alpha.2",
5
+ "release": "0.14.0-alpha.4",
6
6
  "description": "Portable workflow conformance fixtures (spec14 §156-§159). Each file carries a compiled axiom.server.v8 Server IR, the start arguments, a deterministic driver script, and the required logical transition history + terminal state. Physical action attempts may be duplicated; the logical history must match exactly. Running one needs only the in-memory WorkflowStore and the semantics in docs/WORKFLOWS.md.",
7
7
  "fixtures": [
8
8
  {
@@ -31,7 +31,7 @@
31
31
  "contract": "axiom.server.v8",
32
32
  "id": "workflow-conformance",
33
33
  "name": "Workflow Conformance",
34
- "version": "0.14.0-alpha.2",
34
+ "version": "0.14.0-alpha.4",
35
35
  "entities": [
36
36
  {
37
37
  "id": "entity_pay",
@@ -49,7 +49,7 @@
49
49
  "contract": "axiom.server.v8",
50
50
  "id": "workflow-conformance",
51
51
  "name": "Workflow Conformance",
52
- "version": "0.14.0-alpha.2",
52
+ "version": "0.14.0-alpha.4",
53
53
  "entities": [
54
54
  {
55
55
  "id": "entity_pay",
@@ -21,7 +21,7 @@
21
21
  "contract": "axiom.server.v8",
22
22
  "id": "workflow-conformance",
23
23
  "name": "Workflow Conformance",
24
- "version": "0.14.0-alpha.2",
24
+ "version": "0.14.0-alpha.4",
25
25
  "entities": [
26
26
  {
27
27
  "id": "entity_pay",
@@ -27,7 +27,7 @@
27
27
  "contract": "axiom.server.v8",
28
28
  "id": "workflow-conformance",
29
29
  "name": "Workflow Conformance",
30
- "version": "0.14.0-alpha.2",
30
+ "version": "0.14.0-alpha.4",
31
31
  "entities": [
32
32
  {
33
33
  "id": "entity_pay",
@@ -20,7 +20,7 @@
20
20
  "contract": "axiom.server.v8",
21
21
  "id": "workflow-conformance",
22
22
  "name": "Workflow Conformance",
23
- "version": "0.14.0-alpha.2",
23
+ "version": "0.14.0-alpha.4",
24
24
  "entities": [
25
25
  {
26
26
  "id": "entity_pay",
@@ -20,7 +20,7 @@
20
20
  "contract": "axiom.server.v8",
21
21
  "id": "workflow-conformance",
22
22
  "name": "Workflow Conformance",
23
- "version": "0.14.0-alpha.2",
23
+ "version": "0.14.0-alpha.4",
24
24
  "entities": [
25
25
  {
26
26
  "id": "entity_pay",
@@ -31,7 +31,7 @@
31
31
  "contract": "axiom.server.v8",
32
32
  "id": "workflow-conformance",
33
33
  "name": "Workflow Conformance",
34
- "version": "0.14.0-alpha.2",
34
+ "version": "0.14.0-alpha.4",
35
35
  "entities": [
36
36
  {
37
37
  "id": "entity_pay",
@@ -30,7 +30,7 @@
30
30
  "contract": "axiom.server.v8",
31
31
  "id": "workflow-conformance",
32
32
  "name": "Workflow Conformance",
33
- "version": "0.14.0-alpha.2",
33
+ "version": "0.14.0-alpha.4",
34
34
  "entities": [
35
35
  {
36
36
  "id": "entity_pay",
@@ -28,7 +28,7 @@
28
28
  "contract": "axiom.server.v8",
29
29
  "id": "workflow-conformance",
30
30
  "name": "Workflow Conformance",
31
- "version": "0.14.0-alpha.2",
31
+ "version": "0.14.0-alpha.4",
32
32
  "entities": [
33
33
  {
34
34
  "id": "entity_pay",
@@ -27,7 +27,7 @@
27
27
  "contract": "axiom.server.v8",
28
28
  "id": "workflow-conformance",
29
29
  "name": "Workflow Conformance",
30
- "version": "0.14.0-alpha.2",
30
+ "version": "0.14.0-alpha.4",
31
31
  "entities": [
32
32
  {
33
33
  "id": "entity_pay",
@@ -17,7 +17,7 @@
17
17
  "contract": "axiom.server.v8",
18
18
  "id": "workflow-conformance",
19
19
  "name": "Workflow Conformance",
20
- "version": "0.14.0-alpha.2",
20
+ "version": "0.14.0-alpha.4",
21
21
  "entities": [
22
22
  {
23
23
  "id": "entity_pay",
@@ -17,7 +17,7 @@
17
17
  "contract": "axiom.server.v8",
18
18
  "id": "workflow-conformance",
19
19
  "name": "Workflow Conformance",
20
- "version": "0.14.0-alpha.2",
20
+ "version": "0.14.0-alpha.4",
21
21
  "entities": [
22
22
  {
23
23
  "id": "entity_pay",
@@ -23,7 +23,7 @@
23
23
  "contract": "axiom.server.v8",
24
24
  "id": "workflow-conformance",
25
25
  "name": "Workflow Conformance",
26
- "version": "0.14.0-alpha.2",
26
+ "version": "0.14.0-alpha.4",
27
27
  "entities": [
28
28
  {
29
29
  "id": "entity_pay",
@@ -38,14 +38,24 @@ function stripNonSemantic(value) {
38
38
  }
39
39
  return value;
40
40
  }
41
+ // Both are **total** over a hand-tampered `ServerIR` slice (spec14pt4 §31): a slice that is
42
+ // the wrong shape entirely (a string where an array is expected, say) projects to nothing
43
+ // rather than throwing. A structurally invalid workflow is then refused by the engine's
44
+ // admission validator with a structured `WorkflowIRError`; the compatibility key is never
45
+ // the place a malformed IR surfaces as a native error. Valid graphs always have
46
+ // array/object slices, so no valid fingerprint moves.
41
47
  function sortedRecord(record) {
42
- return Object.entries(record ?? {})
48
+ if (!record || typeof record !== 'object')
49
+ return [];
50
+ return Object.entries(record)
43
51
  .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
44
52
  .map(([, v]) => stripNonSemantic(v));
45
53
  }
46
54
  function sortedList(list) {
47
- return [...(list ?? [])]
48
- .sort((a, b) => (String(a.id) < String(b.id) ? -1 : String(a.id) > String(b.id) ? 1 : 0))
55
+ if (!Array.isArray(list))
56
+ return [];
57
+ return [...list]
58
+ .sort((a, b) => (String(a?.id) < String(b?.id) ? -1 : String(a?.id) > String(b?.id) ? 1 : 0))
49
59
  .map((entry) => stripNonSemantic(entry));
50
60
  }
51
61
  /**
package/dist/server.js CHANGED
@@ -5,7 +5,7 @@ import { createMemoryPersistence } from './persistence.js';
5
5
  import { createServerHost } from './host.js';
6
6
  import { createEffectRunner } from './effects.js';
7
7
  import { resolveCoordinationConfig, } from './coordination.js';
8
- import { createWorkflowEngine } from './workflows.js';
8
+ import { WorkflowIRError, createWorkflowEngine } from './workflows.js';
9
9
  import { createMemoryWorkflowStore } from './workflow-store.js';
10
10
  import { createDistributedEffectRunner, } from './distributed-effects.js';
11
11
  import { createDurableWorkStore, createMemoryDurableWorkStorage, } from './durable-work.js';
@@ -182,6 +182,17 @@ export function createAxiomServer(options) {
182
182
  if (!SERVER_IR_CONTRACTS.includes(String(options.ir.contract))) {
183
183
  throw new Error(`Unsupported Server IR contract "${String(options.ir.contract)}"; this runtime executes ${SERVER_IR_CONTRACTS.join(', ')}`);
184
184
  }
185
+ // spec14pt5 — the workflow admission boundary. `understatedContract` /
186
+ // `serverIRExpressions` and the compatibility fingerprint below all traverse
187
+ // `ir.workflows`; a hand-tampered IR where `workflows` is present but not an array (a
188
+ // number, a plain object, a boolean, a string) must fail closed **here** with the same
189
+ // structured `WorkflowIRError` `createWorkflowEngine` raises — never a native iteration
190
+ // error, and never coerced to `[]`. Absent or `[]` is admissible; per-element / reference
191
+ // validation runs later in `createWorkflowEngine`.
192
+ const workflowsContainer = options.ir.workflows;
193
+ if (workflowsContainer !== undefined && !Array.isArray(workflowsContainer)) {
194
+ throw new WorkflowIRError([{ code: 'WORKFLOW_INVALID_IR', message: 'workflows is not an array' }]);
195
+ }
185
196
  // A document may not claim a contract older than the vocabulary it uses. Executing it
186
197
  // anyway would make the label meaningless, and the label is what another implementation
187
198
  // decides by.
@@ -1103,10 +1114,26 @@ export function createAxiomServer(options) {
1103
1114
  return response;
1104
1115
  }
1105
1116
  // ---- Durable workflows (spec14) --------------------------------------------------
1106
- const workflowStore = (ir.workflows?.length ?? 0) > 0 ? options.workflowStore ?? createMemoryWorkflowStore() : undefined;
1117
+ // spec14pt4 §29, §30 a hand-tampered IR may carry `workflows` as the wrong shape
1118
+ // entirely (a string, an object, a one-element array holding `null`). Route anything
1119
+ // present-but-not-an-empty-array into the engine's total admission validator so it fails
1120
+ // closed with a structured `WorkflowIRError` rather than being silently ignored (`{}` has
1121
+ // no `.length`) or reaching a native `TypeError`.
1122
+ // Anything other than absent-or-empty-array is routed into the engine's total admission
1123
+ // validator (`null`, a string, an object, a non-empty array) so it fails closed rather
1124
+ // than being silently ignored (`{}` / `null` have no useful `.length`).
1125
+ const declaredWorkflows = ir.workflows;
1126
+ const workflowsDeclared = declaredWorkflows !== undefined &&
1127
+ (!Array.isArray(declaredWorkflows) || declaredWorkflows.length > 0);
1128
+ const workflowStore = workflowsDeclared
1129
+ ? options.workflowStore ?? createMemoryWorkflowStore()
1130
+ : undefined;
1107
1131
  const workflowEngine = workflowStore
1108
1132
  ? createWorkflowEngine({
1109
- workflows: ir.workflows ?? [],
1133
+ // Pass the declared value **through unchanged** (never `?? []`) so a tampered
1134
+ // `null` / string / object reaches the total admission validator instead of being
1135
+ // coalesced to an empty list (spec14pt4 §29, §63).
1136
+ workflows: declaredWorkflows,
1110
1137
  store: workflowStore,
1111
1138
  compatibilityFingerprint: compatibilityKeyStr,
1112
1139
  instanceId,
package/dist/workflows.js CHANGED
@@ -159,16 +159,27 @@ export function createWorkflowEngine(options) {
159
159
  const pollMs = options.pollMs ?? 250;
160
160
  const recoverBatch = options.recoverBatch ?? 64;
161
161
  const store = options.store;
162
- // spec14pt3 F2 admission validation. The authoritative runtime is handed a `ServerIR`
163
- // it did not necessarily compile itself; a structurally invalid `WorkflowDef` (unknown
164
- // step kind, dangling edge, malformed timer/terminal, missing entry) must fail closed
165
- // *here*, before any instance can be started or advanced, rather than surfacing as a
166
- // native error or a permanently stuck instance deep in execution (spec14pt3 §46, §48).
162
+ // spec14pt3 F2 / spec14pt4 §11-§19, §25 the single authoritative admission validator.
163
+ // The authoritative runtime is handed a `ServerIR` it did not necessarily compile itself;
164
+ // a structurally invalid or referentially inconsistent `WorkflowDef` a malformed
165
+ // container (`workflows` / `steps` not an array), an unknown step kind, a dangling edge, a
166
+ // `bind` to an undeclared binding, a `producedBy` to a non-step, an expression `ref` to an
167
+ // id that is not in scope — must fail closed **here**, before any instance can be started
168
+ // or advanced, rather than surfacing as a native error or a permanently `running` wedge
169
+ // deep in execution (spec14pt4 §3, §26). Totally guarded: `options.workflows` itself may
170
+ // be the wrong shape.
171
+ if (!Array.isArray(options.workflows)) {
172
+ throw new WorkflowIRError([
173
+ { code: 'WORKFLOW_INVALID_IR', message: 'workflows is not an array' },
174
+ ]);
175
+ }
167
176
  const irProblems = options.workflows.flatMap((w) => workflowStructuralProblems(w));
168
177
  if (irProblems.length > 0) {
169
178
  throw new WorkflowIRError(irProblems);
170
179
  }
171
- const byId = new Map(options.workflows.map((w) => [String(w.id), w]));
180
+ // Every entry has now passed the total structural + reference check above, so it is a
181
+ // plain object with a string id and a valid step array.
182
+ const byId = new Map(options.workflows.map((w) => [String(w?.id), w]));
172
183
  let pollTimer;
173
184
  let running = false;
174
185
  const advancing = new Set(); // local re-entrancy guard only
@@ -285,7 +296,44 @@ export function createWorkflowEngine(options) {
285
296
  .catch(() => { });
286
297
  return;
287
298
  }
288
- const progressed = await runStep({ workflow, record, step, fence });
299
+ // spec14pt4 §27, §28 defense in depth. Admission validation makes this
300
+ // unreachable for an admitted workflow, but if a corrupt durable instance or a
301
+ // step object mutated post-construction somehow reaches here and a transition
302
+ // (e.g. a branch predicate over a bad ref) throws, fail the instance with a
303
+ // structured reason. Never let the poll loop swallow the throw and retry forever
304
+ // (`pollOnce` catches, so an unhandled throw here IS a permanent `running` wedge).
305
+ let progressed;
306
+ try {
307
+ progressed = await runStep({ workflow, record, step, fence });
308
+ }
309
+ catch (error) {
310
+ await store
311
+ .transition({
312
+ instanceId: record.instanceId,
313
+ expectedRevision: record.instanceRevision,
314
+ fence,
315
+ next: {
316
+ status: 'failed',
317
+ currentStepId: record.currentStepId,
318
+ activationId: record.activationId,
319
+ attempt: 0,
320
+ pendingAction: null,
321
+ nextEligibleAt: null,
322
+ failure: {
323
+ reason: 'workflow-step-execution-error',
324
+ stepId: record.currentStepId,
325
+ detail: error instanceof Error ? error.message : String(error),
326
+ },
327
+ history: {
328
+ kind: 'failed',
329
+ stepId: record.currentStepId,
330
+ detail: { reason: 'workflow-step-execution-error' },
331
+ },
332
+ },
333
+ })
334
+ .catch(() => { });
335
+ return;
336
+ }
289
337
  if (!progressed)
290
338
  return;
291
339
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cynodia/axiom-server",
3
- "version": "0.14.0-alpha.2",
3
+ "version": "0.14.0-alpha.4",
4
4
  "description": "Authoritative server runtime that executes an Axiom Server IR.",
5
5
  "license": "MIT",
6
6
  "author": "AskTech AS",
@@ -37,8 +37,8 @@
37
37
  "./schema/*": "./schema/*"
38
38
  },
39
39
  "dependencies": {
40
- "@cynodia/axiom-core": "0.14.0-alpha.2",
41
- "@cynodia/axiom-runtime": "0.14.0-alpha.2"
40
+ "@cynodia/axiom-core": "0.14.0-alpha.4",
41
+ "@cynodia/axiom-runtime": "0.14.0-alpha.4"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsc -b tsconfig.json tsconfig.test.json",
@@ -4,7 +4,7 @@
4
4
  "title": "Axiom semantic protocol v1",
5
5
  "description": "What a client may send an authority and what it may receive back. A client requests semantic operations — \"invoke action X with arguments Y\" — never a mutation program. Nothing here mentions a transport.",
6
6
  "contract": "axiom.protocol.v1",
7
- "release": "0.14.0-alpha.2",
7
+ "release": "0.14.0-alpha.4",
8
8
  "oneOf": [
9
9
  {
10
10
  "$ref": "#/$defs/ServerRequest"
@@ -4,7 +4,7 @@
4
4
  "title": "Axiom Server IR v1",
5
5
  "description": "The normative structure of an `axiom.server.v1` document. Structure only: what a conforming runtime must *do* with it is the semantic contract, and the conformance fixtures are the executable statement of that.",
6
6
  "contract": "axiom.server.v1",
7
- "release": "0.14.0-alpha.2",
7
+ "release": "0.14.0-alpha.4",
8
8
  "type": "object",
9
9
  "required": [
10
10
  "contract",
@@ -4,7 +4,7 @@
4
4
  "title": "Axiom Server IR v2",
5
5
  "description": "The normative structure of an `axiom.server.v2` document. Structure only: what a conforming runtime must *do* with it is the semantic contract, and the conformance fixtures are the executable statement of that.",
6
6
  "contract": "axiom.server.v2",
7
- "release": "0.14.0-alpha.2",
7
+ "release": "0.14.0-alpha.4",
8
8
  "type": "object",
9
9
  "required": [
10
10
  "contract",
@@ -4,7 +4,7 @@
4
4
  "title": "Axiom Server IR v3",
5
5
  "description": "The normative structure of an `axiom.server.v3` document. Structure only: what a conforming runtime must *do* with it is the semantic contract, and the conformance fixtures are the executable statement of that.",
6
6
  "contract": "axiom.server.v3",
7
- "release": "0.14.0-alpha.2",
7
+ "release": "0.14.0-alpha.4",
8
8
  "type": "object",
9
9
  "required": [
10
10
  "contract",
@@ -4,7 +4,7 @@
4
4
  "title": "Axiom Server IR v4",
5
5
  "description": "The normative structure of an `axiom.server.v4` document. Structure only: what a conforming runtime must *do* with it is the semantic contract, and the conformance fixtures are the executable statement of that.",
6
6
  "contract": "axiom.server.v4",
7
- "release": "0.14.0-alpha.2",
7
+ "release": "0.14.0-alpha.4",
8
8
  "type": "object",
9
9
  "required": [
10
10
  "contract",
@@ -4,7 +4,7 @@
4
4
  "title": "Axiom Server IR v5",
5
5
  "description": "The normative structure of an `axiom.server.v5` document. Structure only: what a conforming runtime must *do* with it is the semantic contract, and the conformance fixtures are the executable statement of that.",
6
6
  "contract": "axiom.server.v5",
7
- "release": "0.14.0-alpha.2",
7
+ "release": "0.14.0-alpha.4",
8
8
  "type": "object",
9
9
  "required": [
10
10
  "contract",
@@ -4,7 +4,7 @@
4
4
  "title": "Axiom Server IR v6",
5
5
  "description": "The normative structure of an `axiom.server.v6` document. Structure only: what a conforming runtime must *do* with it is the semantic contract, and the conformance fixtures are the executable statement of that.",
6
6
  "contract": "axiom.server.v6",
7
- "release": "0.14.0-alpha.2",
7
+ "release": "0.14.0-alpha.4",
8
8
  "type": "object",
9
9
  "required": [
10
10
  "contract",
@@ -4,7 +4,7 @@
4
4
  "title": "Axiom Server IR v7",
5
5
  "description": "The normative structure of an `axiom.server.v7` document. Structure only: what a conforming runtime must *do* with it is the semantic contract, and the conformance fixtures are the executable statement of that.",
6
6
  "contract": "axiom.server.v7",
7
- "release": "0.14.0-alpha.2",
7
+ "release": "0.14.0-alpha.4",
8
8
  "type": "object",
9
9
  "required": [
10
10
  "contract",
@@ -4,7 +4,7 @@
4
4
  "title": "Axiom Server IR v8",
5
5
  "description": "The normative structure of an `axiom.server.v8` document. Structure only: what a conforming runtime must *do* with it is the semantic contract, and the conformance fixtures are the executable statement of that.",
6
6
  "contract": "axiom.server.v8",
7
- "release": "0.14.0-alpha.2",
7
+ "release": "0.14.0-alpha.4",
8
8
  "type": "object",
9
9
  "required": [
10
10
  "contract",