agent-inspect 6.29.4 → 6.29.5

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 (86) hide show
  1. package/CHANGELOG.md +11 -0
  2. package/README.md +1 -1
  3. package/docs/LIMITATIONS.md +1 -1
  4. package/docs/TRACE-CONTRACTS.md +1 -1
  5. package/package.json +1 -1
  6. package/packages/cli/dist/{chunk-FJRUJSST.mjs → chunk-XWQEHKGB.mjs} +41 -29
  7. package/packages/cli/dist/chunk-XWQEHKGB.mjs.map +1 -0
  8. package/packages/cli/dist/index.cjs +194 -70
  9. package/packages/cli/dist/index.cjs.map +1 -1
  10. package/packages/cli/dist/index.mjs +146 -43
  11. package/packages/cli/dist/index.mjs.map +1 -1
  12. package/packages/cli/dist/{src-GZQVDREP.mjs → src-XNC4EUN3.mjs} +3 -3
  13. package/packages/cli/dist/{src-GZQVDREP.mjs.map → src-XNC4EUN3.mjs.map} +1 -1
  14. package/packages/core/dist/advanced.cjs +20 -9
  15. package/packages/core/dist/advanced.cjs.map +1 -1
  16. package/packages/core/dist/advanced.d.cts +10 -10
  17. package/packages/core/dist/advanced.d.ts +10 -10
  18. package/packages/core/dist/advanced.mjs +15 -14
  19. package/packages/core/dist/advanced.mjs.map +1 -1
  20. package/packages/core/dist/checks.cjs +45 -31
  21. package/packages/core/dist/checks.cjs.map +1 -1
  22. package/packages/core/dist/checks.d.cts +7 -7
  23. package/packages/core/dist/checks.d.ts +7 -7
  24. package/packages/core/dist/checks.mjs +5 -5
  25. package/packages/core/dist/{chunk-7LSVGXCN.mjs → chunk-26YJSETN.mjs} +3 -3
  26. package/packages/core/dist/{chunk-7LSVGXCN.mjs.map → chunk-26YJSETN.mjs.map} +1 -1
  27. package/packages/core/dist/{chunk-5M4QUYFH.mjs → chunk-BGF5JDJN.mjs} +3 -3
  28. package/packages/core/dist/{chunk-5M4QUYFH.mjs.map → chunk-BGF5JDJN.mjs.map} +1 -1
  29. package/packages/core/dist/{chunk-3I6KX32E.mjs → chunk-EE5Z2GQ3.mjs} +20 -12
  30. package/packages/core/dist/chunk-EE5Z2GQ3.mjs.map +1 -0
  31. package/packages/core/dist/{chunk-FKVCTIP6.mjs → chunk-KWBO36PH.mjs} +4 -4
  32. package/packages/core/dist/{chunk-FKVCTIP6.mjs.map → chunk-KWBO36PH.mjs.map} +1 -1
  33. package/packages/core/dist/{chunk-BMRK6XHO.mjs → chunk-PBNBQRXV.mjs} +4 -4
  34. package/packages/core/dist/{chunk-BMRK6XHO.mjs.map → chunk-PBNBQRXV.mjs.map} +1 -1
  35. package/packages/core/dist/{chunk-KNRY24RS.mjs → chunk-Q5SLKV2Y.mjs} +3 -3
  36. package/packages/core/dist/{chunk-KNRY24RS.mjs.map → chunk-Q5SLKV2Y.mjs.map} +1 -1
  37. package/packages/core/dist/{chunk-XPDNO3KH.mjs → chunk-TU47EKKS.mjs} +29 -34
  38. package/packages/core/dist/chunk-TU47EKKS.mjs.map +1 -0
  39. package/packages/core/dist/{chunk-AT7TICCQ.mjs → chunk-WN5PT4GV.mjs} +4 -4
  40. package/packages/core/dist/{chunk-AT7TICCQ.mjs.map → chunk-WN5PT4GV.mjs.map} +1 -1
  41. package/packages/core/dist/{chunk-DZBNXCLA.mjs → chunk-ZFJ2ICTC.mjs} +5 -5
  42. package/packages/core/dist/{chunk-DZBNXCLA.mjs.map → chunk-ZFJ2ICTC.mjs.map} +1 -1
  43. package/packages/core/dist/{context-B8zzsmjX.d.ts → context-B7DqUmsJ.d.ts} +3 -3
  44. package/packages/core/dist/{context-BhaVHtOT.d.cts → context-rR_jW9TH.d.cts} +3 -3
  45. package/packages/core/dist/diff.d.cts +3 -3
  46. package/packages/core/dist/diff.d.ts +3 -3
  47. package/packages/core/dist/exporters.d.cts +3 -3
  48. package/packages/core/dist/exporters.d.ts +3 -3
  49. package/packages/core/dist/exporters.mjs +5 -5
  50. package/packages/core/dist/{index-BT3KcO6-.d.cts → index-Cdww9h50.d.cts} +2 -2
  51. package/packages/core/dist/{index-BaQ48jrq.d.cts → index-DKv7esIo.d.cts} +4 -4
  52. package/packages/core/dist/{index-CrnEOoRu.d.ts → index-DvSbXNot.d.ts} +4 -4
  53. package/packages/core/dist/{index-reskZCVW.d.ts → index-xUbdpcrP.d.ts} +2 -2
  54. package/packages/core/dist/index.cjs +11 -9
  55. package/packages/core/dist/index.cjs.map +1 -1
  56. package/packages/core/dist/index.d.cts +6 -6
  57. package/packages/core/dist/index.d.ts +6 -6
  58. package/packages/core/dist/index.mjs +6 -6
  59. package/packages/core/dist/{inspect-event-CDqjcrG_.d.cts → inspect-event-ClM5Z8om.d.cts} +6 -1
  60. package/packages/core/dist/{inspect-event-CDqjcrG_.d.ts → inspect-event-ClM5Z8om.d.ts} +6 -1
  61. package/packages/core/dist/{log-config-DcjV8ZjF.d.cts → log-config-CyRGaaWd.d.cts} +1 -1
  62. package/packages/core/dist/{log-config-N_c5AE09.d.ts → log-config-DAV_sR9A.d.ts} +1 -1
  63. package/packages/core/dist/logs.d.cts +3 -3
  64. package/packages/core/dist/logs.d.ts +3 -3
  65. package/packages/core/dist/{persisted-inspect-event-BMwvGIB8.d.ts → persisted-inspect-event-DG02LhEP.d.ts} +1 -1
  66. package/packages/core/dist/{persisted-inspect-event-DPaCiars.d.cts → persisted-inspect-event-q2ViiBW6.d.cts} +1 -1
  67. package/packages/core/dist/persisted.cjs +11 -9
  68. package/packages/core/dist/persisted.cjs.map +1 -1
  69. package/packages/core/dist/persisted.d.cts +5 -5
  70. package/packages/core/dist/persisted.d.ts +5 -5
  71. package/packages/core/dist/persisted.mjs +3 -3
  72. package/packages/core/dist/readers.cjs +11 -9
  73. package/packages/core/dist/readers.cjs.map +1 -1
  74. package/packages/core/dist/readers.d.cts +3 -3
  75. package/packages/core/dist/readers.d.ts +3 -3
  76. package/packages/core/dist/readers.mjs +4 -4
  77. package/packages/core/dist/{types-C5Y8Idle.d.ts → types-BX1EPji1.d.ts} +1 -1
  78. package/packages/core/dist/{types-BSzhK7Z1.d.cts → types-bwL8cBv5.d.cts} +1 -1
  79. package/packages/core/dist/writers.cjs +11 -9
  80. package/packages/core/dist/writers.cjs.map +1 -1
  81. package/packages/core/dist/writers.d.cts +2 -2
  82. package/packages/core/dist/writers.d.ts +2 -2
  83. package/packages/core/dist/writers.mjs +3 -3
  84. package/packages/cli/dist/chunk-FJRUJSST.mjs.map +0 -1
  85. package/packages/core/dist/chunk-3I6KX32E.mjs.map +0 -1
  86. package/packages/core/dist/chunk-XPDNO3KH.mjs.map +0 -1
