@cynodia/axiom-server 0.14.0-alpha.1 → 0.14.0-alpha.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 (43) 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.d.ts +36 -5
  29. package/dist/authority-identity.js +64 -19
  30. package/dist/deps.d.ts +2 -2
  31. package/dist/deps.js +1 -1
  32. package/dist/workflows.d.ts +25 -0
  33. package/dist/workflows.js +105 -6
  34. package/package.json +3 -3
  35. package/schema/protocol.v1.schema.json +1 -1
  36. package/schema/server-ir.v1.schema.json +1 -1
  37. package/schema/server-ir.v2.schema.json +1 -1
  38. package/schema/server-ir.v3.schema.json +1 -1
  39. package/schema/server-ir.v4.schema.json +1 -1
  40. package/schema/server-ir.v5.schema.json +1 -1
  41. package/schema/server-ir.v6.schema.json +1 -1
  42. package/schema/server-ir.v7.schema.json +1 -1
  43. 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.1",
13
+ "version": "0.14.0-alpha.2",
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.1",
13
+ "version": "0.14.0-alpha.2",
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.1",
14
+ "version": "0.14.0-alpha.2",
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.1",
12
+ "version": "0.14.0-alpha.2",
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.1",
13
+ "version": "0.14.0-alpha.2",
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.1",
12
+ "version": "0.14.0-alpha.2",
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.1",
5
+ "release": "0.14.0-alpha.2",
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.1",
13
+ "version": "0.14.0-alpha.2",
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.1",
15
+ "version": "0.14.0-alpha.2",
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.1",
12
+ "version": "0.14.0-alpha.2",
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.1",
13
+ "version": "0.14.0-alpha.2",
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.1",
13
+ "version": "0.14.0-alpha.2",
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.1",
12
+ "version": "0.14.0-alpha.2",
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.1",
5
+ "release": "0.14.0-alpha.2",
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.1",
34
+ "version": "0.14.0-alpha.2",
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.1",
52
+ "version": "0.14.0-alpha.2",
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.1",
24
+ "version": "0.14.0-alpha.2",
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.1",
30
+ "version": "0.14.0-alpha.2",
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.1",
23
+ "version": "0.14.0-alpha.2",
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.1",
23
+ "version": "0.14.0-alpha.2",
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.1",
34
+ "version": "0.14.0-alpha.2",
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.1",
33
+ "version": "0.14.0-alpha.2",
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.1",
31
+ "version": "0.14.0-alpha.2",
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.1",
30
+ "version": "0.14.0-alpha.2",
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.1",
20
+ "version": "0.14.0-alpha.2",
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.1",
20
+ "version": "0.14.0-alpha.2",
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.1",
26
+ "version": "0.14.0-alpha.2",
27
27
  "entities": [
28
28
  {
29
29
  "id": "entity_pay",
@@ -10,15 +10,46 @@
10
10
  * The resulting {@link AuthorityCompatibilityKey} is what `createDurableWorkStore` stamps as
11
11
  * its `authorityKey`: an incompatible / older build then refuses to claim work a newer build
12
12
  * created (spec12 §44, §47).
13
+ *
14
+ * **spec14pt3 §5 G1 — one canonical semantic projection.** The slices this hashes are keyed
15
+ * by `core`'s {@link EXECUTABLE_KINDS} — the *same* list the graph-level `semanticFingerprint`
16
+ * iterates — through {@link SERVER_IR_EXECUTABLE_SLICES}. Phase 22 F3 was exactly the failure
17
+ * this now prevents: `WorkflowDef` had been added to `EXECUTABLE_KINDS` (so
18
+ * `semanticFingerprint(graph)` moved for a workflow semantic change) but this projection's
19
+ * hand-maintained slice list omitted `workflows`, so two authorities running different
20
+ * workflow semantics reported `compatible: true` and one silently advanced an in-flight
21
+ * instance under changed meaning. A `server` test now pins that every `EXECUTABLE_KINDS`
22
+ * member is projected here.
23
+ */
24
+ import { EXECUTABLE_KINDS, type AuthorityCompatibilityKey, type ServerIR } from './deps.js';
25
+ type ExecutableKind = (typeof EXECUTABLE_KINDS)[number];
26
+ /**
27
+ * The Server IR slice carrying each executable graph kind. Keyed by `core`'s
28
+ * {@link EXECUTABLE_KINDS} so this projection and the graph-level `semanticFingerprint`
29
+ * cannot disagree about what is executable (spec14pt3 §5, §6, §189).
30
+ *
31
+ * `since: 'v8'` marks a slice added after `axiom.server.v1..v7` were frozen: it contributes
32
+ * to the fingerprint **only when non-empty**, exactly as `core`'s `semanticProjection` skips
33
+ * an empty kind — so every pre-workflow (non-`WorkflowDef`) graph's authority fingerprint is
34
+ * byte-identical to what it was before this correction (spec14pt3 §35, §38, §103). The 13
35
+ * pre-v8 slices stay unconditionally present (an empty array included) to keep *their*
36
+ * frozen bytes unchanged.
13
37
  */
14
- import { type AuthorityCompatibilityKey, type ServerIR } from './deps.js';
38
+ declare const SERVER_IR_EXECUTABLE_SLICES: Record<ExecutableKind, {
39
+ field: keyof ServerIR;
40
+ shape: 'record' | 'list';
41
+ since?: 'v8';
42
+ }>;
15
43
  /**
16
- * The canonical executable-meaning projection of a Server IR: actions, constraints,
17
- * transition constraints, expression defs, integrations + operations, triggers, events,
18
- * subscriptions, storages, read policies, relationships, queries, plus the schema version.
19
- * Everything a distributed worker executes; nothing a rename touches.
44
+ * The canonical executable-meaning projection of a Server IR: everything a distributed
45
+ * worker executes actions, constraints, transition constraints, expression defs,
46
+ * integrations + operations, triggers, events, subscriptions, storages, read policies,
47
+ * relationships, queries, **and workflows** plus the schema version. Nothing a rename
48
+ * touches. Built by iterating {@link EXECUTABLE_KINDS} so a future primitive cannot be
49
+ * omitted (spec14pt3 F3 root cause).
20
50
  */
21
51
  export declare function serverIrSemanticProjection(ir: ServerIR): Record<string, unknown>;
52
+ export { SERVER_IR_EXECUTABLE_SLICES };
22
53
  export declare function serverIrSemanticFingerprint(ir: ServerIR): string;
23
54
  /** The full compatibility key for the authority executing this Server IR (spec12 §45). */
24
55
  export declare function serverIrCompatibilityKey(ir: ServerIR): AuthorityCompatibilityKey;
@@ -10,9 +10,19 @@
10
10
  * The resulting {@link AuthorityCompatibilityKey} is what `createDurableWorkStore` stamps as
11
11
  * its `authorityKey`: an incompatible / older build then refuses to claim work a newer build
12
12
  * created (spec12 §44, §47).
13
+ *
14
+ * **spec14pt3 §5 G1 — one canonical semantic projection.** The slices this hashes are keyed
15
+ * by `core`'s {@link EXECUTABLE_KINDS} — the *same* list the graph-level `semanticFingerprint`
16
+ * iterates — through {@link SERVER_IR_EXECUTABLE_SLICES}. Phase 22 F3 was exactly the failure
17
+ * this now prevents: `WorkflowDef` had been added to `EXECUTABLE_KINDS` (so
18
+ * `semanticFingerprint(graph)` moved for a workflow semantic change) but this projection's
19
+ * hand-maintained slice list omitted `workflows`, so two authorities running different
20
+ * workflow semantics reported `compatible: true` and one silently advanced an in-flight
21
+ * instance under changed meaning. A `server` test now pins that every `EXECUTABLE_KINDS`
22
+ * member is projected here.
13
23
  */
14
24
  import { createHash } from 'node:crypto';
15
- import { SEMANTIC_FINGERPRINT_VERSION, authorityCompatibilityKey, canonicalJSON, compatibilityKeyString, } from './deps.js';
25
+ import { EXECUTABLE_KINDS, SEMANTIC_FINGERPRINT_VERSION, authorityCompatibilityKey, canonicalJSON, canonicalWorkflowForFingerprint, compatibilityKeyString, } from './deps.js';
16
26
  const NON_SEMANTIC_KEYS = new Set(['name', 'description', 'label', 'metadata', 'axiom.authoring']);
17
27
  function stripNonSemantic(value) {
18
28
  if (Array.isArray(value))
@@ -39,30 +49,65 @@ function sortedList(list) {
39
49
  .map((entry) => stripNonSemantic(entry));
40
50
  }
41
51
  /**
42
- * The canonical executable-meaning projection of a Server IR: actions, constraints,
43
- * transition constraints, expression defs, integrations + operations, triggers, events,
44
- * subscriptions, storages, read policies, relationships, queries, plus the schema version.
45
- * Everything a distributed worker executes; nothing a rename touches.
52
+ * The Server IR slice carrying each executable graph kind. Keyed by `core`'s
53
+ * {@link EXECUTABLE_KINDS} so this projection and the graph-level `semanticFingerprint`
54
+ * cannot disagree about what is executable (spec14pt3 §5, §6, §189).
55
+ *
56
+ * `since: 'v8'` marks a slice added after `axiom.server.v1..v7` were frozen: it contributes
57
+ * to the fingerprint **only when non-empty**, exactly as `core`'s `semanticProjection` skips
58
+ * an empty kind — so every pre-workflow (non-`WorkflowDef`) graph's authority fingerprint is
59
+ * byte-identical to what it was before this correction (spec14pt3 §35, §38, §103). The 13
60
+ * pre-v8 slices stay unconditionally present (an empty array included) to keep *their*
61
+ * frozen bytes unchanged.
62
+ */
63
+ const SERVER_IR_EXECUTABLE_SLICES = {
64
+ action: { field: 'actions', shape: 'record' },
65
+ integration: { field: 'integrations', shape: 'list' },
66
+ 'integration-operation': { field: 'integrationOperations', shape: 'record' },
67
+ trigger: { field: 'triggers', shape: 'list' },
68
+ event: { field: 'events', shape: 'list' },
69
+ subscription: { field: 'subscriptions', shape: 'list' },
70
+ 'read-policy': { field: 'readPolicies', shape: 'list' },
71
+ query: { field: 'queries', shape: 'list' },
72
+ expression: { field: 'expressionDefs', shape: 'record' },
73
+ constraint: { field: 'constraints', shape: 'list' },
74
+ 'transition-constraint': { field: 'transitionConstraints', shape: 'list' },
75
+ storage: { field: 'storages', shape: 'list' },
76
+ relationship: { field: 'relationships', shape: 'list' },
77
+ workflow: { field: 'workflows', shape: 'list', since: 'v8' },
78
+ };
79
+ /**
80
+ * The canonical executable-meaning projection of a Server IR: everything a distributed
81
+ * worker executes — actions, constraints, transition constraints, expression defs,
82
+ * integrations + operations, triggers, events, subscriptions, storages, read policies,
83
+ * relationships, queries, **and workflows** — plus the schema version. Nothing a rename
84
+ * touches. Built by iterating {@link EXECUTABLE_KINDS} so a future primitive cannot be
85
+ * omitted (spec14pt3 F3 root cause).
46
86
  */
47
87
  export function serverIrSemanticProjection(ir) {
48
- return {
88
+ const projection = {
49
89
  fingerprintVersion: SEMANTIC_FINGERPRINT_VERSION,
50
90
  schemaVersion: ir.schemaVersion ?? 1,
51
- actions: sortedRecord(ir.actions),
52
- constraints: sortedList(ir.constraints),
53
- transitionConstraints: sortedList(ir.transitionConstraints),
54
- expressionDefs: sortedRecord(ir.expressionDefs),
55
- integrations: sortedList(ir.integrations),
56
- integrationOperations: sortedRecord(ir.integrationOperations),
57
- triggers: sortedList(ir.triggers),
58
- events: sortedList(ir.events),
59
- subscriptions: sortedList(ir.subscriptions),
60
- storages: sortedList(ir.storages),
61
- readPolicies: sortedList(ir.readPolicies),
62
- relationships: sortedList(ir.relationships),
63
- queries: sortedList(ir.queries),
64
91
  };
92
+ for (const kind of EXECUTABLE_KINDS) {
93
+ const slice = SERVER_IR_EXECUTABLE_SLICES[kind];
94
+ let raw = ir[slice.field];
95
+ // Workflows are canonicalized (authoring order of steps / inputs / bindings is not
96
+ // semantic) through the *same* core helper the graph-level fingerprint uses (spec14pt3
97
+ // §5 G1, §64), so the two projections cannot disagree about a workflow.
98
+ if (kind === 'workflow' && Array.isArray(raw)) {
99
+ raw = raw.map((w) => canonicalWorkflowForFingerprint(w));
100
+ }
101
+ const projected = slice.shape === 'record'
102
+ ? sortedRecord(raw)
103
+ : sortedList(raw);
104
+ if (slice.since === 'v8' && projected.length === 0)
105
+ continue;
106
+ projection[slice.field] = projected;
107
+ }
108
+ return projection;
65
109
  }
110
+ export { SERVER_IR_EXECUTABLE_SLICES };
66
111
  export function serverIrSemanticFingerprint(ir) {
67
112
  return createHash('sha256').update(canonicalJSON(serverIrSemanticProjection(ir))).digest('hex');
68
113
  }
package/dist/deps.d.ts CHANGED
@@ -5,9 +5,9 @@
5
5
  * runtime explicit: it is the semantic engine and nothing else. No transport, no database
6
6
  * driver and no host API appears here.
7
7
  */
8
- export type { ActionDef, AnyNode, ApplicationIR, Authority, AuthorityCompatibilityKey, CompatibilityComparison, ConstraintDef, EntityDef, EventDef, Expression, FieldDef, FieldId, IntegrationDef, IntegrationOperationDef, LiteralValue, MigrationDef, MigrationOperation, MigrationOperationKind, NodeId, Operation, SchemaChangeClass, SchemaDiff, SchemaDiffEntry, SchemaProjection, QueryAggregate, QueryAggregateFunction, QueryDef, LiveCapability, LiveChange, LiveQueryDelta, MaterializedResult, QueryDependencySet, CommitChangeset, QueryNullsOrder, QueryPagination, QueryParameter, QueryProjection, QueryRelationshipUse, QuerySortDirection, QuerySortKey, ReadPolicyDef, RelationshipDef, RelationshipCardinality, ServerIR, StateDef, StorageDef, SubscriptionDef, SubscriptionBackpressurePolicy, SubscriptionLifecycleState, TransitionConstraintDef, TriggerDef, TriggerSpec, TypeRef, WorkflowDef, WorkflowStep, WorkflowActionStep, WorkflowWaitEventStep, WorkflowRetryPolicy, WorkflowInput, WorkflowBinding, WorkflowDuration, } from '@cynodia/axiom-core';
8
+ export type { ActionDef, AnyNode, ApplicationIR, Authority, AuthorityCompatibilityKey, CompatibilityComparison, ConstraintDef, EntityDef, EventDef, Expression, FieldDef, FieldId, IntegrationDef, IntegrationOperationDef, LiteralValue, MigrationDef, MigrationOperation, MigrationOperationKind, NodeId, Operation, SchemaChangeClass, SchemaDiff, SchemaDiffEntry, SchemaProjection, QueryAggregate, QueryAggregateFunction, QueryDef, LiveCapability, LiveChange, LiveQueryDelta, MaterializedResult, QueryDependencySet, CommitChangeset, QueryNullsOrder, QueryPagination, QueryParameter, QueryProjection, QueryRelationshipUse, QuerySortDirection, QuerySortKey, ReadPolicyDef, RelationshipDef, RelationshipCardinality, ServerIR, StateDef, StorageDef, SubscriptionDef, SubscriptionBackpressurePolicy, SubscriptionLifecycleState, TransitionConstraintDef, TriggerDef, TriggerSpec, TypeRef, WorkflowDef, WorkflowStep, WorkflowActionStep, WorkflowWaitEventStep, WorkflowRetryPolicy, WorkflowInput, WorkflowBinding, WorkflowDuration, WorkflowStructuralProblem, } from '@cynodia/axiom-core';
9
9
  export type { ActionOutcome, ActionResult, EffectIntentRecord, RuntimeDiagnostic, RuntimeDiagnosticCode, } from '@cynodia/axiom-runtime';
10
10
  export { PRINCIPAL, RUNTIME_DIAGNOSTIC_CODES, SERVER_IR_CONTRACT } from './runtime-deps.js';
11
- export { MIGRATION_OLD_SCOPE, MIGRATION_OPERATION_KINDS, diffSchema, canonicalJSON, walkExpression, applyDelta, commitAffectsQuery, diffResults, queryDependencies, queryLiveCapability, queryStateReferences, rowKey, LIVE_QUERY_NONDETERMINISTIC_BUILTINS, fingerprintProjection, migrationCoversDiff, migrationExpressions, migrationOperationEntityId, migrationOperationExpressions, migrationOperationFieldIds, migrationOperationReadFieldIds, migrationPath, schemaFingerprint, schemaProjection, semanticFingerprint, semanticProjection, authorityCompatibilityKey, compatibilityKeyString, compareAuthorityCompatibility, SEMANTIC_FINGERPRINT_VERSION, sortMigrations, WORKFLOW_EVENT_SCOPE, WORKFLOW_PRINCIPAL_SCOPE, WORKFLOW_STEP_TYPES, workflowStepById, workflowStepSuccessors, workflowStepExpressions, workflowActionIds, workflowEventIds, workflowReachableSteps, workflowHasCycle, workflowExpressions, } from '@cynodia/axiom-core';
11
+ export { MIGRATION_OLD_SCOPE, MIGRATION_OPERATION_KINDS, diffSchema, canonicalJSON, walkExpression, applyDelta, commitAffectsQuery, diffResults, queryDependencies, queryLiveCapability, queryStateReferences, rowKey, LIVE_QUERY_NONDETERMINISTIC_BUILTINS, fingerprintProjection, migrationCoversDiff, migrationExpressions, migrationOperationEntityId, migrationOperationExpressions, migrationOperationFieldIds, migrationOperationReadFieldIds, migrationPath, schemaFingerprint, schemaProjection, semanticFingerprint, semanticProjection, authorityCompatibilityKey, compatibilityKeyString, compareAuthorityCompatibility, EXECUTABLE_KINDS, SEMANTIC_FINGERPRINT_VERSION, sortMigrations, WORKFLOW_EVENT_SCOPE, WORKFLOW_PRINCIPAL_SCOPE, WORKFLOW_STEP_TYPES, workflowStepById, workflowStepSuccessors, workflowStepExpressions, workflowActionIds, workflowEventIds, workflowReachableSteps, workflowHasCycle, workflowExpressions, isWorkflowStep, workflowStructuralProblems, canonicalWorkflowForFingerprint, } from '@cynodia/axiom-core';
12
12
  export { BLOB_CHECKSUM_FIELD, BLOB_FILENAME_FIELD, BLOB_KEY_FIELD, BLOB_MEDIA_TYPE_FIELD, BLOB_SIZE_FIELD, DEFAULT_QUERY_MAX_PAGE_SIZE, DEFAULT_QUERY_PAGE_SIZE, DEFAULT_RELATIONSHIP_PAGE_SIZE, queryDefaultPageSize, queryExpressions, queryIsAggregate, queryIsGrouped, queryMaxPageSize, queryPaginationStrategy, queryRowEntityId, relationshipIsToOne, relationshipTargetEntityId, sortKeyDirection, sortKeyNulls, subscriptionAutoStart, subscriptionBackpressure, subscriptionDeduplicationWindow, subscriptionFailurePolicy, subscriptionIsRequired, subscriptionMaxAttempts, subscriptionQueueLimit, subscriptionReconnectPolicy, subscriptionSourceName, } from '@cynodia/axiom-core';
13
13
  //# sourceMappingURL=deps.d.ts.map
package/dist/deps.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export { PRINCIPAL, RUNTIME_DIAGNOSTIC_CODES, SERVER_IR_CONTRACT } from './runtime-deps.js';
2
- export { MIGRATION_OLD_SCOPE, MIGRATION_OPERATION_KINDS, diffSchema, canonicalJSON, walkExpression, applyDelta, commitAffectsQuery, diffResults, queryDependencies, queryLiveCapability, queryStateReferences, rowKey, LIVE_QUERY_NONDETERMINISTIC_BUILTINS, fingerprintProjection, migrationCoversDiff, migrationExpressions, migrationOperationEntityId, migrationOperationExpressions, migrationOperationFieldIds, migrationOperationReadFieldIds, migrationPath, schemaFingerprint, schemaProjection, semanticFingerprint, semanticProjection, authorityCompatibilityKey, compatibilityKeyString, compareAuthorityCompatibility, SEMANTIC_FINGERPRINT_VERSION, sortMigrations, WORKFLOW_EVENT_SCOPE, WORKFLOW_PRINCIPAL_SCOPE, WORKFLOW_STEP_TYPES, workflowStepById, workflowStepSuccessors, workflowStepExpressions, workflowActionIds, workflowEventIds, workflowReachableSteps, workflowHasCycle, workflowExpressions, } from '@cynodia/axiom-core';
2
+ export { MIGRATION_OLD_SCOPE, MIGRATION_OPERATION_KINDS, diffSchema, canonicalJSON, walkExpression, applyDelta, commitAffectsQuery, diffResults, queryDependencies, queryLiveCapability, queryStateReferences, rowKey, LIVE_QUERY_NONDETERMINISTIC_BUILTINS, fingerprintProjection, migrationCoversDiff, migrationExpressions, migrationOperationEntityId, migrationOperationExpressions, migrationOperationFieldIds, migrationOperationReadFieldIds, migrationPath, schemaFingerprint, schemaProjection, semanticFingerprint, semanticProjection, authorityCompatibilityKey, compatibilityKeyString, compareAuthorityCompatibility, EXECUTABLE_KINDS, SEMANTIC_FINGERPRINT_VERSION, sortMigrations, WORKFLOW_EVENT_SCOPE, WORKFLOW_PRINCIPAL_SCOPE, WORKFLOW_STEP_TYPES, workflowStepById, workflowStepSuccessors, workflowStepExpressions, workflowActionIds, workflowEventIds, workflowReachableSteps, workflowHasCycle, workflowExpressions, isWorkflowStep, workflowStructuralProblems, canonicalWorkflowForFingerprint, } from '@cynodia/axiom-core';
3
3
  export { BLOB_CHECKSUM_FIELD, BLOB_FILENAME_FIELD, BLOB_KEY_FIELD, BLOB_MEDIA_TYPE_FIELD, BLOB_SIZE_FIELD, DEFAULT_QUERY_MAX_PAGE_SIZE, DEFAULT_QUERY_PAGE_SIZE, DEFAULT_RELATIONSHIP_PAGE_SIZE, queryDefaultPageSize, queryExpressions, queryIsAggregate, queryIsGrouped, queryMaxPageSize, queryPaginationStrategy, queryRowEntityId, relationshipIsToOne, relationshipTargetEntityId, sortKeyDirection, sortKeyNulls, subscriptionAutoStart, subscriptionBackpressure, subscriptionDeduplicationWindow, subscriptionFailurePolicy, subscriptionIsRequired, subscriptionMaxAttempts, subscriptionQueueLimit, subscriptionReconnectPolicy, subscriptionSourceName, } from '@cynodia/axiom-core';
@@ -73,6 +73,14 @@ export interface WorkflowInspection {
73
73
  instanceRevision: number;
74
74
  failure?: Record<string, unknown>;
75
75
  output?: Record<string, unknown>;
76
+ /**
77
+ * Whether *this* authority build may semantically advance the instance (spec14pt3 §26,
78
+ * §164). `false` when the instance was created / last advanced under incompatible
79
+ * `WorkflowDef` semantics — read-only inspection stays available so an operator can see
80
+ * *why* it is not progressing rather than finding it silently stuck.
81
+ */
82
+ compatible: boolean;
83
+ incompatibleReason?: 'incompatible-build';
76
84
  }
77
85
  export interface WorkflowEngine {
78
86
  start(): Promise<void>;
@@ -107,5 +115,22 @@ export interface WorkflowEngine {
107
115
  /** Advance one instance now (used by the poll loop and directly after a local start). */
108
116
  advance(instanceId: string): Promise<void>;
109
117
  }
118
+ /**
119
+ * Structurally invalid workflow IR reached the authoritative runtime (spec14pt3 F2 §44-§49).
120
+ * `createWorkflowEngine` fails closed with this rather than letting a hand-tampered / stored /
121
+ * transported `ServerIR` reach a native `TypeError`, a silently skipped step or a wedged
122
+ * instance. `problems` is a structured list; nothing implementation-internal is exposed.
123
+ */
124
+ export declare class WorkflowIRError extends Error {
125
+ readonly code: "WORKFLOW_INVALID_IR";
126
+ readonly problems: ReadonlyArray<{
127
+ code: string;
128
+ message: string;
129
+ }>;
130
+ constructor(problems: ReadonlyArray<{
131
+ code: string;
132
+ message: string;
133
+ }>);
134
+ }
110
135
  export declare function createWorkflowEngine(options: WorkflowEngineOptions): WorkflowEngine;
111
136
  //# sourceMappingURL=workflows.d.ts.map
package/dist/workflows.js CHANGED
@@ -12,7 +12,7 @@
12
12
  * PRINCIPAL).
13
13
  */
14
14
  import { createHash, randomUUID } from 'node:crypto';
15
- import { WORKFLOW_EVENT_SCOPE, WORKFLOW_PRINCIPAL_SCOPE, workflowStepById, } from './deps.js';
15
+ import { WORKFLOW_EVENT_SCOPE, WORKFLOW_PRINCIPAL_SCOPE, isWorkflowStep, workflowStepById, workflowStructuralProblems, } from './deps.js';
16
16
  import { workflowStartKey } from './workflow-store.js';
17
17
  // --------------------------------------------------------------- pure expression eval
18
18
  /**
@@ -132,6 +132,21 @@ function truthy(v) {
132
132
  function canonical(v) {
133
133
  return JSON.stringify(v ?? null);
134
134
  }
135
+ /**
136
+ * Structurally invalid workflow IR reached the authoritative runtime (spec14pt3 F2 §44-§49).
137
+ * `createWorkflowEngine` fails closed with this rather than letting a hand-tampered / stored /
138
+ * transported `ServerIR` reach a native `TypeError`, a silently skipped step or a wedged
139
+ * instance. `problems` is a structured list; nothing implementation-internal is exposed.
140
+ */
141
+ export class WorkflowIRError extends Error {
142
+ code = 'WORKFLOW_INVALID_IR';
143
+ problems;
144
+ constructor(problems) {
145
+ super(`workflow IR is structurally invalid: ${problems.map((p) => p.message).join('; ')}`);
146
+ this.name = 'WorkflowIRError';
147
+ this.problems = problems;
148
+ }
149
+ }
135
150
  const WF_DIAGNOSTIC = {
136
151
  UNKNOWN_WORKFLOW: 'WORKFLOW_NOT_FOUND',
137
152
  ARGUMENT_MISMATCH: 'WORKFLOW_ARGUMENT_MISMATCH',
@@ -144,6 +159,15 @@ export function createWorkflowEngine(options) {
144
159
  const pollMs = options.pollMs ?? 250;
145
160
  const recoverBatch = options.recoverBatch ?? 64;
146
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).
167
+ const irProblems = options.workflows.flatMap((w) => workflowStructuralProblems(w));
168
+ if (irProblems.length > 0) {
169
+ throw new WorkflowIRError(irProblems);
170
+ }
147
171
  const byId = new Map(options.workflows.map((w) => [String(w.id), w]));
148
172
  let pollTimer;
149
173
  let running = false;
@@ -166,6 +190,21 @@ export function createWorkflowEngine(options) {
166
190
  }
167
191
  }
168
192
  // ---- scope + step evaluation -------------------------------------------------
193
+ /**
194
+ * spec14pt3 F3 — whether this authority build may interpret this durable instance. The
195
+ * instance durably records the `AuthorityCompatibilityKey` string it was created under
196
+ * (`{ serverContract, schemaFingerprint, semanticFingerprint }`, and `semanticFingerprint`
197
+ * now covers `WorkflowDef` executable meaning). A build whose key differs — a changed
198
+ * action target, event id, branch predicate, timer duration, retry policy or control-flow
199
+ * edge — must fail closed rather than advance the instance under changed semantics. A
200
+ * missing / malformed stored fingerprint is also incompatible (never "missing ⇒
201
+ * compatible", spec14pt3 §175).
202
+ */
203
+ function isCompatible(record) {
204
+ return (typeof record.compatibilityFingerprint === 'string' &&
205
+ record.compatibilityFingerprint.length > 0 &&
206
+ record.compatibilityFingerprint === options.compatibilityFingerprint);
207
+ }
169
208
  function scopeFor(record, eventPayload) {
170
209
  return {
171
210
  ...record.inputs,
@@ -210,16 +249,42 @@ export function createWorkflowEngine(options) {
210
249
  return;
211
250
  if (record.status === 'completed' || record.status === 'failed' || record.status === 'cancelled')
212
251
  return;
213
- if (record.compatibilityFingerprint !== options.compatibilityFingerprint) {
214
- // A semantically incompatible build must not advance this instance (spec14 §116).
252
+ if (!isCompatible(record)) {
253
+ // spec14pt3 F3 fail closed *before* any semantic step: no ActionDef invoke,
254
+ // no event/timer/branch transition, no binding write, no `instanceRevision`
255
+ // advance. The instance is left exactly as it stands for a compatible authority
256
+ // to resume; incompatibility is an execution-environment problem, never an
257
+ // automatic `failed` / `cancelled` (spec14pt3 §23, §76, §156).
215
258
  return;
216
259
  }
217
260
  const workflow = byId.get(record.workflowId);
218
261
  if (!workflow)
219
262
  return;
220
263
  const step = workflowStepById(workflow, record.currentStepId);
221
- if (!step)
264
+ // spec14pt3 F2: admission validation already rejected a structurally invalid
265
+ // workflow, so this only fires if the in-memory definition was mutated after the
266
+ // engine started. Fail the instance with a structured reason rather than looping
267
+ // the poll forever (a silent permanent wedge is explicitly forbidden, §46).
268
+ if (!step || !isWorkflowStep(step)) {
269
+ await store
270
+ .transition({
271
+ instanceId: record.instanceId,
272
+ expectedRevision: record.instanceRevision,
273
+ fence,
274
+ next: {
275
+ status: 'failed',
276
+ currentStepId: record.currentStepId,
277
+ activationId: record.activationId,
278
+ attempt: 0,
279
+ pendingAction: null,
280
+ nextEligibleAt: null,
281
+ failure: { reason: 'workflow-invalid-step', stepId: record.currentStepId },
282
+ history: { kind: 'failed', stepId: record.currentStepId, detail: { reason: 'workflow-invalid-step' } },
283
+ },
284
+ })
285
+ .catch(() => { });
222
286
  return;
287
+ }
223
288
  const progressed = await runStep({ workflow, record, step, fence });
224
289
  if (!progressed)
225
290
  return;
@@ -369,6 +434,11 @@ export function createWorkflowEngine(options) {
369
434
  case 'action': {
370
435
  return runActionStep({ ...args, step });
371
436
  }
437
+ default:
438
+ // Unreachable: `advance` fails the instance before calling `runStep` for a step
439
+ // that is not one of the six kinds, and admission validation rejects such IR
440
+ // outright. Present so the switch is total and never returns `undefined`.
441
+ return false;
372
442
  }
373
443
  }
374
444
  async function runActionStep(args) {
@@ -499,7 +569,10 @@ export function createWorkflowEngine(options) {
499
569
  if (eventSeq <= wait.sinceEventSeq)
500
570
  continue;
501
571
  const loaded = await store.load(wait.instanceId);
502
- if (!loaded || loaded.compatibilityFingerprint !== options.compatibilityFingerprint)
572
+ // spec14pt3 F3 an incompatible build may journal the canonical event as
573
+ // infrastructure but must not apply its (changed) `where` / `bind` semantics to this
574
+ // instance. A compatible authority reconciles it later from the durable journal.
575
+ if (!loaded || !isCompatible(loaded))
503
576
  continue;
504
577
  const workflow = byId.get(loaded.workflowId ?? '');
505
578
  if (!workflow)
@@ -597,7 +670,7 @@ export function createWorkflowEngine(options) {
597
670
  compatibilityFingerprint: options.compatibilityFingerprint,
598
671
  };
599
672
  const instanceId = `wf_${createHash('sha256').update(workflowStartKey(start)).digest('hex').slice(0, 24)}_${randomUUID().slice(0, 8)}`;
600
- const { instance } = await store.createIdempotent(start, () => ({
673
+ const { instance, created } = await store.createIdempotent(start, () => ({
601
674
  instanceId,
602
675
  workflowId: request.workflowId,
603
676
  compatibilityFingerprint: options.compatibilityFingerprint,
@@ -606,6 +679,18 @@ export function createWorkflowEngine(options) {
606
679
  inputs,
607
680
  entryStepId: String(workflow.entry),
608
681
  }));
682
+ // spec14pt3 §161, §162 — a repeated start identity that resolves to an *existing*
683
+ // instance created under incompatible workflow semantics must NOT silently reuse it and
684
+ // continue it under this build. Return it, plainly labelled incompatible; never
685
+ // reinterpret it. (A brand-new instance created just now always matches this build.)
686
+ if (!created && !isCompatible(instance)) {
687
+ return {
688
+ error: {
689
+ code: WF_DIAGNOSTIC.INCOMPATIBLE,
690
+ message: `Workflow instance ${instance.instanceId} was created under workflow semantics incompatible with this authority build`,
691
+ },
692
+ };
693
+ }
609
694
  // Drive it forward immediately (local fast path); the poll loop is the durable backstop.
610
695
  await advance(instance.instanceId).catch(() => { });
611
696
  const fresh = (await store.load(instance.instanceId)) ?? instance;
@@ -620,6 +705,18 @@ export function createWorkflowEngine(options) {
620
705
  if (record.status === 'completed' || record.status === 'failed') {
621
706
  return { ok: true, status: record.status }; // idempotent; a terminal workflow is not resurrected
622
707
  }
708
+ // spec14pt3 §163 — cancellation writes a durable `cancelled` transition on this
709
+ // instance, so it is compatibility-gated like every other transition: an incompatible
710
+ // build must not transition an instance whose workflow meaning it does not share. The
711
+ // instance is left for a compatible authority to cancel or complete.
712
+ if (!isCompatible(record)) {
713
+ return {
714
+ error: {
715
+ code: WF_DIAGNOSTIC.INCOMPATIBLE,
716
+ message: `Workflow instance ${instanceId} is incompatible with this authority build; it cannot be cancelled here`,
717
+ },
718
+ };
719
+ }
623
720
  const result = await withOwnership(instanceId, async (fence) => {
624
721
  const fresh = await store.load(instanceId);
625
722
  if (!fresh || fresh.status === 'cancelled' || fresh.status === 'completed' || fresh.status === 'failed') {
@@ -663,6 +760,8 @@ export function createWorkflowEngine(options) {
663
760
  instanceRevision: record.instanceRevision,
664
761
  ...(record.failure ? { failure: record.failure } : {}),
665
762
  ...(record.output ? { output: record.output } : {}),
763
+ compatible: isCompatible(record),
764
+ ...(isCompatible(record) ? {} : { incompatibleReason: 'incompatible-build' }),
666
765
  };
667
766
  }
668
767
  async function pollOnce() {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cynodia/axiom-server",
3
- "version": "0.14.0-alpha.1",
3
+ "version": "0.14.0-alpha.2",
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.1",
41
- "@cynodia/axiom-runtime": "0.14.0-alpha.1"
40
+ "@cynodia/axiom-core": "0.14.0-alpha.2",
41
+ "@cynodia/axiom-runtime": "0.14.0-alpha.2"
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.1",
7
+ "release": "0.14.0-alpha.2",
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.1",
7
+ "release": "0.14.0-alpha.2",
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.1",
7
+ "release": "0.14.0-alpha.2",
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.1",
7
+ "release": "0.14.0-alpha.2",
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.1",
7
+ "release": "0.14.0-alpha.2",
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.1",
7
+ "release": "0.14.0-alpha.2",
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.1",
7
+ "release": "0.14.0-alpha.2",
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.1",
7
+ "release": "0.14.0-alpha.2",
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.1",
7
+ "release": "0.14.0-alpha.2",
8
8
  "type": "object",
9
9
  "required": [
10
10
  "contract",