@mettlelabs/mettle 0.0.0-0 → 0.0.0-beta.1-linux-x64

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 (59) hide show
  1. package/THIRD_PARTY_NOTICES.md +11479 -0
  2. package/bin/mettle +4 -0
  3. package/harness/audit-investigation.mjs +203 -0
  4. package/harness/chunk-13tgmdey.mjs +33761 -0
  5. package/harness/chunk-1sygmp11.mjs +18142 -0
  6. package/harness/chunk-1ykxpmaz.mjs +7887 -0
  7. package/harness/chunk-2gt4cy7x.mjs +2290 -0
  8. package/harness/chunk-2pm2sayw.mjs +248 -0
  9. package/harness/chunk-32y07kkp.mjs +3747 -0
  10. package/harness/chunk-3m7jn5ac.mjs +16242 -0
  11. package/harness/chunk-3wvjs93w.mjs +538 -0
  12. package/harness/chunk-4bepyxmq.mjs +113 -0
  13. package/harness/chunk-4jtnt9k5.mjs +95 -0
  14. package/harness/chunk-50sbrf09.mjs +18972 -0
  15. package/harness/chunk-56csr8sw.mjs +322 -0
  16. package/harness/chunk-5cvb1jnb.mjs +41 -0
  17. package/harness/chunk-5wgmv4np.mjs +585 -0
  18. package/harness/chunk-65eyq32y.mjs +225 -0
  19. package/harness/chunk-6fnh6qhk.mjs +195 -0
  20. package/harness/chunk-6kgqw9ny.mjs +32303 -0
  21. package/harness/chunk-7b242j0n.mjs +14 -0
  22. package/harness/chunk-7bg2gnv2.mjs +7540 -0
  23. package/harness/chunk-ageqxj9v.mjs +63008 -0
  24. package/harness/chunk-b0qbt5jd.mjs +14 -0
  25. package/harness/chunk-b5g1r3fz.mjs +4785 -0
  26. package/harness/chunk-b71gpkxg.mjs +1514 -0
  27. package/harness/chunk-bdv1rx4a.mjs +20364 -0
  28. package/harness/chunk-c1631s2x.mjs +12241 -0
  29. package/harness/chunk-d5xgxsnp.mjs +74 -0
  30. package/harness/chunk-erg1fbh0.mjs +0 -0
  31. package/harness/chunk-fh78v9vn.mjs +19366 -0
  32. package/harness/chunk-fjx29qvp.mjs +50 -0
  33. package/harness/chunk-gryka6kg.mjs +39 -0
  34. package/harness/chunk-jb0r19et.mjs +180 -0
  35. package/harness/chunk-mfn574ss.mjs +179 -0
  36. package/harness/chunk-msg872ea.mjs +334 -0
  37. package/harness/chunk-nz5sv9as.mjs +1642 -0
  38. package/harness/chunk-p9d3cgvq.mjs +452 -0
  39. package/harness/chunk-pq6wvwxr.mjs +12 -0
  40. package/harness/chunk-qcm9arf8.mjs +7736 -0
  41. package/harness/chunk-qr8zfqjd.mjs +24 -0
  42. package/harness/chunk-rz2tz6jp.mjs +26 -0
  43. package/harness/chunk-sbkgc3kn.mjs +8 -0
  44. package/harness/chunk-v66qvpnb.mjs +169 -0
  45. package/harness/chunk-vjaxzab3.mjs +136 -0
  46. package/harness/chunk-vr1n5nza.mjs +1045 -0
  47. package/harness/chunk-vsf2zajv.mjs +3867 -0
  48. package/harness/chunk-wq253fj4.mjs +19041 -0
  49. package/harness/chunk-wyv7ceq4.mjs +0 -0
  50. package/harness/chunk-xnqknk2r.mjs +198 -0
  51. package/harness/chunk-xqyc4ca2.mjs +1890 -0
  52. package/harness/chunk-z6n9thea.mjs +45146 -0
  53. package/harness/chunk-zty0d3bw.mjs +0 -0
  54. package/harness/chunk-zvkxtj82.mjs +42 -0
  55. package/harness/issue-api-token.mjs +35 -0
  56. package/harness/launcher.mjs +159 -0
  57. package/harness/sandbox.mjs +132 -0
  58. package/harness/server.mjs +66322 -0
  59. package/package.json +20 -3
