@cynodia/axiom-server 0.14.0-alpha.1 → 0.14.0-alpha.3
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.
- package/conformance/live/aggregate-reset.json +1 -1
- package/conformance/live/dependency-commit-no-change.json +1 -1
- package/conformance/live/f2-state-ref-refused.json +1 -1
- package/conformance/live/initial-result.json +1 -1
- package/conformance/live/insert-on-filter-entry.json +1 -1
- package/conformance/live/limit-boundary.json +1 -1
- package/conformance/live/manifest.json +1 -1
- package/conformance/live/not-live-capable.json +1 -1
- package/conformance/live/provider-only-sequence.json +1 -1
- package/conformance/live/provider-record-remove.json +1 -1
- package/conformance/live/remove-on-filter-exit.json +1 -1
- package/conformance/live/update-with-move.json +1 -1
- package/conformance/live/update-without-move.json +1 -1
- package/conformance/workflow/manifest.json +1 -1
- package/conformance/workflow/workflow-action-on-error.json +1 -1
- package/conformance/workflow/workflow-action-retry.json +1 -1
- package/conformance/workflow/workflow-action-success.json +1 -1
- package/conformance/workflow/workflow-action-terminal-failure.json +1 -1
- package/conformance/workflow/workflow-branch-false.json +1 -1
- package/conformance/workflow/workflow-branch-true.json +1 -1
- package/conformance/workflow/workflow-cancel-waiting.json +1 -1
- package/conformance/workflow/workflow-event-match.json +1 -1
- package/conformance/workflow/workflow-event-nonmatch.json +1 -1
- package/conformance/workflow/workflow-event-timeout.json +1 -1
- package/conformance/workflow/workflow-start-complete.json +1 -1
- package/conformance/workflow/workflow-start-idempotency.json +1 -1
- package/conformance/workflow/workflow-timer.json +1 -1
- package/dist/authority-identity.d.ts +36 -5
- package/dist/authority-identity.js +77 -22
- package/dist/deps.d.ts +2 -2
- package/dist/deps.js +1 -1
- package/dist/server.js +18 -2
- package/dist/workflows.d.ts +25 -0
- package/dist/workflows.js +155 -8
- package/package.json +3 -3
- package/schema/protocol.v1.schema.json +1 -1
- package/schema/server-ir.v1.schema.json +1 -1
- package/schema/server-ir.v2.schema.json +1 -1
- package/schema/server-ir.v3.schema.json +1 -1
- package/schema/server-ir.v4.schema.json +1 -1
- package/schema/server-ir.v5.schema.json +1 -1
- package/schema/server-ir.v6.schema.json +1 -1
- package/schema/server-ir.v7.schema.json +1 -1
- package/schema/server-ir.v8.schema.json +1 -1
|
@@ -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.
|
|
5
|
+
"release": "0.14.0-alpha.3",
|
|
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
|
{
|
|
@@ -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.
|
|
5
|
+
"release": "0.14.0-alpha.3",
|
|
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
|
{
|
|
@@ -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
|
-
|
|
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:
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
*
|
|
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))
|
|
@@ -28,41 +38,86 @@ function stripNonSemantic(value) {
|
|
|
28
38
|
}
|
|
29
39
|
return value;
|
|
30
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.
|
|
31
47
|
function sortedRecord(record) {
|
|
32
|
-
|
|
48
|
+
if (!record || typeof record !== 'object')
|
|
49
|
+
return [];
|
|
50
|
+
return Object.entries(record)
|
|
33
51
|
.sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
34
52
|
.map(([, v]) => stripNonSemantic(v));
|
|
35
53
|
}
|
|
36
54
|
function sortedList(list) {
|
|
37
|
-
|
|
38
|
-
|
|
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))
|
|
39
59
|
.map((entry) => stripNonSemantic(entry));
|
|
40
60
|
}
|
|
41
61
|
/**
|
|
42
|
-
* The
|
|
43
|
-
*
|
|
44
|
-
*
|
|
45
|
-
*
|
|
62
|
+
* The Server IR slice carrying each executable graph kind. Keyed by `core`'s
|
|
63
|
+
* {@link EXECUTABLE_KINDS} so this projection and the graph-level `semanticFingerprint`
|
|
64
|
+
* cannot disagree about what is executable (spec14pt3 §5, §6, §189).
|
|
65
|
+
*
|
|
66
|
+
* `since: 'v8'` marks a slice added after `axiom.server.v1..v7` were frozen: it contributes
|
|
67
|
+
* to the fingerprint **only when non-empty**, exactly as `core`'s `semanticProjection` skips
|
|
68
|
+
* an empty kind — so every pre-workflow (non-`WorkflowDef`) graph's authority fingerprint is
|
|
69
|
+
* byte-identical to what it was before this correction (spec14pt3 §35, §38, §103). The 13
|
|
70
|
+
* pre-v8 slices stay unconditionally present (an empty array included) to keep *their*
|
|
71
|
+
* frozen bytes unchanged.
|
|
72
|
+
*/
|
|
73
|
+
const SERVER_IR_EXECUTABLE_SLICES = {
|
|
74
|
+
action: { field: 'actions', shape: 'record' },
|
|
75
|
+
integration: { field: 'integrations', shape: 'list' },
|
|
76
|
+
'integration-operation': { field: 'integrationOperations', shape: 'record' },
|
|
77
|
+
trigger: { field: 'triggers', shape: 'list' },
|
|
78
|
+
event: { field: 'events', shape: 'list' },
|
|
79
|
+
subscription: { field: 'subscriptions', shape: 'list' },
|
|
80
|
+
'read-policy': { field: 'readPolicies', shape: 'list' },
|
|
81
|
+
query: { field: 'queries', shape: 'list' },
|
|
82
|
+
expression: { field: 'expressionDefs', shape: 'record' },
|
|
83
|
+
constraint: { field: 'constraints', shape: 'list' },
|
|
84
|
+
'transition-constraint': { field: 'transitionConstraints', shape: 'list' },
|
|
85
|
+
storage: { field: 'storages', shape: 'list' },
|
|
86
|
+
relationship: { field: 'relationships', shape: 'list' },
|
|
87
|
+
workflow: { field: 'workflows', shape: 'list', since: 'v8' },
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* The canonical executable-meaning projection of a Server IR: everything a distributed
|
|
91
|
+
* worker executes — actions, constraints, transition constraints, expression defs,
|
|
92
|
+
* integrations + operations, triggers, events, subscriptions, storages, read policies,
|
|
93
|
+
* relationships, queries, **and workflows** — plus the schema version. Nothing a rename
|
|
94
|
+
* touches. Built by iterating {@link EXECUTABLE_KINDS} so a future primitive cannot be
|
|
95
|
+
* omitted (spec14pt3 F3 root cause).
|
|
46
96
|
*/
|
|
47
97
|
export function serverIrSemanticProjection(ir) {
|
|
48
|
-
|
|
98
|
+
const projection = {
|
|
49
99
|
fingerprintVersion: SEMANTIC_FINGERPRINT_VERSION,
|
|
50
100
|
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
101
|
};
|
|
102
|
+
for (const kind of EXECUTABLE_KINDS) {
|
|
103
|
+
const slice = SERVER_IR_EXECUTABLE_SLICES[kind];
|
|
104
|
+
let raw = ir[slice.field];
|
|
105
|
+
// Workflows are canonicalized (authoring order of steps / inputs / bindings is not
|
|
106
|
+
// semantic) through the *same* core helper the graph-level fingerprint uses (spec14pt3
|
|
107
|
+
// §5 G1, §64), so the two projections cannot disagree about a workflow.
|
|
108
|
+
if (kind === 'workflow' && Array.isArray(raw)) {
|
|
109
|
+
raw = raw.map((w) => canonicalWorkflowForFingerprint(w));
|
|
110
|
+
}
|
|
111
|
+
const projected = slice.shape === 'record'
|
|
112
|
+
? sortedRecord(raw)
|
|
113
|
+
: sortedList(raw);
|
|
114
|
+
if (slice.since === 'v8' && projected.length === 0)
|
|
115
|
+
continue;
|
|
116
|
+
projection[slice.field] = projected;
|
|
117
|
+
}
|
|
118
|
+
return projection;
|
|
65
119
|
}
|
|
120
|
+
export { SERVER_IR_EXECUTABLE_SLICES };
|
|
66
121
|
export function serverIrSemanticFingerprint(ir) {
|
|
67
122
|
return createHash('sha256').update(canonicalJSON(serverIrSemanticProjection(ir))).digest('hex');
|
|
68
123
|
}
|
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';
|
package/dist/server.js
CHANGED
|
@@ -1103,10 +1103,26 @@ export function createAxiomServer(options) {
|
|
|
1103
1103
|
return response;
|
|
1104
1104
|
}
|
|
1105
1105
|
// ---- Durable workflows (spec14) --------------------------------------------------
|
|
1106
|
-
|
|
1106
|
+
// spec14pt4 §29, §30 — a hand-tampered IR may carry `workflows` as the wrong shape
|
|
1107
|
+
// entirely (a string, an object, a one-element array holding `null`). Route anything
|
|
1108
|
+
// present-but-not-an-empty-array into the engine's total admission validator so it fails
|
|
1109
|
+
// closed with a structured `WorkflowIRError` rather than being silently ignored (`{}` has
|
|
1110
|
+
// no `.length`) or reaching a native `TypeError`.
|
|
1111
|
+
// Anything other than absent-or-empty-array is routed into the engine's total admission
|
|
1112
|
+
// validator (`null`, a string, an object, a non-empty array) so it fails closed rather
|
|
1113
|
+
// than being silently ignored (`{}` / `null` have no useful `.length`).
|
|
1114
|
+
const declaredWorkflows = ir.workflows;
|
|
1115
|
+
const workflowsDeclared = declaredWorkflows !== undefined &&
|
|
1116
|
+
(!Array.isArray(declaredWorkflows) || declaredWorkflows.length > 0);
|
|
1117
|
+
const workflowStore = workflowsDeclared
|
|
1118
|
+
? options.workflowStore ?? createMemoryWorkflowStore()
|
|
1119
|
+
: undefined;
|
|
1107
1120
|
const workflowEngine = workflowStore
|
|
1108
1121
|
? createWorkflowEngine({
|
|
1109
|
-
|
|
1122
|
+
// Pass the declared value **through unchanged** (never `?? []`) so a tampered
|
|
1123
|
+
// `null` / string / object reaches the total admission validator instead of being
|
|
1124
|
+
// coalesced to an empty list (spec14pt4 §29, §63).
|
|
1125
|
+
workflows: declaredWorkflows,
|
|
1110
1126
|
store: workflowStore,
|
|
1111
1127
|
compatibilityFingerprint: compatibilityKeyStr,
|
|
1112
1128
|
instanceId,
|
package/dist/workflows.d.ts
CHANGED
|
@@ -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,7 +159,27 @@ export function createWorkflowEngine(options) {
|
|
|
144
159
|
const pollMs = options.pollMs ?? 250;
|
|
145
160
|
const recoverBatch = options.recoverBatch ?? 64;
|
|
146
161
|
const store = options.store;
|
|
147
|
-
|
|
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
|
+
}
|
|
176
|
+
const irProblems = options.workflows.flatMap((w) => workflowStructuralProblems(w));
|
|
177
|
+
if (irProblems.length > 0) {
|
|
178
|
+
throw new WorkflowIRError(irProblems);
|
|
179
|
+
}
|
|
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]));
|
|
148
183
|
let pollTimer;
|
|
149
184
|
let running = false;
|
|
150
185
|
const advancing = new Set(); // local re-entrancy guard only
|
|
@@ -166,6 +201,21 @@ export function createWorkflowEngine(options) {
|
|
|
166
201
|
}
|
|
167
202
|
}
|
|
168
203
|
// ---- scope + step evaluation -------------------------------------------------
|
|
204
|
+
/**
|
|
205
|
+
* spec14pt3 F3 — whether this authority build may interpret this durable instance. The
|
|
206
|
+
* instance durably records the `AuthorityCompatibilityKey` string it was created under
|
|
207
|
+
* (`{ serverContract, schemaFingerprint, semanticFingerprint }`, and `semanticFingerprint`
|
|
208
|
+
* now covers `WorkflowDef` executable meaning). A build whose key differs — a changed
|
|
209
|
+
* action target, event id, branch predicate, timer duration, retry policy or control-flow
|
|
210
|
+
* edge — must fail closed rather than advance the instance under changed semantics. A
|
|
211
|
+
* missing / malformed stored fingerprint is also incompatible (never "missing ⇒
|
|
212
|
+
* compatible", spec14pt3 §175).
|
|
213
|
+
*/
|
|
214
|
+
function isCompatible(record) {
|
|
215
|
+
return (typeof record.compatibilityFingerprint === 'string' &&
|
|
216
|
+
record.compatibilityFingerprint.length > 0 &&
|
|
217
|
+
record.compatibilityFingerprint === options.compatibilityFingerprint);
|
|
218
|
+
}
|
|
169
219
|
function scopeFor(record, eventPayload) {
|
|
170
220
|
return {
|
|
171
221
|
...record.inputs,
|
|
@@ -210,17 +260,80 @@ export function createWorkflowEngine(options) {
|
|
|
210
260
|
return;
|
|
211
261
|
if (record.status === 'completed' || record.status === 'failed' || record.status === 'cancelled')
|
|
212
262
|
return;
|
|
213
|
-
if (record
|
|
214
|
-
//
|
|
263
|
+
if (!isCompatible(record)) {
|
|
264
|
+
// spec14pt3 F3 — fail closed *before* any semantic step: no ActionDef invoke,
|
|
265
|
+
// no event/timer/branch transition, no binding write, no `instanceRevision`
|
|
266
|
+
// advance. The instance is left exactly as it stands for a compatible authority
|
|
267
|
+
// to resume; incompatibility is an execution-environment problem, never an
|
|
268
|
+
// automatic `failed` / `cancelled` (spec14pt3 §23, §76, §156).
|
|
215
269
|
return;
|
|
216
270
|
}
|
|
217
271
|
const workflow = byId.get(record.workflowId);
|
|
218
272
|
if (!workflow)
|
|
219
273
|
return;
|
|
220
274
|
const step = workflowStepById(workflow, record.currentStepId);
|
|
221
|
-
|
|
275
|
+
// spec14pt3 F2: admission validation already rejected a structurally invalid
|
|
276
|
+
// workflow, so this only fires if the in-memory definition was mutated after the
|
|
277
|
+
// engine started. Fail the instance with a structured reason rather than looping
|
|
278
|
+
// the poll forever (a silent permanent wedge is explicitly forbidden, §46).
|
|
279
|
+
if (!step || !isWorkflowStep(step)) {
|
|
280
|
+
await store
|
|
281
|
+
.transition({
|
|
282
|
+
instanceId: record.instanceId,
|
|
283
|
+
expectedRevision: record.instanceRevision,
|
|
284
|
+
fence,
|
|
285
|
+
next: {
|
|
286
|
+
status: 'failed',
|
|
287
|
+
currentStepId: record.currentStepId,
|
|
288
|
+
activationId: record.activationId,
|
|
289
|
+
attempt: 0,
|
|
290
|
+
pendingAction: null,
|
|
291
|
+
nextEligibleAt: null,
|
|
292
|
+
failure: { reason: 'workflow-invalid-step', stepId: record.currentStepId },
|
|
293
|
+
history: { kind: 'failed', stepId: record.currentStepId, detail: { reason: 'workflow-invalid-step' } },
|
|
294
|
+
},
|
|
295
|
+
})
|
|
296
|
+
.catch(() => { });
|
|
222
297
|
return;
|
|
223
|
-
|
|
298
|
+
}
|
|
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
|
+
}
|
|
224
337
|
if (!progressed)
|
|
225
338
|
return;
|
|
226
339
|
}
|
|
@@ -369,6 +482,11 @@ export function createWorkflowEngine(options) {
|
|
|
369
482
|
case 'action': {
|
|
370
483
|
return runActionStep({ ...args, step });
|
|
371
484
|
}
|
|
485
|
+
default:
|
|
486
|
+
// Unreachable: `advance` fails the instance before calling `runStep` for a step
|
|
487
|
+
// that is not one of the six kinds, and admission validation rejects such IR
|
|
488
|
+
// outright. Present so the switch is total and never returns `undefined`.
|
|
489
|
+
return false;
|
|
372
490
|
}
|
|
373
491
|
}
|
|
374
492
|
async function runActionStep(args) {
|
|
@@ -499,7 +617,10 @@ export function createWorkflowEngine(options) {
|
|
|
499
617
|
if (eventSeq <= wait.sinceEventSeq)
|
|
500
618
|
continue;
|
|
501
619
|
const loaded = await store.load(wait.instanceId);
|
|
502
|
-
|
|
620
|
+
// spec14pt3 F3 — an incompatible build may journal the canonical event as
|
|
621
|
+
// infrastructure but must not apply its (changed) `where` / `bind` semantics to this
|
|
622
|
+
// instance. A compatible authority reconciles it later from the durable journal.
|
|
623
|
+
if (!loaded || !isCompatible(loaded))
|
|
503
624
|
continue;
|
|
504
625
|
const workflow = byId.get(loaded.workflowId ?? '');
|
|
505
626
|
if (!workflow)
|
|
@@ -597,7 +718,7 @@ export function createWorkflowEngine(options) {
|
|
|
597
718
|
compatibilityFingerprint: options.compatibilityFingerprint,
|
|
598
719
|
};
|
|
599
720
|
const instanceId = `wf_${createHash('sha256').update(workflowStartKey(start)).digest('hex').slice(0, 24)}_${randomUUID().slice(0, 8)}`;
|
|
600
|
-
const { instance } = await store.createIdempotent(start, () => ({
|
|
721
|
+
const { instance, created } = await store.createIdempotent(start, () => ({
|
|
601
722
|
instanceId,
|
|
602
723
|
workflowId: request.workflowId,
|
|
603
724
|
compatibilityFingerprint: options.compatibilityFingerprint,
|
|
@@ -606,6 +727,18 @@ export function createWorkflowEngine(options) {
|
|
|
606
727
|
inputs,
|
|
607
728
|
entryStepId: String(workflow.entry),
|
|
608
729
|
}));
|
|
730
|
+
// spec14pt3 §161, §162 — a repeated start identity that resolves to an *existing*
|
|
731
|
+
// instance created under incompatible workflow semantics must NOT silently reuse it and
|
|
732
|
+
// continue it under this build. Return it, plainly labelled incompatible; never
|
|
733
|
+
// reinterpret it. (A brand-new instance created just now always matches this build.)
|
|
734
|
+
if (!created && !isCompatible(instance)) {
|
|
735
|
+
return {
|
|
736
|
+
error: {
|
|
737
|
+
code: WF_DIAGNOSTIC.INCOMPATIBLE,
|
|
738
|
+
message: `Workflow instance ${instance.instanceId} was created under workflow semantics incompatible with this authority build`,
|
|
739
|
+
},
|
|
740
|
+
};
|
|
741
|
+
}
|
|
609
742
|
// Drive it forward immediately (local fast path); the poll loop is the durable backstop.
|
|
610
743
|
await advance(instance.instanceId).catch(() => { });
|
|
611
744
|
const fresh = (await store.load(instance.instanceId)) ?? instance;
|
|
@@ -620,6 +753,18 @@ export function createWorkflowEngine(options) {
|
|
|
620
753
|
if (record.status === 'completed' || record.status === 'failed') {
|
|
621
754
|
return { ok: true, status: record.status }; // idempotent; a terminal workflow is not resurrected
|
|
622
755
|
}
|
|
756
|
+
// spec14pt3 §163 — cancellation writes a durable `cancelled` transition on this
|
|
757
|
+
// instance, so it is compatibility-gated like every other transition: an incompatible
|
|
758
|
+
// build must not transition an instance whose workflow meaning it does not share. The
|
|
759
|
+
// instance is left for a compatible authority to cancel or complete.
|
|
760
|
+
if (!isCompatible(record)) {
|
|
761
|
+
return {
|
|
762
|
+
error: {
|
|
763
|
+
code: WF_DIAGNOSTIC.INCOMPATIBLE,
|
|
764
|
+
message: `Workflow instance ${instanceId} is incompatible with this authority build; it cannot be cancelled here`,
|
|
765
|
+
},
|
|
766
|
+
};
|
|
767
|
+
}
|
|
623
768
|
const result = await withOwnership(instanceId, async (fence) => {
|
|
624
769
|
const fresh = await store.load(instanceId);
|
|
625
770
|
if (!fresh || fresh.status === 'cancelled' || fresh.status === 'completed' || fresh.status === 'failed') {
|
|
@@ -663,6 +808,8 @@ export function createWorkflowEngine(options) {
|
|
|
663
808
|
instanceRevision: record.instanceRevision,
|
|
664
809
|
...(record.failure ? { failure: record.failure } : {}),
|
|
665
810
|
...(record.output ? { output: record.output } : {}),
|
|
811
|
+
compatible: isCompatible(record),
|
|
812
|
+
...(isCompatible(record) ? {} : { incompatibleReason: 'incompatible-build' }),
|
|
666
813
|
};
|
|
667
814
|
}
|
|
668
815
|
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.
|
|
3
|
+
"version": "0.14.0-alpha.3",
|
|
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.
|
|
41
|
-
"@cynodia/axiom-runtime": "0.14.0-alpha.
|
|
40
|
+
"@cynodia/axiom-core": "0.14.0-alpha.3",
|
|
41
|
+
"@cynodia/axiom-runtime": "0.14.0-alpha.3"
|
|
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.
|
|
7
|
+
"release": "0.14.0-alpha.3",
|
|
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.
|
|
7
|
+
"release": "0.14.0-alpha.3",
|
|
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.
|
|
7
|
+
"release": "0.14.0-alpha.3",
|
|
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.
|
|
7
|
+
"release": "0.14.0-alpha.3",
|
|
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.
|
|
7
|
+
"release": "0.14.0-alpha.3",
|
|
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.
|
|
7
|
+
"release": "0.14.0-alpha.3",
|
|
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.
|
|
7
|
+
"release": "0.14.0-alpha.3",
|
|
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.
|
|
7
|
+
"release": "0.14.0-alpha.3",
|
|
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.
|
|
7
|
+
"release": "0.14.0-alpha.3",
|
|
8
8
|
"type": "object",
|
|
9
9
|
"required": [
|
|
10
10
|
"contract",
|