agent-inspect 6.31.31 → 6.31.33

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/docs/CLI.md +3 -1
  4. package/docs/TRACE-CONTRACTS.md +4 -0
  5. package/package.json +1 -1
  6. package/packages/cli/dist/{chunk-4GTOJ3G2.mjs → chunk-AILSHDEF.mjs} +191 -31
  7. package/packages/cli/dist/chunk-AILSHDEF.mjs.map +1 -0
  8. package/packages/cli/dist/index.cjs +209 -33
  9. package/packages/cli/dist/index.cjs.map +1 -1
  10. package/packages/cli/dist/index.mjs +23 -7
  11. package/packages/cli/dist/index.mjs.map +1 -1
  12. package/packages/cli/dist/{src-BF74ZVDF.mjs → src-SP36M4VB.mjs} +3 -3
  13. package/packages/cli/dist/{src-BF74ZVDF.mjs.map → src-SP36M4VB.mjs.map} +1 -1
  14. package/packages/core/dist/advanced.cjs +80 -18
  15. package/packages/core/dist/advanced.cjs.map +1 -1
  16. package/packages/core/dist/advanced.d.cts +2 -2
  17. package/packages/core/dist/advanced.d.ts +2 -2
  18. package/packages/core/dist/advanced.mjs +9 -9
  19. package/packages/core/dist/checks.cjs +185 -29
  20. package/packages/core/dist/checks.cjs.map +1 -1
  21. package/packages/core/dist/checks.d.cts +2 -2
  22. package/packages/core/dist/checks.d.ts +2 -2
  23. package/packages/core/dist/checks.mjs +3 -3
  24. package/packages/core/dist/{chunk-76QIWWJ5.mjs → chunk-6S666BF4.mjs} +3 -3
  25. package/packages/core/dist/{chunk-76QIWWJ5.mjs.map → chunk-6S666BF4.mjs.map} +1 -1
  26. package/packages/core/dist/{chunk-BYNAJPNH.mjs → chunk-EMDJLFRK.mjs} +188 -32
  27. package/packages/core/dist/chunk-EMDJLFRK.mjs.map +1 -0
  28. package/packages/core/dist/{chunk-QMO3ITYF.mjs → chunk-FBPDF7HO.mjs} +3 -3
  29. package/packages/core/dist/{chunk-QMO3ITYF.mjs.map → chunk-FBPDF7HO.mjs.map} +1 -1
  30. package/packages/core/dist/{chunk-XM27TZLD.mjs → chunk-RB6WANSW.mjs} +6 -2
  31. package/packages/core/dist/chunk-RB6WANSW.mjs.map +1 -0
  32. package/packages/core/dist/{chunk-JTJN4KBJ.mjs → chunk-VIEJJ5JB.mjs} +4 -4
  33. package/packages/core/dist/{chunk-JTJN4KBJ.mjs.map → chunk-VIEJJ5JB.mjs.map} +1 -1
  34. package/packages/core/dist/exporters.cjs +4 -0
  35. package/packages/core/dist/exporters.cjs.map +1 -1
  36. package/packages/core/dist/exporters.mjs +3 -3
  37. package/packages/core/dist/{index-DACU4Dy1.d.cts → index-Ceyw5x7b.d.cts} +4 -2
  38. package/packages/core/dist/{index-b4tIGrzq.d.ts → index-K5Cinf1r.d.ts} +4 -2
  39. package/packages/core/dist/index.cjs +4 -0
  40. package/packages/core/dist/index.cjs.map +1 -1
  41. package/packages/core/dist/index.mjs +4 -4
  42. package/packages/core/dist/writers.cjs +4 -0
  43. package/packages/core/dist/writers.cjs.map +1 -1
  44. package/packages/core/dist/writers.mjs +1 -1
  45. package/packages/cli/dist/chunk-4GTOJ3G2.mjs.map +0 -1
  46. package/packages/core/dist/chunk-BYNAJPNH.mjs.map +0 -1
  47. package/packages/core/dist/chunk-XM27TZLD.mjs.map +0 -1