@@ -0,0 +1,2290 @@
1
+ import {
2
+ exports_iso
3
+ } from "./chunk-b71gpkxg.mjs";
4
+ import {
5
+ ZodError,
6
+ string,
7
+ uuid,
8
+ url,
9
+ number,
10
+ boolean,
11
+ _null,
12
+ unknown,
13
+ never,
14
+ array,
15
+ object,
16
+ strictObject,
17
+ looseObject,
18
+ union,
19
+ discriminatedUnion,
20
+ tuple,
21
+ record,
22
+ _enum,
23
+ literal,
24
+ lazy
25
+ } from "./chunk-1sygmp11.mjs";
26
+
27
+ // packages/contract/src/providers.ts
28
+ var PROVIDER_KEYS = Object.freeze({
29
+ openai: "OPENAI_API_KEY",
30
+ foundry: "FOUNDRY_API_KEY"
31
+ });
32
+ var FOUNDRY_ENDPOINT = "FOUNDRY_ENDPOINT";
33
+ var FOUNDRY_MODELS = "FOUNDRY_MODELS";
34
+ var FOUNDRY_LIMITS = "HARNESS_FOUNDRY_LIMITS";
35
+ var LimitsSchema = strictObject({
36
+ contextTokens: number().int().positive(),
37
+ maxOutputTokens: number().int().positive()
38
+ }).refine((limits) => limits.maxOutputTokens < limits.contextTokens);
39
+ var ListedSchema = object({
40
+ data: array(looseObject({ id: string() }))
41
+ });
42
+ function foundryLimits(value) {
43
+ if (!value)
44
+ return {};
45
+ try {
46
+ const parsed = record(string(), LimitsSchema).safeParse(JSON.parse(value));
47
+ return parsed.success ? parsed.data : {};
48
+ } catch {
49
+ return {};
50
+ }
51
+ }
52
+ var AZURE_HOST = /^[a-z0-9][a-z0-9-]{0,62}\.(openai\.azure\.com|services\.ai\.azure\.com)$/;
53
+ function foundryEndpoint(value) {
54
+ const url = URL.parse(value.trim());
55
+ if (url?.protocol !== "https:" || url.username || url.password || url.search || url.hash)
56
+ return;
57
+ const path = url.pathname.replace(/\/+$/, "");
58
+ if (!AZURE_HOST.test(url.hostname))
59
+ return `${url.origin}${path}`;
60
+ if (url.port || !["", "/openai", "/openai/v1"].includes(path))
61
+ return;
62
+ return `https://${url.hostname}/openai/v1`;
63
+ }
64
+ function foundryDeployments(value) {
65
+ return (value ?? "").split(",").map((entry) => entry.trim()).filter(Boolean).flatMap((entry) => {
66
+ const [name, model = name] = entry.split("=").map((part) => part.trim());
67
+ return name && model ? [{ name, model }] : [];
68
+ });
69
+ }
70
+ var PROVIDERS = Object.freeze(Object.keys(PROVIDER_KEYS));
71
+ function isLoopback(host) {
72
+ return ["127.0.0.1", "::1", "[::1]"].includes(host);
73
+ }
74
+ function providerFixture(environment) {
75
+ const origin = environment.HARNESS_PROVIDER_FIXTURE?.trim();
76
+ if (!origin)
77
+ return;
78
+ const fixture = URL.parse(origin);
79
+ if (fixture?.protocol !== "http:" || !isLoopback(fixture.hostname))
80
+ throw new Error("HARNESS_PROVIDER_FIXTURE must be a loopback http origin.");
81
+ return (input, init) => {
82
+ const called = new URL(input instanceof Request ? input.url : input);
83
+ return fetch(new URL(`${called.pathname}${called.search}`, fixture), init);
84
+ };
85
+ }
86
+
87
+ // packages/contract/src/common.ts
88
+ var CONTRACT_VERSION = "1.0.0";
89
+ var SEAM_VERSION = {
90
+ oracle: "1.0.0",
91
+ ranges: "1.0.0",
92
+ model: "1.0.0"
93
+ };
94
+ var IdentifierSchema = string().min(1);
95
+ var PositiveIntegerSchema = number().int().positive().max(2147483647);
96
+ var InvestigationModeSchema = _enum(["pentest", "codereview"]);
97
+ var RunModeSchema = _enum([
98
+ ...InvestigationModeSchema.options,
99
+ "chat"
100
+ ]);
101
+ var ProductCapabilitySchema = _enum([
102
+ "code",
103
+ "pull_requests",
104
+ "agentic_pentesting",
105
+ "secrets",
106
+ "supply_chain",
107
+ "dependency_firewall"
108
+ ]);
109
+ var ChangeContextSchema = strictObject({
110
+ repository: IdentifierSchema,
111
+ baseRevision: IdentifierSchema,
112
+ headRevision: IdentifierSchema,
113
+ pullRequestId: IdentifierSchema.optional()
114
+ });
115
+ var ContractContextSchema = strictObject({
116
+ contractVersion: literal(CONTRACT_VERSION)
117
+ });
118
+ var ContractVersionErrorSchema = strictObject({
119
+ code: literal("contract_version_mismatch"),
120
+ expected: literal(CONTRACT_VERSION),
121
+ received: string().nullable(),
122
+ message: string()
123
+ });
124
+ var RunConfigSchema = strictObject({
125
+ contractVersion: literal(CONTRACT_VERSION),
126
+ model: IdentifierSchema.optional(),
127
+ capabilities: array(ProductCapabilitySchema).min(1).optional(),
128
+ change: ChangeContextSchema.optional(),
129
+ continues: uuid().optional(),
130
+ targetKind: _enum(["repo", "web"]).optional(),
131
+ scope: array(IdentifierSchema).min(1).optional()
132
+ }).superRefine((config, context) => {
133
+ if (config.capabilities && new Set(config.capabilities).size !== config.capabilities.length)
134
+ context.addIssue({
135
+ code: "custom",
136
+ message: "Capabilities must be unique."
137
+ });
138
+ if (config.capabilities?.includes("pull_requests") && !config.change)
139
+ context.addIssue({
140
+ code: "custom",
141
+ message: "PR capability requires pinned change context."
142
+ });
143
+ });
144
+ var RunStartSchema = strictObject({
145
+ target: string(),
146
+ config: RunConfigSchema
147
+ });
148
+ var BudgetSchema = strictObject({
149
+ tokens: number().int().nonnegative(),
150
+ wallSec: number().finite().nonnegative(),
151
+ usd: number().finite().nonnegative().optional()
152
+ });
153
+ var CapsSchema = strictObject({
154
+ tokens: PositiveIntegerSchema
155
+ });
156
+ var TerminalSchema = strictObject({
157
+ outcome: _enum(["completed", "stopped", "failed", "incomplete"]),
158
+ cleanupOk: boolean(),
159
+ reportPath: string().optional()
160
+ });
161
+ var MAX_STEER_MESSAGE = 32768;
162
+ var MAX_LABEL = 128;
163
+ var MAX_PREVIEW_LINES = 20;
164
+ var MAX_PREVIEW_LINE = 200;
165
+ var IMAGE_MEDIA_TYPES = ["image/png", "image/jpeg"];
166
+ var ImageRefSchema = strictObject({
167
+ ref: string().regex(/^sha256:[0-9a-f]{64}$/),
168
+ mediaType: _enum(IMAGE_MEDIA_TYPES),
169
+ label: string().regex(/^\[Image #[1-9][0-9]*\]$/)
170
+ });
171
+ var ImageRefsSchema = array(ImageRefSchema).min(1);
172
+ var AgentControlSchema = discriminatedUnion("type", [
173
+ strictObject({
174
+ contractVersion: literal(CONTRACT_VERSION),
175
+ type: literal("stop")
176
+ }),
177
+ strictObject({
178
+ contractVersion: literal(CONTRACT_VERSION),
179
+ type: literal("interrupt")
180
+ }),
181
+ strictObject({
182
+ contractVersion: literal(CONTRACT_VERSION),
183
+ type: literal("steer"),
184
+ message: string().min(1).max(MAX_STEER_MESSAGE),
185
+ images: ImageRefsSchema.optional()
186
+ }),
187
+ strictObject({
188
+ contractVersion: literal(CONTRACT_VERSION),
189
+ type: literal("pause")
190
+ }),
191
+ strictObject({
192
+ contractVersion: literal(CONTRACT_VERSION),
193
+ type: literal("resume")
194
+ }),
195
+ strictObject({
196
+ contractVersion: literal(CONTRACT_VERSION),
197
+ type: literal("approve"),
198
+ approvalId: IdentifierSchema,
199
+ decision: _enum(["allow", "deny"])
200
+ }),
201
+ strictObject({
202
+ contractVersion: literal(CONTRACT_VERSION),
203
+ type: literal("review"),
204
+ reviewRequestId: IdentifierSchema,
205
+ findingId: IdentifierSchema,
206
+ decision: _enum(["confirm", "reject"]),
207
+ reason: IdentifierSchema,
208
+ evidenceRev: IdentifierSchema
209
+ })
210
+ ]);
211
+
212
+ // packages/contract/src/api.ts
213
+ var MOST_IMAGE_BYTES = 10485760;
214
+ var ImageUploadSchema = strictObject({
215
+ contractVersion: literal(CONTRACT_VERSION),
216
+ ref: ImageRefSchema.shape.ref
217
+ });
218
+ var ModelCatalogSchema = strictObject({
219
+ contractVersion: literal(CONTRACT_VERSION),
220
+ defaultModel: string().min(1).nullable(),
221
+ models: array(strictObject({
222
+ id: string().min(1),
223
+ provider: string().min(1),
224
+ maxOutputTokens: number().int().positive(),
225
+ contextTokens: number().int().positive(),
226
+ vision: boolean()
227
+ }))
228
+ });
229
+ var MAX_RUN_PAGE = 100;
230
+ var RunPageSchema = strictObject({
231
+ contractVersion: literal(CONTRACT_VERSION),
232
+ items: array(strictObject({
233
+ runId: uuid(),
234
+ target: string(),
235
+ startedAt: exports_iso.datetime(),
236
+ seq: number().int().nonnegative(),
237
+ state: _enum([
238
+ "unfinished",
239
+ "completed",
240
+ "stopped",
241
+ "failed",
242
+ "incomplete"
243
+ ])
244
+ })).max(MAX_RUN_PAGE),
245
+ nextCursor: uuid().nullable()
246
+ });
247
+ // packages/contract/src/clients.ts
248
+ var EngineIdentitySchema = strictObject({
249
+ protocol: literal("mettle/1"),
250
+ engineId: uuid(),
251
+ instanceId: uuid()
252
+ });
253
+ var EngineConnectionSchema = strictObject({
254
+ version: literal(1),
255
+ engineId: uuid(),
256
+ origin: url(),
257
+ tokenFile: string().min(1),
258
+ launch: RunStartSchema
259
+ });
260
+ // packages/contract/src/findings.ts
261
+ var text = string().min(1);
262
+ var timestamp = exports_iso.datetime();
263
+ var change = strictObject({
264
+ repository: text,
265
+ baseRevision: text,
266
+ headRevision: text,
267
+ pullRequestId: text.optional()
268
+ });
269
+ var policy = strictObject({ id: text, revision: text });
270
+ var packageIdentity = strictObject({
271
+ ecosystem: text,
272
+ name: text,
273
+ version: text,
274
+ registry: text,
275
+ artifactDigest: text.optional()
276
+ });
277
+ var EvidenceToolCallSchema = strictObject({
278
+ callId: text,
279
+ tool: text,
280
+ artifactRef: text
281
+ });
282
+ var claims = _enum([
283
+ "vulnerability",
284
+ "weak_cryptography",
285
+ "configuration_violation",
286
+ "secret_exposure",
287
+ "credential_validity",
288
+ "advisory_match",
289
+ "dependency_reachability",
290
+ "dependency_exploitability",
291
+ "malicious_package"
292
+ ]);
293
+ var methods = _enum([
294
+ "flag",
295
+ "witness",
296
+ "replay",
297
+ "credential_check",
298
+ "advisory_match",
299
+ "reachability",
300
+ "package_analysis",
301
+ "policy_check",
302
+ "human_review"
303
+ ]);
304
+ var VerificationReceiptSchema = strictObject({
305
+ receiptId: text,
306
+ runId: text,
307
+ findingId: text,
308
+ candidateRevision: text,
309
+ subjectDigest: text,
310
+ evidenceRev: text,
311
+ claim: claims,
312
+ policy,
313
+ authority: strictObject({
314
+ kind: _enum(["gyms_oracle", "independent_check", "human"]),
315
+ id: text
316
+ }),
317
+ checkedAt: timestamp,
318
+ expiresAt: timestamp.optional()
319
+ });
320
+ var ReviewSchema = strictObject({
321
+ reviewer: text,
322
+ reason: text,
323
+ at: timestamp,
324
+ evidenceRev: text,
325
+ decision: _enum(["confirm", "reject"])
326
+ });
327
+ var automaticMethods = {
328
+ vulnerability: ["flag", "witness", "replay"],
329
+ weak_cryptography: ["policy_check"],
330
+ configuration_violation: ["policy_check"],
331
+ secret_exposure: ["policy_check"],
332
+ credential_validity: ["credential_check"],
333
+ advisory_match: ["advisory_match"],
334
+ dependency_reachability: ["reachability"],
335
+ dependency_exploitability: ["witness", "replay"],
336
+ malicious_package: ["package_analysis"]
337
+ };
338
+ var VerificationSchema = strictObject({
339
+ result: _enum(["pending", "pass", "fail", "needs_human"]),
340
+ method: methods.optional(),
341
+ artifactRef: text.optional(),
342
+ receipt: VerificationReceiptSchema.optional(),
343
+ review: ReviewSchema.optional()
344
+ }).superRefine((checked, context) => {
345
+ const reject = (message) => {
346
+ context.addIssue({ code: "custom", message });
347
+ };
348
+ const receipt = checked.receipt;
349
+ if (!receipt || !checked.method)
350
+ return;
351
+ if (checked.result !== "pass" && checked.result !== "fail")
352
+ return;
353
+ if (receipt.expiresAt && Date.parse(receipt.expiresAt) <= Date.parse(receipt.checkedAt))
354
+ reject("Receipt expiry must follow the check.");
355
+ if (receipt.authority.kind === "human") {
356
+ if (!checked.review || !["replay", "human_review"].includes(checked.method))
357
+ reject("Human adjudication requires an explicit review and method.");
358
+ if (checked.review && (checked.review.reviewer !== receipt.authority.id || checked.review.evidenceRev !== receipt.evidenceRev || checked.review.at !== receipt.checkedAt || checked.review.decision !== (checked.result === "pass" ? "confirm" : "reject")))
359
+ reject("Human review and receipt disagree.");
360
+ if (checked.method === "replay" && !["vulnerability", "dependency_exploitability"].includes(receipt.claim))
361
+ reject("Runtime replay cannot prove a different kind of claim.");
362
+ return;
363
+ }
364
+ if (checked.review || !automaticMethods[receipt.claim].includes(checked.method))
365
+ reject("This automatic method cannot establish the named claim.");
366
+ const expectedAuthority = [
367
+ "vulnerability",
368
+ "dependency_exploitability"
369
+ ].includes(receipt.claim) ? "gyms_oracle" : "independent_check";
370
+ if (receipt.authority.kind !== expectedAuthority)
371
+ reject("Claim requires its accepted independent authority.");
372
+ });
373
+ var DISCOVERY_RULE_IDS_MAX = 40;
374
+ var SeveritySchema = _enum(["critical", "high", "medium", "low"]);
375
+ var FindingStatusSchema = _enum([
376
+ "candidate",
377
+ "confirmed",
378
+ "discarded"
379
+ ]);
380
+ var common = {
381
+ contractVersion: literal(CONTRACT_VERSION),
382
+ id: text,
383
+ runId: text,
384
+ title: text,
385
+ severity: SeveritySchema,
386
+ cwe: text.optional(),
387
+ target: text,
388
+ location: text,
389
+ found_via: array(strictObject({
390
+ callId: text,
391
+ technique: _enum([
392
+ "source-inspection",
393
+ "saved-http-observation",
394
+ "live-http-observation",
395
+ "browser-observation",
396
+ "static-rule",
397
+ "secret-pattern",
398
+ "dependency-advisory",
399
+ "http-template",
400
+ "sqli-probe",
401
+ "active-http-rule",
402
+ "unknown"
403
+ ]),
404
+ version: string().min(1).max(128).optional(),
405
+ ruleIds: array(string().min(1).max(256)).max(DISCOVERY_RULE_IDS_MAX).optional()
406
+ })).min(1).max(64).optional(),
407
+ public_template_hit: boolean().nullable().optional(),
408
+ change: change.optional(),
409
+ evidence: strictObject({
410
+ revision: text,
411
+ toolCalls: array(EvidenceToolCallSchema),
412
+ detail: text
413
+ }),
414
+ poc: text.optional(),
415
+ chain: array(strictObject({
416
+ findingId: text.optional(),
417
+ summary: text,
418
+ capabilityGained: text.optional()
419
+ })).optional(),
420
+ status: FindingStatusSchema,
421
+ verification: VerificationSchema
422
+ };
423
+ var installSubject = strictObject({
424
+ kind: literal("install"),
425
+ requestId: text,
426
+ package: packageIdentity.extend({ artifactDigest: text }),
427
+ contextRef: text
428
+ });
429
+ var findingVariants = union([
430
+ strictObject({
431
+ ...common,
432
+ capability: _enum(["code", "pull_requests"]),
433
+ surface: literal("code"),
434
+ claim: _enum(["vulnerability", "weak_cryptography"]),
435
+ subject: strictObject({
436
+ kind: literal("source"),
437
+ repository: text,
438
+ revision: text,
439
+ path: text
440
+ })
441
+ }),
442
+ strictObject({
443
+ ...common,
444
+ capability: _enum(["code", "pull_requests"]),
445
+ surface: literal("configuration"),
446
+ claim: literal("configuration_violation"),
447
+ subject: strictObject({
448
+ kind: literal("configuration"),
449
+ revisionRef: text,
450
+ resourceRef: text,
451
+ ruleId: text
452
+ })
453
+ }),
454
+ strictObject({
455
+ ...common,
456
+ capability: literal("agentic_pentesting"),
457
+ surface: _enum(["web", "runtime"]),
458
+ claim: literal("vulnerability"),
459
+ endpoint: strictObject({
460
+ url: url().max(2048),
461
+ method: _enum([
462
+ "GET",
463
+ "HEAD",
464
+ "OPTIONS",
465
+ "POST",
466
+ "PUT",
467
+ "PATCH",
468
+ "DELETE"
469
+ ]),
470
+ parameter: string().regex(/^[a-zA-Z0-9_]{1,64}$/).optional()
471
+ }).optional(),
472
+ subject: strictObject({
473
+ kind: literal("runtime"),
474
+ targetRef: text,
475
+ buildIdentityRef: text
476
+ })
477
+ }),
478
+ strictObject({
479
+ ...common,
480
+ capability: literal("secrets"),
481
+ surface: _enum(["code", "ci", "web", "runtime"]),
482
+ claim: _enum(["secret_exposure", "credential_validity"]),
483
+ subject: strictObject({
484
+ kind: literal("secret"),
485
+ credentialRef: text,
486
+ locationRef: text,
487
+ provider: text.optional()
488
+ })
489
+ }),
490
+ strictObject({
491
+ ...common,
492
+ capability: literal("supply_chain"),
493
+ surface: literal("dependency"),
494
+ claim: _enum([
495
+ "advisory_match",
496
+ "dependency_reachability",
497
+ "dependency_exploitability",
498
+ "malicious_package"
499
+ ]),
500
+ subject: strictObject({
501
+ kind: literal("dependency"),
502
+ package: packageIdentity,
503
+ contextRef: text,
504
+ advisoryIds: array(text)
505
+ })
506
+ }),
507
+ strictObject({
508
+ ...common,
509
+ capability: literal("dependency_firewall"),
510
+ surface: literal("install"),
511
+ claim: literal("malicious_package"),
512
+ subject: installSubject
513
+ })
514
+ ]);
515
+ var FindingSchema = findingVariants.superRefine((finding, context) => {
516
+ const reject = (message) => {
517
+ context.addIssue({ code: "custom", message });
518
+ };
519
+ const checked = finding.verification;
520
+ if (finding.found_via === undefined !== (finding.public_template_hit === undefined))
521
+ reject("Discovery provenance fields must be recorded together.");
522
+ if (finding.found_via && (finding.found_via.length !== finding.evidence.toolCalls.length || new Set(finding.found_via.map((entry) => entry.callId)).size !== finding.found_via.length || finding.found_via.some((entry) => !finding.evidence.toolCalls.some((call) => call.callId === entry.callId))))
523
+ reject("Discovery provenance must bind the cited evidence calls.");
524
+ if (finding.capability === "pull_requests" && !finding.change)
525
+ reject("PR findings require pinned change context.");
526
+ if (finding.subject.kind === "source" && finding.change && (finding.subject.revision !== finding.change.headRevision || finding.subject.repository !== finding.change.repository))
527
+ reject("Source identity must match the pinned head.");
528
+ if (new Set(finding.evidence.toolCalls.map((call) => call.callId)).size !== finding.evidence.toolCalls.length)
529
+ reject("Evidence tool-call identities must be unique.");
530
+ if (checked.result === "pending" || checked.result === "needs_human") {
531
+ if (finding.status !== "candidate")
532
+ reject("An unverified finding cannot be terminal.");
533
+ if (checked.method || checked.receipt || checked.review || checked.result === "pending" && checked.artifactRef)
534
+ reject("An unverified candidate cannot supply a verification receipt.");
535
+ return;
536
+ }
537
+ if (finding.status !== (checked.result === "pass" ? "confirmed" : "discarded"))
538
+ reject("Finding status and verification result disagree.");
539
+ if (!checked.method || !checked.artifactRef || !checked.receipt || !finding.evidence.toolCalls.length) {
540
+ reject("Terminal findings require independent proof and grounded observations.");
541
+ return;
542
+ }
543
+ const receipt = checked.receipt;
544
+ if (receipt.runId !== finding.runId || receipt.findingId !== finding.id || receipt.claim !== finding.claim || receipt.evidenceRev !== finding.evidence.revision)
545
+ reject("Receipt does not bind the original candidate and evidence.");
546
+ if (["flag", "witness", "replay"].includes(checked.method) && !finding.poc)
547
+ reject("Runtime proof requires redacted replay instructions.");
548
+ });
549
+ var InstallDecisionSchema = strictObject({
550
+ contractVersion: literal(CONTRACT_VERSION),
551
+ id: text,
552
+ subject: installSubject,
553
+ policy,
554
+ decision: _enum(["allow", "block", "error"]),
555
+ basis: _enum(["known_malware", "policy", "heuristic", "unavailable"]),
556
+ effect: _enum(["released", "blocked", "unknown"]),
557
+ artifactRef: text,
558
+ at: timestamp
559
+ }).superRefine((decision, context) => {
560
+ if (decision.effect === "released" && decision.decision !== "allow")
561
+ context.addIssue({
562
+ code: "custom",
563
+ message: "A release requires an allow decision."
564
+ });
565
+ });
566
+
567
+ // packages/contract/src/core.ts
568
+ var PendingApprovalSchema = strictObject({
569
+ approvalId: IdentifierSchema,
570
+ action: IdentifierSchema,
571
+ permission: IdentifierSchema,
572
+ why: IdentifierSchema,
573
+ cleanup: IdentifierSchema,
574
+ detail: IdentifierSchema,
575
+ investigationId: string().min(1).optional()
576
+ });
577
+ var ApprovalDecisionSchema = _enum(["allow", "deny", "expired"]);
578
+ var ToolOutcomeSchema = _enum(["ok", "failed", "rejected"]);
579
+ var PendingReviewSchema = strictObject({
580
+ reviewRequestId: IdentifierSchema,
581
+ findingId: IdentifierSchema,
582
+ evidenceRev: IdentifierSchema
583
+ });
584
+ var envelope = {
585
+ contractVersion: literal(CONTRACT_VERSION),
586
+ runId: IdentifierSchema,
587
+ seq: number().int().nonnegative()
588
+ };
589
+ var InvestigationStageSchema = _enum([
590
+ "recon",
591
+ "hunt",
592
+ "triage",
593
+ "verify",
594
+ "report"
595
+ ]);
596
+ var FindingTallySchema = strictObject({
597
+ confirmed: number().int().nonnegative(),
598
+ needsHuman: number().int().nonnegative(),
599
+ discarded: number().int().nonnegative()
600
+ });
601
+ var target = {
602
+ target: IdentifierSchema,
603
+ mode: RunModeSchema,
604
+ capabilities: array(ProductCapabilitySchema),
605
+ caps: CapsSchema
606
+ };
607
+ function eventVariants(envelope) {
608
+ const base = {
609
+ ...envelope,
610
+ type: literal("investigation.progress"),
611
+ investigationId: string().min(1),
612
+ label: string().min(1).max(MAX_LABEL),
613
+ kind: InvestigationModeSchema
614
+ };
615
+ const progress = discriminatedUnion("phase", [
616
+ strictObject({ ...base, phase: literal("started") }),
617
+ strictObject({
618
+ ...base,
619
+ phase: literal("stage"),
620
+ stage: strictObject({
621
+ name: InvestigationStageSchema,
622
+ round: number().int().nonnegative(),
623
+ state: _enum(["started", "completed"])
624
+ })
625
+ }),
626
+ strictObject({
627
+ ...base,
628
+ phase: literal("action"),
629
+ action: strictObject({
630
+ label: string().min(1).max(MAX_LABEL),
631
+ args: string().max(512)
632
+ })
633
+ }),
634
+ strictObject({
635
+ ...base,
636
+ phase: literal("finding"),
637
+ finding: strictObject({
638
+ findingId: string().min(1),
639
+ severity: SeveritySchema,
640
+ title: string(),
641
+ status: FindingStatusSchema
642
+ })
643
+ }),
644
+ strictObject({
645
+ ...base,
646
+ phase: literal("finished"),
647
+ outcome: strictObject({
648
+ outcome: TerminalSchema.shape.outcome,
649
+ ...FindingTallySchema.shape,
650
+ elapsedSec: number().finite().nonnegative()
651
+ })
652
+ })
653
+ ]);
654
+ return [
655
+ strictObject({ ...envelope, type: literal("run.started"), ...target }),
656
+ strictObject({
657
+ ...envelope,
658
+ type: literal("run.snapshot"),
659
+ ...target,
660
+ spent: BudgetSchema,
661
+ findings: array(FindingSchema),
662
+ installDecisions: array(InstallDecisionSchema),
663
+ pendingApprovals: array(PendingApprovalSchema),
664
+ pendingReviews: array(PendingReviewSchema),
665
+ terminal: TerminalSchema.optional()
666
+ }),
667
+ strictObject({
668
+ ...envelope,
669
+ type: literal("step"),
670
+ stepId: IdentifierSchema,
671
+ summary: string()
672
+ }),
673
+ strictObject({
674
+ ...envelope,
675
+ type: literal("tool.call"),
676
+ callId: IdentifierSchema,
677
+ tool: IdentifierSchema,
678
+ label: string().min(1).max(MAX_LABEL),
679
+ quiet: boolean(),
680
+ argsSummary: string()
681
+ }),
682
+ strictObject({
683
+ ...envelope,
684
+ type: literal("tool.result"),
685
+ callId: IdentifierSchema,
686
+ outcome: ToolOutcomeSchema,
687
+ summary: string(),
688
+ preview: array(string().max(MAX_PREVIEW_LINE)).max(MAX_PREVIEW_LINES).optional(),
689
+ artifactRef: IdentifierSchema
690
+ }),
691
+ strictObject({
692
+ ...envelope,
693
+ type: literal("model.call"),
694
+ requestId: IdentifierSchema,
695
+ model: IdentifierSchema,
696
+ deadline: exports_iso.datetime()
697
+ }),
698
+ strictObject({
699
+ ...envelope,
700
+ type: literal("model.result"),
701
+ requestId: IdentifierSchema,
702
+ ok: boolean()
703
+ }),
704
+ strictObject({
705
+ ...envelope,
706
+ type: literal("coverage"),
707
+ surface: IdentifierSchema,
708
+ outcome: _enum(["checked", "cleared", "ruled_out"])
709
+ }),
710
+ strictObject({
711
+ ...envelope,
712
+ type: literal("dependency.decision"),
713
+ decision: InstallDecisionSchema
714
+ }),
715
+ strictObject({
716
+ ...envelope,
717
+ type: literal("finding.candidate"),
718
+ finding: FindingSchema
719
+ }),
720
+ strictObject({
721
+ ...envelope,
722
+ type: literal("finding.update"),
723
+ findingId: IdentifierSchema,
724
+ status: FindingStatusSchema,
725
+ verification: VerificationSchema
726
+ }),
727
+ strictObject({
728
+ ...envelope,
729
+ type: literal("budget"),
730
+ caps: CapsSchema,
731
+ spent: BudgetSchema
732
+ }),
733
+ strictObject({
734
+ ...envelope,
735
+ type: literal("approval.request"),
736
+ ...PendingApprovalSchema.shape
737
+ }),
738
+ strictObject({
739
+ ...envelope,
740
+ type: literal("approval.decision"),
741
+ approvalId: IdentifierSchema,
742
+ decision: ApprovalDecisionSchema,
743
+ decidedBy: IdentifierSchema
744
+ }),
745
+ strictObject({
746
+ ...envelope,
747
+ type: literal("review.request"),
748
+ ...PendingReviewSchema.shape
749
+ }),
750
+ strictObject({
751
+ ...envelope,
752
+ type: literal("run.finished"),
753
+ ...TerminalSchema.shape,
754
+ ...FindingTallySchema.shape
755
+ }),
756
+ strictObject({
757
+ ...envelope,
758
+ type: literal("operator.message"),
759
+ message: string().min(1).max(MAX_STEER_MESSAGE),
760
+ images: ImageRefsSchema.optional()
761
+ }),
762
+ strictObject({
763
+ ...envelope,
764
+ type: literal("operator.message.taken"),
765
+ messageSeq: number().int().positive()
766
+ }),
767
+ progress,
768
+ strictObject({ ...envelope, type: literal("turn.interrupted") }),
769
+ strictObject({
770
+ ...envelope,
771
+ type: literal("turn.finished"),
772
+ elapsedSec: number().finite().nonnegative(),
773
+ usd: number().finite().nonnegative().optional()
774
+ }),
775
+ strictObject({
776
+ ...envelope,
777
+ type: literal("recovery.needed"),
778
+ reason: IdentifierSchema
779
+ }),
780
+ strictObject({
781
+ ...envelope,
782
+ type: literal("error"),
783
+ message: string(),
784
+ fatal: boolean()
785
+ })
786
+ ];
787
+ }
788
+ var EventSchema = discriminatedUnion("type", eventVariants(envelope)).superRefine((event, context) => {
789
+ const reject = (message) => {
790
+ context.addIssue({ code: "custom", message });
791
+ };
792
+ const unique = (values) => {
793
+ if (new Set(values).size !== values.length)
794
+ reject("Duplicate event identities.");
795
+ };
796
+ if (event.type === "run.started" || event.type === "run.snapshot")
797
+ unique(event.capabilities);
798
+ if (event.type === "operator.message.taken" && event.messageSeq >= event.seq)
799
+ reject("A message is taken only after it was sent.");
800
+ if (event.type === "finding.candidate" && (event.finding.runId !== event.runId || event.finding.status !== "candidate" || event.finding.verification.result !== "pending"))
801
+ reject("A candidate event must introduce a pending candidate in this run.");
802
+ if (event.type === "finding.update") {
803
+ const checked = event.verification;
804
+ const status = checked.result === "pass" ? "confirmed" : checked.result === "fail" ? "discarded" : "candidate";
805
+ if (event.status !== status)
806
+ reject("Finding update status disagrees with verification.");
807
+ if (checked.result === "pending")
808
+ reject("A finding update must report a check outcome.");
809
+ if (status !== "candidate" && (!checked.method || !checked.artifactRef || !checked.receipt))
810
+ reject("Terminal updates require independent proof.");
811
+ if (status === "candidate" && (checked.method || checked.receipt || checked.review || checked.result === "pending" && checked.artifactRef))
812
+ reject("Pending updates cannot claim proof.");
813
+ if (checked.receipt && (checked.receipt.runId !== event.runId || checked.receipt.findingId !== event.findingId))
814
+ reject("Receipt identity differs from the update.");
815
+ }
816
+ if (event.type === "run.snapshot") {
817
+ unique(event.findings.map((finding) => finding.id));
818
+ unique(event.installDecisions.map((decision) => decision.id));
819
+ unique(event.pendingApprovals.map((approval) => approval.approvalId));
820
+ unique(event.pendingReviews.map((review) => review.reviewRequestId));
821
+ unique(event.pendingReviews.map((review) => review.findingId));
822
+ for (const finding of event.findings) {
823
+ if (finding.runId !== event.runId || !event.capabilities.includes(finding.capability))
824
+ reject("Snapshot finding is outside this run.");
825
+ }
826
+ for (const review of event.pendingReviews) {
827
+ const finding = event.findings.find((entry) => entry.id === review.findingId);
828
+ if (finding?.verification.result !== "needs_human" || finding.evidence.revision !== review.evidenceRev)
829
+ reject("Review does not bind an inconclusive finding and its evidence.");
830
+ }
831
+ }
832
+ });
833
+ // packages/contract/src/evidence.ts
834
+ var EVIDENCE_MAX_BYTES = 65536;
835
+ var INLINE_EVIDENCE_STORE_ID = "postgres-inline-v1";
836
+ var EVIDENCE_STATEMENT_TYPE = "https://in-toto.io/Statement/v1";
837
+ var EVIDENCE_PREDICATE_TYPE = "https://pazago.com/mettle/attestation/evidence/v1";
838
+ var EVIDENCE_PAYLOAD_TYPE = "application/vnd.in-toto+json";
839
+ var ArtifactRefSchema = string().regex(/^sha256:[a-f0-9]{64}$/);
840
+ var Hex64Schema = string().regex(/^[a-f0-9]{64}$/);
841
+ var Base64Schema = string().min(1).max(1048576).regex(/^[A-Za-z0-9+/]+={0,2}$/);
842
+ var ArtifactManifestSchema = strictObject({
843
+ contractVersion: literal(CONTRACT_VERSION),
844
+ runId: uuid(),
845
+ artifactRef: ArtifactRefSchema,
846
+ authorityDigest: Hex64Schema,
847
+ byteLength: number().int().nonnegative().max(EVIDENCE_MAX_BYTES),
848
+ capturePolicy: literal("structured-secrets-v1"),
849
+ redacted: literal(true),
850
+ storage: discriminatedUnion("kind", [
851
+ strictObject({
852
+ kind: literal("postgres"),
853
+ storeId: literal(INLINE_EVIDENCE_STORE_ID)
854
+ }),
855
+ strictObject({
856
+ kind: literal("local"),
857
+ storeId: string().min(1).max(256),
858
+ key: string().regex(/^[a-f0-9]{64}_[a-f0-9]{64}$/),
859
+ version: Hex64Schema
860
+ }),
861
+ strictObject({
862
+ kind: literal("s3"),
863
+ storeId: string().min(1).max(256),
864
+ key: string().regex(/^[a-f0-9]{64}_[a-f0-9]{64}$/),
865
+ version: string().min(1).max(1024).refine((value) => value !== "null")
866
+ })
867
+ ])
868
+ });
869
+ var EvidencePredicateSchema = strictObject({
870
+ runId: uuid(),
871
+ authorityDigest: Hex64Schema,
872
+ runtimeVersion: string().min(1).max(512),
873
+ capturedAt: exports_iso.datetime(),
874
+ tool: string().min(1).max(256).optional(),
875
+ callId: string().min(1).max(512).optional()
876
+ });
877
+ var EvidenceStatementSchema = strictObject({
878
+ _type: literal(EVIDENCE_STATEMENT_TYPE),
879
+ subject: tuple([
880
+ strictObject({
881
+ name: ArtifactRefSchema,
882
+ digest: strictObject({ sha256: Hex64Schema })
883
+ })
884
+ ]),
885
+ predicateType: literal(EVIDENCE_PREDICATE_TYPE),
886
+ predicate: EvidencePredicateSchema
887
+ });
888
+ var EvidenceEnvelopeSchema = strictObject({
889
+ payloadType: literal(EVIDENCE_PAYLOAD_TYPE),
890
+ payload: Base64Schema,
891
+ signatures: tuple([
892
+ strictObject({ keyid: Hex64Schema, sig: Base64Schema })
893
+ ])
894
+ });
895
+ var EvidenceSigningKeySchema = strictObject({
896
+ keyId: Hex64Schema,
897
+ algorithm: literal("ed25519"),
898
+ publicKey: string().regex(/^-----BEGIN PUBLIC KEY-----\n[A-Za-z0-9+/=\n]+-----END PUBLIC KEY-----\n?$/)
899
+ });
900
+ // packages/contract/src/gyms.ts
901
+ var TargetIdentitySchema = strictObject({
902
+ rangeId: IdentifierSchema,
903
+ instanceId: IdentifierSchema,
904
+ resetGeneration: IdentifierSchema,
905
+ taskRevision: IdentifierSchema,
906
+ targetRevision: IdentifierSchema
907
+ });
908
+ var VerificationIdentitySchema = TargetIdentitySchema.extend({
909
+ runId: IdentifierSchema,
910
+ attemptId: IdentifierSchema,
911
+ candidateId: IdentifierSchema,
912
+ candidateRevision: IdentifierSchema,
913
+ pocInputsDigest: IdentifierSchema,
914
+ predicateRevision: IdentifierSchema,
915
+ executionPathDigest: IdentifierSchema
916
+ });
917
+ var VerifyRequestSchema = strictObject({
918
+ seamVersion: literal(SEAM_VERSION.oracle),
919
+ identity: VerificationIdentitySchema,
920
+ mode: InvestigationModeSchema,
921
+ candidate: FindingSchema,
922
+ pocInputs: array(string()),
923
+ executionPathRef: IdentifierSchema
924
+ }).superRefine((request, context) => {
925
+ if (request.candidate.id !== request.identity.candidateId || request.candidate.runId !== request.identity.runId || request.candidate.status !== "candidate" || request.candidate.verification.result !== "pending") {
926
+ context.addIssue({
927
+ code: "custom",
928
+ message: "Verification requires a pending candidate with matching run and candidate identity."
929
+ });
930
+ }
931
+ });
932
+ var verdictEnvelope = {
933
+ seamVersion: literal(SEAM_VERSION.oracle),
934
+ identity: VerificationIdentitySchema
935
+ };
936
+ var VerifyVerdictSchema = union([
937
+ strictObject({
938
+ ...verdictEnvelope,
939
+ result: _enum(["pass", "fail"]),
940
+ method: _enum(["flag", "witness", "replay"]),
941
+ artifactRef: IdentifierSchema,
942
+ receipt: VerificationReceiptSchema,
943
+ detail: string().optional()
944
+ }),
945
+ strictObject({
946
+ ...verdictEnvelope,
947
+ result: literal("needs_human"),
948
+ reason: _enum(["unsupported", "insufficient_evidence", "human_replay"]),
949
+ artifactRef: IdentifierSchema.optional(),
950
+ detail: string()
951
+ })
952
+ ]).superRefine((verdict, context) => {
953
+ if (verdict.result === "needs_human")
954
+ return;
955
+ const receipt = verdict.receipt;
956
+ if (receipt.authority.kind !== "gyms_oracle" || !["vulnerability", "dependency_exploitability"].includes(receipt.claim) || receipt.claim === "dependency_exploitability" && verdict.method === "flag" || receipt.runId !== verdict.identity.runId || receipt.findingId !== verdict.identity.candidateId || receipt.candidateRevision !== verdict.identity.candidateRevision || receipt.policy.revision !== verdict.identity.predicateRevision) {
957
+ context.addIssue({
958
+ code: "custom",
959
+ message: "Oracle receipt does not bind a supported runtime claim and predicate."
960
+ });
961
+ }
962
+ });
963
+ var OracleErrorSchema = strictObject({
964
+ code: _enum([
965
+ "engine_failure",
966
+ "timeout",
967
+ "version_mismatch",
968
+ "unavailable",
969
+ "invalid_request",
970
+ "identity_mismatch",
971
+ "attempt_conflict",
972
+ "in_progress",
973
+ "uncertain_execution"
974
+ ]),
975
+ message: string()
976
+ });
977
+ var RangeEligibilitySchema = discriminatedUnion("eligible", [
978
+ strictObject({
979
+ eligible: literal(true),
980
+ identity: TargetIdentitySchema,
981
+ endpoint: IdentifierSchema,
982
+ expiresAt: exports_iso.datetime({ offset: true })
983
+ }),
984
+ strictObject({ eligible: literal(false), reason: IdentifierSchema })
985
+ ]);
986
+ // packages/contract/src/investigations.ts
987
+ var WorkflowKindSchema = _enum([
988
+ "repository-review",
989
+ "pr-review",
990
+ "pentest"
991
+ ]);
992
+ var WorkflowBindingSchema = strictObject({
993
+ id: string().regex(/^[a-zA-Z0-9_-]{1,128}$/),
994
+ revision: number().int().positive(),
995
+ digest: Hex64Schema
996
+ });
997
+ var WebsiteEngagementSchema = strictObject({
998
+ target: url().max(2048),
999
+ model: string().min(1).max(128),
1000
+ authorization: literal(true),
1001
+ policy: literal("website-live-v1"),
1002
+ scope: array(url().max(2048)).max(7).optional(),
1003
+ browser: boolean().optional()
1004
+ });
1005
+ var InvestigationUrlSchema = strictObject({
1006
+ target: string().min(1).max(2048),
1007
+ model: string().min(1).max(128)
1008
+ });
1009
+ var InvestigationPrepareSchema = strictObject({
1010
+ workflow: WorkflowBindingSchema.optional(),
1011
+ profileId: string().regex(/^[a-zA-Z0-9_-]{1,128}$/),
1012
+ target: string().min(1).max(2048),
1013
+ model: string().min(1).max(256)
1014
+ });
1015
+ var WorkflowDefinitionSchema = strictObject({
1016
+ kind: WorkflowKindSchema,
1017
+ label: string().min(1).max(128),
1018
+ profileId: InvestigationPrepareSchema.shape.profileId,
1019
+ model: InvestigationPrepareSchema.shape.model
1020
+ });
1021
+ var WorkflowRevisionSchema = WorkflowBindingSchema.extend({
1022
+ definition: WorkflowDefinitionSchema
1023
+ });
1024
+ var WorkflowSaveSchema = strictObject({
1025
+ expectedRevision: number().int().nonnegative(),
1026
+ definition: WorkflowDefinitionSchema
1027
+ });
1028
+ var WorkflowPrepareSchema = strictObject({
1029
+ workflow: WorkflowBindingSchema,
1030
+ target: string().min(1).max(2048)
1031
+ });
1032
+ var PreparationStateSchema = _enum([
1033
+ "pending",
1034
+ "preparing",
1035
+ "ready",
1036
+ "failed",
1037
+ "started"
1038
+ ]);
1039
+ var PreparationViewSchema = InvestigationPrepareSchema.extend({
1040
+ preparationId: uuid(),
1041
+ state: PreparationStateSchema,
1042
+ expiresAt: exports_iso.datetime(),
1043
+ grantDigest: string().regex(/^[a-f0-9]{64}$/).optional(),
1044
+ runId: uuid().optional(),
1045
+ coverage: array(string()),
1046
+ source: strictObject({
1047
+ revision: string().min(1),
1048
+ files: number().int().nonnegative(),
1049
+ excluded: number().int().nonnegative()
1050
+ }).optional(),
1051
+ error: string().optional(),
1052
+ cleanupError: string().optional()
1053
+ });
1054
+ var InvestigationStartSchema = strictObject({
1055
+ preparationId: uuid(),
1056
+ grantDigest: string().regex(/^[a-f0-9]{64}$/)
1057
+ });
1058
+ var InvestigationRunIdSchema = strictObject({ runId: uuid() });
1059
+ var InvestigationModelSchema = strictObject({
1060
+ id: string().min(1).max(256),
1061
+ provider: string().min(1).max(256)
1062
+ });
1063
+ var execution = {
1064
+ runtime: _enum(["runc", "mettle-runsc", "host-read"]),
1065
+ location: _enum(["local", "vm", "backend-host"]),
1066
+ engineId: string().nullable(),
1067
+ image: string().nullable()
1068
+ };
1069
+ var InvestigationCapabilitiesSchema = strictObject({
1070
+ profiles: array(strictObject({
1071
+ id: InvestigationPrepareSchema.shape.profileId,
1072
+ mode: _enum(["codereview", "pentest"]),
1073
+ ...execution,
1074
+ targets: array(string()),
1075
+ models: array(InvestigationModelSchema),
1076
+ expiresAt: exports_iso.datetime()
1077
+ }))
1078
+ });
1079
+ var InvestigationLaunchResultSchema = InvestigationRunIdSchema.extend({
1080
+ created: boolean().optional(),
1081
+ recovered: boolean().optional()
1082
+ });
1083
+ var InvestigationProgressSchema = InvestigationRunIdSchema.extend({
1084
+ target: string(),
1085
+ model: string().optional(),
1086
+ terminal: TerminalSchema.nullable(),
1087
+ stopRequested: boolean(),
1088
+ stages: array(strictObject({ stage: string(), committed: literal(true) })),
1089
+ actions: array(strictObject({
1090
+ tool: string(),
1091
+ state: _enum(["prepared", "dispatched", "completed", "failed"]),
1092
+ callId: string()
1093
+ })).max(30),
1094
+ spent: BudgetSchema,
1095
+ reservations: array(strictObject({
1096
+ requestId: string(),
1097
+ state: _enum(["reserved", "completed", "failed"]),
1098
+ tokens: number().int().nonnegative(),
1099
+ nanousd: string().regex(/^\d+$/).nullable()
1100
+ })),
1101
+ pendingApprovals: array(strictObject({
1102
+ id: string(),
1103
+ action: string(),
1104
+ permission: string(),
1105
+ expiresAt: exports_iso.datetime()
1106
+ })),
1107
+ execution: strictObject({
1108
+ workflow: WorkflowBindingSchema.optional(),
1109
+ profileId: InvestigationPrepareSchema.shape.profileId,
1110
+ ...execution
1111
+ }),
1112
+ coverage: array(string()),
1113
+ recovery: _enum([
1114
+ "approval_required",
1115
+ "running",
1116
+ "reconciliation_required",
1117
+ "finished",
1118
+ "recoverable_after_lease_expiry"
1119
+ ])
1120
+ });
1121
+
1122
+ // packages/contract/src/http.ts
1123
+ var wireRecord = looseObject({
1124
+ contractVersion: never().optional()
1125
+ });
1126
+ var record2 = record(string(), unknown());
1127
+
1128
+ class HttpProtocol {
1129
+ path = "/v1";
1130
+ readRecord(value) {
1131
+ return { ...wireRecord.parse(value), contractVersion: CONTRACT_VERSION };
1132
+ }
1133
+ writeRecord(value) {
1134
+ const { contractVersion, ...fields } = value;
1135
+ return fields;
1136
+ }
1137
+ start(value) {
1138
+ return { ...value, config: this.writeRecord(value.config) };
1139
+ }
1140
+ readStart(value) {
1141
+ const input = record2.parse(value);
1142
+ return RunStartSchema.parse({
1143
+ ...input,
1144
+ config: this.readRecord(input.config)
1145
+ });
1146
+ }
1147
+ readControl(value) {
1148
+ return AgentControlSchema.parse(this.readRecord(value));
1149
+ }
1150
+ readContext(value) {
1151
+ return ContractContextSchema.parse(this.readRecord(value));
1152
+ }
1153
+ event(event) {
1154
+ return this.writeRecord({
1155
+ ...event,
1156
+ ...event.type === "finding.candidate" ? { finding: this.writeRecord(event.finding) } : event.type === "dependency.decision" ? { decision: this.writeRecord(event.decision) } : event.type === "run.snapshot" ? {
1157
+ findings: event.findings.map((entry) => this.writeRecord(entry)),
1158
+ installDecisions: event.installDecisions.map((entry) => this.writeRecord(entry))
1159
+ } : {}
1160
+ });
1161
+ }
1162
+ readEvent(value) {
1163
+ try {
1164
+ const event = this.readRecord(value);
1165
+ if (event.type === "finding.candidate")
1166
+ event.finding = this.readRecord(event.finding);
1167
+ if (event.type === "dependency.decision")
1168
+ event.decision = this.readRecord(event.decision);
1169
+ if (event.type === "run.snapshot") {
1170
+ event.findings = array(unknown()).parse(event.findings).map((entry) => this.readRecord(entry));
1171
+ event.installDecisions = array(unknown()).parse(event.installDecisions).map((entry) => this.readRecord(entry));
1172
+ }
1173
+ return EventSchema.parse(event);
1174
+ } catch (error) {
1175
+ if (error instanceof ZodError)
1176
+ throw new Error(error.issues[0].message);
1177
+ throw error;
1178
+ }
1179
+ }
1180
+ capabilities(value) {
1181
+ return InvestigationCapabilitiesSchema.parse(value);
1182
+ }
1183
+ preparation(value) {
1184
+ return PreparationViewSchema.parse(value);
1185
+ }
1186
+ investigationLaunch(value) {
1187
+ return InvestigationLaunchResultSchema.parse(value);
1188
+ }
1189
+ investigationProgress(value) {
1190
+ return InvestigationProgressSchema.parse(value);
1191
+ }
1192
+ catalog(value) {
1193
+ return this.writeRecord(value);
1194
+ }
1195
+ readCatalog(value) {
1196
+ return ModelCatalogSchema.parse(this.readRecord(value));
1197
+ }
1198
+ imageUpload(value) {
1199
+ return this.writeRecord(value);
1200
+ }
1201
+ readImageUpload(value) {
1202
+ return ImageUploadSchema.parse(this.readRecord(value));
1203
+ }
1204
+ page(value) {
1205
+ return this.writeRecord(value);
1206
+ }
1207
+ manifest(value) {
1208
+ return this.writeRecord(value);
1209
+ }
1210
+ report(report) {
1211
+ return this.writeRecord({
1212
+ ...report,
1213
+ findings: report.findings.map((entry) => this.writeRecord(entry)),
1214
+ installDecisions: report.installDecisions.map((entry) => this.writeRecord(entry))
1215
+ });
1216
+ }
1217
+ }
1218
+ var tuiProtocol = new HttpProtocol;
1219
+ // packages/contract/src/model.ts
1220
+ var JsonValueSchema = lazy(() => union([
1221
+ _null(),
1222
+ boolean(),
1223
+ number().finite(),
1224
+ string(),
1225
+ array(JsonValueSchema),
1226
+ record(string(), JsonValueSchema)
1227
+ ]));
1228
+ var JsonObjectSchema = record(string(), JsonValueSchema);
1229
+ var ModelContinuationSchema = strictObject({
1230
+ provider: string().min(1),
1231
+ items: array(JsonObjectSchema).max(128)
1232
+ });
1233
+ var ModelUsageSchema = strictObject({
1234
+ inputTokens: number().int().nonnegative(),
1235
+ outputTokens: number().int().nonnegative(),
1236
+ costNanousd: number().int().nonnegative().max(Number.MAX_SAFE_INTEGER).optional()
1237
+ });
1238
+ var ModelToolCallSchema = strictObject({
1239
+ callId: IdentifierSchema,
1240
+ name: IdentifierSchema,
1241
+ arguments: JsonObjectSchema
1242
+ });
1243
+ var ModelMessageSchema = union([
1244
+ strictObject({ role: literal("system"), content: string() }),
1245
+ strictObject({
1246
+ role: literal("user"),
1247
+ content: string(),
1248
+ images: ImageRefsSchema.optional()
1249
+ }),
1250
+ strictObject({
1251
+ role: literal("assistant"),
1252
+ content: string(),
1253
+ toolCalls: array(ModelToolCallSchema).optional(),
1254
+ continuation: ModelContinuationSchema.optional()
1255
+ }),
1256
+ strictObject({
1257
+ role: literal("tool"),
1258
+ callId: IdentifierSchema,
1259
+ content: string(),
1260
+ isError: boolean()
1261
+ })
1262
+ ]);
1263
+ var ModelToolSchema = strictObject({
1264
+ name: IdentifierSchema,
1265
+ description: string(),
1266
+ inputSchema: JsonObjectSchema
1267
+ });
1268
+ var ModelRequestSchema = strictObject({
1269
+ seamVersion: literal(SEAM_VERSION.model),
1270
+ requestId: IdentifierSchema,
1271
+ model: IdentifierSchema,
1272
+ messages: array(ModelMessageSchema).min(1),
1273
+ tools: array(ModelToolSchema),
1274
+ toolChoice: _enum(["auto", "none"]).optional(),
1275
+ maxOutputTokens: PositiveIntegerSchema,
1276
+ sampling: strictObject({
1277
+ temperature: number().finite().optional(),
1278
+ seed: number().int().optional()
1279
+ }).optional()
1280
+ }).superRefine((request, context) => {
1281
+ const reject = (message) => {
1282
+ context.addIssue({ code: "custom", message });
1283
+ };
1284
+ const names = new Set(request.tools.map((tool) => tool.name));
1285
+ if (names.size !== request.tools.length)
1286
+ reject("Tool names must be unique.");
1287
+ const seen = new Set;
1288
+ const pending = new Set;
1289
+ for (const message of request.messages) {
1290
+ if (message.role !== "tool" && pending.size)
1291
+ reject("Tool results must resolve preceding calls before another message.");
1292
+ if (message.role === "assistant") {
1293
+ for (const call of message.toolCalls ?? []) {
1294
+ if (seen.has(call.callId) || !names.has(call.name))
1295
+ reject("Duplicate call identity or unregistered tool.");
1296
+ seen.add(call.callId);
1297
+ pending.add(call.callId);
1298
+ }
1299
+ } else if (message.role === "tool" && !pending.delete(message.callId))
1300
+ reject("Tool result has no unique preceding call.");
1301
+ }
1302
+ if (pending.size)
1303
+ reject("Unresolved tool calls cannot be submitted for inference.");
1304
+ });
1305
+ var ModelResponseSchema = strictObject({
1306
+ requestId: IdentifierSchema,
1307
+ model: IdentifierSchema,
1308
+ content: string(),
1309
+ toolCalls: array(ModelToolCallSchema),
1310
+ finishReason: _enum(["stop", "tool_calls", "length", "refusal"]),
1311
+ usage: ModelUsageSchema,
1312
+ continuation: ModelContinuationSchema.optional()
1313
+ }).superRefine((response, context) => {
1314
+ if (new Set(response.toolCalls.map((call) => call.callId)).size !== response.toolCalls.length)
1315
+ context.addIssue({
1316
+ code: "custom",
1317
+ message: "Tool-call identities must be unique."
1318
+ });
1319
+ if (response.finishReason === "tool_calls" !== response.toolCalls.length > 0)
1320
+ context.addIssue({
1321
+ code: "custom",
1322
+ message: "Only a finalized tool-call response may expose executable calls."
1323
+ });
1324
+ });
1325
+ var ModelStreamEventSchema = discriminatedUnion("type", [
1326
+ strictObject({
1327
+ type: literal("text.delta"),
1328
+ requestId: IdentifierSchema,
1329
+ text: string()
1330
+ }),
1331
+ strictObject({
1332
+ type: literal("tool_call.delta"),
1333
+ requestId: IdentifierSchema,
1334
+ callId: IdentifierSchema,
1335
+ name: IdentifierSchema.optional(),
1336
+ argumentsDelta: string()
1337
+ }),
1338
+ strictObject({
1339
+ type: literal("usage"),
1340
+ requestId: IdentifierSchema,
1341
+ usage: ModelUsageSchema
1342
+ }),
1343
+ strictObject({
1344
+ type: literal("completed"),
1345
+ requestId: IdentifierSchema,
1346
+ response: ModelResponseSchema
1347
+ })
1348
+ ]).superRefine((event, context) => {
1349
+ if (event.type === "completed" && event.response.requestId !== event.requestId)
1350
+ context.addIssue({
1351
+ code: "custom",
1352
+ message: "Completed response identity differs from its envelope."
1353
+ });
1354
+ });
1355
+ var ModelErrorSchema = strictObject({
1356
+ code: _enum([
1357
+ "version_mismatch",
1358
+ "invalid_request",
1359
+ "unsupported",
1360
+ "timeout",
1361
+ "aborted",
1362
+ "provider_failure",
1363
+ "unavailable",
1364
+ "incomplete_stream"
1365
+ ]),
1366
+ requestId: IdentifierSchema,
1367
+ message: string()
1368
+ });
1369
+ // packages/contract/src/patches.ts
1370
+ var PatchEditSchema = strictObject({
1371
+ path: string().min(1).max(512),
1372
+ beforeSha256: Hex64Schema,
1373
+ afterSha256: Hex64Schema,
1374
+ content: string().max(8192)
1375
+ });
1376
+ var PatchProposalSchema = strictObject({
1377
+ proposalId: string().min(1).max(256),
1378
+ repository: string(),
1379
+ revision: string(),
1380
+ status: literal("unverified-proposal"),
1381
+ findingId: string().min(1).optional(),
1382
+ unifiedDiff: string().max(131072).optional(),
1383
+ diffSha256: Hex64Schema.optional(),
1384
+ edits: array(PatchEditSchema).min(1).max(4)
1385
+ });
1386
+ var TestRunResultSchema = strictObject({
1387
+ repository: string(),
1388
+ revision: string(),
1389
+ profileId: string(),
1390
+ patchProposalId: string().nullable(),
1391
+ verification: literal("not-independent"),
1392
+ status: _enum([
1393
+ "passed",
1394
+ "failed",
1395
+ "timed_out",
1396
+ "output_limit",
1397
+ "unavailable"
1398
+ ]),
1399
+ exitCode: number().int().nullable(),
1400
+ stdout: string(),
1401
+ stderr: string(),
1402
+ truncated: boolean()
1403
+ });
1404
+ var PatchRecommendationSchema = PatchProposalSchema.omit({
1405
+ edits: true,
1406
+ diffSha256: true
1407
+ }).extend({
1408
+ artifactRef: ArtifactRefSchema,
1409
+ applicability: _enum(["exact", "redacted", "legacy"]),
1410
+ validation: _enum(["not_run", "passed", "failed", "incomplete"]),
1411
+ files: array(PatchEditSchema.omit({ content: true })).min(1).max(4),
1412
+ tests: array(EvidenceToolCallSchema.extend({
1413
+ status: TestRunResultSchema.shape.status
1414
+ })).max(2000)
1415
+ });
1416
+ // packages/contract/src/report.ts
1417
+ var ReportFormatSchema = _enum(["json", "markdown", "sarif"]);
1418
+ var ReportSchema = strictObject({
1419
+ contractVersion: literal(CONTRACT_VERSION),
1420
+ reportVersion: _enum(["1.0.0", "1.1.0"]),
1421
+ patchRecommendations: array(PatchRecommendationSchema).max(500).optional(),
1422
+ generatedAt: exports_iso.datetime(),
1423
+ coverage: array(string().max(2048)).max(500).optional(),
1424
+ scope: _enum(["development-fixture", "assessment"]),
1425
+ runId: IdentifierSchema,
1426
+ seq: number().int().nonnegative(),
1427
+ target: IdentifierSchema,
1428
+ mode: InvestigationModeSchema,
1429
+ capabilities: array(ProductCapabilitySchema).min(1),
1430
+ caps: CapsSchema,
1431
+ spent: BudgetSchema,
1432
+ consumption: BudgetSchema.extend({
1433
+ steps: number().int().nonnegative()
1434
+ }).optional(),
1435
+ terminal: TerminalSchema,
1436
+ findings: array(FindingSchema).max(500),
1437
+ installDecisions: array(InstallDecisionSchema).max(500),
1438
+ pendingApprovals: array(PendingApprovalSchema).max(500),
1439
+ pendingReviews: array(PendingReviewSchema).max(500),
1440
+ observations: array(EvidenceToolCallSchema).max(2000),
1441
+ evidence: array(strictObject({
1442
+ artifactRef: ArtifactRefSchema,
1443
+ byteLength: number().int().nonnegative().max(1048576)
1444
+ })).max(2500)
1445
+ }).superRefine((report, context) => {
1446
+ const {
1447
+ reportVersion: _version,
1448
+ patchRecommendations: _patches,
1449
+ generatedAt: _generatedAt,
1450
+ scope: _scope,
1451
+ observations: _observations,
1452
+ evidence: _evidence,
1453
+ consumption: _consumption,
1454
+ coverage: _coverage,
1455
+ ...snapshot
1456
+ } = report;
1457
+ if (report.reportVersion === "1.0.0" && report.patchRecommendations !== undefined)
1458
+ context.addIssue({
1459
+ code: "custom",
1460
+ path: ["reportVersion"],
1461
+ message: "Patch recommendations require report version 1.1.0."
1462
+ });
1463
+ const result = EventSchema.safeParse({ ...snapshot, type: "run.snapshot" });
1464
+ if (!result.success)
1465
+ for (const issue of result.error.issues)
1466
+ context.addIssue({
1467
+ code: "custom",
1468
+ path: issue.path,
1469
+ message: issue.message
1470
+ });
1471
+ });
1472
+ // packages/foundation/src/errors.ts
1473
+ class HarnessError extends Error {
1474
+ code;
1475
+ constructor(code, message) {
1476
+ super(message);
1477
+ this.code = code;
1478
+ this.name = "HarnessError";
1479
+ }
1480
+ }
1481
+ function publicError(error) {
1482
+ if (error instanceof HarnessError)
1483
+ return `${error.code}: ${error.message}`;
1484
+ return "internal_failure: The operation failed; no further execution is authorized.";
1485
+ }
1486
+
1487
+ // packages/foundation/src/digest.ts
1488
+ import { createHash } from "node:crypto";
1489
+ function canonicalJson(value) {
1490
+ const ancestors = new WeakSet;
1491
+ function encode(entry) {
1492
+ if (entry === null || typeof entry === "boolean" || typeof entry === "string")
1493
+ return JSON.stringify(entry);
1494
+ if (typeof entry === "number" && Number.isFinite(entry))
1495
+ return JSON.stringify(entry);
1496
+ if (typeof entry === "object" && entry !== null && (Array.isArray(entry) || Object.getPrototypeOf(entry) === Object.prototype)) {
1497
+ if (ancestors.has(entry))
1498
+ throw new HarnessError("invalid_json", "Cyclic values are not JSON.");
1499
+ ancestors.add(entry);
1500
+ try {
1501
+ if (Array.isArray(entry))
1502
+ return `[${Array.from(entry, encode).join(",")}]`;
1503
+ return `{${Object.entries(entry).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0).map(([key, child]) => `${JSON.stringify(key)}:${encode(child)}`).join(",")}}`;
1504
+ } finally {
1505
+ ancestors.delete(entry);
1506
+ }
1507
+ }
1508
+ throw new HarnessError("invalid_json", "Only finite JSON values are accepted.");
1509
+ }
1510
+ return encode(value);
1511
+ }
1512
+ function sha256(bytes) {
1513
+ return createHash("sha256").update(bytes).digest("hex");
1514
+ }
1515
+ function digest(value) {
1516
+ return sha256(canonicalJson(value));
1517
+ }
1518
+ function digestUuid(value) {
1519
+ const hash = digest(value);
1520
+ return `${hash.slice(0, 8)}-${hash.slice(8, 12)}-5${hash.slice(13, 16)}-a${hash.slice(17, 20)}-${hash.slice(20, 32)}`;
1521
+ }
1522
+
1523
+ // packages/foundation/src/fixture-contract.ts
1524
+ var FIXTURE_TARGET = "fixture://counter";
1525
+ var COORDINATOR_TARGET = "mettle://coordinator";
1526
+ var FIXTURE_MODEL = "harness-fixture-v1";
1527
+ var RUNTIME_VERSION = "harness-mastra-fixture/0.6.0";
1528
+ var FIXTURE_CONTEXT_TOKENS = 1000;
1529
+ var envelope2 = {
1530
+ contractVersion: literal(CONTRACT_VERSION),
1531
+ runId: uuid(),
1532
+ seq: number().int().nonnegative()
1533
+ };
1534
+ var FixtureEventSchema = discriminatedUnion("type", eventVariants(envelope2));
1535
+ function validateVersion(value) {
1536
+ if (typeof value !== "object" || value === null || !("contractVersion" in value) || value.contractVersion !== CONTRACT_VERSION) {
1537
+ throw new HarnessError("contract_version_mismatch", `Expected contract ${CONTRACT_VERSION}.`);
1538
+ }
1539
+ }
1540
+ function validateRunConfig(input) {
1541
+ validateVersion(input);
1542
+ const result = RunConfigSchema.safeParse(input);
1543
+ if (!result.success)
1544
+ throw new HarnessError("invalid_config", "Run configuration does not match the supported contract.");
1545
+ return result.data;
1546
+ }
1547
+ function validateFixtureRun(target, input) {
1548
+ const config = validateRunConfig(input);
1549
+ if (target !== FIXTURE_TARGET || config.model !== FIXTURE_MODEL || config.targetKind !== "web" || config.change !== undefined || config.capabilities !== undefined && (config.capabilities.length !== 1 || config.capabilities[0] !== "agentic_pentesting")) {
1550
+ throw new HarnessError("unsupported_profile", "Only the explicit local counter fixture and fixture model are implemented. Live targets are disabled.");
1551
+ }
1552
+ return config;
1553
+ }
1554
+ function fixtureConfig(overrides = {}) {
1555
+ return {
1556
+ contractVersion: CONTRACT_VERSION,
1557
+ model: FIXTURE_MODEL,
1558
+ targetKind: "web",
1559
+ capabilities: ["agentic_pentesting"],
1560
+ ...overrides
1561
+ };
1562
+ }
1563
+
1564
+ // packages/foundation/src/attestation.ts
1565
+ import {
1566
+ createHash as createHash2,
1567
+ createPrivateKey,
1568
+ createPublicKey,
1569
+ sign,
1570
+ verify
1571
+ } from "node:crypto";
1572
+ function preAuthenticationEncoding(payloadType, payload) {
1573
+ const type = Buffer.from(payloadType, "utf8");
1574
+ return Buffer.concat([
1575
+ Buffer.from(`DSSEv1 ${type.byteLength} `, "utf8"),
1576
+ type,
1577
+ Buffer.from(` ${payload.byteLength} `, "utf8"),
1578
+ payload
1579
+ ]);
1580
+ }
1581
+ function evidenceKeyId(publicKey) {
1582
+ return createHash2("sha256").update(publicKey.export({ type: "spki", format: "der" })).digest("hex");
1583
+ }
1584
+ function evidenceStatement(subject, predicate) {
1585
+ return EvidenceStatementSchema.parse({
1586
+ _type: EVIDENCE_STATEMENT_TYPE,
1587
+ subject: [
1588
+ { name: subject.artifactRef, digest: { sha256: subject.sha256 } }
1589
+ ],
1590
+ predicateType: EVIDENCE_PREDICATE_TYPE,
1591
+ predicate
1592
+ });
1593
+ }
1594
+ function signEvidence(statement, privateKeyPem) {
1595
+ const privateKey = createPrivateKey(privateKeyPem);
1596
+ if (privateKey.asymmetricKeyType !== "ed25519")
1597
+ throw new HarnessError("evidence_key", "Evidence signing requires an Ed25519 private key.");
1598
+ const payload = Buffer.from(canonicalJson(EvidenceStatementSchema.parse(statement)), "utf8");
1599
+ return EvidenceEnvelopeSchema.parse({
1600
+ payloadType: EVIDENCE_PAYLOAD_TYPE,
1601
+ payload: payload.toString("base64"),
1602
+ signatures: [
1603
+ {
1604
+ keyid: evidenceKeyId(createPublicKey(privateKey)),
1605
+ sig: sign(null, preAuthenticationEncoding(EVIDENCE_PAYLOAD_TYPE, payload), privateKey).toString("base64")
1606
+ }
1607
+ ]
1608
+ });
1609
+ }
1610
+ function verifyEvidence(envelope, publicKeyPem, subject, expected) {
1611
+ const deny = () => {
1612
+ throw new HarnessError("verification_denied", "The evidence attestation is missing, malformed or not signed for this artifact.");
1613
+ };
1614
+ try {
1615
+ const parsed = EvidenceEnvelopeSchema.parse(envelope);
1616
+ const publicKey = createPublicKey(publicKeyPem);
1617
+ if (publicKey.asymmetricKeyType !== "ed25519" || evidenceKeyId(publicKey) !== parsed.signatures[0].keyid)
1618
+ deny();
1619
+ const payload = Buffer.from(parsed.payload, "base64");
1620
+ if (!verify(null, preAuthenticationEncoding(parsed.payloadType, payload), publicKey, Buffer.from(parsed.signatures[0].sig, "base64")))
1621
+ deny();
1622
+ const text = payload.toString("utf8");
1623
+ const statement = EvidenceStatementSchema.parse(JSON.parse(text));
1624
+ if (canonicalJson(statement) !== text || statement.subject[0].name !== subject.artifactRef || statement.subject[0].digest.sha256 !== subject.sha256 || statement.predicate.runId !== expected.runId || statement.predicate.authorityDigest !== expected.authorityDigest)
1625
+ deny();
1626
+ return statement;
1627
+ } catch (error) {
1628
+ if (error instanceof HarnessError)
1629
+ throw error;
1630
+ return deny();
1631
+ }
1632
+ }
1633
+ // packages/foundation/src/bounded-json.ts
1634
+ async function readBoundedJson(response, limit, options = {}) {
1635
+ if (!response.ok || !response.body || options.contentType !== undefined && response.headers.get("content-type")?.split(";")[0]?.trim() !== options.contentType) {
1636
+ await response.body?.cancel();
1637
+ throw new Error("The response was refused, empty or not JSON.");
1638
+ }
1639
+ const reader = response.body.getReader();
1640
+ const abort = () => {
1641
+ reader.cancel().catch(() => {
1642
+ return;
1643
+ });
1644
+ };
1645
+ options.signal?.addEventListener("abort", abort, { once: true });
1646
+ const chunks = [];
1647
+ let size = 0;
1648
+ try {
1649
+ while (true) {
1650
+ if (options.signal?.aborted)
1651
+ throw new Error("The read was aborted.");
1652
+ const chunk = await reader.read();
1653
+ if (options.signal?.aborted)
1654
+ throw new Error("The read was aborted.");
1655
+ if (chunk.done)
1656
+ break;
1657
+ size += chunk.value.byteLength;
1658
+ if (size > limit)
1659
+ throw new Error("The response exceeded its limit.");
1660
+ chunks.push(chunk.value);
1661
+ }
1662
+ } finally {
1663
+ options.signal?.removeEventListener("abort", abort);
1664
+ await reader.cancel().catch(() => {
1665
+ return;
1666
+ });
1667
+ }
1668
+ return JSON.parse(new TextDecoder("utf-8", { fatal: true }).decode(Buffer.concat(chunks)));
1669
+ }
1670
+ // packages/foundation/src/capture.ts
1671
+ var CAPTURE_POLICY = "structured-secrets-v1";
1672
+ var sensitiveKey = /^(?:authorization|proxyauthorization|cookie|setcookie|password|passwd|pwd|secret|secretkey|clientsecret|token|accesstoken|refreshtoken|idtoken|apitoken|apikey|xapikey|accesskey|clientkey|privatekey|credential|credentials|sessionid|ssn|connectionstring|databaseurl|awsaccesskeyid|awssecretaccesskey|awssessiontoken|xauthtoken|xamzsecuritytoken|sessiontoken|securitytoken)$/;
1673
+ var credentialText = /\b(?:[Bb]earer|[Bb]asic)\s+[A-Za-z0-9._~+/=]+(?:-[A-Za-z0-9._~+/=]+)*|\b[a-z][a-z0-9+.-]*:\/\/[^\s/@]+:[^\s/@]+@|\b(?:sk-[A-Za-z0-9_-]{16,}|gh[pousr]_[A-Za-z0-9]{20,}|github_pat_[A-Za-z0-9_]{20,}|AKIA[A-Z0-9]{16}|AIza[0-9A-Za-z_-]{35}|xox[baprse]-[0-9A-Za-z-]{10,}|xapp-[0-9A-Za-z-]{10,})(?![A-Za-z0-9_-])|\beyJ[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+(?![A-Za-z0-9_-])|-----BEGIN (?:[A-Z]+ )?PRIVATE KEY-----[\s\S]*?-----END (?:[A-Z]+ )?PRIVATE KEY-----/g;
1674
+ var credentialAssignment = /(?:password|passwd|pwd|secret|token|apikey|api_key|access_key|secret_key)=[^\s&"';]+/gi;
1675
+ function redactText(value) {
1676
+ let current = value;
1677
+ for (let pass = 0;pass < 8; pass += 1) {
1678
+ const next = current.replace(credentialText, "[REDACTED]").replace(credentialAssignment, "[REDACTED]");
1679
+ if (next === current)
1680
+ return next;
1681
+ current = next;
1682
+ }
1683
+ throw new Error("Redaction did not converge.");
1684
+ }
1685
+ function sanitize(value, depth) {
1686
+ if (depth > 32)
1687
+ throw new Error;
1688
+ if (typeof value === "string")
1689
+ return redactText(value);
1690
+ if (Array.isArray(value))
1691
+ return value.map((entry) => sanitize(entry, depth + 1));
1692
+ if (value && typeof value === "object")
1693
+ return Object.fromEntries(Object.entries(value).map(([key, entry]) => [
1694
+ key,
1695
+ sensitiveKey.test(key.normalize("NFKC").toLowerCase().replace(/[-_\s]/g, "")) ? "[REDACTED]" : sanitize(entry, depth + 1)
1696
+ ]));
1697
+ return value;
1698
+ }
1699
+ function captureResponseText(text) {
1700
+ try {
1701
+ if (Buffer.byteLength(text, "utf8") > 1048576)
1702
+ throw new Error;
1703
+ let value;
1704
+ try {
1705
+ value = JSON.parse(text);
1706
+ } catch {
1707
+ value = text;
1708
+ }
1709
+ const sanitized = sanitize(value, 0);
1710
+ const result = typeof value === "string" && value === text ? String(sanitized) : canonicalJson(sanitized);
1711
+ if (Buffer.byteLength(result, "utf8") > 1048576)
1712
+ throw new Error;
1713
+ return result;
1714
+ } catch {
1715
+ throw new HarnessError("capture_rejected", "Response text exceeds the bounded redaction policy.");
1716
+ }
1717
+ }
1718
+ function captureEvidence(input) {
1719
+ try {
1720
+ const raw = canonicalJson(input);
1721
+ if (Buffer.byteLength(raw, "utf8") > EVIDENCE_MAX_BYTES)
1722
+ throw new Error;
1723
+ const value = sanitize(JSON.parse(raw), 0);
1724
+ const bytes = canonicalJson(value);
1725
+ if (Buffer.byteLength(bytes, "utf8") > EVIDENCE_MAX_BYTES)
1726
+ throw new Error;
1727
+ return { value, bytes, policy: CAPTURE_POLICY };
1728
+ } catch {
1729
+ throw new HarnessError("capture_rejected", "Evidence capture requires bounded JSON compatible with the redaction policy.");
1730
+ }
1731
+ }
1732
+ // packages/foundation/src/evidence.ts
1733
+ async function groundEvidence(calls, additionalRefs, context) {
1734
+ const deny = (cause) => {
1735
+ process.stderr.write(`${JSON.stringify({ component: "evidence", runId: context.runId, code: "evidence_integrity", cause })}
1736
+ `);
1737
+ throw new HarnessError("evidence_integrity", "Evidence is missing, unredacted, misbound, oversized or modified.");
1738
+ };
1739
+ try {
1740
+ if (calls.length > 2000 || additionalRefs.length > 2500)
1741
+ deny("record_count");
1742
+ const captured = calls.map((call) => EvidenceToolCallSchema.parse(call));
1743
+ const references = new Set([
1744
+ ...captured.map((call) => call.artifactRef),
1745
+ ...additionalRefs
1746
+ ]);
1747
+ if (references.size > 2500)
1748
+ deny("reference_count");
1749
+ const identities = new Set;
1750
+ for (const call of captured) {
1751
+ if (identities.has(call.callId))
1752
+ deny("duplicate_call");
1753
+ identities.add(call.callId);
1754
+ const recorded = await context.getToolCall(context.runId, call.callId);
1755
+ if (!recorded || recorded.callId !== call.callId || recorded.tool !== call.tool || recorded.artifactRef !== call.artifactRef)
1756
+ deny("tool_call_binding");
1757
+ }
1758
+ let totalBytes = 0;
1759
+ const evidence = new Map;
1760
+ for (const artifactRef of [...references].sort()) {
1761
+ if (!ArtifactRefSchema.safeParse(artifactRef).success)
1762
+ deny("reference_format");
1763
+ const artifact = await context.getArtifact(context.runId, artifactRef);
1764
+ if (typeof artifact.bytes !== "string" || artifact.redacted !== true)
1765
+ deny("unredacted_artifact");
1766
+ const byteLength = Buffer.byteLength(artifact.bytes, "utf8");
1767
+ totalBytes += byteLength;
1768
+ if (byteLength > 1048576)
1769
+ deny("artifact_too_large");
1770
+ if (totalBytes > 8388608)
1771
+ deny("evidence_too_large");
1772
+ if (artifactRef !== `sha256:${sha256(artifact.bytes)}`)
1773
+ deny("artifact_digest");
1774
+ evidence.set(artifactRef, { bytes: artifact.bytes, byteLength });
1775
+ }
1776
+ return evidence;
1777
+ } catch (error) {
1778
+ if (error instanceof HarnessError)
1779
+ throw error;
1780
+ if (error instanceof ZodError)
1781
+ deny("malformed_record");
1782
+ return deny("storage_error");
1783
+ }
1784
+ }
1785
+ // packages/foundation/src/findings.ts
1786
+ function candidateRevision(finding) {
1787
+ return digest({
1788
+ ...finding,
1789
+ status: "candidate",
1790
+ verification: { result: "pending" }
1791
+ });
1792
+ }
1793
+ function subjectDigest(finding) {
1794
+ return digest({
1795
+ subject: finding.subject,
1796
+ ...finding.change ? { change: finding.change } : {}
1797
+ });
1798
+ }
1799
+ var AdmittedFindingSchema = FindingSchema.superRefine((finding, context) => {
1800
+ const receipt = finding.verification.receipt;
1801
+ if (receipt && (receipt.candidateRevision !== candidateRevision(finding) || receipt.subjectDigest !== subjectDigest(finding))) {
1802
+ context.addIssue({
1803
+ code: "custom",
1804
+ message: "Receipt does not bind the original candidate and subject."
1805
+ });
1806
+ }
1807
+ });
1808
+ var independentVerdict = VerificationSchema.safeExtend({
1809
+ result: _enum(["pass", "fail"]),
1810
+ method: VerificationSchema.shape.method.unwrap(),
1811
+ artifactRef: string().min(1),
1812
+ receipt: VerificationReceiptSchema,
1813
+ review: never().optional()
1814
+ });
1815
+ function checkedBefore(receipt, now) {
1816
+ const time = now.getTime();
1817
+ return Number.isFinite(time) && Date.parse(receipt.checkedAt) <= time;
1818
+ }
1819
+ async function admitIndependentVerification(candidate, verdict, context) {
1820
+ validateVersion(candidate);
1821
+ const finding = AdmittedFindingSchema.parse(candidate);
1822
+ const checked = independentVerdict.parse(verdict);
1823
+ const deny = () => {
1824
+ throw new HarnessError("verification_denied", "Verification identity, policy, authority, freshness or evidence was not accepted.");
1825
+ };
1826
+ if (finding.status !== "candidate" || finding.verification.result !== "pending" || finding.runId !== context.runId || !context.capabilities.includes(finding.capability) || !context.policy.claims.includes(finding.claim))
1827
+ deny();
1828
+ const receipt = checked.receipt;
1829
+ if (receipt.authority.kind !== context.authority.kind || receipt.authority.id !== context.authority.id || receipt.policy.id !== context.policy.id || receipt.policy.revision !== context.policy.revision)
1830
+ deny();
1831
+ const now = context.now.getTime();
1832
+ if (!checkedBefore(receipt, context.now) || receipt.expiresAt && Date.parse(receipt.expiresAt) <= now || (context.policy.requiresExpiry || finding.claim === "credential_validity") && !receipt.expiresAt)
1833
+ deny();
1834
+ const terminal = AdmittedFindingSchema.parse({
1835
+ ...finding,
1836
+ status: checked.result === "pass" ? "confirmed" : "discarded",
1837
+ verification: checked
1838
+ });
1839
+ try {
1840
+ await groundEvidence(finding.evidence.toolCalls, [checked.artifactRef], context);
1841
+ } catch {
1842
+ deny();
1843
+ }
1844
+ return terminal;
1845
+ }
1846
+ // packages/foundation/src/report-patches.ts
1847
+ var TestSchema = TestRunResultSchema.pick({
1848
+ repository: true,
1849
+ revision: true,
1850
+ patchProposalId: true,
1851
+ verification: true,
1852
+ status: true
1853
+ }).strip();
1854
+ function reportPatches(calls, findings, artifacts) {
1855
+ const tests = calls.filter((call) => call.tool === "test_run").map((call) => ({
1856
+ call,
1857
+ result: TestSchema.parse(JSON.parse(artifacts.get(call.artifactRef).bytes))
1858
+ }));
1859
+ return calls.filter((call) => call.tool === "patch_propose").map((call) => {
1860
+ const proposal = PatchProposalSchema.parse(JSON.parse(artifacts.get(call.artifactRef).bytes));
1861
+ const finding = findings.find((entry) => entry.id === proposal.findingId);
1862
+ if (proposal.proposalId !== call.callId || proposal.findingId && (finding?.subject.kind !== "source" || finding.subject.repository !== proposal.repository || finding.subject.revision !== proposal.revision))
1863
+ throw new HarnessError("evidence_integrity", "A patch recommendation must bind its committed proposal and source finding.");
1864
+ const results = tests.filter((test) => test.result.patchProposalId === proposal.proposalId && test.result.repository === proposal.repository && test.result.revision === proposal.revision);
1865
+ const exact = proposal.unifiedDiff !== undefined && proposal.diffSha256 === sha256(proposal.unifiedDiff) && proposal.edits.every((edit) => sha256(edit.content) === edit.afterSha256);
1866
+ return PatchRecommendationSchema.parse({
1867
+ proposalId: proposal.proposalId,
1868
+ repository: proposal.repository,
1869
+ revision: proposal.revision,
1870
+ status: proposal.status,
1871
+ ...proposal.findingId ? { findingId: proposal.findingId } : {},
1872
+ artifactRef: call.artifactRef,
1873
+ applicability: proposal.unifiedDiff === undefined ? "legacy" : exact ? "exact" : "redacted",
1874
+ ...exact ? { unifiedDiff: proposal.unifiedDiff } : {},
1875
+ validation: !results.length ? "not_run" : results.some((test) => test.result.status === "failed") ? "failed" : results.every((test) => test.result.status === "passed") ? "passed" : "incomplete",
1876
+ files: proposal.edits.map(({ path, beforeSha256, afterSha256 }) => ({
1877
+ path,
1878
+ beforeSha256,
1879
+ afterSha256
1880
+ })),
1881
+ tests: results.map(({ call: testCall, result }) => ({
1882
+ ...testCall,
1883
+ status: result.status
1884
+ }))
1885
+ });
1886
+ });
1887
+ }
1888
+
1889
+ // packages/foundation/src/report.ts
1890
+ function humanReviewArtifact(review, receipt) {
1891
+ return canonicalJson({ review, receipt });
1892
+ }
1893
+ var notice = "Only recorded observations are included. No findings is not proof of security or complete coverage.";
1894
+ function escapedCharacter(character) {
1895
+ return `\\u${character.charCodeAt(0).toString(16).padStart(4, "0")}`;
1896
+ }
1897
+ var controlCharacter = /[\p{Cc}\u200b-\u200f\u2028-\u202e\u2060-\u206f\ufeff]/u;
1898
+ var controlCharacters = new RegExp(controlCharacter, "gu");
1899
+ function markdownLiteral(value) {
1900
+ return value.replace(/[\p{Cc}\u200b-\u200f\u2028-\u202e\u2060-\u206f\ufeff&<>"'\\`*_[\]{}()#+.!|~:@-]/gu, (character) => controlCharacter.test(character) ? escapedCharacter(character) : `&#${character.charCodeAt(0)};`);
1901
+ }
1902
+ function json(value) {
1903
+ return `${JSON.stringify(value, null, 2).replace(/[\u007f-\u009f\u200b-\u200f\u2028-\u202e\u2060-\u206f\ufeff]/gu, escapedCharacter)}
1904
+ `;
1905
+ }
1906
+ function markdown(report) {
1907
+ const lines = [
1908
+ "# Mettle run report",
1909
+ "",
1910
+ ...report.scope === "development-fixture" ? ["**Development fixture only; not a security assessment.**", ""] : [],
1911
+ notice,
1912
+ "",
1913
+ `- Run: ${markdownLiteral(report.runId)}`,
1914
+ `- Target: ${markdownLiteral(report.target)}`,
1915
+ `- Mode: ${report.mode}`,
1916
+ `- Committed sequence: ${report.seq}`,
1917
+ `- Outcome: ${report.terminal.outcome}`,
1918
+ `- Cleanup complete: ${report.terminal.cleanupOk ? "yes" : "no"}`,
1919
+ `- Generated: ${markdownLiteral(report.generatedAt)}`,
1920
+ `- Context tokens: ${report.spent.tokens}; wall seconds: ${report.spent.wallSec}`,
1921
+ ...report.consumption ? [
1922
+ `- Cumulative tokens: ${report.consumption.tokens}; steps: ${report.consumption.steps}`
1923
+ ] : [],
1924
+ ...report.spent.usd === undefined ? ["- USD accounting: not recorded"] : [`- Recorded USD: ${report.spent.usd}`],
1925
+ `- Pending approvals: ${report.pendingApprovals.length}; pending reviews: ${report.pendingReviews.length}`,
1926
+ `- Operational install decisions: ${report.installDecisions.length} (see JSON; not vulnerability verdicts)`,
1927
+ "",
1928
+ ...report.coverage ? [
1929
+ "## Coverage",
1930
+ "",
1931
+ ...report.coverage.map((line) => `- ${markdownLiteral(line)}`),
1932
+ ""
1933
+ ] : [],
1934
+ "## Findings",
1935
+ "",
1936
+ ...report.findings.length ? [] : ["No findings recorded.", ""]
1937
+ ];
1938
+ for (const finding of report.findings) {
1939
+ lines.push(`### ${markdownLiteral(finding.title)}`, "", `- ID: ${markdownLiteral(finding.id)}`, `- Status: ${finding.status}; verification: ${finding.verification.result}`, `- Severity: ${finding.severity}; claim: ${markdownLiteral(finding.claim)}`, `- Location: ${markdownLiteral(finding.location)}`, `- Evidence revision: ${markdownLiteral(finding.evidence.revision)}`, `- Detail: ${markdownLiteral(finding.evidence.detail)}`);
1940
+ if (finding.subject.kind === "source")
1941
+ lines.push(`- Source: ${markdownLiteral(finding.subject.repository)} at ${markdownLiteral(finding.subject.revision)}; path: ${markdownLiteral(finding.subject.path)}`);
1942
+ if (finding.change)
1943
+ lines.push(`- Change: ${markdownLiteral(finding.change.baseRevision)} → ${markdownLiteral(finding.change.headRevision)}`);
1944
+ if (finding.found_via)
1945
+ lines.push(`- Discovery: ${markdownLiteral(finding.found_via.map((entry) => `${finding.evidence.toolCalls.find((call) => call.callId === entry.callId).tool}: ${entry.technique}`).join(", "))}; public rule/template hit: ${finding.public_template_hit === null ? "unknown" : finding.public_template_hit ? "yes" : "not recorded"}`);
1946
+ for (const call of finding.evidence.toolCalls)
1947
+ lines.push(`- Evidence: ${markdownLiteral(call.callId)} / ${markdownLiteral(call.tool)} / ${markdownLiteral(call.artifactRef)}`);
1948
+ if (finding.verification.artifactRef)
1949
+ lines.push(`- Verification artifact: ${markdownLiteral(finding.verification.artifactRef)}`);
1950
+ if (finding.verification.receipt) {
1951
+ const receipt = finding.verification.receipt;
1952
+ lines.push(`- Authority: ${receipt.authority.kind} / ${markdownLiteral(receipt.authority.id)}`, `- Policy: ${markdownLiteral(receipt.policy.id)} / ${markdownLiteral(receipt.policy.revision)}`);
1953
+ }
1954
+ lines.push("");
1955
+ }
1956
+ if (report.patchRecommendations?.length) {
1957
+ lines.push("", "## Recommended patches", "", "Proposals only. Passing repository tests does not independently prove a repair.", "");
1958
+ for (const patch of report.patchRecommendations) {
1959
+ lines.push(`### ${markdownLiteral(patch.findingId ?? patch.proposalId)}`, "", `- Revision: ${markdownLiteral(patch.revision)}`, `- Validation: ${patch.validation}; applicability: ${patch.applicability}`, `- Proposal evidence: ${markdownLiteral(patch.artifactRef)}`, "");
1960
+ if (patch.unifiedDiff !== undefined) {
1961
+ const fence = "`".repeat(Math.max(3, ...[...patch.unifiedDiff.matchAll(/`+/g)].map((match) => match[0].length + 1)));
1962
+ lines.push(`${fence}diff`, ...patch.unifiedDiff.split(`
1963
+ `).map((line) => line.replace(controlCharacters, escapedCharacter)), fence, "");
1964
+ }
1965
+ }
1966
+ }
1967
+ lines.push("## Committed observations", "");
1968
+ for (const call of report.observations)
1969
+ lines.push(`- ${markdownLiteral(call.callId)} / ${markdownLiteral(call.tool)} / ${markdownLiteral(call.artifactRef)}`);
1970
+ lines.push("", "## Checked evidence manifest", "");
1971
+ for (const artifact of report.evidence)
1972
+ lines.push(`- ${markdownLiteral(artifact.artifactRef)} (${artifact.byteLength} bytes)`);
1973
+ return `${lines.join(`
1974
+ `)}
1975
+ `;
1976
+ }
1977
+ function sourceUri(path) {
1978
+ if (!path || /[\\:\p{Cc}\u200b-\u200f\u2028-\u202e\u2060-\u206f\ufeff]/u.test(path) || path.split("/").some((part) => !part || part === "." || part === ".."))
1979
+ return;
1980
+ return path.split("/").map(encodeURIComponent).join("/");
1981
+ }
1982
+ function sarif(report) {
1983
+ const results = [];
1984
+ const omitted = [];
1985
+ for (const finding of report.findings) {
1986
+ const discovery = finding.found_via ? {
1987
+ found_via: finding.found_via,
1988
+ public_template_hit: finding.public_template_hit
1989
+ } : {};
1990
+ const uri = finding.subject.kind === "source" ? sourceUri(finding.subject.path) : undefined;
1991
+ if (finding.status !== "confirmed" || !uri) {
1992
+ omitted.push({
1993
+ findingId: finding.id,
1994
+ ...discovery,
1995
+ reason: finding.status !== "confirmed" ? "not_confirmed" : "unsupported_location"
1996
+ });
1997
+ continue;
1998
+ }
1999
+ results.push({
2000
+ ruleId: `mettle/${finding.claim}`,
2001
+ level: finding.severity === "low" ? "note" : finding.severity === "medium" ? "warning" : "error",
2002
+ message: { text: `${finding.title}
2003
+ ${finding.evidence.detail}` },
2004
+ locations: [{ physicalLocation: { artifactLocation: { uri } } }],
2005
+ properties: {
2006
+ findingId: finding.id,
2007
+ severity: finding.severity,
2008
+ claim: finding.claim,
2009
+ ...finding.cwe ? { cwe: finding.cwe } : {},
2010
+ subject: finding.subject,
2011
+ ...finding.change ? { change: finding.change } : {},
2012
+ evidence: finding.evidence.toolCalls,
2013
+ ...discovery,
2014
+ verification: finding.verification
2015
+ }
2016
+ });
2017
+ }
2018
+ return json({
2019
+ $schema: "https://docs.oasis-open.org/sarif/sarif/v2.1.0/errata01/os/schemas/sarif-schema-2.1.0.json",
2020
+ version: "2.1.0",
2021
+ runs: [
2022
+ {
2023
+ tool: { driver: { name: "Mettle Harness", version: "0.1.0" } },
2024
+ invocations: [
2025
+ {
2026
+ executionSuccessful: report.scope === "assessment" && report.terminal.outcome === "completed" && report.terminal.cleanupOk && report.pendingApprovals.length === 0 && report.pendingReviews.length === 0 && !report.findings.some((finding) => finding.status === "candidate") && !omitted.some((entry) => entry.reason === "unsupported_location")
2027
+ }
2028
+ ],
2029
+ results,
2030
+ properties: {
2031
+ runId: report.runId,
2032
+ committedSequence: report.seq,
2033
+ generatedAt: report.generatedAt,
2034
+ scope: report.scope,
2035
+ target: report.target,
2036
+ terminal: report.terminal,
2037
+ notice,
2038
+ ...report.coverage ? { coverage: report.coverage } : {},
2039
+ omittedFindings: omitted,
2040
+ evidence: report.evidence,
2041
+ ...report.patchRecommendations ? { patchRecommendations: report.patchRecommendations } : {}
2042
+ }
2043
+ }
2044
+ ]
2045
+ });
2046
+ }
2047
+ function representable(build) {
2048
+ try {
2049
+ return build();
2050
+ } catch (error) {
2051
+ if (error instanceof HarnessError)
2052
+ throw error;
2053
+ throw new HarnessError("report_not_representable", "The run cannot be represented as a bounded report.");
2054
+ }
2055
+ }
2056
+ async function exportRunReport(snapshot, observations, context, format, protocol) {
2057
+ ReportFormatSchema.parse(format);
2058
+ const encoded = canonicalJson({ snapshot, observations });
2059
+ if (Buffer.byteLength(encoded, "utf8") > 1048576)
2060
+ throw new HarnessError("report_too_large", "Report input exceeds its size limit.");
2061
+ const captured = JSON.parse(encoded);
2062
+ const event = EventSchema.parse(captured.snapshot);
2063
+ if (event.type !== "run.snapshot" || !event.terminal)
2064
+ throw new HarnessError("report_not_ready", "A committed terminal snapshot is required.");
2065
+ if (event.runId !== context.runId)
2066
+ throw new HarnessError("report_denied", "The report belongs to another run.");
2067
+ const { type: _type, ...state } = event;
2068
+ let report = representable(() => ReportSchema.parse({
2069
+ ...state,
2070
+ ...context.consumption ? { consumption: context.consumption } : {},
2071
+ scope: context.scope,
2072
+ ...context.coverage ? { coverage: context.coverage } : {},
2073
+ reportVersion: "1.0.0",
2074
+ generatedAt: context.now.toISOString(),
2075
+ observations: captured.observations,
2076
+ evidence: []
2077
+ }));
2078
+ if (report.scope === "development-fixture" && report.findings.length)
2079
+ throw new HarnessError("report_denied", "Development fixtures cannot export assessment findings.");
2080
+ for (const finding of report.findings) {
2081
+ if (finding.status === "candidate")
2082
+ continue;
2083
+ const receipt = finding.verification.receipt;
2084
+ if (receipt.authority.kind === "human") {
2085
+ const verification = finding.verification;
2086
+ if (verification.method !== "human_review" || !verification.review || verification.review.reviewer !== receipt.authority.id || receipt.policy.id !== "human-review" || !AdmittedFindingSchema.safeParse(finding).success || !checkedBefore(receipt, context.now) || receipt.expiresAt !== undefined)
2087
+ throw new HarnessError("verification_denied", "The human verdict must name its reviewer and a current human-review receipt.");
2088
+ const grounded = await groundEvidence(finding.evidence.toolCalls, [verification.artifactRef], context);
2089
+ if (grounded.get(verification.artifactRef).bytes !== humanReviewArtifact(verification.review, receipt))
2090
+ throw new HarnessError("verification_denied", "The human review artifact does not bind the recorded decision.");
2091
+ continue;
2092
+ }
2093
+ const policies = context.verificationPolicies.filter((entry) => entry.authority.kind === receipt.authority.kind && entry.authority.id === receipt.authority.id && entry.policy.id === receipt.policy.id && entry.policy.revision === receipt.policy.revision);
2094
+ if (policies.length !== 1)
2095
+ throw new HarnessError("verification_denied", "Report verification authority is not configured uniquely.");
2096
+ try {
2097
+ await admitIndependentVerification({
2098
+ ...finding,
2099
+ status: "candidate",
2100
+ verification: { result: "pending" }
2101
+ }, finding.verification, {
2102
+ ...context,
2103
+ ...policies[0],
2104
+ capabilities: report.capabilities,
2105
+ now: context.verifiedAt ?? context.now
2106
+ });
2107
+ } catch (error) {
2108
+ if (error instanceof HarnessError)
2109
+ throw error;
2110
+ throw new HarnessError("verification_denied", "Independent verification could not be admitted for a finding.");
2111
+ }
2112
+ }
2113
+ const calls = new Map(report.observations.map((call) => [call.callId, call]));
2114
+ if (calls.size !== report.observations.length)
2115
+ throw new HarnessError("evidence_integrity", "Duplicate report observations are not accepted.");
2116
+ for (const finding of report.findings) {
2117
+ for (const call of finding.evidence.toolCalls) {
2118
+ const observation = calls.get(call.callId);
2119
+ if (!observation || canonicalJson(observation) !== canonicalJson(call))
2120
+ throw new HarnessError("evidence_integrity", "A finding references an unrecorded observation.");
2121
+ }
2122
+ }
2123
+ const artifacts = await groundEvidence(report.observations, report.findings.flatMap((finding) => finding.verification.artifactRef ? [finding.verification.artifactRef] : []), context);
2124
+ report.evidence = [...artifacts].map(([artifactRef, { byteLength }]) => ({
2125
+ artifactRef,
2126
+ byteLength
2127
+ }));
2128
+ report = representable(() => {
2129
+ const patches = reportPatches(report.observations, report.findings, artifacts);
2130
+ return patches.length ? ReportSchema.parse({
2131
+ ...report,
2132
+ reportVersion: "1.1.0",
2133
+ patchRecommendations: patches
2134
+ }) : report;
2135
+ });
2136
+ const rendered = protocol ? protocol.report(report) : report;
2137
+ const body = format === "json" ? json(rendered) : format === "markdown" ? markdown(rendered) : sarif(rendered);
2138
+ if (Buffer.byteLength(body, "utf8") > 8388608)
2139
+ throw new HarnessError("report_too_large", "Report output exceeds its size limit.");
2140
+ return {
2141
+ body,
2142
+ mediaType: format === "markdown" ? "text/markdown; charset=utf-8" : format === "sarif" ? "application/sarif+json" : "application/json",
2143
+ extension: format === "markdown" ? "md" : format === "sarif" ? "sarif" : "json"
2144
+ };
2145
+ }
2146
+ // packages/foundation/src/target.ts
2147
+ var OWNER = "([a-zA-Z0-9][a-zA-Z0-9-]*)";
2148
+ var NAME = "([a-zA-Z0-9_.-]+?)";
2149
+ var REPOSITORY = [
2150
+ new RegExp(`^https://github\\.com/${OWNER}/${NAME}(?:\\.git)?/?$`),
2151
+ new RegExp(`^git@github\\.com:${OWNER}/${NAME}(?:\\.git)?$`),
2152
+ new RegExp(`^ssh://git@github\\.com/${OWNER}/${NAME}(?:\\.git)?/?$`)
2153
+ ];
2154
+ var PULL = new RegExp(`^https://github\\.com/${OWNER}/${NAME}/pull/([1-9][0-9]*)(?:/(?:files|changes|commits|checks))?/?(?:[?#].*)?$`);
2155
+ var GIT_HOSTS = ["gitlab.com", "bitbucket.org", "codeberg.org"];
2156
+ var SCP = /^[^\s/@:]+@([^\s/:]+):/;
2157
+ var SCHEME = /^([a-z][a-z0-9+.-]*):\/\//i;
2158
+ var LOCAL = /^\/[^\p{Cc}]*$/u;
2159
+ var ROUTE_CAPABILITIES = {
2160
+ repository: ["code"],
2161
+ pull_request: ["pull_requests", "code"],
2162
+ web: ["agentic_pentesting"],
2163
+ local: ["code"]
2164
+ };
2165
+ var ambiguous = () => new HarnessError("target_ambiguous", "The target is ambiguous. Use https://github.com/<owner>/<repo>, https://github.com/<owner>/<repo>/pull/<number>, git@github.com:<owner>/<repo>.git or a credential-free http(s) site URL; no request was sent.");
2166
+ var unsupported = (message) => new HarnessError("target_unsupported", `${message} No request was sent.`);
2167
+ function sourceRoute(repository, pullRequestId) {
2168
+ return pullRequestId === undefined ? {
2169
+ kind: "repository",
2170
+ targetKind: "repo",
2171
+ target: `https://github.com/${repository}`,
2172
+ repository,
2173
+ capabilities: ROUTE_CAPABILITIES.repository
2174
+ } : {
2175
+ kind: "pull_request",
2176
+ targetKind: "repo",
2177
+ target: `https://github.com/${repository}/pull/${pullRequestId}`,
2178
+ repository,
2179
+ pullRequestId,
2180
+ capabilities: ROUTE_CAPABILITIES.pull_request
2181
+ };
2182
+ }
2183
+ function github(target) {
2184
+ const pull = PULL.exec(target);
2185
+ const match = pull ?? REPOSITORY.map((pattern) => pattern.exec(target)).find(Boolean);
2186
+ if (!match)
2187
+ return;
2188
+ const [, owner, name, id] = match;
2189
+ if (name === "." || name === ".." || pull && name.endsWith(".git"))
2190
+ return;
2191
+ return sourceRoute(`${owner}/${name}`, id);
2192
+ }
2193
+ function local(target) {
2194
+ if (!LOCAL.test(target))
2195
+ return;
2196
+ if (target.split("/").slice(1).some((segment) => segment === "" || segment === "." || segment === ".."))
2197
+ return;
2198
+ return {
2199
+ kind: "local",
2200
+ targetKind: "repo",
2201
+ target,
2202
+ capabilities: ROUTE_CAPABILITIES.local
2203
+ };
2204
+ }
2205
+ function targetLabel(target) {
2206
+ try {
2207
+ const route = routeTarget(target);
2208
+ if (route.kind === "pull_request")
2209
+ return `PR #${route.pullRequestId} in ${route.repository}`;
2210
+ if (route.kind === "repository")
2211
+ return route.repository;
2212
+ return new URL(target).host;
2213
+ } catch {
2214
+ return target.slice(0, MAX_LABEL);
2215
+ }
2216
+ }
2217
+ function routeTarget(target) {
2218
+ if (!target || target.length > 2048)
2219
+ throw ambiguous();
2220
+ if (target.startsWith("/")) {
2221
+ const route = local(target);
2222
+ if (!route)
2223
+ throw ambiguous();
2224
+ return route;
2225
+ }
2226
+ if (/[^!-~]/.test(target))
2227
+ throw ambiguous();
2228
+ const scheme = SCHEME.exec(target)?.[1]?.toLowerCase();
2229
+ const url = scheme ? URL.parse(target) : undefined;
2230
+ if (url === null)
2231
+ throw ambiguous();
2232
+ const host = (url ? url.hostname : SCP.exec(target)?.[1])?.toLowerCase().replace(/\.+$/, "");
2233
+ if (host === undefined)
2234
+ throw ambiguous();
2235
+ if (host === "github.com" || host.endsWith(".github.com")) {
2236
+ const route = github(target);
2237
+ if (!route)
2238
+ throw ambiguous();
2239
+ return route;
2240
+ }
2241
+ if (!url || GIT_HOSTS.some((name) => host === name || host === `www.${name}`) || scheme !== "http" && scheme !== "https")
2242
+ throw unsupported(scheme && !["http", "https", "ssh", "git", "git+ssh"].includes(scheme) ? "Use an https GitHub repository or pull request, or an http(s) site." : "Only GitHub repositories and pull requests are supported.");
2243
+ if (url.username || url.password || url.search || url.hash)
2244
+ throw unsupported("A site target must not carry credentials, a query or a fragment.");
2245
+ return {
2246
+ kind: "web",
2247
+ targetKind: "web",
2248
+ target: url.href,
2249
+ capabilities: ROUTE_CAPABILITIES.web
2250
+ };
2251
+ }
2252
+ // packages/foundation/src/verification.ts
2253
+ function validateVerificationRequest(input, executionPathBytes) {
2254
+ if (!input || typeof input !== "object" || !("seamVersion" in input) || input.seamVersion !== SEAM_VERSION.oracle) {
2255
+ throw new HarnessError("version_mismatch", "Expected the supported Oracle seam version.");
2256
+ }
2257
+ const request = VerifyRequestSchema.parse(input);
2258
+ AdmittedFindingSchema.parse(request.candidate);
2259
+ if (["vulnerability", "dependency_exploitability"].includes(request.candidate.claim) && !request.candidate.poc)
2260
+ throw new HarnessError("invalid_request", "Runtime verification requires redacted replay instructions before dispatch.");
2261
+ if (request.identity.candidateRevision !== candidateRevision(request.candidate) || request.identity.pocInputsDigest !== digest(request.pocInputs) || request.identity.executionPathDigest !== sha256(executionPathBytes)) {
2262
+ throw new HarnessError("identity_mismatch", "Verification input differs from its captured identity.");
2263
+ }
2264
+ return request;
2265
+ }
2266
+ function validateOracleVerdict(request, input) {
2267
+ VerifyRequestSchema.parse(request);
2268
+ const parsed = VerifyVerdictSchema.safeParse(input);
2269
+ if (!parsed.success)
2270
+ throw new HarnessError("identity_mismatch", "Oracle receipt does not bind the verified candidate and predicate.");
2271
+ const verdict = parsed.data;
2272
+ if (canonicalJson(verdict.identity) !== canonicalJson(request.identity))
2273
+ throw new HarnessError("identity_mismatch", "Oracle returned a different verification identity.");
2274
+ if (verdict.result !== "needs_human") {
2275
+ const admitted = AdmittedFindingSchema.safeParse({
2276
+ ...request.candidate,
2277
+ status: verdict.result === "pass" ? "confirmed" : "discarded",
2278
+ verification: {
2279
+ result: verdict.result,
2280
+ method: verdict.method,
2281
+ artifactRef: verdict.artifactRef,
2282
+ receipt: verdict.receipt
2283
+ }
2284
+ });
2285
+ if (!admitted.success)
2286
+ throw new HarnessError("identity_mismatch", "Oracle receipt does not bind the verified candidate and evidence.");
2287
+ }
2288
+ return verdict;
2289
+ }
2290
+ export { CONTRACT_VERSION, SEAM_VERSION, PositiveIntegerSchema, ProductCapabilitySchema, ChangeContextSchema, ContractContextSchema, RunConfigSchema, CapsSchema, TerminalSchema, MAX_LABEL, MAX_PREVIEW_LINES, MAX_PREVIEW_LINE, ImageRefSchema, ImageRefsSchema, AgentControlSchema, MOST_IMAGE_BYTES, ModelCatalogSchema, MAX_RUN_PAGE, RunPageSchema, EngineIdentitySchema, DISCOVERY_RULE_IDS_MAX, FindingSchema, InvestigationStageSchema, EventSchema, EVIDENCE_MAX_BYTES, INLINE_EVIDENCE_STORE_ID, ArtifactRefSchema, ArtifactManifestSchema, EvidenceEnvelopeSchema, EvidenceSigningKeySchema, TargetIdentitySchema, VerifyRequestSchema, OracleErrorSchema, RangeEligibilitySchema, WorkflowBindingSchema, WebsiteEngagementSchema, InvestigationUrlSchema, InvestigationPrepareSchema, WorkflowRevisionSchema, WorkflowSaveSchema, WorkflowPrepareSchema, PreparationViewSchema, InvestigationStartSchema, InvestigationRunIdSchema, InvestigationModelSchema, InvestigationCapabilitiesSchema, InvestigationLaunchResultSchema, InvestigationProgressSchema, tuiProtocol, JsonObjectSchema, ModelContinuationSchema, ModelUsageSchema, ModelMessageSchema, ModelRequestSchema, ModelResponseSchema, ModelStreamEventSchema, PatchProposalSchema, TestRunResultSchema, PROVIDER_KEYS, FOUNDRY_ENDPOINT, FOUNDRY_MODELS, FOUNDRY_LIMITS, foundryLimits, foundryEndpoint, foundryDeployments, isLoopback, providerFixture, ReportFormatSchema, HarnessError, publicError, canonicalJson, sha256, digest, digestUuid, evidenceKeyId, evidenceStatement, signEvidence, verifyEvidence, readBoundedJson, CAPTURE_POLICY, captureResponseText, captureEvidence, groundEvidence, FIXTURE_TARGET, COORDINATOR_TARGET, FIXTURE_MODEL, RUNTIME_VERSION, FIXTURE_CONTEXT_TOKENS, FixtureEventSchema, validateVersion, validateRunConfig, validateFixtureRun, fixtureConfig, candidateRevision, subjectDigest, AdmittedFindingSchema, admitIndependentVerification, humanReviewArtifact, exportRunReport, ROUTE_CAPABILITIES, sourceRoute, targetLabel, routeTarget, validateVerificationRequest, validateOracleVerdict };