@mettlelabs/mettle 0.0.0-beta.1-linux-arm64 → 0.0.0-beta.10

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.
Files changed (61) hide show
  1. package/LICENSE +22 -0
  2. package/bin/mettle.cjs +152 -0
  3. package/package.json +28 -16
  4. package/THIRD_PARTY_NOTICES.md +0 -11479
  5. package/bin/mettle +0 -4
  6. package/harness/audit-investigation.mjs +0 -203
  7. package/harness/chunk-13tgmdey.mjs +0 -33761
  8. package/harness/chunk-1sygmp11.mjs +0 -18142
  9. package/harness/chunk-1ykxpmaz.mjs +0 -7887
  10. package/harness/chunk-2gt4cy7x.mjs +0 -2290
  11. package/harness/chunk-2pm2sayw.mjs +0 -248
  12. package/harness/chunk-32y07kkp.mjs +0 -3747
  13. package/harness/chunk-3m7jn5ac.mjs +0 -16242
  14. package/harness/chunk-3wvjs93w.mjs +0 -538
  15. package/harness/chunk-4bepyxmq.mjs +0 -113
  16. package/harness/chunk-4jtnt9k5.mjs +0 -95
  17. package/harness/chunk-50sbrf09.mjs +0 -18972
  18. package/harness/chunk-56csr8sw.mjs +0 -322
  19. package/harness/chunk-5cvb1jnb.mjs +0 -41
  20. package/harness/chunk-5wgmv4np.mjs +0 -585
  21. package/harness/chunk-65eyq32y.mjs +0 -225
  22. package/harness/chunk-6fnh6qhk.mjs +0 -195
  23. package/harness/chunk-6kgqw9ny.mjs +0 -32303
  24. package/harness/chunk-7b242j0n.mjs +0 -14
  25. package/harness/chunk-7bg2gnv2.mjs +0 -7540
  26. package/harness/chunk-ageqxj9v.mjs +0 -63008
  27. package/harness/chunk-b0qbt5jd.mjs +0 -14
  28. package/harness/chunk-b5g1r3fz.mjs +0 -4785
  29. package/harness/chunk-b71gpkxg.mjs +0 -1514
  30. package/harness/chunk-bdv1rx4a.mjs +0 -20364
  31. package/harness/chunk-c1631s2x.mjs +0 -12241
  32. package/harness/chunk-d5xgxsnp.mjs +0 -74
  33. package/harness/chunk-erg1fbh0.mjs +0 -0
  34. package/harness/chunk-fh78v9vn.mjs +0 -19366
  35. package/harness/chunk-fjx29qvp.mjs +0 -50
  36. package/harness/chunk-gryka6kg.mjs +0 -39
  37. package/harness/chunk-jb0r19et.mjs +0 -180
  38. package/harness/chunk-mfn574ss.mjs +0 -179
  39. package/harness/chunk-msg872ea.mjs +0 -334
  40. package/harness/chunk-nz5sv9as.mjs +0 -1642
  41. package/harness/chunk-p9d3cgvq.mjs +0 -452
  42. package/harness/chunk-pq6wvwxr.mjs +0 -12
  43. package/harness/chunk-qcm9arf8.mjs +0 -7736
  44. package/harness/chunk-qr8zfqjd.mjs +0 -24
  45. package/harness/chunk-rz2tz6jp.mjs +0 -26
  46. package/harness/chunk-sbkgc3kn.mjs +0 -8
  47. package/harness/chunk-v66qvpnb.mjs +0 -169
  48. package/harness/chunk-vjaxzab3.mjs +0 -136
  49. package/harness/chunk-vr1n5nza.mjs +0 -1045
  50. package/harness/chunk-vsf2zajv.mjs +0 -3867
  51. package/harness/chunk-wq253fj4.mjs +0 -19041
  52. package/harness/chunk-wyv7ceq4.mjs +0 -0
  53. package/harness/chunk-xnqknk2r.mjs +0 -198
  54. package/harness/chunk-xqyc4ca2.mjs +0 -1890
  55. package/harness/chunk-z6n9thea.mjs +0 -45146
  56. package/harness/chunk-zty0d3bw.mjs +0 -0
  57. package/harness/chunk-zvkxtj82.mjs +0 -42
  58. package/harness/issue-api-token.mjs +0 -35
  59. package/harness/launcher.mjs +0 -159
  60. package/harness/sandbox.mjs +0 -132
  61. package/harness/server.mjs +0 -66322
