@mettlelabs/mettle 0.0.0-beta.1-linux-arm64 → 0.0.0-beta.2-darwin-arm64
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/THIRD_PARTY_NOTICES.md +503 -8
- package/bin/mettle +2 -2
- package/harness/audit-investigation.mjs +16 -16
- package/harness/chunk-3wt8a8fq.mjs +1716 -0
- package/harness/{chunk-13tgmdey.mjs → chunk-49ytr8d5.mjs} +1 -1
- package/harness/chunk-4vx34w5h.mjs +2357 -0
- package/harness/{chunk-xqyc4ca2.mjs → chunk-9dg1btk1.mjs} +1220 -292
- package/harness/chunk-c7dx5mdd.mjs +10807 -0
- package/harness/{chunk-msg872ea.mjs → chunk-h1td5kq9.mjs} +97 -9
- package/harness/{chunk-4jtnt9k5.mjs → chunk-jp69h6sj.mjs} +1 -1
- package/harness/chunk-rd80vvc5.mjs +22047 -0
- package/harness/{chunk-5cvb1jnb.mjs → chunk-w0qwc5z2.mjs} +2 -2
- package/harness/issue-api-token.mjs +2 -2
- package/harness/launcher.mjs +318 -18
- package/harness/sandbox.mjs +8 -7
- package/harness/server.mjs +22883 -1891
- package/package.json +2 -5
- package/harness/chunk-2gt4cy7x.mjs +0 -2290
- package/harness/chunk-32y07kkp.mjs +0 -3747
- package/harness/chunk-7bg2gnv2.mjs +0 -7540
|
@@ -7,16 +7,16 @@ import {
|
|
|
7
7
|
digest,
|
|
8
8
|
captureEvidence,
|
|
9
9
|
RUNTIME_VERSION
|
|
10
|
-
} from "./chunk-
|
|
11
|
-
import {
|
|
12
|
-
PostgresJournal
|
|
13
|
-
} from "./chunk-7bg2gnv2.mjs";
|
|
10
|
+
} from "./chunk-rd80vvc5.mjs";
|
|
14
11
|
import {
|
|
15
12
|
PROBE_TOOL,
|
|
16
13
|
SANDBOX_TOOLS,
|
|
14
|
+
PostgresJournal
|
|
15
|
+
} from "./chunk-c7dx5mdd.mjs";
|
|
16
|
+
import {
|
|
17
17
|
dockerJson,
|
|
18
18
|
SandboxWorker
|
|
19
|
-
} from "./chunk-
|
|
19
|
+
} from "./chunk-9dg1btk1.mjs";
|
|
20
20
|
|
|
21
21
|
// apps/harness/src/execution/tool-executor.ts
|
|
22
22
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
@@ -24,6 +24,8 @@ var APPROVAL_TTL_MS = 600000;
|
|
|
24
24
|
var INTERRUPTED = "The operator interrupted this call while it ran; its outcome is unknown.";
|
|
25
25
|
var SETTLED_FAILURES = new Set([
|
|
26
26
|
"tool_denied",
|
|
27
|
+
"work_denied",
|
|
28
|
+
"coverage_denied",
|
|
27
29
|
"approval_denied",
|
|
28
30
|
"approval_expired",
|
|
29
31
|
"invalid_artifact",
|
|
@@ -38,6 +40,9 @@ var SETTLED_FAILURES = new Set([
|
|
|
38
40
|
"candidate_denied",
|
|
39
41
|
"candidate_conflict",
|
|
40
42
|
"repository_bound",
|
|
43
|
+
"source_busy",
|
|
44
|
+
"source_unavailable",
|
|
45
|
+
"source_encoding",
|
|
41
46
|
"scanner_denied",
|
|
42
47
|
"web_denied",
|
|
43
48
|
"sandbox_task_failed",
|
|
@@ -85,6 +90,10 @@ class ToolExecutor {
|
|
|
85
90
|
}, tool.idempotent === true);
|
|
86
91
|
if (cachedRef)
|
|
87
92
|
return this.cached(cachedRef, tool);
|
|
93
|
+
if (tool.unavailableReason) {
|
|
94
|
+
await this.journal.failAction(this.lease, callId, tool.unavailableReason, "tool_denied");
|
|
95
|
+
throw new HarnessError("tool_denied", tool.unavailableReason);
|
|
96
|
+
}
|
|
88
97
|
const approval = await this.requested(callId, tool, args, summary);
|
|
89
98
|
await this.hooks.at?.("after-intent");
|
|
90
99
|
if (this.signal.aborted)
|
|
@@ -102,7 +111,13 @@ class ToolExecutor {
|
|
|
102
111
|
}
|
|
103
112
|
if (this.signal.aborted)
|
|
104
113
|
throw new HarnessError("stop_requested", "Execution cancelled before dispatch.");
|
|
105
|
-
|
|
114
|
+
try {
|
|
115
|
+
await this.journal.dispatchAction(this.lease, callId);
|
|
116
|
+
} catch (error) {
|
|
117
|
+
if (error instanceof HarnessError && error.code === "tool_denied")
|
|
118
|
+
await this.journal.failAction(this.lease, callId, error.message, error.code);
|
|
119
|
+
throw error;
|
|
120
|
+
}
|
|
106
121
|
await this.hooks.at?.("after-dispatch");
|
|
107
122
|
let ref;
|
|
108
123
|
try {
|
|
@@ -191,13 +206,18 @@ class SandboxJournal {
|
|
|
191
206
|
this.journal = journal;
|
|
192
207
|
this.lease = lease;
|
|
193
208
|
}
|
|
194
|
-
async reserve(callId, workerId, image, policyDigest, binding = { tool: PROBE_TOOL, args: {} }) {
|
|
209
|
+
async reserve(callId, workerId, image, policyDigest, binding = { tool: PROBE_TOOL, args: {} }, page) {
|
|
195
210
|
if (!SANDBOX_TOOLS.includes(binding.tool) || binding.tool === PROBE_TOOL && digest(binding.args) !== digest({}))
|
|
196
211
|
throw new HarnessError("sandbox_denied", "Only an approved isolated observation or fixed probe may reserve a sandbox.");
|
|
197
212
|
return this.journal.fenced(this.lease, async ({ client }) => {
|
|
198
213
|
const action = await client.query("SELECT 1 FROM harness_mastra.actions WHERE run_id=$1 AND call_id=$2 AND tool=$4 AND args_digest=$3 AND state='dispatched'", [this.lease.runId, callId, digest(binding.args), binding.tool]);
|
|
199
214
|
if (!action.rowCount)
|
|
200
215
|
throw new HarnessError("sandbox_denied", "A sandbox requires the exact committed observation dispatch.");
|
|
216
|
+
if (page) {
|
|
217
|
+
const available = await client.query("SELECT count(*)::int AS count,clock_timestamp()<$2::timestamptz AS active FROM harness_mastra.browser_pages WHERE run_id=$1 AND NOT closed", [this.lease.runId, page.expiresAt]);
|
|
218
|
+
if (binding.tool !== "web_browse" || page.operation !== "open" || available.rows[0].count >= 4 || !available.rows[0].active)
|
|
219
|
+
throw new HarnessError("browser_page_denied", "A live page requires an open operation, active grant and fewer than four retained pages.");
|
|
220
|
+
}
|
|
201
221
|
const record = {
|
|
202
222
|
runId: this.lease.runId,
|
|
203
223
|
callId,
|
|
@@ -220,9 +240,69 @@ class SandboxJournal {
|
|
|
220
240
|
]);
|
|
221
241
|
if (!inserted.rowCount)
|
|
222
242
|
throw new HarnessError("uncertain_execution", "A prior sandbox reservation cannot be executed again.");
|
|
243
|
+
if (page)
|
|
244
|
+
await client.query("INSERT INTO harness_mastra.browser_pages(run_id,page_id,sandbox_call,owner_call,child_id,identity_id,binding_digest,epoch,expires_at) VALUES($1,$2,$3,$3,$4,$5,$6,$7,LEAST($8::timestamptz,clock_timestamp()+interval '10 minutes'))", [
|
|
245
|
+
record.runId,
|
|
246
|
+
page.id,
|
|
247
|
+
callId,
|
|
248
|
+
this.lease.child?.id ?? null,
|
|
249
|
+
page.identity,
|
|
250
|
+
page.digest,
|
|
251
|
+
this.lease.epoch,
|
|
252
|
+
page.expiresAt
|
|
253
|
+
]);
|
|
223
254
|
return record;
|
|
224
255
|
});
|
|
225
256
|
}
|
|
257
|
+
async acquirePage(callId, args, page) {
|
|
258
|
+
return this.journal.fenced(this.lease, async ({ client }) => {
|
|
259
|
+
const result = await client.query(`SELECT s.run_id AS "runId",s.call_id AS "callId",s.epoch,s.worker_id AS "workerId",s.name,s.image,s.policy_digest AS "policyDigest",s.container_id AS "containerId",s.state
|
|
260
|
+
FROM harness_mastra.browser_pages p JOIN harness_mastra.sandboxes s ON s.run_id=p.run_id AND s.call_id=p.sandbox_call
|
|
261
|
+
JOIN harness_mastra.actions a ON a.run_id=p.run_id AND a.call_id=$3
|
|
262
|
+
WHERE p.run_id=$1 AND p.page_id=$2 AND NOT p.closed AND p.owner_call IS NULL AND p.epoch=$4 AND p.child_id IS NOT DISTINCT FROM $5 AND p.identity_id=$6 AND p.binding_digest=$7 AND clock_timestamp()<p.expires_at
|
|
263
|
+
AND s.state='running' AND a.tool='web_browse' AND a.state='dispatched' AND a.args_digest=$8 AND a.child_id IS NOT DISTINCT FROM $5 FOR UPDATE OF p`, [
|
|
264
|
+
this.lease.runId,
|
|
265
|
+
page.id,
|
|
266
|
+
callId,
|
|
267
|
+
this.lease.epoch,
|
|
268
|
+
this.lease.child?.id ?? null,
|
|
269
|
+
page.identity,
|
|
270
|
+
page.digest,
|
|
271
|
+
digest(args)
|
|
272
|
+
]);
|
|
273
|
+
if (page.operation === "open" || result.rowCount !== 1)
|
|
274
|
+
throw new HarnessError("browser_page_lost", "The page is absent, busy, expired, closed, or belongs to another identity, child, grant or worker epoch. Open a new page; previous actions are never replayed.");
|
|
275
|
+
await client.query("UPDATE harness_mastra.browser_pages SET owner_call=$3 WHERE run_id=$1 AND page_id=$2", [this.lease.runId, page.id, callId]);
|
|
276
|
+
return result.rows[0];
|
|
277
|
+
});
|
|
278
|
+
}
|
|
279
|
+
async suspendPages() {
|
|
280
|
+
await this.journal.fenced(this.lease, async ({ client }) => {
|
|
281
|
+
await client.query("UPDATE harness_mastra.browser_pages SET suspended_owner=$3 WHERE run_id=$1 AND epoch=$2 AND NOT closed AND owner_call IS NULL AND EXISTS (SELECT 1 FROM harness_mastra.approvals approval JOIN harness_mastra.actions action ON action.run_id=approval.run_id AND action.call_id=approval.call_id WHERE approval.run_id=$1 AND action.state='prepared')", [this.lease.runId, this.lease.epoch, this.lease.owner]);
|
|
282
|
+
}, "settlement");
|
|
283
|
+
}
|
|
284
|
+
async resumePages(previous) {
|
|
285
|
+
if (previous.runId !== this.lease.runId || previous.epoch + 1 !== this.lease.epoch)
|
|
286
|
+
throw new HarnessError("browser_page_lost", "Only the next owner can resume an approval suspension.");
|
|
287
|
+
await this.journal.fenced(this.lease, async ({ client }) => {
|
|
288
|
+
await client.query("UPDATE harness_mastra.browser_pages SET epoch=$4,suspended_owner=NULL WHERE run_id=$1 AND epoch=$2 AND suspended_owner=$3 AND NOT closed AND owner_call IS NULL AND clock_timestamp()<expires_at", [this.lease.runId, previous.epoch, previous.owner, this.lease.epoch]);
|
|
289
|
+
}, "settlement");
|
|
290
|
+
}
|
|
291
|
+
async releasePage(record, callId) {
|
|
292
|
+
await this.journal.fenced(this.lease, async ({ client }) => {
|
|
293
|
+
await this.assertState(record, "running", client);
|
|
294
|
+
const result = await client.query("UPDATE harness_mastra.browser_pages SET owner_call=NULL WHERE run_id=$1 AND sandbox_call=$2 AND owner_call=$3 AND epoch=$4 AND NOT closed", [this.lease.runId, record.callId, callId, this.lease.epoch]);
|
|
295
|
+
if (result.rowCount !== 1)
|
|
296
|
+
throw new HarnessError("browser_page_lost", "A different action owns this page.");
|
|
297
|
+
});
|
|
298
|
+
}
|
|
299
|
+
async pages() {
|
|
300
|
+
const retained = await this.journal.fenced(this.lease, async ({ client }) => {
|
|
301
|
+
const result = await client.query("SELECT sandbox_call FROM harness_mastra.browser_pages WHERE run_id=$1 AND NOT closed AND ($2::uuid IS NULL OR child_id=$2)", [this.lease.runId, this.lease.child?.id ?? null]);
|
|
302
|
+
return new Set(result.rows.map((row) => row.sandbox_call));
|
|
303
|
+
}, "settlement");
|
|
304
|
+
return (await this.pending()).filter((record) => retained.has(record.callId));
|
|
305
|
+
}
|
|
226
306
|
async provision(record, operation) {
|
|
227
307
|
await this.journal.fenced(this.lease, async ({ client }) => {
|
|
228
308
|
await this.assertState(record, "reserved", client);
|
|
@@ -258,8 +338,15 @@ class SandboxJournal {
|
|
|
258
338
|
});
|
|
259
339
|
}
|
|
260
340
|
async assertState(record, state, client) {
|
|
261
|
-
const result = await client.query("SELECT 1 FROM harness_mastra.sandboxes WHERE run_id=$1 AND call_id=$2 AND epoch=$3 AND name=$4 AND state=$5
|
|
262
|
-
|
|
341
|
+
const result = await client.query("SELECT 1 FROM harness_mastra.sandboxes s WHERE run_id=$1 AND call_id=$2 AND epoch=$3 AND name=$4 AND state=$5 AND (epoch=$6 OR (state='running' AND EXISTS (SELECT 1 FROM harness_mastra.browser_pages p WHERE p.run_id=s.run_id AND p.sandbox_call=s.call_id AND p.epoch=$6 AND NOT p.closed AND p.owner_call IS NOT NULL)))", [
|
|
342
|
+
this.lease.runId,
|
|
343
|
+
record.callId,
|
|
344
|
+
record.epoch,
|
|
345
|
+
record.name,
|
|
346
|
+
state,
|
|
347
|
+
this.lease.epoch
|
|
348
|
+
]);
|
|
349
|
+
if (record.runId !== this.lease.runId || result.rowCount !== 1)
|
|
263
350
|
throw new HarnessError("sandbox_denied", "Sandbox ownership or lifecycle no longer permits this operation.");
|
|
264
351
|
}
|
|
265
352
|
async removed(record) {
|
|
@@ -267,6 +354,7 @@ class SandboxJournal {
|
|
|
267
354
|
const result = await client.query("UPDATE harness_mastra.sandboxes SET state='removed',removed_at=clock_timestamp() WHERE run_id=$1 AND call_id=$2 AND name=$3 AND worker_id=$4", [this.lease.runId, record.callId, record.name, record.workerId]);
|
|
268
355
|
if (record.runId !== this.lease.runId || !result.rowCount)
|
|
269
356
|
throw new HarnessError("sandbox_denied", "Cleanup receipt does not belong to this run.");
|
|
357
|
+
await client.query("UPDATE harness_mastra.browser_pages SET closed=true,owner_call=NULL WHERE run_id=$1 AND sandbox_call=$2", [this.lease.runId, record.callId]);
|
|
270
358
|
record.state = "removed";
|
|
271
359
|
}, "settlement");
|
|
272
360
|
}
|