@@ -268,6 +268,10 @@ var init_credential_value_patterns = __esm({
268
268
  /\b[a-z0-9_.-]+=[^;\s]+(?:;\s*[a-z0-9_.-]+=[^;\s]+)+/i,
269
269
  /\beyJ[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\b/,
270
270
  /\b(?:sk-(?:proj-)?[a-zA-Z0-9_-]{16,}|sk-ant-[a-zA-Z0-9_-]{16,}|AIza[0-9A-Za-z_-]{20,})\b/,
271
+ // Stripe secret / restricted keys use underscores (not sk-). Keep in sync with
272
+ // packages/redact/src/index.ts + packages/core/src/checks DEFAULT_SECRET_PATTERNS (#520).
273
+ /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/,
274
+ /\bxox[abposr]-[A-Za-z0-9-]{10,}\b/,
271
275
  /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\b/,
272
276
  /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/,
273
277
  /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*-----END [A-Z ]*PRIVATE KEY-----/,
@@ -5734,6 +5738,11 @@ function compareFindings(eventById) {
5734
5738
  if (STATUS_RANK[a.status] !== STATUS_RANK[b.status]) {
5735
5739
  return STATUS_RANK[a.status] - STATUS_RANK[b.status];
5736
5740
  }
5741
+ if (a.ruleId === "tool.usage") {
5742
+ const aHasEvent = a.evidence[0]?.eventId !== void 0;
5743
+ const bHasEvent = b.evidence[0]?.eventId !== void 0;
5744
+ if (aHasEvent !== bHasEvent) return aHasEvent ? -1 : 1;
5745
+ }
5737
5746
  const byRun = compareStrings(a.evidence[0]?.runId, b.evidence[0]?.runId);
5738
5747
  if (byRun !== 0) return byRun;
5739
5748
  const byTime = eventTimestamp(a, eventById).localeCompare(eventTimestamp(b, eventById));
@@ -5859,6 +5868,37 @@ function failFinding(ruleId, message, evidence, expected, actual, meta2) {
5859
5868
  function toolName(event) {
5860
5869
  return resolveCanonicalToolName(event);
5861
5870
  }
5871
+ function formatToolNameForMessage(name) {
5872
+ const details = [];
5873
+ for (let index = 0; index < name.length; ) {
5874
+ const codePoint = name.codePointAt(index);
5875
+ const width = codePoint > 65535 ? 2 : 1;
5876
+ if (codePoint > 127) {
5877
+ details.push(
5878
+ `U+${codePoint.toString(16).toUpperCase().padStart(4, "0")} at index ${index}`
5879
+ );
5880
+ }
5881
+ index += width;
5882
+ }
5883
+ if (details.length === 0) return name;
5884
+ return `"${name}" (contains ${details.join("; ")})`;
5885
+ }
5886
+ function describeRunningEvent(event) {
5887
+ if (event.kind === "TOOL") {
5888
+ return `tool ${formatToolNameForMessage(resolveCanonicalToolName(event))}`;
5889
+ }
5890
+ if (event.kind === "LLM") {
5891
+ return `llm ${stepEndpointName(event, "LLM")}`;
5892
+ }
5893
+ return `${event.kind} ${event.name}`;
5894
+ }
5895
+ function incompleteRunningMessage(prefix, running) {
5896
+ const labels = running.map(describeRunningEvent);
5897
+ if (labels.length === 1) {
5898
+ return `${prefix}: ${labels[0]} never completed.`;
5899
+ }
5900
+ return `${prefix}: ${labels.join("; ")}.`;
5901
+ }
5862
5902
  function stepEndpointName(event, kind) {
5863
5903
  if (kind === "TOOL") return resolveCanonicalToolName(event);
5864
5904
  for (const prefix of ["llm:", "generation:", "transcription:", "speech:"]) {
@@ -5933,6 +5973,56 @@ function eventEndMs(event) {
5933
5973
  }
5934
5974
  return void 0;
5935
5975
  }
5976
+ function rowIndexByEventId(events) {
5977
+ const index = /* @__PURE__ */ new Map();
5978
+ for (const [position, event] of events.entries()) {
5979
+ if (!index.has(event.eventId)) index.set(event.eventId, position);
5980
+ }
5981
+ return index;
5982
+ }
5983
+ function recordedRowSpan(rowIndex, event) {
5984
+ const sourceIds = "sourceEventIds" in event && Array.isArray(event.sourceEventIds) ? event.sourceEventIds : [event.eventId];
5985
+ const rows = [];
5986
+ for (const id of sourceIds) {
5987
+ const row = typeof id === "string" ? rowIndex.get(id) : void 0;
5988
+ if (row === void 0) return void 0;
5989
+ rows.push(row);
5990
+ }
5991
+ if (rows.length === 0) return void 0;
5992
+ return { first: Math.min(...rows), last: Math.max(...rows) };
5993
+ }
5994
+ function recordedTieOrder(context, tiedBefore, tiedAfter) {
5995
+ const rowIndex = rowIndexByEventId(context.events);
5996
+ let lastFinished;
5997
+ let firstStarted;
5998
+ for (const event of tiedBefore) {
5999
+ const span = recordedRowSpan(rowIndex, event);
6000
+ if (span === void 0) return { inOrder: void 0 };
6001
+ if (lastFinished === void 0 || span.last > lastFinished.row) {
6002
+ lastFinished = { event, row: span.last };
6003
+ }
6004
+ }
6005
+ for (const event of tiedAfter) {
6006
+ const span = recordedRowSpan(rowIndex, event);
6007
+ if (span === void 0) return { inOrder: void 0 };
6008
+ if (firstStarted === void 0 || span.first < firstStarted.row) {
6009
+ firstStarted = { event, row: span.first };
6010
+ }
6011
+ }
6012
+ if (lastFinished === void 0 || firstStarted === void 0) return { inOrder: void 0 };
6013
+ return {
6014
+ inOrder: lastFinished.row < firstStarted.row,
6015
+ lastFinishedBefore: lastFinished.event,
6016
+ firstStartedAfter: firstStarted.event
6017
+ };
6018
+ }
6019
+ function tieResolution(order) {
6020
+ return order.inOrder === void 0 ? "recorded-order-unavailable" : "recorded-order";
6021
+ }
6022
+ function tieMessage(order, beforeLabel, afterLabel) {
6023
+ if (order === void 0 || order.inOrder === true) return "";
6024
+ return order.inOrder === void 0 ? " Their timestamps tie at the same millisecond and the recorded event order could not be resolved." : ` Their timestamps tie at the same millisecond; the recorded event order shows ${afterLabel} started before ${beforeLabel} finished.`;
6025
+ }
5936
6026
  function normalizedKey(value) {
5937
6027
  return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
5938
6028
  }
@@ -6150,10 +6240,13 @@ function createRunStatusRule(options = {}) {
6150
6240
  findings.push(
6151
6241
  failFinding(
6152
6242
  "run.status",
6153
- "Run contains incomplete running events.",
6243
+ incompleteRunningMessage("Run contains incomplete running events", running),
6154
6244
  running.map((event) => eventEvidence(event)),
6155
6245
  "no running events",
6156
- running.length
6246
+ {
6247
+ count: running.length,
6248
+ unfinished: running.map(describeRunningEvent)
6249
+ }
6157
6250
  )
6158
6251
  );
6159
6252
  }
@@ -6323,6 +6416,34 @@ function createToolUsageRule(options) {
6323
6416
  const names = tools.map(toolName);
6324
6417
  const nameSet = new Set(names);
6325
6418
  const findings = [];
6419
+ const forbidden = new Set(options.forbidden ?? []);
6420
+ const allowed = options.allowed?.length ? new Set(options.allowed) : void 0;
6421
+ for (const event of tools) {
6422
+ const name = toolName(event);
6423
+ const display = formatToolNameForMessage(name);
6424
+ if (forbidden.has(name)) {
6425
+ findings.push(
6426
+ failFinding(
6427
+ "tool.usage",
6428
+ `Forbidden tool ${display} appeared.`,
6429
+ [eventEvidence(event)],
6430
+ "tool absent",
6431
+ name
6432
+ )
6433
+ );
6434
+ }
6435
+ if (allowed && !allowed.has(name)) {
6436
+ findings.push(
6437
+ failFinding(
6438
+ "tool.usage",
6439
+ `Tool ${display} is not in the allowed tool set.`,
6440
+ [eventEvidence(event)],
6441
+ [...allowed].sort(),
6442
+ name
6443
+ )
6444
+ );
6445
+ }
6446
+ }
6326
6447
  for (const required of options.required ?? []) {
6327
6448
  if (!nameSet.has(required)) {
6328
6449
  const otherKinds = [
@@ -6340,7 +6461,7 @@ function createToolUsageRule(options) {
6340
6461
  findings.push(
6341
6462
  failFinding(
6342
6463
  "tool.usage",
6343
- `Required tool ${required} did not appear.${hint}`,
6464
+ `Required tool ${formatToolNameForMessage(required)} did not appear.${hint}`,
6344
6465
  runEvidence(context.selectedRun),
6345
6466
  required,
6346
6467
  names
@@ -6348,21 +6469,6 @@ function createToolUsageRule(options) {
6348
6469
  );
6349
6470
  }
6350
6471
  }
6351
- const forbidden = new Set(options.forbidden ?? []);
6352
- const allowed = options.allowed?.length ? new Set(options.allowed) : void 0;
6353
- for (const event of tools) {
6354
- const name = toolName(event);
6355
- if (forbidden.has(name)) {
6356
- findings.push(
6357
- failFinding("tool.usage", `Forbidden tool ${name} appeared.`, [eventEvidence(event)], "tool absent", name)
6358
- );
6359
- }
6360
- if (allowed && !allowed.has(name)) {
6361
- findings.push(
6362
- failFinding("tool.usage", `Tool ${name} is not in the allowed tool set.`, [eventEvidence(event)], [...allowed].sort(), name)
6363
- );
6364
- }
6365
- }
6366
6472
  if (options.minCount !== void 0 && tools.length < options.minCount) {
6367
6473
  findings.push(
6368
6474
  failFinding("tool.usage", `Tool count ${tools.length} was below minimum ${options.minCount}.`, runEvidence(context.selectedRun), { minCount: options.minCount }, tools.length)
@@ -6396,6 +6502,28 @@ function createStepOrderingRule(options) {
6396
6502
  const afterEvents = finishedEvents(context, options.after.kind).filter(
6397
6503
  (event) => stepEndpointName(event, options.after.kind) === options.after.name
6398
6504
  );
6505
+ const beforeRunning = semanticEvents(context).filter(
6506
+ (event) => event.kind === options.before.kind && event.status === "running" && stepEndpointName(event, options.before.kind) === options.before.name
6507
+ );
6508
+ if (beforeEvents.length === 0 && afterEvents.length > 0 && beforeRunning.length > 0) {
6509
+ const endpointExpected2 = bothTools ? { before: options.before.name, after: options.after.name } : { before: options.before, after: options.after };
6510
+ return [
6511
+ failFinding(
6512
+ ruleId,
6513
+ `${subject} ${beforeLabel} started but never finished before ${afterLabel} ran.`,
6514
+ [
6515
+ ...beforeRunning.map((event) => eventEvidence(event)),
6516
+ eventEvidence(afterEvents[0])
6517
+ ],
6518
+ { ...endpointExpected2, mode },
6519
+ {
6520
+ code: bothTools ? "tool.order.interval-unresolved" : "step.order.interval-unresolved",
6521
+ unfinishedBefore: true,
6522
+ beforeStatus: "running"
6523
+ }
6524
+ )
6525
+ ];
6526
+ }
6399
6527
  if (beforeEvents.length === 0 || afterEvents.length === 0) {
6400
6528
  if (!requireEndpoints) return [];
6401
6529
  const findings = [];
@@ -6512,16 +6640,18 @@ function createStepOrderingRule(options) {
6512
6640
  )
6513
6641
  ];
6514
6642
  }
6515
- if (beforeEnd > afterStart) {
6643
+ const tie = beforeEnd === afterStart ? recordedTieOrder(context, [beforeEvent], [afterEvent]) : void 0;
6644
+ if (beforeEnd > afterStart || tie !== void 0 && tie.inOrder !== true) {
6516
6645
  return [
6517
6646
  failFinding(
6518
6647
  ruleId,
6519
- `${subject} ${beforeLabel} must finish before ${afterLabel} starts.`,
6648
+ `${subject} ${beforeLabel} must finish before ${afterLabel} starts.${tieMessage(tie, beforeLabel, afterLabel)}`,
6520
6649
  [eventEvidence(beforeEvent), eventEvidence(afterEvent)],
6521
6650
  expected,
6522
6651
  {
6523
6652
  beforeEndedAt: new Date(beforeEnd).toISOString(),
6524
- afterStartedAt: new Date(afterStart).toISOString()
6653
+ afterStartedAt: new Date(afterStart).toISOString(),
6654
+ ...tie !== void 0 ? { resolvedBy: tieResolution(tie) } : {}
6525
6655
  }
6526
6656
  )
6527
6657
  ];
@@ -6584,16 +6714,27 @@ function createStepOrderingRule(options) {
6584
6714
  )
6585
6715
  ];
6586
6716
  }
6587
- if (latestBefore.end > earliestAfter.start) {
6717
+ const tiedEnd = latestBefore.end;
6718
+ const tiedStart = earliestAfter.start;
6719
+ const tie = tiedEnd === tiedStart ? recordedTieOrder(
6720
+ context,
6721
+ beforeEvents.filter((event) => eventEndMs(event) === tiedEnd),
6722
+ afterEvents.filter((event) => eventStartMs(event) === tiedStart)
6723
+ ) : void 0;
6724
+ if (latestBefore.end > earliestAfter.start || tie !== void 0 && tie.inOrder !== true) {
6588
6725
  return [
6589
6726
  failFinding(
6590
6727
  ruleId,
6591
- bothTools ? `Every ${options.before.name} tool call must finish before any ${options.after.name} tool call starts.` : `Every ${beforeLabel} must finish before any ${afterLabel} starts.`,
6592
- [eventEvidence(latestBefore.event), eventEvidence(earliestAfter.event)],
6728
+ (bothTools ? `Every ${options.before.name} tool call must finish before any ${options.after.name} tool call starts.` : `Every ${beforeLabel} must finish before any ${afterLabel} starts.`) + tieMessage(tie, beforeLabel, afterLabel),
6729
+ [
6730
+ eventEvidence(tie?.lastFinishedBefore ?? latestBefore.event),
6731
+ eventEvidence(tie?.firstStartedAfter ?? earliestAfter.event)
6732
+ ],
6593
6733
  expected,
6594
6734
  {
6595
6735
  latestBeforeEndedAt: new Date(latestBefore.end).toISOString(),
6596
- earliestAfterStartedAt: new Date(earliestAfter.start).toISOString()
6736
+ earliestAfterStartedAt: new Date(earliestAfter.start).toISOString(),
6737
+ ...tie !== void 0 ? { resolvedBy: tieResolution(tie) } : {}
6597
6738
  }
6598
6739
  )
6599
6740
  ];
@@ -6759,10 +6900,13 @@ function createStructureIncompleteRule(options = {}) {
6759
6900
  findings.push(
6760
6901
  failFinding(
6761
6902
  "structure.incomplete",
6762
- "Trace contains incomplete running events.",
6903
+ incompleteRunningMessage("Trace contains incomplete running events", running),
6763
6904
  running.map((event) => eventEvidence(event, "status")),
6764
6905
  "no running events",
6765
- running.length
6906
+ {
6907
+ count: running.length,
6908
+ unfinished: running.map(describeRunningEvent)
6909
+ }
6766
6910
  )
6767
6911
  );
6768
6912
  }
@@ -7540,6 +7684,12 @@ var init_checks2 = __esm({
7540
7684
  DEFAULT_SECRET_PATTERNS = [
7541
7685
  { id: "bearer-token", pattern: /Bearer\s+[A-Za-z0-9._~+/-]{12,}=*/ },
7542
7686
  { id: "openai-key", pattern: /sk-[A-Za-z0-9_-]{16,}/ },
7687
+ // Stripe + Slack: keep in sync with packages/redact + credential-value-patterns (#520).
7688
+ {
7689
+ id: "stripe-key",
7690
+ pattern: /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/
7691
+ },
7692
+ { id: "slack-token", pattern: /\bxox[abposr]-[A-Za-z0-9-]{10,}\b/ },
7543
7693
  { id: "aws-access-key", pattern: /AKIA[0-9A-Z]{16}/ },
7544
7694
  { id: "github-token", pattern: /gh[opsu]_[A-Za-z0-9_]{20,}/ },
7545
7695
  // Keep in sync with packages/redact/src/key-value-secret.ts (KEY_VALUE_SECRET_PATTERN_SOURCE).
@@ -9491,10 +9641,17 @@ function contractToRules(contract) {
9491
9641
  (event) => event.status === "running"
9492
9642
  );
9493
9643
  if (running.length > 0) {
9644
+ const labels = running.map((event) => {
9645
+ if (event.kind === "TOOL") {
9646
+ return `tool ${resolveCanonicalToolName(event)}`;
9647
+ }
9648
+ return `${event.kind} ${event.name}`;
9649
+ });
9650
+ const message = labels.length === 1 ? `Run contains incomplete running events: ${labels[0]} never completed.` : `Run contains incomplete running events: ${labels.join("; ")}.`;
9494
9651
  findings.push(
9495
9652
  contractFailFinding(
9496
9653
  "contract.run.allowedStatuses",
9497
- "Run contains incomplete running events.",
9654
+ message,
9498
9655
  running.map((event) => ({
9499
9656
  runId: event.runId,
9500
9657
  eventId: event.eventId,
@@ -9503,7 +9660,10 @@ function contractToRules(contract) {
9503
9660
  status: event.status
9504
9661
  })),
9505
9662
  "no running events",
9506
- running.length
9663
+ {
9664
+ count: running.length,
9665
+ unfinished: labels
9666
+ }
9507
9667
  )
9508
9668
  );
9509
9669
  }
@@ -17304,7 +17464,7 @@ var init_src = __esm({
17304
17464
  });
17305
17465
 
17306
17466
  // package.json
17307
- var version = "6.31.31";
17467
+ var version = "6.31.33";
17308
17468
 
17309
17469
  // packages/cli/src/list.ts
17310
17470
  init_advanced();
@@ -22499,6 +22659,18 @@ var credentialDetectors = [
22499
22659
  pattern: /\b(?:sk-(?:proj-)?[a-zA-Z0-9_-]{16,}|sk-ant-[a-zA-Z0-9_-]{16,}|AIza[0-9A-Za-z_-]{20,})\b/,
22500
22660
  severity: "error"
22501
22661
  }),
22662
+ // Stripe secret/restricted keys (underscore form). Keep in sync with
22663
+ // packages/core/src/safety/credential-value-patterns.ts + checks DEFAULT_SECRET_PATTERNS (#520).
22664
+ patternDetector({
22665
+ id: "value.stripeSecretKey",
22666
+ pattern: /\b(?:sk|rk)_(?:live|test)_[A-Za-z0-9]{16,}\b/,
22667
+ severity: "error"
22668
+ }),
22669
+ patternDetector({
22670
+ id: "value.slackToken",
22671
+ pattern: /\bxox[abposr]-[A-Za-z0-9-]{10,}\b/,
22672
+ severity: "error"
22673
+ }),
22502
22674
  patternDetector({
22503
22675
  id: "value.githubToken",
22504
22676
  pattern: /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\b/,
@@ -24264,8 +24436,9 @@ function parseEvidenceFormat(value) {
24264
24436
  `Unsupported --evidence-format "${value}". Use directory, html, or zip.`
24265
24437
  );
24266
24438
  }
24267
- function toAssessmentStatus(failed) {
24268
- return failed ? "UNSAFE" : "SAFE";
24439
+ function residualStatusToEvidenceSafe(status) {
24440
+ if (status === "SAFE_WITH_WARNINGS") return "SAFE WITH WARNINGS";
24441
+ return status;
24269
24442
  }
24270
24443
  function stableJson2(value) {
24271
24444
  return `${JSON.stringify(value, null, 2)}
@@ -24305,7 +24478,10 @@ async function writeLocalEvidence(input3) {
24305
24478
  combined += redacted.content.endsWith("\n") ? redacted.content : `${redacted.content}
24306
24479
  `;
24307
24480
  }
24308
- const assessmentStatus = toAssessmentStatus(input3.failed);
24481
+ const residual = await assessResidualFromContent(combined, {
24482
+ format: "agent-inspect-jsonl"
24483
+ });
24484
+ const assessmentStatus = residualStatusToEvidenceSafe(residual.status);
24309
24485
  const evidencePackage = buildEvidenceCiPackage({
24310
24486
  generatorVersion: version,
24311
24487
  runIds: input3.runIds,