@parmanasystems/execution-runtime 1.65.0
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/README.md +26 -0
- package/dist/index.d.ts +105 -0
- package/dist/index.js +263 -0
- package/dist/index.js.map +1 -0
- package/package.json +30 -0
package/README.md
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
\# @parmanasystems/execution-runtime
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
Runtime orchestration layer for Parmana Systems deterministic governance execution.
|
|
6
|
+
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
Provides:
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
\- executeFromSignals
|
|
14
|
+
|
|
15
|
+
\- replay protection
|
|
16
|
+
|
|
17
|
+
\- Redis replay coordination
|
|
18
|
+
|
|
19
|
+
\- batch execution
|
|
20
|
+
|
|
21
|
+
\- runtime execution orchestration
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
This package separates operational execution flows from deterministic execution-core semantics.
|
|
26
|
+
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import * as _parmanasystems_execution from '@parmanasystems/execution';
|
|
2
|
+
import { Signer, Verifier, ReplayStore, ExecutionAttestation, ExecutionContext, AsyncReplayStore, DecisionResult } from '@parmanasystems/execution';
|
|
3
|
+
|
|
4
|
+
declare function executeFromSignals(input: {
|
|
5
|
+
policyId: string;
|
|
6
|
+
policyVersion: string;
|
|
7
|
+
signals: Record<string, unknown>;
|
|
8
|
+
}, signer: Signer, verifier: Verifier, replayStore: ReplayStore): Promise<ExecutionAttestation>;
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* 🟢 ASYNC ADAPTER
|
|
12
|
+
* Handles distributed replay protection
|
|
13
|
+
* while preserving deterministic execution core.
|
|
14
|
+
*/
|
|
15
|
+
declare function executeWithRedis(context: ExecutionContext, redisStore: AsyncReplayStore): Promise<ExecutionAttestation>;
|
|
16
|
+
|
|
17
|
+
/**
|
|
18
|
+
* Executes multiple records sequentially.
|
|
19
|
+
*
|
|
20
|
+
* Each record is processed independently.
|
|
21
|
+
* Errors are captured per-record (fail-isolated).
|
|
22
|
+
*/
|
|
23
|
+
declare function executeBatch(records: Array<{
|
|
24
|
+
policyId: string;
|
|
25
|
+
policyVersion: string;
|
|
26
|
+
signals: Record<string, unknown>;
|
|
27
|
+
governed_time: string;
|
|
28
|
+
}>, signer: Signer, verifier: Verifier, replayStore: AsyncReplayStore): Promise<({
|
|
29
|
+
input: {
|
|
30
|
+
policyId: string;
|
|
31
|
+
policyVersion: string;
|
|
32
|
+
signals: Record<string, unknown>;
|
|
33
|
+
governed_time: string;
|
|
34
|
+
};
|
|
35
|
+
output: _parmanasystems_execution.ExecutionAttestation;
|
|
36
|
+
} | {
|
|
37
|
+
input: {
|
|
38
|
+
policyId: string;
|
|
39
|
+
policyVersion: string;
|
|
40
|
+
signals: Record<string, unknown>;
|
|
41
|
+
governed_time: string;
|
|
42
|
+
};
|
|
43
|
+
output: {
|
|
44
|
+
status: string;
|
|
45
|
+
error: string;
|
|
46
|
+
};
|
|
47
|
+
})[]>;
|
|
48
|
+
|
|
49
|
+
/**
|
|
50
|
+
* 🔒 Distributed replay protection
|
|
51
|
+
*
|
|
52
|
+
* Replay protection operates on deterministic
|
|
53
|
+
* semantic execution fingerprints rather than
|
|
54
|
+
* operational execution IDs.
|
|
55
|
+
*/
|
|
56
|
+
declare class RedisReplayStore implements AsyncReplayStore {
|
|
57
|
+
private client;
|
|
58
|
+
constructor(url: string);
|
|
59
|
+
hasExecuted(execution_fingerprint: string): Promise<boolean>;
|
|
60
|
+
markExecuted(execution_fingerprint: string): Promise<void>;
|
|
61
|
+
get(key: string): Promise<string | null>;
|
|
62
|
+
set(key: string, value: string): Promise<void>;
|
|
63
|
+
del(key: string): Promise<void>;
|
|
64
|
+
close(): Promise<void>;
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/**
|
|
68
|
+
* 🔒 In-memory replay protection
|
|
69
|
+
*
|
|
70
|
+
* Replay protection operates on deterministic
|
|
71
|
+
* semantic execution fingerprints rather than
|
|
72
|
+
* operational execution IDs.
|
|
73
|
+
*/
|
|
74
|
+
declare class MemoryReplayStore implements ReplayStore {
|
|
75
|
+
private store;
|
|
76
|
+
markExecuted(execution_fingerprint: string): Promise<void>;
|
|
77
|
+
hasExecuted(execution_fingerprint: string): Promise<boolean>;
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
declare function resolveOverride(executionId: string, replayStore: AsyncReplayStore & {
|
|
81
|
+
get: (key: string) => Promise<string | null>;
|
|
82
|
+
del: (key: string) => Promise<void>;
|
|
83
|
+
}, signer: Signer, verifier: Verifier): Promise<{
|
|
84
|
+
status: "success";
|
|
85
|
+
executionId: string;
|
|
86
|
+
signature: string;
|
|
87
|
+
resolved: boolean;
|
|
88
|
+
}>;
|
|
89
|
+
|
|
90
|
+
declare function addReviewTask(task: any): void;
|
|
91
|
+
declare function getAllTasks(): any;
|
|
92
|
+
|
|
93
|
+
interface DryRunResult {
|
|
94
|
+
policyId: string;
|
|
95
|
+
policyVersion: string;
|
|
96
|
+
schemaVersion: string;
|
|
97
|
+
decision: DecisionResult;
|
|
98
|
+
rule_trace: string[];
|
|
99
|
+
governed: false;
|
|
100
|
+
dry_run: true;
|
|
101
|
+
evaluated_at: string;
|
|
102
|
+
}
|
|
103
|
+
declare function evaluateDryRun(policyId: string, policyVersion: string, signals: Record<string, unknown>, governed_time?: string): DryRunResult;
|
|
104
|
+
|
|
105
|
+
export { type DryRunResult, MemoryReplayStore, RedisReplayStore, addReviewTask, evaluateDryRun, executeBatch, executeFromSignals, executeWithRedis, getAllTasks, resolveOverride };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
// src/execute-from-signals.ts
|
|
2
|
+
import {
|
|
3
|
+
executeDecision,
|
|
4
|
+
issueToken,
|
|
5
|
+
getRuntimeManifest,
|
|
6
|
+
evaluatePolicy,
|
|
7
|
+
loadPolicy,
|
|
8
|
+
canonicalizeForSigning
|
|
9
|
+
} from "@parmanasystems/execution";
|
|
10
|
+
import crypto from "crypto";
|
|
11
|
+
async function executeFromSignals(input, signer, verifier, replayStore) {
|
|
12
|
+
const policy = loadPolicy(
|
|
13
|
+
input.policyId,
|
|
14
|
+
input.policyVersion
|
|
15
|
+
);
|
|
16
|
+
const decision = evaluatePolicy(
|
|
17
|
+
policy,
|
|
18
|
+
input.signals
|
|
19
|
+
);
|
|
20
|
+
if (decision.status !== "decided") {
|
|
21
|
+
throw new Error(
|
|
22
|
+
"[SYS-006] Policy evaluation returned undecided"
|
|
23
|
+
);
|
|
24
|
+
}
|
|
25
|
+
const execution_fingerprint = crypto.createHash("sha256").update(
|
|
26
|
+
JSON.stringify({
|
|
27
|
+
policyId: input.policyId,
|
|
28
|
+
policyVersion: input.policyVersion,
|
|
29
|
+
signals: input.signals
|
|
30
|
+
})
|
|
31
|
+
).digest("hex");
|
|
32
|
+
replayStore.markExecuted(
|
|
33
|
+
execution_fingerprint
|
|
34
|
+
);
|
|
35
|
+
const runtimeManifest = getRuntimeManifest();
|
|
36
|
+
const token = issueToken({
|
|
37
|
+
executionId: execution_fingerprint,
|
|
38
|
+
policyId: input.policyId,
|
|
39
|
+
policyVersion: input.policyVersion,
|
|
40
|
+
schemaVersion: policy.schemaVersion,
|
|
41
|
+
runtimeVersion: runtimeManifest.runtimeVersion,
|
|
42
|
+
decision_payload: decision.outcome,
|
|
43
|
+
signalsHash: execution_fingerprint
|
|
44
|
+
});
|
|
45
|
+
const token_signature = signer.sign(
|
|
46
|
+
canonicalizeForSigning(
|
|
47
|
+
token
|
|
48
|
+
)
|
|
49
|
+
);
|
|
50
|
+
return executeDecision({
|
|
51
|
+
token,
|
|
52
|
+
execution_fingerprint,
|
|
53
|
+
token_signature,
|
|
54
|
+
signer,
|
|
55
|
+
verifier,
|
|
56
|
+
runtime_manifest: runtimeManifest,
|
|
57
|
+
runtime_requirements: {
|
|
58
|
+
supported_runtimeVersions: [
|
|
59
|
+
runtimeManifest.runtimeVersion
|
|
60
|
+
],
|
|
61
|
+
supported_schemaVersions: runtimeManifest.supported_schemaVersions
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
// src/execute-with-redis.ts
|
|
67
|
+
import {
|
|
68
|
+
executeDecision as executeDecision2
|
|
69
|
+
} from "@parmanasystems/execution";
|
|
70
|
+
async function executeWithRedis(context, redisStore) {
|
|
71
|
+
await redisStore.markExecuted(
|
|
72
|
+
context.execution_fingerprint
|
|
73
|
+
);
|
|
74
|
+
return executeDecision2(
|
|
75
|
+
context
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// src/execute-batch.ts
|
|
80
|
+
async function executeBatch(records, signer, verifier, replayStore) {
|
|
81
|
+
const outputs = [];
|
|
82
|
+
for (const record of records) {
|
|
83
|
+
try {
|
|
84
|
+
const output = await executeFromSignals(
|
|
85
|
+
record,
|
|
86
|
+
signer,
|
|
87
|
+
verifier,
|
|
88
|
+
replayStore
|
|
89
|
+
);
|
|
90
|
+
outputs.push({
|
|
91
|
+
input: record,
|
|
92
|
+
output
|
|
93
|
+
});
|
|
94
|
+
} catch (err) {
|
|
95
|
+
outputs.push({
|
|
96
|
+
input: record,
|
|
97
|
+
output: {
|
|
98
|
+
status: "error",
|
|
99
|
+
error: err instanceof Error ? err.message : "Unknown error"
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
return outputs;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
// src/redis-replay-store.ts
|
|
108
|
+
import Redis from "ioredis";
|
|
109
|
+
var RedisReplayStore = class {
|
|
110
|
+
constructor(url) {
|
|
111
|
+
this.client = new Redis(url);
|
|
112
|
+
}
|
|
113
|
+
async hasExecuted(execution_fingerprint) {
|
|
114
|
+
const res = await this.client.exists(
|
|
115
|
+
`exec:${execution_fingerprint}`
|
|
116
|
+
);
|
|
117
|
+
return res === 1;
|
|
118
|
+
}
|
|
119
|
+
async markExecuted(execution_fingerprint) {
|
|
120
|
+
const result = await this.client.set(
|
|
121
|
+
`exec:${execution_fingerprint}`,
|
|
122
|
+
"1",
|
|
123
|
+
"NX"
|
|
124
|
+
);
|
|
125
|
+
if (result !== "OK") {
|
|
126
|
+
throw new Error(
|
|
127
|
+
`[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`
|
|
128
|
+
);
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
async get(key) {
|
|
132
|
+
return this.client.get(key);
|
|
133
|
+
}
|
|
134
|
+
async set(key, value) {
|
|
135
|
+
await this.client.set(
|
|
136
|
+
key,
|
|
137
|
+
value
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
async del(key) {
|
|
141
|
+
await this.client.del(key);
|
|
142
|
+
}
|
|
143
|
+
async close() {
|
|
144
|
+
await this.client.quit();
|
|
145
|
+
}
|
|
146
|
+
};
|
|
147
|
+
|
|
148
|
+
// src/memory-replay-store.ts
|
|
149
|
+
var MemoryReplayStore = class {
|
|
150
|
+
constructor() {
|
|
151
|
+
this.store = /* @__PURE__ */ new Set();
|
|
152
|
+
}
|
|
153
|
+
async markExecuted(execution_fingerprint) {
|
|
154
|
+
if (this.store.has(
|
|
155
|
+
execution_fingerprint
|
|
156
|
+
)) {
|
|
157
|
+
throw new Error(
|
|
158
|
+
`[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`
|
|
159
|
+
);
|
|
160
|
+
}
|
|
161
|
+
this.store.add(
|
|
162
|
+
execution_fingerprint
|
|
163
|
+
);
|
|
164
|
+
}
|
|
165
|
+
async hasExecuted(execution_fingerprint) {
|
|
166
|
+
return this.store.has(
|
|
167
|
+
execution_fingerprint
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
// src/resolve-override.ts
|
|
173
|
+
async function resolveOverride(executionId, replayStore, signer, verifier) {
|
|
174
|
+
const raw = await replayStore.get(
|
|
175
|
+
`pending:${executionId}`
|
|
176
|
+
);
|
|
177
|
+
if (!raw) {
|
|
178
|
+
throw new Error(
|
|
179
|
+
`[SYS-021] No pending execution found for ${executionId}`
|
|
180
|
+
);
|
|
181
|
+
}
|
|
182
|
+
const stored = JSON.parse(raw);
|
|
183
|
+
const execution = await executeWithRedis(
|
|
184
|
+
{
|
|
185
|
+
token: stored.token,
|
|
186
|
+
execution_fingerprint: stored.token.executionId,
|
|
187
|
+
token_signature: stored.token_signature,
|
|
188
|
+
signer,
|
|
189
|
+
verifier,
|
|
190
|
+
runtime_manifest: stored.runtime_manifest,
|
|
191
|
+
runtime_requirements: stored.runtime_requirements
|
|
192
|
+
},
|
|
193
|
+
replayStore
|
|
194
|
+
);
|
|
195
|
+
await replayStore.del(
|
|
196
|
+
`pending:${executionId}`
|
|
197
|
+
);
|
|
198
|
+
return {
|
|
199
|
+
status: "success",
|
|
200
|
+
executionId,
|
|
201
|
+
signature: execution.signature,
|
|
202
|
+
resolved: true
|
|
203
|
+
};
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
// src/review-store.ts
|
|
207
|
+
import * as fs from "fs";
|
|
208
|
+
var FILE = "./review-queue.json";
|
|
209
|
+
function addReviewTask(task) {
|
|
210
|
+
let data = [];
|
|
211
|
+
if (fs.existsSync(FILE)) {
|
|
212
|
+
data = JSON.parse(fs.readFileSync(FILE, "utf-8"));
|
|
213
|
+
}
|
|
214
|
+
data.push(task);
|
|
215
|
+
fs.writeFileSync(FILE, JSON.stringify(data, null, 2));
|
|
216
|
+
}
|
|
217
|
+
function getAllTasks() {
|
|
218
|
+
if (!fs.existsSync(FILE)) return [];
|
|
219
|
+
return JSON.parse(fs.readFileSync(FILE, "utf-8"));
|
|
220
|
+
}
|
|
221
|
+
|
|
222
|
+
// src/dry-run.ts
|
|
223
|
+
import {
|
|
224
|
+
evaluatePolicy as evaluatePolicy2,
|
|
225
|
+
loadPolicy as loadPolicy2,
|
|
226
|
+
validateSignalsStrict
|
|
227
|
+
} from "@parmanasystems/execution";
|
|
228
|
+
function evaluateDryRun(policyId, policyVersion, signals, governed_time = (/* @__PURE__ */ new Date()).toISOString()) {
|
|
229
|
+
const policy = loadPolicy2(
|
|
230
|
+
policyId,
|
|
231
|
+
policyVersion
|
|
232
|
+
);
|
|
233
|
+
validateSignalsStrict(
|
|
234
|
+
signals,
|
|
235
|
+
policy
|
|
236
|
+
);
|
|
237
|
+
const decision = evaluatePolicy2(
|
|
238
|
+
policy,
|
|
239
|
+
signals
|
|
240
|
+
);
|
|
241
|
+
return {
|
|
242
|
+
policyId,
|
|
243
|
+
policyVersion,
|
|
244
|
+
schemaVersion: policy.schemaVersion,
|
|
245
|
+
decision,
|
|
246
|
+
rule_trace: [],
|
|
247
|
+
governed: false,
|
|
248
|
+
dry_run: true,
|
|
249
|
+
evaluated_at: governed_time
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
export {
|
|
253
|
+
MemoryReplayStore,
|
|
254
|
+
RedisReplayStore,
|
|
255
|
+
addReviewTask,
|
|
256
|
+
evaluateDryRun,
|
|
257
|
+
executeBatch,
|
|
258
|
+
executeFromSignals,
|
|
259
|
+
executeWithRedis,
|
|
260
|
+
getAllTasks,
|
|
261
|
+
resolveOverride
|
|
262
|
+
};
|
|
263
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/execute-from-signals.ts","../src/execute-with-redis.ts","../src/execute-batch.ts","../src/redis-replay-store.ts","../src/memory-replay-store.ts","../src/resolve-override.ts","../src/review-store.ts","../src/dry-run.ts"],"sourcesContent":["import {\r\n executeDecision,\r\n issueToken,\r\n getRuntimeManifest,\r\n evaluatePolicy,\r\n loadPolicy,\r\n canonicalizeForSigning\r\n} from \"@parmanasystems/execution\";\r\n\r\nimport type {\r\n ExecutionAttestation,\r\n Signer,\r\n Verifier,\r\n ReplayStore\r\n} from \"@parmanasystems/execution\";\r\n\r\nimport crypto from \"crypto\";\r\n\r\nexport async function executeFromSignals(\r\n input: {\r\n policyId: string;\r\n policyVersion: string;\r\n signals: Record<string, unknown>;\r\n },\r\n\r\n signer: Signer,\r\n verifier: Verifier,\r\n replayStore: ReplayStore\r\n): Promise<ExecutionAttestation> {\r\n\r\n // -----------------------------\r\n // Load policy\r\n // -----------------------------\r\n const policy =\r\n loadPolicy(\r\n input.policyId,\r\n input.policyVersion\r\n );\r\n\r\n // -----------------------------\r\n // Evaluate policy\r\n // -----------------------------\r\n const decision =\r\n evaluatePolicy(\r\n policy,\r\n input.signals\r\n );\r\n\r\n if (\r\n decision.status !== \"decided\"\r\n ) {\r\n\r\n throw new Error(\r\n \"[SYS-006] Policy evaluation returned undecided\"\r\n );\r\n }\r\n\r\n // -----------------------------\r\n // Deterministic execution identity\r\n // -----------------------------\r\n const execution_fingerprint =\r\n crypto\r\n .createHash(\"sha256\")\r\n .update(\r\n JSON.stringify({\r\n policyId:\r\n input.policyId,\r\n\r\n policyVersion:\r\n input.policyVersion,\r\n\r\n signals:\r\n input.signals\r\n })\r\n )\r\n .digest(\"hex\");\r\n\r\n // -----------------------------\r\n // Replay protection\r\n // -----------------------------\r\n replayStore.markExecuted(\r\n execution_fingerprint\r\n );\r\n\r\n // -----------------------------\r\n // Runtime manifest\r\n // -----------------------------\r\n const runtimeManifest =\r\n getRuntimeManifest();\r\n\r\n // -----------------------------\r\n // Deterministic governance token\r\n // -----------------------------\r\n const token =\r\n issueToken({\r\n\r\n executionId:\r\n execution_fingerprint,\r\n\r\n policyId:\r\n input.policyId,\r\n\r\n policyVersion:\r\n input.policyVersion,\r\n\r\n schemaVersion:\r\n policy.schemaVersion,\r\n\r\n runtimeVersion:\r\n runtimeManifest.runtimeVersion,\r\n\r\n decision_payload:\r\n decision.outcome,\r\n\r\n signalsHash:\r\n execution_fingerprint\r\n });\r\n\r\n// -----------------------------\r\n// Explicit cryptographic signing\r\n// -----------------------------\r\nconst token_signature =\r\n signer.sign(\r\n canonicalizeForSigning(\r\n token\r\n )\r\n );\r\n\r\n // -----------------------------\r\n // Deterministic execution\r\n // -----------------------------\r\n return executeDecision({\r\n\r\n token,\r\n\r\n execution_fingerprint,\r\n\r\n token_signature,\r\n\r\n signer,\r\n\r\n verifier,\r\n\r\n runtime_manifest:\r\n runtimeManifest,\r\n\r\n runtime_requirements: {\r\n\r\n supported_runtimeVersions: [\r\n runtimeManifest.runtimeVersion\r\n ],\r\n\r\n supported_schemaVersions:\r\n runtimeManifest\r\n .supported_schemaVersions\r\n }\r\n });\r\n}","import {\r\n executeDecision\r\n} from \"@parmanasystems/execution\";\r\n\r\nimport type {\r\n ExecutionContext,\r\n ExecutionAttestation,\r\n AsyncReplayStore\r\n} from \"@parmanasystems/execution\";\r\n\r\n/**\r\n * 🟢 ASYNC ADAPTER\r\n * Handles distributed replay protection\r\n * while preserving deterministic execution core.\r\n */\r\nexport async function executeWithRedis(\r\n context: ExecutionContext,\r\n redisStore: AsyncReplayStore\r\n): Promise<ExecutionAttestation> {\r\n\r\n // -----------------------------\r\n // Distributed replay protection\r\n // -----------------------------\r\n await redisStore.markExecuted(\r\n context.execution_fingerprint\r\n );\r\n\r\n // -----------------------------\r\n // Deterministic execution\r\n // -----------------------------\r\n return executeDecision(\r\n context\r\n );\r\n}","import type {\r\n Signer,\r\n Verifier,\r\n AsyncReplayStore\r\n} from \"@parmanasystems/execution\";\r\n\r\nimport {\r\n executeFromSignals,\r\n} from \"./execute-from-signals.js\";\r\n\r\n/**\r\n * Executes multiple records sequentially.\r\n *\r\n * Each record is processed independently.\r\n * Errors are captured per-record (fail-isolated).\r\n */\r\nexport async function executeBatch(\r\n records: Array<{\r\n policyId: string;\r\n policyVersion: string;\r\n signals: Record<string, unknown>;\r\n governed_time: string;\r\n }>,\r\n\r\n signer: Signer,\r\n\r\n verifier: Verifier,\r\n\r\n replayStore: AsyncReplayStore\r\n) {\r\n\r\n const outputs = [];\r\n\r\n for (const record of records) {\r\n\r\n try {\r\n\r\n const output =\r\n await executeFromSignals(\r\n record,\r\n signer,\r\n verifier,\r\n replayStore\r\n );\r\n\r\n outputs.push({\r\n input: record,\r\n output\r\n });\r\n\r\n } catch (err: unknown) {\r\n\r\n outputs.push({\r\n input: record,\r\n\r\n output: {\r\n status: \"error\",\r\n\r\n error:\r\n err instanceof Error\r\n ? err.message\r\n : \"Unknown error\"\r\n }\r\n });\r\n\r\n }\r\n }\r\n\r\n return outputs;\r\n}","import Redis from \"ioredis\";\r\n\r\nimport type {\r\n Redis as RedisClient\r\n} from \"ioredis\";\r\n\r\nimport type {\r\n AsyncReplayStore\r\n} from \"@parmanasystems/execution\";\r\n\r\n/**\r\n * 🔒 Distributed replay protection\r\n *\r\n * Replay protection operates on deterministic\r\n * semantic execution fingerprints rather than\r\n * operational execution IDs.\r\n */\r\nexport class RedisReplayStore\r\n implements AsyncReplayStore {\r\n\r\n private client: RedisClient;\r\n\r\n constructor(\r\n url: string\r\n ) {\r\n\r\n this.client =\r\n new (Redis as any)(url);\r\n }\r\n\r\n async hasExecuted(\r\n execution_fingerprint: string\r\n ): Promise<boolean> {\r\n\r\n const res =\r\n await this.client.exists(\r\n `exec:${execution_fingerprint}`\r\n );\r\n\r\n return res === 1;\r\n }\r\n\r\n async markExecuted(\r\n execution_fingerprint: string\r\n ): Promise<void> {\r\n\r\n const result =\r\n await this.client.set(\r\n `exec:${execution_fingerprint}`,\r\n \"1\",\r\n \"NX\"\r\n );\r\n\r\n if (result !== \"OK\") {\r\n\r\n throw new Error(\r\n `[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`\r\n );\r\n }\r\n }\r\n\r\n async get(\r\n key: string\r\n ): Promise<string | null> {\r\n\r\n return this.client.get(key);\r\n }\r\n\r\n async set(\r\n key: string,\r\n value: string\r\n ): Promise<void> {\r\n\r\n await this.client.set(\r\n key,\r\n value\r\n );\r\n }\r\n\r\n async del(\r\n key: string\r\n ): Promise<void> {\r\n\r\n await this.client.del(key);\r\n }\r\n\r\n async close(): Promise<void> {\r\n\r\n await this.client.quit();\r\n }\r\n}","import type {\r\n ReplayStore\r\n} from \"@parmanasystems/execution\";\r\n\r\n/**\r\n * 🔒 In-memory replay protection\r\n *\r\n * Replay protection operates on deterministic\r\n * semantic execution fingerprints rather than\r\n * operational execution IDs.\r\n */\r\nexport class MemoryReplayStore\r\n implements ReplayStore {\r\n\r\n private store =\r\n new Set<string>();\r\n\r\n async markExecuted(\r\n execution_fingerprint: string\r\n ): Promise<void> {\r\n\r\n if (\r\n this.store.has(\r\n execution_fingerprint\r\n )\r\n ) {\r\n\r\n throw new Error(\r\n `[INV-013@replay] Replay detected: execution_fingerprint ${execution_fingerprint} has already been consumed`\r\n );\r\n }\r\n\r\n this.store.add(\r\n execution_fingerprint\r\n );\r\n }\r\n\r\n async hasExecuted(\r\n execution_fingerprint: string\r\n ): Promise<boolean> {\r\n\r\n return this.store.has(\r\n execution_fingerprint\r\n );\r\n }\r\n}","import {\r\n executeWithRedis\r\n} from \"./execute-with-redis.js\";\r\n\r\nimport type {\r\n AsyncReplayStore,\r\n Signer,\r\n Verifier\r\n} from \"@parmanasystems/execution\";\r\n\r\nexport async function resolveOverride(\r\n executionId: string,\r\n\r\n replayStore: AsyncReplayStore & {\r\n get: (\r\n key: string\r\n ) => Promise<string | null>;\r\n\r\n del: (\r\n key: string\r\n ) => Promise<void>;\r\n },\r\n\r\n signer: Signer,\r\n\r\n verifier: Verifier\r\n) {\r\n\r\n // -----------------------------\r\n // 1. Load pending execution\r\n // -----------------------------\r\n const raw =\r\n await replayStore.get(\r\n `pending:${executionId}`\r\n );\r\n\r\n if (!raw) {\r\n\r\n throw new Error(\r\n `[SYS-021] No pending execution found for ${executionId}`\r\n );\r\n }\r\n\r\n const stored =\r\n JSON.parse(raw);\r\n\r\n // -----------------------------\r\n // 2. Execute approved override\r\n // -----------------------------\r\n const execution =\r\n await executeWithRedis(\r\n {\r\n token:\r\n stored.token,\r\n\r\n execution_fingerprint:\r\n stored.token.executionId,\r\n\r\n token_signature:\r\n stored.token_signature,\r\n\r\n signer,\r\n\r\n verifier,\r\n\r\n runtime_manifest:\r\n stored.runtime_manifest,\r\n\r\n runtime_requirements:\r\n stored.runtime_requirements\r\n },\r\n\r\n replayStore\r\n );\r\n\r\n // -----------------------------\r\n // 3. Remove pending state\r\n // -----------------------------\r\n await replayStore.del(\r\n `pending:${executionId}`\r\n );\r\n\r\n // -----------------------------\r\n // 4. Return deterministic result\r\n // -----------------------------\r\n return {\r\n\r\n status:\r\n \"success\" as const,\r\n\r\n executionId,\r\n\r\n signature:\r\n execution.signature,\r\n\r\n resolved:\r\n true\r\n };\r\n}","import * as fs from \"node:fs\";\r\n\r\nconst FILE = \"./review-queue.json\";\r\n\r\nexport function addReviewTask(task: any) {\r\n let data: any[] = [];\r\n\r\n if (fs.existsSync(FILE)) {\r\n data = JSON.parse(fs.readFileSync(FILE, \"utf-8\"));\r\n }\r\n\r\n data.push(task);\r\n\r\n fs.writeFileSync(FILE, JSON.stringify(data, null, 2));\r\n}\r\n\r\nexport function getAllTasks() {\r\n if (!fs.existsSync(FILE)) return [];\r\n return JSON.parse(fs.readFileSync(FILE, \"utf-8\"));\r\n}\r\n","import {\r\n evaluatePolicy,\r\n loadPolicy,\r\n validateSignalsStrict\r\n} from \"@parmanasystems/execution\";\r\n\r\nimport type {\r\n DecisionResult\r\n} from \"@parmanasystems/execution\";\r\n\r\nexport interface DryRunResult {\r\n\r\n policyId: string;\r\n\r\n policyVersion: string;\r\n\r\n schemaVersion: string;\r\n\r\n decision: DecisionResult;\r\n\r\n rule_trace: string[];\r\n\r\n governed: false;\r\n\r\n dry_run: true;\r\n\r\n evaluated_at: string;\r\n}\r\n\r\nexport function evaluateDryRun(\r\n policyId: string,\r\n policyVersion: string,\r\n signals: Record<string, unknown>,\r\n governed_time = new Date().toISOString()\r\n): DryRunResult {\r\n\r\n // -----------------------------\r\n // 1. Load policy\r\n // -----------------------------\r\n const policy =\r\n loadPolicy(\r\n policyId,\r\n policyVersion\r\n );\r\n\r\n // -----------------------------\r\n // 2. Validate signals\r\n // -----------------------------\r\n validateSignalsStrict(\r\n signals,\r\n policy\r\n );\r\n\r\n // -----------------------------\r\n // 3. Evaluate policy\r\n // -----------------------------\r\n const decision: DecisionResult =\r\n evaluatePolicy(\r\n policy,\r\n signals\r\n );\r\n\r\n // -----------------------------\r\n // 4. Return dry-run result\r\n // -----------------------------\r\n return {\r\n\r\n policyId,\r\n\r\n policyVersion,\r\n\r\n schemaVersion:\r\n policy.schemaVersion,\r\n\r\n decision,\r\n\r\n rule_trace: [],\r\n\r\n governed: false,\r\n\r\n dry_run: true,\r\n\r\n evaluated_at:\r\n governed_time\r\n };\r\n}"],"mappings":"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","names":["executeDecision","evaluatePolicy","loadPolicy"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@parmanasystems/execution-runtime",
|
|
3
|
+
"version": "1.65.0",
|
|
4
|
+
"private": false,
|
|
5
|
+
"type": "module",
|
|
6
|
+
"description": "Runtime orchestration layer for Parmana Systems.",
|
|
7
|
+
"main": "./dist/index.js",
|
|
8
|
+
"types": "./dist/index.d.ts",
|
|
9
|
+
"exports": {
|
|
10
|
+
".": {
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
12
|
+
"import": "./dist/index.js"
|
|
13
|
+
}
|
|
14
|
+
},
|
|
15
|
+
"files": [
|
|
16
|
+
"dist",
|
|
17
|
+
"README.md"
|
|
18
|
+
],
|
|
19
|
+
"scripts": {
|
|
20
|
+
"build": "tsup"
|
|
21
|
+
},
|
|
22
|
+
"dependencies": {
|
|
23
|
+
"@parmanasystems/execution": "^1.65.0",
|
|
24
|
+
"ioredis": "^5.4.1"
|
|
25
|
+
},
|
|
26
|
+
"devDependencies": {
|
|
27
|
+
"tsup": "^8.5.1",
|
|
28
|
+
"typescript": "^5.8.3"
|
|
29
|
+
}
|
|
30
|
+
}
|