@zelari/core 1.29.0 → 1.30.1
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/dist/kraken/graph.d.ts +5 -2
- package/dist/kraken/graph.d.ts.map +1 -1
- package/dist/kraken/graph.js.map +1 -1
- package/dist/kraken/index.d.ts +10 -2
- package/dist/kraken/index.d.ts.map +1 -1
- package/dist/kraken/index.js +10 -2
- package/dist/kraken/index.js.map +1 -1
- package/dist/kraken/personas/conformance.d.ts +25 -0
- package/dist/kraken/personas/conformance.d.ts.map +1 -0
- package/dist/kraken/personas/conformance.js +89 -0
- package/dist/kraken/personas/conformance.js.map +1 -0
- package/dist/kraken/personas/index.d.ts +12 -0
- package/dist/kraken/personas/index.d.ts.map +1 -0
- package/dist/kraken/personas/index.js +12 -0
- package/dist/kraken/personas/index.js.map +1 -0
- package/dist/kraken/personas/registry.d.ts +62 -0
- package/dist/kraken/personas/registry.d.ts.map +1 -0
- package/dist/kraken/personas/registry.js +49 -0
- package/dist/kraken/personas/registry.js.map +1 -0
- package/dist/kraken/personas/specReviewer.d.ts +21 -0
- package/dist/kraken/personas/specReviewer.d.ts.map +1 -0
- package/dist/kraken/personas/specReviewer.js +74 -0
- package/dist/kraken/personas/specReviewer.js.map +1 -0
- package/dist/kraken/runtime/index.d.ts +13 -0
- package/dist/kraken/runtime/index.d.ts.map +1 -0
- package/dist/kraken/runtime/index.js +16 -0
- package/dist/kraken/runtime/index.js.map +1 -0
- package/dist/kraken/runtime/runner.d.ts +80 -0
- package/dist/kraken/runtime/runner.d.ts.map +1 -0
- package/dist/kraken/runtime/runner.js +253 -0
- package/dist/kraken/runtime/runner.js.map +1 -0
- package/dist/kraken/runtime/sandbox.d.ts +65 -0
- package/dist/kraken/runtime/sandbox.d.ts.map +1 -0
- package/dist/kraken/runtime/sandbox.js +158 -0
- package/dist/kraken/runtime/sandbox.js.map +1 -0
- package/dist/kraken/runtime/sdk.d.ts +32 -0
- package/dist/kraken/runtime/sdk.d.ts.map +1 -0
- package/dist/kraken/runtime/sdk.js +61 -0
- package/dist/kraken/runtime/sdk.js.map +1 -0
- package/dist/kraken/runtime/types.d.ts +220 -0
- package/dist/kraken/runtime/types.d.ts.map +1 -0
- package/dist/kraken/runtime/types.js +35 -0
- package/dist/kraken/runtime/types.js.map +1 -0
- package/dist/kraken/verdict.d.ts +53 -0
- package/dist/kraken/verdict.d.ts.map +1 -1
- package/dist/kraken/verdict.js +75 -0
- package/dist/kraken/verdict.js.map +1 -1
- package/dist/kraken/weakness.d.ts +160 -0
- package/dist/kraken/weakness.d.ts.map +1 -0
- package/dist/kraken/weakness.js +305 -0
- package/dist/kraken/weakness.js.map +1 -0
- package/package.json +1 -1
|
@@ -0,0 +1,253 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kraken script runtime — runner.
|
|
3
|
+
*
|
|
4
|
+
* The `ScriptRunner` is the host-side orchestrator that owns the script's
|
|
5
|
+
* lifecycle: it builds the `PlanCapabilities` object exposed as
|
|
6
|
+
* `__zelari_sdk__` in the sandbox, enforces the tentacle and merge budgets,
|
|
7
|
+
* tracks every tentacle for snapshotting, and converts the host's
|
|
8
|
+
* `TentacleResult` into the script's `TentacleRef`.
|
|
9
|
+
*
|
|
10
|
+
* It does NOT itself compile the bundle (that's the CLI side; see
|
|
11
|
+
* `src/cli/kraken/runtime/compile.ts`) and does NOT itself run the
|
|
12
|
+
* sandbox (that's `sandbox.ts`). It only wires the two together.
|
|
13
|
+
*
|
|
14
|
+
* @since Kraken v1.30.x — workflow script runtime (F1.1)
|
|
15
|
+
*/
|
|
16
|
+
import { MAX_FINDINGS_CHARS } from '../verdict.js';
|
|
17
|
+
import { isReviewerKind, defaultPersonaParse } from '../personas/index.js';
|
|
18
|
+
import { PlanError, } from './types.js';
|
|
19
|
+
/** Default cap on `tentacle()` calls per plan. Configurable via env. */
|
|
20
|
+
export const DEFAULT_MAX_TENTACLES = 200;
|
|
21
|
+
export function resolveMaxTentacles(env = process.env) {
|
|
22
|
+
const raw = env.ZELARI_KRAKEN_MAX_TENTACLES;
|
|
23
|
+
if (raw === undefined || raw === '')
|
|
24
|
+
return DEFAULT_MAX_TENTACLES;
|
|
25
|
+
const n = Number.parseInt(raw, 10);
|
|
26
|
+
return Number.isFinite(n) && n > 0 ? n : DEFAULT_MAX_TENTACLES;
|
|
27
|
+
}
|
|
28
|
+
/** Default wall-clock cap (ms) for the whole plan. */
|
|
29
|
+
export const DEFAULT_PLAN_TIMEOUT_MS = 30 * 60_000;
|
|
30
|
+
export function resolvePlanTimeoutMs(env = process.env) {
|
|
31
|
+
const raw = env.ZELARI_KRAKEN_PLAN_TIMEOUT_MS;
|
|
32
|
+
if (raw === undefined || raw === '')
|
|
33
|
+
return DEFAULT_PLAN_TIMEOUT_MS;
|
|
34
|
+
const n = Number.parseInt(raw, 10);
|
|
35
|
+
return Number.isFinite(n) && n >= 0 ? n : DEFAULT_PLAN_TIMEOUT_MS;
|
|
36
|
+
}
|
|
37
|
+
/** Truncate text safely. Mirrors the verdict helper so we don't ship two
|
|
38
|
+
* implementations. */
|
|
39
|
+
function cap(text, max) {
|
|
40
|
+
if (text.length <= max)
|
|
41
|
+
return text;
|
|
42
|
+
return `${text.slice(0, max)}\n… [truncated]`;
|
|
43
|
+
}
|
|
44
|
+
/** Build a TentacleRef from a host result + the options that produced it. */
|
|
45
|
+
function buildRef(id, opts, result) {
|
|
46
|
+
const findings = cap(result.ok ? (result.result ?? '').trim() : (result.error ?? 'unknown error'), MAX_FINDINGS_CHARS);
|
|
47
|
+
const ref = {
|
|
48
|
+
id,
|
|
49
|
+
kind: opts.kind,
|
|
50
|
+
label: opts.label,
|
|
51
|
+
status: result.ok ? 'done' : 'error',
|
|
52
|
+
findings,
|
|
53
|
+
scope: opts.scope,
|
|
54
|
+
...(result.durationMs !== undefined ? { durationMs: result.durationMs } : {}),
|
|
55
|
+
...(result.worktree !== undefined ? { worktree: result.worktree } : {}),
|
|
56
|
+
};
|
|
57
|
+
// Parse a verdict trailer for any reviewer kind. The persona system
|
|
58
|
+
// (Pillar 2) handles `verify`, `spec`, `conformance`; the default
|
|
59
|
+
// parser extracts both the trailer and the per-requirement table.
|
|
60
|
+
if (isReviewerKind(opts.kind)) {
|
|
61
|
+
ref.verdict = defaultPersonaParse(findings).verdict;
|
|
62
|
+
}
|
|
63
|
+
return ref;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* A `ScriptRunner` is constructed once per script plan, then drives the
|
|
67
|
+
* script by exposing its `sdk` to the sandbox and bookkeeping the tentacles.
|
|
68
|
+
*/
|
|
69
|
+
export class ScriptRunner {
|
|
70
|
+
host;
|
|
71
|
+
goal;
|
|
72
|
+
graphId;
|
|
73
|
+
parentCwd;
|
|
74
|
+
sessionId;
|
|
75
|
+
maxTentacles;
|
|
76
|
+
planTimeoutMs;
|
|
77
|
+
startTime;
|
|
78
|
+
tentaclesById = new Map();
|
|
79
|
+
tentacleCount = 0;
|
|
80
|
+
mergeCount = 0;
|
|
81
|
+
cancelled = false;
|
|
82
|
+
constructor(opts) {
|
|
83
|
+
this.host = opts.host;
|
|
84
|
+
this.goal = opts.goal;
|
|
85
|
+
this.graphId = opts.graphId;
|
|
86
|
+
this.parentCwd = opts.parentCwd;
|
|
87
|
+
this.sessionId = opts.sessionId;
|
|
88
|
+
this.maxTentacles = opts.maxTentacles ?? resolveMaxTentacles();
|
|
89
|
+
this.planTimeoutMs = opts.planTimeoutMs ?? resolvePlanTimeoutMs();
|
|
90
|
+
this.startTime = Date.now();
|
|
91
|
+
}
|
|
92
|
+
/** Build the `PlanCapabilities` object the sandbox will see. */
|
|
93
|
+
buildSdk() {
|
|
94
|
+
return {
|
|
95
|
+
tentacle: (opts) => this.callTentacle(opts),
|
|
96
|
+
barrier: (refs) => this.callBarrier(refs),
|
|
97
|
+
race: (refs) => this.callRace(refs),
|
|
98
|
+
while_: (cond, body, maxIter) => this.callWhile(cond, body, maxIter),
|
|
99
|
+
until: (cond, body, maxIter) => this.callUntil(cond, body, maxIter),
|
|
100
|
+
merge: (refs, opts) => this.callMerge(refs, opts),
|
|
101
|
+
checkpoint: (label) => this.callCheckpoint(label),
|
|
102
|
+
log: (msg, data) => this.callLog(msg, data),
|
|
103
|
+
emit: (payload) => this.callEmit(payload),
|
|
104
|
+
getContext: () => this.callGetContext(),
|
|
105
|
+
sendTo: (peerId, payload) => this.callSendTo(peerId, payload),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
/** One tentacle = one `runTentacle` call. The host returns a raw result;
|
|
109
|
+
* we turn it into a `TentacleRef` and stash it. */
|
|
110
|
+
async callTentacle(opts) {
|
|
111
|
+
if (this.cancelled)
|
|
112
|
+
throw new PlanError('cancelled', 'runner is cancelled');
|
|
113
|
+
if (this.tentacleCount >= this.maxTentacles) {
|
|
114
|
+
throw new PlanError('budget_exceeded', `tentacle cap (${this.maxTentacles}) reached; raise ZELARI_KRAKEN_MAX_TENTACLES`);
|
|
115
|
+
}
|
|
116
|
+
if (this.tentacleCount > 0 && Date.now() - this.startTime > this.planTimeoutMs) {
|
|
117
|
+
throw new PlanError('budget_exceeded', `plan wall-clock budget (${this.planTimeoutMs}ms) exceeded`);
|
|
118
|
+
}
|
|
119
|
+
this.tentacleCount += 1;
|
|
120
|
+
// Build a stable id. We deliberately do NOT let the script pick ids
|
|
121
|
+
// (collision risk); we synthesize one from a monotonic counter.
|
|
122
|
+
const id = `t${String(this.tentacleCount).padStart(4, '0')}`;
|
|
123
|
+
const res = await this.host.runTentacle({
|
|
124
|
+
node: opts,
|
|
125
|
+
parentCwd: this.parentCwd,
|
|
126
|
+
sessionId: this.sessionId,
|
|
127
|
+
});
|
|
128
|
+
const ref = buildRef(id, opts, res);
|
|
129
|
+
this.tentaclesById.set(id, ref);
|
|
130
|
+
return ref;
|
|
131
|
+
}
|
|
132
|
+
async callBarrier(refs) {
|
|
133
|
+
// All refs are already resolved (tentacle() awaits). The barrier is a
|
|
134
|
+
// *type* helper that lets the script treat parallel `tentacle()` calls
|
|
135
|
+
// as a single awaitable tuple. It still costs one cap entry per ref —
|
|
136
|
+
// the script MUST have called `tentacle()` for each.
|
|
137
|
+
if (refs.some((r) => !this.tentaclesById.has(r.id))) {
|
|
138
|
+
throw new PlanError('runtime_error', 'barrier() received a ref not in this runner');
|
|
139
|
+
}
|
|
140
|
+
return refs;
|
|
141
|
+
}
|
|
142
|
+
async callRace(refs) {
|
|
143
|
+
if (refs.length === 0) {
|
|
144
|
+
throw new PlanError('runtime_error', 'race() requires at least one ref');
|
|
145
|
+
}
|
|
146
|
+
// Tentacles are already resolved at the moment race() is called, so
|
|
147
|
+
// "first to complete" is moot — we return the ref whose `durationMs`
|
|
148
|
+
// is smallest (ties broken by id order for determinism). The script
|
|
149
|
+
// can re-spawn losers if it needs actual racing in real time.
|
|
150
|
+
let winner = refs[0];
|
|
151
|
+
for (const r of refs) {
|
|
152
|
+
const a = winner.durationMs ?? Number.POSITIVE_INFINITY;
|
|
153
|
+
const b = r.durationMs ?? Number.POSITIVE_INFINITY;
|
|
154
|
+
if (b < a || (b === a && r.id < winner.id))
|
|
155
|
+
winner = r;
|
|
156
|
+
}
|
|
157
|
+
return winner;
|
|
158
|
+
}
|
|
159
|
+
async callWhile(cond, body, maxIter) {
|
|
160
|
+
if (maxIter < 1)
|
|
161
|
+
throw new PlanError('runtime_error', 'while_() maxIter must be ≥ 1');
|
|
162
|
+
const out = [];
|
|
163
|
+
let iter = 0;
|
|
164
|
+
while (await cond()) {
|
|
165
|
+
if (iter >= maxIter) {
|
|
166
|
+
throw new PlanError('budget_exceeded', `while_() exceeded maxIter=${maxIter} without cond turning false`);
|
|
167
|
+
}
|
|
168
|
+
out.push(await body());
|
|
169
|
+
iter += 1;
|
|
170
|
+
}
|
|
171
|
+
return out;
|
|
172
|
+
}
|
|
173
|
+
async callUntil(cond, body, maxIter) {
|
|
174
|
+
return this.callWhile(async () => !(await cond()), body, maxIter);
|
|
175
|
+
}
|
|
176
|
+
/** One merge per plan. A second call is a structured error. */
|
|
177
|
+
async callMerge(refs, opts = {}) {
|
|
178
|
+
if (this.mergeCount > 0) {
|
|
179
|
+
throw new PlanError('merge_already_done', 'merge() called more than once; a plan can merge at most one batch');
|
|
180
|
+
}
|
|
181
|
+
if (refs.length === 0) {
|
|
182
|
+
throw new PlanError('runtime_error', 'merge() requires at least one ref');
|
|
183
|
+
}
|
|
184
|
+
for (const r of refs) {
|
|
185
|
+
if (!this.tentaclesById.has(r.id)) {
|
|
186
|
+
throw new PlanError('runtime_error', `merge() received unknown ref "${r.id}"`);
|
|
187
|
+
}
|
|
188
|
+
}
|
|
189
|
+
this.mergeCount += 1;
|
|
190
|
+
return this.host.mergeWorktrees({
|
|
191
|
+
refs,
|
|
192
|
+
parentCwd: this.parentCwd,
|
|
193
|
+
strategy: opts.strategy ?? 'squash-sequential',
|
|
194
|
+
...(opts.message ? { message: opts.message } : {}),
|
|
195
|
+
...(opts.cleanup !== undefined ? { cleanup: opts.cleanup } : {}),
|
|
196
|
+
});
|
|
197
|
+
}
|
|
198
|
+
async callCheckpoint(label) {
|
|
199
|
+
const snapshot = {
|
|
200
|
+
graphId: this.graphId,
|
|
201
|
+
goal: this.goal,
|
|
202
|
+
takenAt: new Date().toISOString(),
|
|
203
|
+
completed: [...this.tentaclesById.values()].filter((r) => r.status === 'done'),
|
|
204
|
+
inFlight: [...this.tentaclesById.values()].filter((r) => r.status === 'running'),
|
|
205
|
+
failed: [...this.tentaclesById.values()].filter((r) => r.status === 'error'),
|
|
206
|
+
pending: [],
|
|
207
|
+
};
|
|
208
|
+
const path = await this.host.saveSnapshot(snapshot, '.zelari/kraken/snapshots');
|
|
209
|
+
this.host.log(`checkpoint: ${label ?? 'auto'} → ${path}`);
|
|
210
|
+
return snapshot;
|
|
211
|
+
}
|
|
212
|
+
callLog(msg, data) {
|
|
213
|
+
const line = data ? `${msg} ${JSON.stringify(data)}` : msg;
|
|
214
|
+
this.host.log(line);
|
|
215
|
+
}
|
|
216
|
+
callEmit(payload) {
|
|
217
|
+
this.host.log(`emit: ${payload.kind}${payload.detail ? ` — ${payload.detail}` : ''}`);
|
|
218
|
+
}
|
|
219
|
+
callGetContext() {
|
|
220
|
+
return {
|
|
221
|
+
graphId: this.graphId,
|
|
222
|
+
goal: this.goal,
|
|
223
|
+
parentCwd: this.parentCwd,
|
|
224
|
+
sessionId: this.sessionId,
|
|
225
|
+
tentacles: this.tentaclesById,
|
|
226
|
+
maxTentacles: this.maxTentacles,
|
|
227
|
+
planTimeoutMs: this.planTimeoutMs,
|
|
228
|
+
};
|
|
229
|
+
}
|
|
230
|
+
callSendTo(peerId, payload) {
|
|
231
|
+
this.host.log(`sendTo(${peerId}): ${payload.kind}${payload.detail ? ` — ${payload.detail}` : ''}`);
|
|
232
|
+
}
|
|
233
|
+
/** Called by the host after the sandbox returns, to mark the run. */
|
|
234
|
+
finalize(opts) {
|
|
235
|
+
if (opts.cancelled)
|
|
236
|
+
this.cancelled = true;
|
|
237
|
+
const failed = [...this.tentaclesById.values()].filter((r) => r.status === 'error');
|
|
238
|
+
return {
|
|
239
|
+
tentacles: this.tentaclesById,
|
|
240
|
+
mergeCount: this.mergeCount,
|
|
241
|
+
converged: opts.converged,
|
|
242
|
+
cancelled: this.cancelled,
|
|
243
|
+
durationMs: Date.now() - this.startTime,
|
|
244
|
+
unresolvedFindings: failed.map((r) => ({
|
|
245
|
+
nodeId: r.id,
|
|
246
|
+
label: r.label,
|
|
247
|
+
reason: r.status === 'error' ? 'fail' : 'unknown',
|
|
248
|
+
findings: r.findings,
|
|
249
|
+
})),
|
|
250
|
+
};
|
|
251
|
+
}
|
|
252
|
+
}
|
|
253
|
+
//# sourceMappingURL=runner.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runner.js","sourceRoot":"","sources":["../../../src/kraken/runtime/runner.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kraken script runtime — Node `vm` sandbox.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the compiled script bundle in a fresh V8 context with a
|
|
5
|
+
* capability-based global. The sandbox has NO `process`, `require`,
|
|
6
|
+
* `Buffer`, `global`, `__dirname`, `__filename`, or any other Node
|
|
7
|
+
* built-in — only the explicit capabilities the host injects.
|
|
8
|
+
*
|
|
9
|
+
* Security model:
|
|
10
|
+
* - The bundle is a single async IIFE produced by esbuild. The sandbox
|
|
11
|
+
* object exposes ONE global: `__zelari_sdk__` (frozen), holding the
|
|
12
|
+
* capability functions. Scripts can only call into the host through
|
|
13
|
+
* these functions; they cannot read `process.env` or `fs` because those
|
|
14
|
+
* do not exist in the context.
|
|
15
|
+
* - Wall-clock bound is enforced by the `vm` timeout. Per-tentacle
|
|
16
|
+
* bound is enforced by the host (existing `runTentacle` timeout).
|
|
17
|
+
* - A footgun guard scans the script for obviously dangerous tokens
|
|
18
|
+
* (e.g. `process`, `require`, `globalThis`) BEFORE running and
|
|
19
|
+
* surfaces a structured `PlanError('sandbox_breach')` when found.
|
|
20
|
+
* This is best-effort: a sufficiently obfuscated script can sneak
|
|
21
|
+
* around the regex, but the absence of these tokens in the sandbox
|
|
22
|
+
* means even bypassing the guard leaves nothing to call.
|
|
23
|
+
*
|
|
24
|
+
* @since Kraken v1.30.x — workflow script runtime (F1.1)
|
|
25
|
+
*/
|
|
26
|
+
export interface SandboxRunOptions {
|
|
27
|
+
/** The compiled JS bundle (esbuild IIFE output). */
|
|
28
|
+
bundleCode: string;
|
|
29
|
+
/** Capability object to expose as `__zelari_sdk__`. Will be deep-frozen. */
|
|
30
|
+
sdk: Record<string, unknown>;
|
|
31
|
+
/** Wall-clock cap (ms) for the whole script. */
|
|
32
|
+
timeoutMs: number;
|
|
33
|
+
/** Optional abort signal. */
|
|
34
|
+
signal?: AbortSignal;
|
|
35
|
+
/**
|
|
36
|
+
* Skip the pre-flight token scan. **Test-only**: production LLM plans
|
|
37
|
+
* benefit from the footgun guard, but the guard rejects test bundles
|
|
38
|
+
* that intentionally probe the sandbox for forbidden tokens. Always
|
|
39
|
+
* leave `false` (the default) outside tests.
|
|
40
|
+
*/
|
|
41
|
+
skipFootgunScan?: boolean;
|
|
42
|
+
}
|
|
43
|
+
/** Result of a sandbox run. The IIFE's resolved value (if any). */
|
|
44
|
+
export interface SandboxRunResult {
|
|
45
|
+
/** Whatever the bundle's final expression resolved to (usually `undefined`). */
|
|
46
|
+
value: unknown;
|
|
47
|
+
/** Wall-clock time the script took (ms). */
|
|
48
|
+
durationMs: number;
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Token-level scan of the bundle. Cheap and catches the common LLM mistakes
|
|
52
|
+
* (writing `process.env.X` from muscle memory). Runs BEFORE the bundle
|
|
53
|
+
* executes; a hit raises `PlanError('sandbox_breach')` and the bundle is
|
|
54
|
+
* discarded without being run.
|
|
55
|
+
*/
|
|
56
|
+
export declare function scanForFootguns(bundleCode: string): string[];
|
|
57
|
+
/**
|
|
58
|
+
* Run a compiled bundle in a fresh sandbox with the given capabilities.
|
|
59
|
+
* The script gets ONE global: `__zelari_sdk__`. Standard JS intrinsics
|
|
60
|
+
* (Object, Array, Promise, Math, JSON, Date, console) are available because
|
|
61
|
+
* they are V8 intrinsics — there is no way to exclude them without a
|
|
62
|
+
* custom V8 build, and they are not security risks on their own.
|
|
63
|
+
*/
|
|
64
|
+
export declare function runInSandbox(opts: SandboxRunOptions): Promise<SandboxRunResult>;
|
|
65
|
+
//# sourceMappingURL=sandbox.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.d.ts","sourceRoot":"","sources":["../../../src/kraken/runtime/sandbox.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAyBH,MAAM,WAAW,iBAAiB;IAChC,oDAAoD;IACpD,UAAU,EAAE,MAAM,CAAC;IACnB,4EAA4E;IAC5E,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC7B,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAClB,6BAA6B;IAC7B,MAAM,CAAC,EAAE,WAAW,CAAC;IACrB;;;;;OAKG;IACH,eAAe,CAAC,EAAE,OAAO,CAAC;CAC3B;AAED,mEAAmE;AACnE,MAAM,WAAW,gBAAgB;IAC/B,gFAAgF;IAChF,KAAK,EAAE,OAAO,CAAC;IACf,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,EAAE,CAa5D;AAWD;;;;;;GAMG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,iBAAiB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAkErF"}
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kraken script runtime — Node `vm` sandbox.
|
|
3
|
+
*
|
|
4
|
+
* Wraps the compiled script bundle in a fresh V8 context with a
|
|
5
|
+
* capability-based global. The sandbox has NO `process`, `require`,
|
|
6
|
+
* `Buffer`, `global`, `__dirname`, `__filename`, or any other Node
|
|
7
|
+
* built-in — only the explicit capabilities the host injects.
|
|
8
|
+
*
|
|
9
|
+
* Security model:
|
|
10
|
+
* - The bundle is a single async IIFE produced by esbuild. The sandbox
|
|
11
|
+
* object exposes ONE global: `__zelari_sdk__` (frozen), holding the
|
|
12
|
+
* capability functions. Scripts can only call into the host through
|
|
13
|
+
* these functions; they cannot read `process.env` or `fs` because those
|
|
14
|
+
* do not exist in the context.
|
|
15
|
+
* - Wall-clock bound is enforced by the `vm` timeout. Per-tentacle
|
|
16
|
+
* bound is enforced by the host (existing `runTentacle` timeout).
|
|
17
|
+
* - A footgun guard scans the script for obviously dangerous tokens
|
|
18
|
+
* (e.g. `process`, `require`, `globalThis`) BEFORE running and
|
|
19
|
+
* surfaces a structured `PlanError('sandbox_breach')` when found.
|
|
20
|
+
* This is best-effort: a sufficiently obfuscated script can sneak
|
|
21
|
+
* around the regex, but the absence of these tokens in the sandbox
|
|
22
|
+
* means even bypassing the guard leaves nothing to call.
|
|
23
|
+
*
|
|
24
|
+
* @since Kraken v1.30.x — workflow script runtime (F1.1)
|
|
25
|
+
*/
|
|
26
|
+
import vm from 'node:vm';
|
|
27
|
+
import { PlanError } from './types.js';
|
|
28
|
+
/** Maximum size of a bundled script (bytes). Anything bigger is almost
|
|
29
|
+
* certainly an LLM loop, not a real plan. */
|
|
30
|
+
const MAX_BUNDLE_BYTES = 256 * 1024;
|
|
31
|
+
/** Footgun guard: token-level regexes applied to the source before running. */
|
|
32
|
+
const FORBIDDEN_TOKENS = [
|
|
33
|
+
/\bprocess\b/,
|
|
34
|
+
/\brequire\b/,
|
|
35
|
+
/\bmodule\b/,
|
|
36
|
+
/\bexports\b/,
|
|
37
|
+
/\b__dirname\b/,
|
|
38
|
+
/\b__filename\b/,
|
|
39
|
+
/\bglobalThis\b/,
|
|
40
|
+
/\bglobal\b(?!\s*=)/,
|
|
41
|
+
/\bBuffer\b/,
|
|
42
|
+
/\beval\b/,
|
|
43
|
+
/\bFunction\s*\(/,
|
|
44
|
+
/\bnew\s+Function\b/,
|
|
45
|
+
];
|
|
46
|
+
/**
|
|
47
|
+
* Token-level scan of the bundle. Cheap and catches the common LLM mistakes
|
|
48
|
+
* (writing `process.env.X` from muscle memory). Runs BEFORE the bundle
|
|
49
|
+
* executes; a hit raises `PlanError('sandbox_breach')` and the bundle is
|
|
50
|
+
* discarded without being run.
|
|
51
|
+
*/
|
|
52
|
+
export function scanForFootguns(bundleCode) {
|
|
53
|
+
if (bundleCode.length > MAX_BUNDLE_BYTES) {
|
|
54
|
+
return [
|
|
55
|
+
`bundle is ${bundleCode.length} bytes; max is ${MAX_BUNDLE_BYTES} ` +
|
|
56
|
+
`(LLM is almost certainly looping)`,
|
|
57
|
+
];
|
|
58
|
+
}
|
|
59
|
+
const hits = [];
|
|
60
|
+
for (const re of FORBIDDEN_TOKENS) {
|
|
61
|
+
const m = re.exec(bundleCode);
|
|
62
|
+
if (m)
|
|
63
|
+
hits.push(`forbidden token "${m[0]}"`);
|
|
64
|
+
}
|
|
65
|
+
return hits;
|
|
66
|
+
}
|
|
67
|
+
/** Deep-freeze an object so scripts cannot mutate capabilities. */
|
|
68
|
+
function deepFreeze(value) {
|
|
69
|
+
if (value === null || typeof value !== 'object')
|
|
70
|
+
return value;
|
|
71
|
+
if (Object.isFrozen(value))
|
|
72
|
+
return value;
|
|
73
|
+
const obj = value;
|
|
74
|
+
for (const k of Object.keys(obj))
|
|
75
|
+
deepFreeze(obj[k]);
|
|
76
|
+
return Object.freeze(value);
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* Run a compiled bundle in a fresh sandbox with the given capabilities.
|
|
80
|
+
* The script gets ONE global: `__zelari_sdk__`. Standard JS intrinsics
|
|
81
|
+
* (Object, Array, Promise, Math, JSON, Date, console) are available because
|
|
82
|
+
* they are V8 intrinsics — there is no way to exclude them without a
|
|
83
|
+
* custom V8 build, and they are not security risks on their own.
|
|
84
|
+
*/
|
|
85
|
+
export async function runInSandbox(opts) {
|
|
86
|
+
const { bundleCode, sdk, timeoutMs } = opts;
|
|
87
|
+
// 1. Pre-flight: reject obviously-unsafe bundles. Tests opt out via
|
|
88
|
+
// `skipFootgunScan: true` so they can probe the sandbox for forbidden
|
|
89
|
+
// tokens without tripping the guard.
|
|
90
|
+
if (!opts.skipFootgunScan) {
|
|
91
|
+
const footguns = scanForFootguns(bundleCode);
|
|
92
|
+
if (footguns.length > 0) {
|
|
93
|
+
throw new PlanError('sandbox_breach', `script bundle failed footgun scan: ${footguns.join('; ')}`);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
// 2. Freeze the capabilities so a script cannot replace them.
|
|
97
|
+
const frozen = deepFreeze({ ...sdk });
|
|
98
|
+
// 3. Build a minimal sandbox global. We do NOT add `process`, `require`,
|
|
99
|
+
// `Buffer`, `global`, etc. — V8 will not put them in the new context
|
|
100
|
+
// by default, and we never add them ourselves.
|
|
101
|
+
const sandbox = {
|
|
102
|
+
__zelari_sdk__: frozen,
|
|
103
|
+
// A console that prefixes lines with the graph id; useful for the
|
|
104
|
+
// workbench view and harmless to expose (it just logs to stdout).
|
|
105
|
+
console: makeSandboxConsole(),
|
|
106
|
+
};
|
|
107
|
+
const context = vm.createContext(sandbox, {
|
|
108
|
+
name: 'kraken-script',
|
|
109
|
+
codeGeneration: { strings: false, wasm: false },
|
|
110
|
+
});
|
|
111
|
+
// 4. Run the bundle. `runInContext` accepts a `timeout` option that
|
|
112
|
+
// aborts the script after N ms; we cap at the requested budget.
|
|
113
|
+
// esbuild's IIFE format with top-level await produces an async
|
|
114
|
+
// function, so the result is a Promise.
|
|
115
|
+
const start = Date.now();
|
|
116
|
+
const vmOpts = {
|
|
117
|
+
timeout: Math.max(1, timeoutMs),
|
|
118
|
+
displayErrors: true,
|
|
119
|
+
breakOnSigint: true,
|
|
120
|
+
};
|
|
121
|
+
try {
|
|
122
|
+
const value = await vm.runInContext(bundleCode, context, vmOpts);
|
|
123
|
+
return { value, durationMs: Date.now() - start };
|
|
124
|
+
}
|
|
125
|
+
catch (err) {
|
|
126
|
+
// Distinguish "script was cancelled" from "script threw". The vm
|
|
127
|
+
// module throws a `Script execution timed out` Error when the timeout
|
|
128
|
+
// fires; we re-raise as a structured PlanError. Node's vm error has
|
|
129
|
+
// a `message` field but isn't always a true `Error` instance, so we
|
|
130
|
+
// match on the message string defensively.
|
|
131
|
+
const msg = err && typeof err === 'object' && 'message' in err
|
|
132
|
+
? String(err.message ?? '')
|
|
133
|
+
: String(err);
|
|
134
|
+
if (/timed out/i.test(msg)) {
|
|
135
|
+
throw new PlanError('budget_exceeded', `script exceeded ${timeoutMs}ms budget`);
|
|
136
|
+
}
|
|
137
|
+
if (opts.signal?.aborted) {
|
|
138
|
+
throw new PlanError('cancelled', 'script aborted by host');
|
|
139
|
+
}
|
|
140
|
+
if (err instanceof PlanError)
|
|
141
|
+
throw err;
|
|
142
|
+
throw new PlanError('runtime_error', msg, err);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
/** A console that the script can use without leaking to the real stdout. */
|
|
146
|
+
function makeSandboxConsole() {
|
|
147
|
+
// We proxy to a captured console; this is for debuggability only and
|
|
148
|
+
// does not change the script's ability to do its work.
|
|
149
|
+
const prefix = '[kraken-script]';
|
|
150
|
+
return {
|
|
151
|
+
...console,
|
|
152
|
+
log: (...args) => console.log(prefix, ...args),
|
|
153
|
+
info: (...args) => console.info(prefix, ...args),
|
|
154
|
+
warn: (...args) => console.warn(prefix, ...args),
|
|
155
|
+
error: (...args) => console.error(prefix, ...args),
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
//# sourceMappingURL=sandbox.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sandbox.js","sourceRoot":"","sources":["../../../src/kraken/runtime/sandbox.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kraken script runtime — SDK stub (bundled into user plans).
|
|
3
|
+
*
|
|
4
|
+
* This file is **only** meant to be consumed by the bundler. It defines
|
|
5
|
+
* the public API that user plans import (`@zelari/kraken-runtime` is
|
|
6
|
+
* aliased to this file in the esbuild config). At type-check time the
|
|
7
|
+
* imports resolve to the real `PlanCapabilities` from `./types.js`; at
|
|
8
|
+
* runtime, every exported function forwards to `globalThis.__zelari_sdk__`,
|
|
9
|
+
* which the host populates before running the sandbox.
|
|
10
|
+
*
|
|
11
|
+
* Do NOT call any of these functions outside a script. They are designed
|
|
12
|
+
* to run in a vm context where `globalThis.__zelari_sdk__` exists; if you
|
|
13
|
+
* call them in a normal Node process you'll get a `TypeError`.
|
|
14
|
+
*
|
|
15
|
+
* @since Kraken v1.30.x — workflow script runtime (F1.1)
|
|
16
|
+
*/
|
|
17
|
+
import type { EmitPayload, MergeOptions, MergeResult, PlanContext, PlanSnapshot, TentacleOptions, TentacleRef } from './types.js';
|
|
18
|
+
export declare function tentacle<T = unknown>(opts: TentacleOptions<T>): Promise<TentacleRef<T>>;
|
|
19
|
+
export declare function barrier<T extends readonly TentacleRef[]>(refs: T): Promise<{
|
|
20
|
+
-readonly [K in keyof T]: T[K];
|
|
21
|
+
}>;
|
|
22
|
+
export declare function race<T extends readonly TentacleRef[]>(refs: T): Promise<T[number]>;
|
|
23
|
+
export declare function while_<T>(cond: () => boolean | Promise<boolean>, body: () => Promise<T>, maxIter: number): Promise<T[]>;
|
|
24
|
+
export declare function until<T>(cond: () => boolean | Promise<boolean>, body: () => Promise<T>, maxIter: number): Promise<T[]>;
|
|
25
|
+
export declare function merge(refs: readonly TentacleRef[], opts?: MergeOptions): Promise<MergeResult>;
|
|
26
|
+
export declare function checkpoint(label?: string): Promise<PlanSnapshot>;
|
|
27
|
+
export declare function log(msg: string, data?: Record<string, unknown>): void;
|
|
28
|
+
export declare function emit(payload: EmitPayload): void;
|
|
29
|
+
export declare function getContext(): PlanContext;
|
|
30
|
+
export declare function sendTo(peerId: string, payload: EmitPayload): void;
|
|
31
|
+
export type { EmitPayload, MergeOptions, MergeResult, PlanCapabilities, PlanContext, PlanSnapshot, TentacleOptions, TentacleRef, } from './types.js';
|
|
32
|
+
//# sourceMappingURL=sdk.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk.d.ts","sourceRoot":"","sources":["../../../src/kraken/runtime/sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,OAAO,KAAK,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EAEX,WAAW,EACX,YAAY,EACZ,eAAe,EACf,WAAW,EACZ,MAAM,YAAY,CAAC;AAkBpB,wBAAsB,QAAQ,CAAC,CAAC,GAAG,OAAO,EAAE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,CAE7F;AAED,wBAAsB,OAAO,CAAC,CAAC,SAAS,SAAS,WAAW,EAAE,EAC5D,IAAI,EAAE,CAAC,GACN,OAAO,CAAC;IAAE,CAAC,UAAU,CAAC,IAAI,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC;CAAE,CAAC,CAE7C;AAED,wBAAsB,IAAI,CAAC,CAAC,SAAS,SAAS,WAAW,EAAE,EAAE,IAAI,EAAE,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAExF;AAED,wBAAsB,MAAM,CAAC,CAAC,EAC5B,IAAI,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EACtC,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,EAAE,CAAC,CAEd;AAED,wBAAsB,KAAK,CAAC,CAAC,EAC3B,IAAI,EAAE,MAAM,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,EACtC,IAAI,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EACtB,OAAO,EAAE,MAAM,GACd,OAAO,CAAC,CAAC,EAAE,CAAC,CAEd;AAED,wBAAsB,KAAK,CACzB,IAAI,EAAE,SAAS,WAAW,EAAE,EAC5B,IAAI,CAAC,EAAE,YAAY,GAClB,OAAO,CAAC,WAAW,CAAC,CAEtB;AAED,wBAAsB,UAAU,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAEtE;AAED,wBAAgB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAErE;AAED,wBAAgB,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,IAAI,CAE/C;AAED,wBAAgB,UAAU,IAAI,WAAW,CAExC;AAED,wBAAgB,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,GAAG,IAAI,CAEjE;AAID,YAAY,EACV,WAAW,EACX,YAAY,EACZ,WAAW,EACX,gBAAgB,EAChB,WAAW,EACX,YAAY,EACZ,eAAe,EACf,WAAW,GACZ,MAAM,YAAY,CAAC"}
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Kraken script runtime — SDK stub (bundled into user plans).
|
|
3
|
+
*
|
|
4
|
+
* This file is **only** meant to be consumed by the bundler. It defines
|
|
5
|
+
* the public API that user plans import (`@zelari/kraken-runtime` is
|
|
6
|
+
* aliased to this file in the esbuild config). At type-check time the
|
|
7
|
+
* imports resolve to the real `PlanCapabilities` from `./types.js`; at
|
|
8
|
+
* runtime, every exported function forwards to `globalThis.__zelari_sdk__`,
|
|
9
|
+
* which the host populates before running the sandbox.
|
|
10
|
+
*
|
|
11
|
+
* Do NOT call any of these functions outside a script. They are designed
|
|
12
|
+
* to run in a vm context where `globalThis.__zelari_sdk__` exists; if you
|
|
13
|
+
* call them in a normal Node process you'll get a `TypeError`.
|
|
14
|
+
*
|
|
15
|
+
* @since Kraken v1.30.x — workflow script runtime (F1.1)
|
|
16
|
+
*/
|
|
17
|
+
function sdk() {
|
|
18
|
+
// The host injects `__zelari_sdk__` into the sandbox before the bundle
|
|
19
|
+
// runs. In a normal Node process this global is undefined and the
|
|
20
|
+
// explicit throw below catches misuse early.
|
|
21
|
+
const g = globalThis;
|
|
22
|
+
if (!g.__zelari_sdk__) {
|
|
23
|
+
throw new Error('@zelari/kraken-runtime must run inside a Kraken script sandbox; ' +
|
|
24
|
+
'no __zelari_sdk__ capability was provided');
|
|
25
|
+
}
|
|
26
|
+
return g.__zelari_sdk__;
|
|
27
|
+
}
|
|
28
|
+
export async function tentacle(opts) {
|
|
29
|
+
return sdk().tentacle(opts);
|
|
30
|
+
}
|
|
31
|
+
export async function barrier(refs) {
|
|
32
|
+
return sdk().barrier(refs);
|
|
33
|
+
}
|
|
34
|
+
export async function race(refs) {
|
|
35
|
+
return sdk().race(refs);
|
|
36
|
+
}
|
|
37
|
+
export async function while_(cond, body, maxIter) {
|
|
38
|
+
return sdk().while_(cond, body, maxIter);
|
|
39
|
+
}
|
|
40
|
+
export async function until(cond, body, maxIter) {
|
|
41
|
+
return sdk().until(cond, body, maxIter);
|
|
42
|
+
}
|
|
43
|
+
export async function merge(refs, opts) {
|
|
44
|
+
return sdk().merge(refs, opts);
|
|
45
|
+
}
|
|
46
|
+
export async function checkpoint(label) {
|
|
47
|
+
return sdk().checkpoint(label);
|
|
48
|
+
}
|
|
49
|
+
export function log(msg, data) {
|
|
50
|
+
sdk().log(msg, data);
|
|
51
|
+
}
|
|
52
|
+
export function emit(payload) {
|
|
53
|
+
sdk().emit(payload);
|
|
54
|
+
}
|
|
55
|
+
export function getContext() {
|
|
56
|
+
return sdk().getContext();
|
|
57
|
+
}
|
|
58
|
+
export function sendTo(peerId, payload) {
|
|
59
|
+
sdk().sendTo(peerId, payload);
|
|
60
|
+
}
|
|
61
|
+
//# sourceMappingURL=sdk.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sdk.js","sourceRoot":"","sources":["../../../src/kraken/runtime/sdk.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAeH,SAAS,GAAG;IACV,uEAAuE;IACvE,kEAAkE;IAClE,6CAA6C;IAC7C,MAAM,CAAC,GAAG,UAAiD,CAAC;IAC5D,IAAI,CAAC,CAAC,CAAC,cAAc,EAAE,CAAC;QACtB,MAAM,IAAI,KAAK,CACb,kEAAkE;YAChE,2CAA2C,CAC9C,CAAC;IACJ,CAAC;IACD,OAAO,CAAC,CAAC,cAAc,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,QAAQ,CAAc,IAAwB;IAClE,OAAO,GAAG,EAAE,CAAC,QAAQ,CAAI,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,OAAO,CAC3B,IAAO;IAEP,OAAO,GAAG,EAAE,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,IAAI,CAAmC,IAAO;IAClE,OAAO,GAAG,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;AAC1B,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,MAAM,CAC1B,IAAsC,EACtC,IAAsB,EACtB,OAAe;IAEf,OAAO,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,IAAsC,EACtC,IAAsB,EACtB,OAAe;IAEf,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,KAAK,CACzB,IAA4B,EAC5B,IAAmB;IAEnB,OAAO,GAAG,EAAE,CAAC,KAAK,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,KAAc;IAC7C,OAAO,GAAG,EAAE,CAAC,UAAU,CAAC,KAAK,CAAC,CAAC;AACjC,CAAC;AAED,MAAM,UAAU,GAAG,CAAC,GAAW,EAAE,IAA8B;IAC7D,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;AACvB,CAAC;AAED,MAAM,UAAU,IAAI,CAAC,OAAoB;IACvC,GAAG,EAAE,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,UAAU;IACxB,OAAO,GAAG,EAAE,CAAC,UAAU,EAAE,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,MAAc,EAAE,OAAoB;IACzD,GAAG,EAAE,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;AAChC,CAAC"}
|