@melra/protocol 0.3.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.
@@ -0,0 +1,125 @@
1
+ // Copyright 2026 XAGI Labs Private Limited
2
+ // SPDX-License-Identifier: Apache-2.0
3
+ import { describe, expect, it } from "vitest";
4
+ import { BoundedLoopNodeSchema, ConditionNodeSchema, EncryptedPayloadSchema, ParallelNodeSchema, WorkflowAdvanceInputSchema, WorkflowDefinitionSchema, WorkflowEventSchema, WorkflowRunSchema, WorkflowSnapshotSchema, } from "./index.js";
5
+ const workflowId = "11111111-1111-4111-8111-111111111111";
6
+ const traceId = "22222222-2222-4222-8222-222222222222";
7
+ const occurredAt = "2026-07-30T12:00:00.000Z";
8
+ describe("durable workflow protocol", () => {
9
+ it("parses a bounded two-node workflow and rejects schema smuggling", () => {
10
+ const definition = WorkflowDefinitionSchema.parse({
11
+ schemaVersion: "1.0.0",
12
+ id: workflowId,
13
+ version: 1,
14
+ name: "restart-safe",
15
+ nodes: [
16
+ {
17
+ id: "inspect",
18
+ type: "operation",
19
+ dependsOn: [],
20
+ request: {
21
+ goal: "Inspect the runtime",
22
+ operation: { kind: "system", action: "info" },
23
+ },
24
+ },
25
+ { id: "checkpoint", type: "checkpoint", dependsOn: ["inspect"] },
26
+ ],
27
+ });
28
+ expect(definition.nodes).toHaveLength(2);
29
+ expect(() => WorkflowDefinitionSchema.parse({ ...definition, executeAnyway: true })).toThrow();
30
+ });
31
+ it.each([
32
+ [
33
+ BoundedLoopNodeSchema,
34
+ {
35
+ id: "loop",
36
+ type: "bounded_loop",
37
+ dependsOn: [],
38
+ body: [
39
+ {
40
+ goal: "Inspect the runtime",
41
+ operation: { kind: "system", action: "info" },
42
+ },
43
+ ],
44
+ maxIterations: 0,
45
+ },
46
+ ],
47
+ [
48
+ ParallelNodeSchema,
49
+ {
50
+ id: "parallel",
51
+ type: "parallel",
52
+ dependsOn: [],
53
+ branches: [],
54
+ },
55
+ ],
56
+ [
57
+ ConditionNodeSchema,
58
+ {
59
+ id: "condition",
60
+ type: "condition",
61
+ dependsOn: [],
62
+ sourceNodeId: "",
63
+ predicate: { type: "result_equals", path: "ready", value: true },
64
+ },
65
+ ],
66
+ ])("rejects an invalid bounded control-flow node", (schema, value) => {
67
+ expect(schema.safeParse(value).success).toBe(false);
68
+ });
69
+ it("validates events, snapshots, encrypted payloads, and advance inputs", () => {
70
+ const run = WorkflowRunSchema.parse({
71
+ schemaVersion: "1.0.0",
72
+ id: workflowId,
73
+ definitionId: "33333333-3333-4333-8333-333333333333",
74
+ definitionVersion: 1,
75
+ status: "running",
76
+ stateVersion: 2,
77
+ nodes: {
78
+ inspect: {
79
+ status: "verified_complete",
80
+ taskIds: ["44444444-4444-4444-8444-444444444444"],
81
+ },
82
+ checkpoint: { status: "ready" },
83
+ },
84
+ traceId,
85
+ createdAt: occurredAt,
86
+ updatedAt: occurredAt,
87
+ });
88
+ expect(WorkflowEventSchema.parse({
89
+ schemaVersion: "1.0.0",
90
+ id: "55555555-5555-4555-8555-555555555555",
91
+ aggregateId: workflowId,
92
+ sequence: 2,
93
+ traceId,
94
+ type: "workflow.node_completed",
95
+ data: { nodeId: "inspect" },
96
+ occurredAt,
97
+ }).type).toBe("workflow.node_completed");
98
+ expect(EncryptedPayloadSchema.parse({
99
+ version: 1,
100
+ algorithm: "aes-256-gcm",
101
+ iv: "AQIDBA",
102
+ ciphertext: "BQYHCA",
103
+ tag: "CQoLDA",
104
+ }).algorithm).toBe("aes-256-gcm");
105
+ expect(WorkflowAdvanceInputSchema.parse({
106
+ workflowId,
107
+ approvals: [],
108
+ }).approvals).toEqual([]);
109
+ expect(WorkflowSnapshotSchema.parse({
110
+ schemaVersion: "1.0.0",
111
+ workflowId,
112
+ sequence: 2,
113
+ run,
114
+ createdAt: occurredAt,
115
+ }).sequence).toBe(2);
116
+ expect(() => WorkflowSnapshotSchema.parse({
117
+ schemaVersion: "1.0.0",
118
+ workflowId,
119
+ sequence: 1,
120
+ run,
121
+ createdAt: occurredAt,
122
+ })).toThrow();
123
+ });
124
+ });
125
+ //# sourceMappingURL=workflow.test.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"workflow.test.js","sourceRoot":"","sources":["../src/workflow.test.ts"],"names":[],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@melra/protocol",
3
+ "version": "0.3.0-alpha.3",
4
+ "description": "Versioned task, workflow, capability, policy, and evidence contracts for MELRA.",
5
+ "license": "Apache-2.0",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/XAGI-Lab/melra.git",
9
+ "directory": "packages/protocol"
10
+ },
11
+ "homepage": "https://github.com/XAGI-Lab/melra#readme",
12
+ "bugs": "https://github.com/XAGI-Lab/melra/issues",
13
+ "type": "module",
14
+ "exports": {
15
+ ".": {
16
+ "types": "./dist/index.d.ts",
17
+ "default": "./dist/index.js"
18
+ }
19
+ },
20
+ "files": [
21
+ "dist"
22
+ ],
23
+ "dependencies": {
24
+ "zod": "4.4.3"
25
+ },
26
+ "scripts": {
27
+ "build": "tsc -p tsconfig.json",
28
+ "clean": "rm -rf dist",
29
+ "test": "vitest run --passWithNoTests",
30
+ "typecheck": "tsc -p tsconfig.json --noEmit"
31
+ }
32
+ }