@mettlelabs/mettle 0.0.0-beta.1-linux-arm64 → 0.0.0-beta.2-darwin-arm64
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/THIRD_PARTY_NOTICES.md +503 -8
- package/bin/mettle +2 -2
- package/harness/audit-investigation.mjs +16 -16
- package/harness/chunk-3wt8a8fq.mjs +1716 -0
- package/harness/{chunk-13tgmdey.mjs → chunk-49ytr8d5.mjs} +1 -1
- package/harness/chunk-4vx34w5h.mjs +2357 -0
- package/harness/{chunk-xqyc4ca2.mjs → chunk-9dg1btk1.mjs} +1220 -292
- package/harness/chunk-c7dx5mdd.mjs +10807 -0
- package/harness/{chunk-msg872ea.mjs → chunk-h1td5kq9.mjs} +97 -9
- package/harness/{chunk-4jtnt9k5.mjs → chunk-jp69h6sj.mjs} +1 -1
- package/harness/chunk-rd80vvc5.mjs +22047 -0
- package/harness/{chunk-5cvb1jnb.mjs → chunk-w0qwc5z2.mjs} +2 -2
- package/harness/issue-api-token.mjs +2 -2
- package/harness/launcher.mjs +318 -18
- package/harness/sandbox.mjs +8 -7
- package/harness/server.mjs +22883 -1891
- package/package.json +2 -5
- package/harness/chunk-2gt4cy7x.mjs +0 -2290
- package/harness/chunk-32y07kkp.mjs +0 -3747
- package/harness/chunk-7bg2gnv2.mjs +0 -7540
|
@@ -1,2290 +0,0 @@
|
|
|
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 };
|