package/bin/mettle DELETED
@@ -1,4 +0,0 @@
1
- [diffend] Oversized file quarantined before diffing.
2
- name: package/bin/mettle
3
- size: 100649256 bytes
4
- sha256: 23bbc6e76a1f3c103e121e0cdf01325cf6ec66a5e8e6626ab38a0b99cd96fa61
@@ -1,203 +0,0 @@
1
- import {
2
- HarnessError,
3
- publicError,
4
- sha256,
5
- captureEvidence
6
- } from "./chunk-2gt4cy7x.mjs";
7
- import {
8
- privateDirectory,
9
- createJournalPool
10
- } from "./chunk-7bg2gnv2.mjs";
11
- import"./chunk-zvkxtj82.mjs";
12
- import {
13
- databaseConfig
14
- } from "./chunk-5cvb1jnb.mjs";
15
- import {
16
- uuid
17
- } from "./chunk-1sygmp11.mjs";
18
-
19
- // apps/harness/src/audit.ts
20
- import { randomUUID } from "node:crypto";
21
- import { constants } from "node:fs";
22
- import { mkdir, open, rename, rm, writeFile } from "node:fs/promises";
23
- import { homedir } from "node:os";
24
- import { join } from "node:path";
25
- import { setTimeout as sleep } from "node:timers/promises";
26
- async function readRunAudit(pool, selector) {
27
- if (selector !== "latest")
28
- uuid().parse(selector);
29
- const client = await pool.connect();
30
- try {
31
- await client.query("BEGIN ISOLATION LEVEL REPEATABLE READ READ ONLY");
32
- const found = await client.query("SELECT r.id,r.target,r.config->>'model' AS model,r.started_at,r.finished_at,r.seq,r.spent_tokens,r.spent_nanousd::text,r.active_ms::text,r.terminal FROM harness_mastra.runs r WHERE NOT r.chat AND ($1::uuid IS NULL OR r.id=$1) ORDER BY r.started_at DESC,r.id DESC LIMIT 1", [selector === "latest" ? null : selector]);
33
- const run = found.rows[0];
34
- if (!run)
35
- throw new HarnessError("run_not_found", "No matching investigation exists in this database.");
36
- const events = await client.query("SELECT payload FROM harness_mastra.events WHERE run_id=$1 ORDER BY seq", [run.id]);
37
- const actions = await client.query("SELECT a.call_id,a.tool,a.state,a.args_digest,a.child_id,a.artifact_ref,e.sha256,e.manifest,e.envelope,e.bytes FROM harness_mastra.actions a LEFT JOIN harness_mastra.artifacts e ON e.run_id=a.run_id AND e.ref=a.artifact_ref WHERE a.run_id=$1 ORDER BY a.call_id", [run.id]);
38
- const models = await client.query("SELECT request_id,child_id,provider,requested_model,state,failure_code,provider_observation,final_usage_known,reserved_tokens,reserved_nanousd::text,observed_input_tokens,observed_output_tokens,observed_nanousd::text,charged_nanousd::text,response->>'content' AS commentary,response->'toolCalls' AS proposed_tool_calls FROM harness_mastra.model_dispatches WHERE run_id=$1 ORDER BY request_id", [run.id]);
39
- const network = await client.query("SELECT id,call_id,state,bytes,request_digest,response_digest,dispatched_at FROM harness_mastra.web_requests WHERE run_id=$1 ORDER BY dispatched_at,id", [run.id]);
40
- const sandboxes = await client.query("SELECT call_id,worker_id,container_id,image,state,created_at,removed_at FROM harness_mastra.sandboxes WHERE run_id=$1 ORDER BY created_at,call_id", [run.id]);
41
- const stages = await client.query("SELECT stage_key,input_digest FROM harness_mastra.investigation_stages WHERE run_id=$1 ORDER BY stage_key", [run.id]);
42
- const findings = await client.query("SELECT id,status,result,finding FROM harness_mastra.findings WHERE run_id=$1 ORDER BY id", [run.id]);
43
- await client.query("COMMIT");
44
- const clean = (value) => captureEvidence(value).value;
45
- return {
46
- capturedAt: new Date().toISOString(),
47
- source: "PostgreSQL committed records; read-only snapshot",
48
- run: {
49
- ...run,
50
- started_at: run.started_at.toISOString(),
51
- finished_at: run.finished_at?.toISOString() ?? null,
52
- target: clean(run.target)
53
- },
54
- usage: {
55
- tokens: run.spent_tokens,
56
- usd: Number(run.spent_nanousd) / 1e9,
57
- wallSec: Number(run.active_ms) / 1000
58
- },
59
- stages: stages.rows,
60
- events: events.rows.map(({ payload }) => ({
61
- seq: payload.seq,
62
- type: payload.type,
63
- record: clean(payload)
64
- })),
65
- actions: actions.rows.map(({ bytes, ...action }) => ({
66
- ...action,
67
- evidenceHashMatches: typeof bytes === "string" ? sha256(bytes) === action.sha256 : null,
68
- outputExcerpt: typeof bytes === "string" ? clean(bytes.slice(0, 8192)) : null,
69
- outputTruncated: typeof bytes === "string" && bytes.length > 8192
70
- })),
71
- models: models.rows.map(clean),
72
- network: network.rows.map((row) => ({
73
- ...row,
74
- dispatched_at: row.dispatched_at.toISOString()
75
- })),
76
- sandboxes: sandboxes.rows.map((row) => ({
77
- ...row,
78
- created_at: row.created_at.toISOString(),
79
- removed_at: row.removed_at?.toISOString() ?? null
80
- })),
81
- findings: findings.rows.map(clean),
82
- limitsOfThisExport: [
83
- "Model commentary and proposed tool calls are not execution proof; match them to committed actions and evidence.",
84
- "Reserved model cost is not a charge. Dispatched network bytes may still be held reservations.",
85
- "Output excerpts are redacted and bounded. Full artifacts remain in the evidence store; external objects are not downloaded here.",
86
- "Inline artifact hashes are compared; this export does not independently verify evidence signatures or vulnerability claims.",
87
- "An unchanged event sequence or heartbeat alone does not prove forward progress."
88
- ]
89
- };
90
- } catch (error) {
91
- await client.query("ROLLBACK");
92
- throw error;
93
- } finally {
94
- client.release();
95
- }
96
- }
97
- async function atomic(path, value) {
98
- const temporary = `${path}.${randomUUID()}.tmp`;
99
- try {
100
- await writeFile(temporary, value, { flag: "wx", mode: 384 });
101
- await rename(temporary, path);
102
- } finally {
103
- await rm(temporary, { force: true });
104
- }
105
- }
106
- async function saveRunAudit(root, audit, after = -1, writeStatus = true) {
107
- uuid().parse(audit.run.id);
108
- await mkdir(root, { recursive: true, mode: 448 });
109
- const base = await privateDirectory(root);
110
- const directory = join(base, audit.run.id);
111
- await mkdir(directory, { mode: 448 }).catch((error) => {
112
- if (error.code !== "EEXIST")
113
- throw error;
114
- });
115
- await privateDirectory(directory);
116
- const path = join(directory, "progress.log");
117
- const file = await open(path, constants.O_CREAT | constants.O_WRONLY | constants.O_APPEND | constants.O_NOFOLLOW | constants.O_NONBLOCK, 384);
118
- try {
119
- const info = await file.stat();
120
- if (!info.isFile() || info.uid !== process.getuid?.() || info.mode & 63)
121
- throw new HarnessError("private_file", "The audit log must be a private operator-owned regular file.");
122
- const fresh = audit.events.filter((event) => event.seq > after);
123
- const lines = fresh.map((event) => `[observed ${audit.capturedAt}] ${event.type === "step" ? "MODEL/STAGE NOTE" : "JOURNAL"} ${JSON.stringify(event.record)}`);
124
- const latest = audit.events.at(-1);
125
- const lastErrorEvent = [...audit.events].reverse().find((event) => event.type === "error");
126
- const lastError = lastErrorEvent && typeof lastErrorEvent.record.message === "string" ? lastErrorEvent.record.message.slice(0, 200) : null;
127
- if (writeStatus)
128
- lines.push(`[observed ${audit.capturedAt}] STATUS ${JSON.stringify({ runId: audit.run.id, seq: audit.run.seq, usage: audit.usage, terminal: audit.run.terminal, completedStages: audit.stages.map((stage) => stage.stage_key), modelCalls: audit.models.length, toolActions: audit.actions.length, httpRequests: audit.network.length, containersPendingRemoval: audit.sandboxes.filter((container) => container.state !== "removed").length, lastEvent: latest?.type ?? null, lastError, stalled: fresh.length === 0 && !audit.run.terminal })}`);
129
- if (lines.length)
130
- await file.appendFile(`${lines.join(`
131
- `)}
132
- `, "utf8");
133
- } finally {
134
- await file.close();
135
- }
136
- await atomic(join(directory, "audit.json"), `${JSON.stringify(audit, null, 2)}
137
- `);
138
- if (after < 0)
139
- await atomic(join(base, "latest.txt"), `${directory}
140
- `);
141
- return directory;
142
- }
143
- async function auditInvestigation(args) {
144
- const [selector, flag] = args;
145
- if (!selector || args.length > 2 || flag !== undefined && flag !== "--watch")
146
- throw new HarnessError("audit_usage", "Use investigation:audit <RUN_ID|latest> [--watch]. Latest selects the newest investigation once.");
147
- if (selector !== "latest")
148
- uuid().parse(selector);
149
- const pool = createJournalPool(databaseConfig(), "investigation-audit-read-only");
150
- const leaving = new AbortController;
151
- const stop = () => leaving.abort();
152
- process.once("SIGINT", stop);
153
- process.once("SIGTERM", stop);
154
- let runId = selector;
155
- let after = -1;
156
- let lastStatusSeq = -2;
157
- let polls = 0;
158
- try {
159
- while (!leaving.signal.aborted) {
160
- const audit = await readRunAudit(pool, runId);
161
- runId = audit.run.id;
162
- polls += 1;
163
- const writeStatus = audit.run.seq !== lastStatusSeq || polls % 15 === 0;
164
- if (writeStatus)
165
- lastStatusSeq = audit.run.seq;
166
- const directory = await saveRunAudit(join(homedir(), ".mettle", "audits"), audit, after, writeStatus);
167
- console.log(JSON.stringify({
168
- directory,
169
- runId,
170
- seq: audit.run.seq,
171
- usage: audit.usage,
172
- terminal: audit.run.terminal,
173
- providerCallsByAudit: 0
174
- }));
175
- after = audit.run.seq;
176
- if (flag !== "--watch" || audit.run.terminal)
177
- break;
178
- await sleep(2000, undefined, { signal: leaving.signal }).catch((error) => {
179
- if (!leaving.signal.aborted)
180
- throw error;
181
- });
182
- }
183
- } finally {
184
- process.off("SIGINT", stop);
185
- process.off("SIGTERM", stop);
186
- try {
187
- if (leaving.signal.aborted && runId !== "latest") {
188
- const final = await readRunAudit(pool, runId);
189
- await saveRunAudit(join(homedir(), ".mettle", "audits"), final, after);
190
- }
191
- } finally {
192
- await pool.end();
193
- }
194
- }
195
- }
196
-
197
- // apps/harness/scripts/audit-investigation.ts
198
- try {
199
- await auditInvestigation(process.argv.slice(2));
200
- } catch (error) {
201
- console.error(publicError(error));
202
- process.exitCode = 1;
203
- }