@@ -330,6 +330,28 @@ var init_types = __esm({
330
330
  }
331
331
  });
332
332
 
333
+ // packages/core/src/types/inspect-event.ts
334
+ function isAttributionConfidence(value) {
335
+ return typeof value === "string" && ATTRIBUTION_CONFIDENCES.includes(value);
336
+ }
337
+ var ATTRIBUTION_CONFIDENCES, ATTRIBUTION_CONFIDENCE_RANK;
338
+ var init_inspect_event = __esm({
339
+ "packages/core/src/types/inspect-event.ts"() {
340
+ ATTRIBUTION_CONFIDENCES = [
341
+ "unknown",
342
+ "heuristic",
343
+ "correlated",
344
+ "explicit"
345
+ ];
346
+ ATTRIBUTION_CONFIDENCE_RANK = {
347
+ unknown: 0,
348
+ heuristic: 1,
349
+ correlated: 2,
350
+ explicit: 3
351
+ };
352
+ }
353
+ });
354
+
333
355
  // packages/core/src/types/persisted-inspect-event.ts
334
356
  function isRecord3(value) {
335
357
  return typeof value === "object" && value !== null && !Array.isArray(value);
@@ -352,9 +374,6 @@ function isOptionalNonNegativeNumber(value) {
352
374
  function isInspectKind(value) {
353
375
  return typeof value === "string" && INSPECT_KINDS.includes(value);
354
376
  }
355
- function isAttributionConfidence(value) {
356
- return typeof value === "string" && ATTRIBUTION_CONFIDENCES.includes(value);
357
- }
358
377
  function isPersistedEventSourceType(value) {
359
378
  return typeof value === "string" && PERSISTED_EVENT_SOURCE_TYPES.includes(value);
360
379
  }
@@ -429,9 +448,10 @@ function isPersistedInspectEvent(value) {
429
448
  }
430
449
  return true;
431
450
  }
432
- var INSPECT_KINDS, ATTRIBUTION_CONFIDENCES, PERSISTED_EVENT_SOURCE_TYPES, PERSISTED_EVENT_STATUSES;
451
+ var INSPECT_KINDS, PERSISTED_EVENT_SOURCE_TYPES, PERSISTED_EVENT_STATUSES;
433
452
  var init_persisted_inspect_event = __esm({
434
453
  "packages/core/src/types/persisted-inspect-event.ts"() {
454
+ init_inspect_event();
435
455
  INSPECT_KINDS = [
436
456
  "RUN",
437
457
  "AGENT",
@@ -446,12 +466,6 @@ var init_persisted_inspect_event = __esm({
446
466
  "LOG",
447
467
  "OUTCOME"
448
468
  ];
449
- ATTRIBUTION_CONFIDENCES = [
450
- "explicit",
451
- "correlated",
452
- "heuristic",
453
- "unknown"
454
- ];
455
469
  PERSISTED_EVENT_SOURCE_TYPES = [
456
470
  "manual",
457
471
  "json-log",
@@ -5442,7 +5456,7 @@ function flattenNodes(nodes) {
5442
5456
  function buildFacts2(input3, selectedRun) {
5443
5457
  const scopedRuns = selectedRun ? [selectedRun] : input3.read.runs;
5444
5458
  const scopedRunIds = new Set(scopedRuns.map((run) => run.runId));
5445
- const scopedEvents = selectedRun === void 0 ? input3.read.events : input3.read.events.filter((event) => scopedRunIds.has(event.runId));
5459
+ const scopedEvents2 = selectedRun === void 0 ? input3.read.events : input3.read.events.filter((event) => scopedRunIds.has(event.runId));
5446
5460
  const nodes = flattenNodes(scopedRuns.flatMap((run) => run.children));
5447
5461
  const nodesByEventId = /* @__PURE__ */ new Map();
5448
5462
  const childrenByParentId = /* @__PURE__ */ new Map();
@@ -5455,11 +5469,11 @@ function buildFacts2(input3, selectedRun) {
5455
5469
  childrenByParentId.set(parentId, children);
5456
5470
  }
5457
5471
  }
5458
- const projection = projectLogicalEvents(scopedEvents);
5472
+ const projection = projectLogicalEvents(scopedEvents2);
5459
5473
  return {
5460
5474
  format: input3.read.format,
5461
5475
  runs: Object.freeze([...input3.read.runs]),
5462
- events: Object.freeze([...scopedEvents]),
5476
+ events: Object.freeze([...scopedEvents2]),
5463
5477
  logicalEvents: projection.logicalEvents,
5464
5478
  logicalProjectionDiagnostics: projection.diagnostics,
5465
5479
  readerWarnings: Object.freeze([...input3.read.warnings]),
@@ -6293,6 +6307,12 @@ function createStructureCycleRule() {
6293
6307
  };
6294
6308
  }
6295
6309
  function createStructureRelationshipRule(options = {}) {
6310
+ if (options.minConfidence !== void 0 && !isAttributionConfidence(options.minConfidence)) {
6311
+ throw new TypeError(
6312
+ `createStructureRelationshipRule: minConfidence must be one of: ${ATTRIBUTION_CONFIDENCES.join(", ")}.`
6313
+ );
6314
+ }
6315
+ const minConfidence = options.minConfidence;
6296
6316
  return {
6297
6317
  id: "structure.relationship",
6298
6318
  category: "structure",
@@ -6300,18 +6320,21 @@ function createStructureRelationshipRule(options = {}) {
6300
6320
  evaluate(context) {
6301
6321
  const byId = eventMap(semanticEvents(context));
6302
6322
  const findings = [];
6303
- const minConfidence = options.minConfidence;
6304
6323
  for (const event of semanticEvents(context)) {
6305
- if (minConfidence && CONFIDENCE_RANK[event.confidence] < CONFIDENCE_RANK[minConfidence]) {
6306
- findings.push(
6307
- failFinding(
6308
- "structure.relationship",
6309
- `Event confidence ${event.confidence} is below ${minConfidence}.`,
6310
- [eventEvidence(event, "confidence")],
6311
- { minConfidence },
6312
- event.confidence
6313
- )
6314
- );
6324
+ if (minConfidence) {
6325
+ const eventRank = CONFIDENCE_RANK[event.confidence] ?? CONFIDENCE_RANK.unknown;
6326
+ const minRank = CONFIDENCE_RANK[minConfidence];
6327
+ if (eventRank < minRank) {
6328
+ findings.push(
6329
+ failFinding(
6330
+ "structure.relationship",
6331
+ `Event confidence ${event.confidence} is below ${minConfidence}.`,
6332
+ [eventEvidence(event, "confidence")],
6333
+ { minConfidence },
6334
+ event.confidence
6335
+ )
6336
+ );
6337
+ }
6315
6338
  }
6316
6339
  if (!event.parentId) continue;
6317
6340
  if (event.parentId === event.eventId) {
@@ -6882,6 +6905,7 @@ function runTraceChecks(input3, options = {}) {
6882
6905
  var SEVERITY_RANK, STATUS_RANK, CONFIDENCE_RANK, DEFAULT_SENSITIVE_KEYS, DEFAULT_RAW_CONTENT_KEYS, DEFAULT_SAFE_RAW_CONTENT_PATH_PREFIXES, SAFE_USAGE_LEAF_KEYS, DEFAULT_SECRET_PATTERNS;
6883
6906
  var init_checks2 = __esm({
6884
6907
  "packages/core/src/checks/index.ts"() {
6908
+ init_inspect_event();
6885
6909
  init_programmatic();
6886
6910
  init_outcomes();
6887
6911
  init_sensitive_key();
@@ -6901,12 +6925,7 @@ var init_checks2 = __esm({
6901
6925
  warning: 1,
6902
6926
  pass: 2
6903
6927
  };
6904
- CONFIDENCE_RANK = {
6905
- unknown: 0,
6906
- heuristic: 1,
6907
- correlated: 2,
6908
- explicit: 3
6909
- };
6928
+ CONFIDENCE_RANK = ATTRIBUTION_CONFIDENCE_RANK;
6910
6929
  DEFAULT_SENSITIVE_KEYS = DEFAULT_CREDENTIAL_SENSITIVE_KEYS;
6911
6930
  DEFAULT_RAW_CONTENT_KEYS = [
6912
6931
  "body",
@@ -13273,6 +13292,7 @@ var init_advanced = __esm({
13273
13292
  init_terminal();
13274
13293
  init_utils();
13275
13294
  init_types();
13295
+ init_inspect_event();
13276
13296
  init_storage();
13277
13297
  init_read_trace();
13278
13298
  init_trace_directory();
@@ -13759,7 +13779,7 @@ var init_src = __esm({
13759
13779
  });
13760
13780
 
13761
13781
  // package.json
13762
- var version = "6.29.4";
13782
+ var version = "6.29.5";
13763
13783
 
13764
13784
  // packages/cli/src/list.ts
13765
13785
  init_advanced();
@@ -18439,6 +18459,7 @@ async function loadRedactionPolicy(policyPath) {
18439
18459
 
18440
18460
  // packages/core/src/entries/checks.ts
18441
18461
  init_checks2();
18462
+ init_inspect_event();
18442
18463
 
18443
18464
  // packages/cli/src/trace-input.ts
18444
18465
  init_advanced();
@@ -19807,12 +19828,22 @@ function open2(ruleId, message, evidence, severity = "error") {
19807
19828
  };
19808
19829
  }
19809
19830
  function isToolEvent(event) {
19831
+ const kind = typeof event.kind === "string" ? event.kind.toLowerCase() : "";
19832
+ if (kind === "tool") return true;
19833
+ if (kind === "llm" || kind === "run" || kind === "agent" || kind === "logic" || kind === "log" || kind === "outcome" || kind === "chain" || kind === "retriever" || kind === "decision" || kind === "result" || kind === "error") {
19834
+ return false;
19835
+ }
19810
19836
  const name = event.name.toLowerCase();
19811
- return event.kind === "tool" || name.startsWith("tool:") || name.startsWith("function:") || name.includes(".tool.") || name.startsWith("mcp:");
19837
+ return name.startsWith("tool:") || name.startsWith("function:") || name.includes(".tool.") || name.startsWith("mcp:");
19812
19838
  }
19813
19839
  function isLlmEvent(event) {
19840
+ const kind = typeof event.kind === "string" ? event.kind.toLowerCase() : "";
19841
+ if (kind === "llm") return true;
19842
+ if (kind === "tool" || kind === "run" || kind === "agent" || kind === "logic" || kind === "log" || kind === "outcome" || kind === "chain" || kind === "retriever" || kind === "decision" || kind === "result" || kind === "error") {
19843
+ return false;
19844
+ }
19814
19845
  const name = event.name.toLowerCase();
19815
- return event.kind === "llm" || name.startsWith("llm:") || name.includes(".llm.") || name.includes("generation");
19846
+ return name.startsWith("llm:") || name.includes(".llm.") || name.includes("generation");
19816
19847
  }
19817
19848
  function toolLabel(event) {
19818
19849
  const attrs = event.attributes ?? {};
@@ -20257,6 +20288,14 @@ var CIRCUIT_ALIASES = {
20257
20288
  "runaway-llm-loop": "circuit.runaway-llm-loop",
20258
20289
  "excessive-branch-width": "circuit.excessive-branch-width"
20259
20290
  };
20291
+ var KNOWN_CIRCUIT_RULES = /* @__PURE__ */ new Set([
20292
+ ...Object.values(CIRCUIT_ALIASES),
20293
+ ...ALL_RULES
20294
+ ]);
20295
+ var KNOWN_GUARDRAIL_RULES = /* @__PURE__ */ new Set([
20296
+ ...Object.values(GUARDRAIL_ALIASES),
20297
+ ...ALL_RULES2
20298
+ ]);
20260
20299
  function parseGuardrailRules(values) {
20261
20300
  if (!values?.length) return void 0;
20262
20301
  return values.map((value) => {
@@ -20319,16 +20358,21 @@ function eventToCircuit(event) {
20319
20358
  status: event.status
20320
20359
  };
20321
20360
  }
20322
- function collectGuardrailInputs(read) {
20361
+ function scopedEvents(read, runId) {
20362
+ if (runId === void 0) return [...read.events];
20363
+ return read.events.filter((event) => event.runId === runId);
20364
+ }
20365
+ function collectGuardrailInputs(events) {
20323
20366
  const inputs = [];
20324
- for (const event of read.events) {
20367
+ for (const event of events) {
20325
20368
  const attrs = event.attributes ?? {};
20326
20369
  for (const key of ["output", "answer", "text", "content", "message"]) {
20327
20370
  const value = attrs[key];
20328
20371
  if (typeof value === "string") inputs.push({ text: value });
20329
20372
  else if (value !== void 0) inputs.push({ value });
20330
20373
  }
20331
- if (event.kind === "TOOL" || event.name.startsWith("tool:")) {
20374
+ const kind = typeof event.kind === "string" ? event.kind.toLowerCase() : "";
20375
+ if (kind === "tool" || event.name.startsWith("tool:")) {
20332
20376
  inputs.push({
20333
20377
  toolName: String(attrs.toolName ?? attrs.tool ?? event.name),
20334
20378
  toolArgs: attrs.arguments ?? attrs.args ?? attrs.input
@@ -20337,6 +20381,21 @@ function collectGuardrailInputs(read) {
20337
20381
  }
20338
20382
  return inputs;
20339
20383
  }
20384
+ function classifyExtensionExecution(findings, errored) {
20385
+ if (errored) return "error";
20386
+ if (findings.some((finding) => finding.status === "fail")) return "fail";
20387
+ if (findings.some((finding) => finding.status === "warning")) return "warning";
20388
+ return "pass";
20389
+ }
20390
+ function extensionExecution(ruleId, findings, options) {
20391
+ return {
20392
+ ruleId,
20393
+ category: "safety",
20394
+ status: classifyExtensionExecution(findings, options.errored === true),
20395
+ findingCount: findings.length,
20396
+ ...options.runId !== void 0 ? { runId: options.runId } : {}
20397
+ };
20398
+ }
20340
20399
  var DEFAULT_GUARDRAIL_OPTIONS = {
20341
20400
  bannedPhrase: { phrases: ["delete all data", "ignore all instructions"] },
20342
20401
  promptInjection: {},
@@ -20353,53 +20412,116 @@ var DEFAULT_CIRCUIT_OPTIONS = {
20353
20412
  };
20354
20413
  function mergeSafetyExtensions(result, read, options) {
20355
20414
  const findings = [...result.findings];
20415
+ const ruleExecutions = [...result.ruleExecutions ?? []];
20356
20416
  let failed = result.summary.failed;
20357
20417
  let warnings = result.summary.warnings;
20358
20418
  let passed = result.summary.passed;
20419
+ let errors = result.summary.errors;
20420
+ const events = scopedEvents(read, options.runId);
20421
+ const runId = options.runId;
20359
20422
  const guardrailRules = parseGuardrailRules(options.guardrails);
20360
20423
  if (guardrailRules) {
20361
- for (const input3 of collectGuardrailInputs(read)) {
20362
- const run = runGuardrails(input3, {
20363
- ...DEFAULT_GUARDRAIL_OPTIONS,
20364
- rules: guardrailRules
20365
- });
20366
- for (const item of run.results) {
20367
- const finding = guardrailFinding(item);
20424
+ const inputs = collectGuardrailInputs(events);
20425
+ for (const ruleId of guardrailRules) {
20426
+ if (!KNOWN_GUARDRAIL_RULES.has(ruleId)) {
20427
+ const finding = {
20428
+ ruleId,
20429
+ severity: "error",
20430
+ status: "fail",
20431
+ message: `Unknown guardrail rule: ${ruleId}.`,
20432
+ evidence: []
20433
+ };
20368
20434
  findings.push(finding);
20369
- if (finding.status === "fail") failed += 1;
20370
- else if (finding.status === "warning") warnings += 1;
20371
- else passed += 1;
20435
+ failed += 1;
20436
+ ruleExecutions.push(extensionExecution(ruleId, [finding], { runId, errored: true }));
20437
+ errors += 1;
20438
+ continue;
20439
+ }
20440
+ const ruleFindings = [];
20441
+ if (inputs.length === 0) {
20442
+ ruleExecutions.push(extensionExecution(ruleId, [], { runId }));
20443
+ continue;
20444
+ }
20445
+ for (const input3 of inputs) {
20446
+ const run = runGuardrails(input3, {
20447
+ ...DEFAULT_GUARDRAIL_OPTIONS,
20448
+ rules: [ruleId]
20449
+ });
20450
+ for (const item of run.results) {
20451
+ const finding = guardrailFinding(item);
20452
+ ruleFindings.push(finding);
20453
+ findings.push(finding);
20454
+ if (finding.status === "fail") failed += 1;
20455
+ else if (finding.status === "warning") warnings += 1;
20456
+ else passed += 1;
20457
+ }
20372
20458
  }
20459
+ ruleExecutions.push(extensionExecution(ruleId, ruleFindings, { runId }));
20373
20460
  }
20374
20461
  }
20375
20462
  const circuitRules = parseCircuitRules(options.circuits);
20376
20463
  if (circuitRules) {
20377
- const circuitRun = runCircuits(
20378
- read.events.map(eventToCircuit),
20379
- { ...DEFAULT_CIRCUIT_OPTIONS, rules: circuitRules }
20380
- );
20381
- for (const item of circuitRun.results) {
20382
- const finding = circuitFinding(item);
20383
- findings.push(finding);
20384
- if (finding.status === "fail") failed += 1;
20385
- else if (finding.status === "warning") warnings += 1;
20386
- else passed += 1;
20464
+ const projected = projectLogicalEvents(events);
20465
+ const circuitEvents = projected.logicalEvents.map(eventToCircuit);
20466
+ for (const ruleId of circuitRules) {
20467
+ if (!KNOWN_CIRCUIT_RULES.has(ruleId)) {
20468
+ const finding = {
20469
+ ruleId,
20470
+ severity: "error",
20471
+ status: "fail",
20472
+ message: `Unknown circuit rule: ${ruleId}.`,
20473
+ evidence: []
20474
+ };
20475
+ findings.push(finding);
20476
+ failed += 1;
20477
+ errors += 1;
20478
+ ruleExecutions.push(extensionExecution(ruleId, [finding], { runId, errored: true }));
20479
+ continue;
20480
+ }
20481
+ const circuitRun = runCircuits(circuitEvents, {
20482
+ ...DEFAULT_CIRCUIT_OPTIONS,
20483
+ rules: [ruleId]
20484
+ });
20485
+ if (circuitRun.results.length === 0) {
20486
+ const finding = {
20487
+ ruleId,
20488
+ severity: "error",
20489
+ status: "fail",
20490
+ message: `Circuit rule ${ruleId} produced no evaluation result.`,
20491
+ evidence: []
20492
+ };
20493
+ findings.push(finding);
20494
+ failed += 1;
20495
+ errors += 1;
20496
+ ruleExecutions.push(extensionExecution(ruleId, [finding], { runId, errored: true }));
20497
+ continue;
20498
+ }
20499
+ const ruleFindings = [];
20500
+ for (const item of circuitRun.results) {
20501
+ const finding = circuitFinding(item);
20502
+ ruleFindings.push(finding);
20503
+ findings.push(finding);
20504
+ if (finding.status === "fail") failed += 1;
20505
+ else if (finding.status === "warning") warnings += 1;
20506
+ else passed += 1;
20507
+ }
20508
+ ruleExecutions.push(extensionExecution(ruleId, ruleFindings, { runId }));
20387
20509
  }
20388
20510
  }
20389
- const ok = failed === 0 && result.summary.errors === 0;
20511
+ const status = result.status === "error" || errors > 0 ? "error" : failed > 0 ? "fail" : result.status;
20390
20512
  return {
20391
20513
  ...result,
20392
- ok,
20393
- status: failed > 0 ? "fail" : result.status,
20514
+ ok: status === "pass",
20515
+ status,
20394
20516
  summary: {
20395
20517
  passed,
20396
20518
  failed,
20397
20519
  warnings,
20398
- errors: result.summary.errors,
20399
- rulesEvaluated: result.summary.rulesEvaluated ?? 0
20520
+ errors,
20521
+ rulesEvaluated: ruleExecutions.length
20400
20522
  },
20401
20523
  findings,
20402
- ruleExecutions: result.ruleExecutions ?? []
20524
+ ruleExecutions
20403
20525
  };
20404
20526
  }
20405
20527
 
@@ -20603,7 +20725,7 @@ var SAFETY_KEYS = /* @__PURE__ */ new Set([
20603
20725
  "maxFindings"
20604
20726
  ]);
20605
20727
  var RUN_EXPECTED = /* @__PURE__ */ new Set(["ok", "error", "running"]);
20606
- var CONFIDENCE_VALUES = /* @__PURE__ */ new Set(["exact", "high", "medium", "low", "inferred"]);
20728
+ var CONFIDENCE_LIST = ATTRIBUTION_CONFIDENCES.join(", ");
20607
20729
  var CheckConfigError = class extends Error {
20608
20730
  code;
20609
20731
  constructor(code, message) {
@@ -20745,10 +20867,10 @@ function parseStructureSection(value) {
20745
20867
  rejectUnknownKeys(record, STRUCTURE_KEYS, "checks.structure");
20746
20868
  const out = {};
20747
20869
  if (record.minConfidence !== void 0) {
20748
- if (typeof record.minConfidence !== "string" || !CONFIDENCE_VALUES.has(record.minConfidence)) {
20870
+ if (!isAttributionConfidence(record.minConfidence)) {
20749
20871
  throw new CheckConfigError(
20750
20872
  "AI_CHECK_CONFIG_INVALID_VALUE",
20751
- `checks.structure.minConfidence must be one of: exact, high, medium, low, inferred.`
20873
+ `checks.structure.minConfidence must be one of: ${CONFIDENCE_LIST}.`
20752
20874
  );
20753
20875
  }
20754
20876
  out.minConfidence = record.minConfidence;
@@ -21258,7 +21380,8 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
21258
21380
  read,
21259
21381
  {
21260
21382
  ...options.guardrails ? { guardrails: options.guardrails } : {},
21261
- ...options.circuit ? { circuits: options.circuit } : {}
21383
+ ...options.circuit ? { circuits: options.circuit } : {},
21384
+ runId: meta2.runId
21262
21385
  }
21263
21386
  )
21264
21387
  );
@@ -21311,7 +21434,8 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
21311
21434
  read,
21312
21435
  {
21313
21436
  ...options.guardrails ? { guardrails: options.guardrails } : {},
21314
- ...options.circuit ? { circuits: options.circuit } : {}
21437
+ ...options.circuit ? { circuits: options.circuit } : {},
21438
+ ...options.run !== void 0 ? { runId: options.run } : {}
21315
21439
  }
21316
21440
  );
21317
21441
  }
@@ -23490,10 +23614,10 @@ function selectRun4(read, runId) {
23490
23614
  }
23491
23615
  function summarizeTrace(read, run) {
23492
23616
  const runId = run?.runId;
23493
- const scopedEvents = runId === void 0 ? read.events : read.events.filter((event) => event.runId === runId);
23617
+ const scopedEvents2 = runId === void 0 ? read.events : read.events.filter((event) => event.runId === runId);
23494
23618
  const eventsByKind = {};
23495
23619
  const eventsByStatus = {};
23496
- for (const event of scopedEvents) {
23620
+ for (const event of scopedEvents2) {
23497
23621
  increment(eventsByKind, event.kind);
23498
23622
  increment(eventsByStatus, event.status);
23499
23623
  }
@@ -23503,7 +23627,7 @@ function summarizeTrace(read, run) {
23503
23627
  ...run?.status !== void 0 ? { runStatus: run.status } : {},
23504
23628
  ...run?.durationMs !== void 0 ? { runDurationMs: run.durationMs } : {},
23505
23629
  runCount: read.runs.length,
23506
- eventCount: scopedEvents.length,
23630
+ eventCount: scopedEvents2.length,
23507
23631
  eventsByKind: Object.fromEntries(Object.entries(eventsByKind).sort()),
23508
23632
  eventsByStatus: Object.fromEntries(Object.entries(eventsByStatus).sort()),
23509
23633
  readerWarnings: read.warnings.length,