agent-inspect 6.17.3 → 6.17.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 (40) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/docs/ADAPTER-CONFORMANCE.md +24 -0
  4. package/docs/ADAPTERS.md +3 -3
  5. package/docs/API.md +13 -7
  6. package/docs/CI-ARTIFACTS.md +2 -1
  7. package/docs/CLI.md +2 -0
  8. package/docs/LIMITATIONS.md +1 -0
  9. package/docs/OPENAI-AGENTS-LOCAL.md +14 -0
  10. package/docs/SAFE-TRACE-SHARING.md +1 -0
  11. package/docs/SELF-HOSTING.md +2 -0
  12. package/docs/STANDARDS.md +15 -0
  13. package/docs/SUPPORT-LEVELS.md +23 -0
  14. package/docs/TRACE-CONTRACTS.md +90 -0
  15. package/package.json +7 -3
  16. package/packages/cli/dist/{chunk-5GGYDIZD.mjs → chunk-GOHYSE7W.mjs} +93 -19
  17. package/packages/cli/dist/chunk-GOHYSE7W.mjs.map +1 -0
  18. package/packages/cli/dist/index.cjs +505 -88
  19. package/packages/cli/dist/index.cjs.map +1 -1
  20. package/packages/cli/dist/index.mjs +417 -74
  21. package/packages/cli/dist/index.mjs.map +1 -1
  22. package/packages/cli/dist/{src-IDMCWKRH.mjs → src-OYGG7QAZ.mjs} +3 -3
  23. package/packages/cli/dist/{src-IDMCWKRH.mjs.map → src-OYGG7QAZ.mjs.map} +1 -1
  24. package/packages/core/dist/advanced.cjs +86 -17
  25. package/packages/core/dist/advanced.cjs.map +1 -1
  26. package/packages/core/dist/advanced.d.cts +1 -1
  27. package/packages/core/dist/advanced.d.ts +1 -1
  28. package/packages/core/dist/advanced.mjs +15 -5
  29. package/packages/core/dist/advanced.mjs.map +1 -1
  30. package/packages/core/dist/checks.cjs +126 -28
  31. package/packages/core/dist/checks.cjs.map +1 -1
  32. package/packages/core/dist/checks.d.cts +28 -2
  33. package/packages/core/dist/checks.d.ts +28 -2
  34. package/packages/core/dist/checks.mjs +1 -1
  35. package/packages/core/dist/{chunk-UFP54T7F.mjs → chunk-DIZPIPY2.mjs} +128 -30
  36. package/packages/core/dist/chunk-DIZPIPY2.mjs.map +1 -0
  37. package/packages/core/dist/{index-Xk9X-yjY.d.cts → index-DWu54Y28.d.cts} +107 -122
  38. package/packages/core/dist/{index-BsCcOKxy.d.ts → index-DlwbVqEs.d.ts} +107 -122
  39. package/packages/cli/dist/chunk-5GGYDIZD.mjs.map +0 -1
  40. package/packages/core/dist/chunk-UFP54T7F.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
- import { L as LogicalProjectionDiagnostic, a as LogicalTraceEvent, T as TraceCheckInput, b as TraceCheckResult } from './index-Xk9X-yjY.cjs';
2
- export { B as BaselineRegressionRuleOptions, D as DecisionRuleOptions, G as GuardrailRuleOptions, c as LlmUsageRuleOptions, M as MaxStepDurationRuleOptions, O as ObservedOutcomeRuleOptions, R as RetrievalRuleOptions, d as RunDepthRuleOptions, e as RunDurationRuleOptions, f as RunEventCountRuleOptions, g as RunStatusRuleOptions, h as RunTraceChecksOptions, S as SafetyFindingCategory, i as SafetyFindingConfidence, j as SafetyOversizedAttributeRuleOptions, k as SafetyRawContentRuleOptions, l as SafetyRedactionRuleOptions, m as SafetySecretPattern, n as SafetySecretPatternRuleOptions, o as StallDetectionRuleOptions, p as StructureIncompleteRuleOptions, q as StructureOrphanRuleOptions, r as StructureParallelWidthRuleOptions, s as StructureRelationshipRuleOptions, t as ToolFailureRuleOptions, u as ToolOrderingRuleOptions, v as ToolUsageRuleOptions, w as TraceCheckContext, x as TraceCheckDiagnostic, y as TraceCheckDiagnosticCode, z as TraceCheckEvidence, A as TraceCheckFacts, C as TraceCheckFinding, E as TraceCheckFindingStatus, F as TraceCheckRule, H as TraceCheckRuleCategory, I as TraceCheckSeverity, J as TraceCheckStatus, K as TraceCheckSummary, N as TraceSignalRuleOptions, P as createBaselineRegressionRule, Q as createDecisionRule, U as createGuardrailRule, V as createLlmUsageRule, W as createMaxStepDurationRule, X as createObservedOutcomeRule, Y as createRequireCompletedRule, Z as createRetrievalRule, _ as createRunDepthRule, $ as createRunDurationRule, a0 as createRunEventCountRule, a1 as createRunStatusRule, a2 as createSafetyOversizedAttributeRule, a3 as createSafetyRawContentRule, a4 as createSafetyRedactionRule, a5 as createSafetySecretPatternRule, a6 as createStallDetectionRule, a7 as createStructureCycleRule, a8 as createStructureIncompleteRule, a9 as createStructureOrphanRule, aa as createStructureParallelWidthRule, ab as createStructureRelationshipRule, ac as createToolFailureRule, ad as createToolOrderingRule, ae as createToolUsageRule, af as projectLogicalEvents, ag as resolveCanonicalToolName, ah as runTraceChecks } from './index-Xk9X-yjY.cjs';
1
+ import { L as LogicalProjectionDiagnostic, a as LogicalTraceEvent, T as TraceCheckInput, b as TraceCheckResult } from './index-DWu54Y28.cjs';
2
+ export { B as BaselineRegressionRuleOptions, D as DecisionRuleOptions, G as GuardrailRuleOptions, c as LlmUsageRuleOptions, M as MaxStepDurationRuleOptions, O as ObservedOutcomeRuleOptions, R as RetrievalRuleOptions, d as RunDepthRuleOptions, e as RunDurationRuleOptions, f as RunEventCountRuleOptions, g as RunStatusRuleOptions, h as RunTraceChecksOptions, S as SafetyFindingCategory, i as SafetyFindingConfidence, j as SafetyOversizedAttributeRuleOptions, k as SafetyRawContentRuleOptions, l as SafetyRedactionRuleOptions, m as SafetySecretPattern, n as SafetySecretPatternRuleOptions, o as StallDetectionRuleOptions, p as StructureIncompleteRuleOptions, q as StructureOrphanRuleOptions, r as StructureParallelWidthRuleOptions, s as StructureRelationshipRuleOptions, t as ToolFailureRuleOptions, u as ToolOrderingRuleOptions, v as ToolUsageRuleOptions, w as TraceCheckContext, x as TraceCheckDiagnostic, y as TraceCheckDiagnosticCode, z as TraceCheckEvidence, A as TraceCheckFacts, C as TraceCheckFinding, E as TraceCheckFindingStatus, F as TraceCheckRule, H as TraceCheckRuleCategory, I as TraceCheckRuleExecution, J as TraceCheckRuleExecutionStatus, K as TraceCheckSeverity, N as TraceCheckStatus, P as TraceCheckSummary, Q as TraceSignalRuleOptions, U as createBaselineRegressionRule, V as createDecisionRule, W as createGuardrailRule, X as createLlmUsageRule, Y as createMaxStepDurationRule, Z as createObservedOutcomeRule, _ as createRequireCompletedRule, $ as createRetrievalRule, a0 as createRunDepthRule, a1 as createRunDurationRule, a2 as createRunEventCountRule, a3 as createRunStatusRule, a4 as createSafetyOversizedAttributeRule, a5 as createSafetyRawContentRule, a6 as createSafetyRedactionRule, a7 as createSafetySecretPatternRule, a8 as createStallDetectionRule, a9 as createStructureCycleRule, aa as createStructureIncompleteRule, ab as createStructureOrphanRule, ac as createStructureParallelWidthRule, ad as createStructureRelationshipRule, ae as createToolFailureRule, af as createToolOrderingRule, ag as createToolUsageRule, ah as projectLogicalEvents, ai as resolveCanonicalToolName, aj as runTraceChecks } from './index-DWu54Y28.cjs';
3
3
  export { PROGRAMMATIC_DIAGNOSTIC_SPECS, ProgrammaticDiagnosticCode, ProgrammaticDiagnosticSpec, formatProgrammaticDiagnostic } from './readers.cjs';
4
4
  import { T as TraceReadResult } from './index-B259NKkH.cjs';
5
5
  import { P as PersistedInspectEvent } from './persisted-inspect-event-CVZWZldL.cjs';
@@ -66,6 +66,13 @@ interface TraceContractRunRules {
66
66
  maxDurationMs?: number;
67
67
  }
68
68
  interface TraceContractToolRules {
69
+ /**
70
+ * Unconditional tool presence invariant. Every named tool must appear at least
71
+ * once. Do not use for cache-hit or alternate-path shortcuts — prefer
72
+ * `observations.required` until `alternatives.anyOf` ships (planned 6.20.0).
73
+ *
74
+ * @see docs/TRACE-CONTRACTS.md
75
+ */
69
76
  required?: string[];
70
77
  /** Alias of `required` (TraceContract v2 normalization). */
71
78
  requiredTools?: string[];
@@ -74,6 +81,25 @@ interface TraceContractToolRules {
74
81
  forbiddenTools?: string[];
75
82
  allowed?: string[];
76
83
  maxCalls?: number;
84
+ /**
85
+ * Required tool order as adjacent first-occurrence pairs (start/encounter order).
86
+ *
87
+ * `[A, B, C]` expands to “A before B” and “B before C”, each comparing the
88
+ * first occurrence of the named tool. Unlisted intermediate tools are
89
+ * allowed. Later repetitions do not invalidate an earlier valid order.
90
+ *
91
+ * TraceContract `requiredOrder` **implies presence**: every listed name is
92
+ * added to the effective required-tool set. Low-level `createToolOrderingRule`
93
+ * alone may still pass vacuously when an endpoint is missing.
94
+ *
95
+ * This is **not** causal happens-before. Overlapping intervals emit a
96
+ * non-failing overlap warning. Planned modes (6.20.0, GitHub #308):
97
+ * `happens-before`, `all-occurrences`.
98
+ *
99
+ * @see docs/TRACE-CONTRACTS.md
100
+ * @beta Available through `agent-inspect/checks`. Additive changes may ship
101
+ * in minor releases; breaking changes require a future major.
102
+ */
77
103
  requiredOrder?: string[];
78
104
  }
79
105
  interface TraceContractLlmRules {
@@ -1,5 +1,5 @@
1
- import { L as LogicalProjectionDiagnostic, a as LogicalTraceEvent, T as TraceCheckInput, b as TraceCheckResult } from './index-BsCcOKxy.js';
2
- export { B as BaselineRegressionRuleOptions, D as DecisionRuleOptions, G as GuardrailRuleOptions, c as LlmUsageRuleOptions, M as MaxStepDurationRuleOptions, O as ObservedOutcomeRuleOptions, R as RetrievalRuleOptions, d as RunDepthRuleOptions, e as RunDurationRuleOptions, f as RunEventCountRuleOptions, g as RunStatusRuleOptions, h as RunTraceChecksOptions, S as SafetyFindingCategory, i as SafetyFindingConfidence, j as SafetyOversizedAttributeRuleOptions, k as SafetyRawContentRuleOptions, l as SafetyRedactionRuleOptions, m as SafetySecretPattern, n as SafetySecretPatternRuleOptions, o as StallDetectionRuleOptions, p as StructureIncompleteRuleOptions, q as StructureOrphanRuleOptions, r as StructureParallelWidthRuleOptions, s as StructureRelationshipRuleOptions, t as ToolFailureRuleOptions, u as ToolOrderingRuleOptions, v as ToolUsageRuleOptions, w as TraceCheckContext, x as TraceCheckDiagnostic, y as TraceCheckDiagnosticCode, z as TraceCheckEvidence, A as TraceCheckFacts, C as TraceCheckFinding, E as TraceCheckFindingStatus, F as TraceCheckRule, H as TraceCheckRuleCategory, I as TraceCheckSeverity, J as TraceCheckStatus, K as TraceCheckSummary, N as TraceSignalRuleOptions, P as createBaselineRegressionRule, Q as createDecisionRule, U as createGuardrailRule, V as createLlmUsageRule, W as createMaxStepDurationRule, X as createObservedOutcomeRule, Y as createRequireCompletedRule, Z as createRetrievalRule, _ as createRunDepthRule, $ as createRunDurationRule, a0 as createRunEventCountRule, a1 as createRunStatusRule, a2 as createSafetyOversizedAttributeRule, a3 as createSafetyRawContentRule, a4 as createSafetyRedactionRule, a5 as createSafetySecretPatternRule, a6 as createStallDetectionRule, a7 as createStructureCycleRule, a8 as createStructureIncompleteRule, a9 as createStructureOrphanRule, aa as createStructureParallelWidthRule, ab as createStructureRelationshipRule, ac as createToolFailureRule, ad as createToolOrderingRule, ae as createToolUsageRule, af as projectLogicalEvents, ag as resolveCanonicalToolName, ah as runTraceChecks } from './index-BsCcOKxy.js';
1
+ import { L as LogicalProjectionDiagnostic, a as LogicalTraceEvent, T as TraceCheckInput, b as TraceCheckResult } from './index-DlwbVqEs.js';
2
+ export { B as BaselineRegressionRuleOptions, D as DecisionRuleOptions, G as GuardrailRuleOptions, c as LlmUsageRuleOptions, M as MaxStepDurationRuleOptions, O as ObservedOutcomeRuleOptions, R as RetrievalRuleOptions, d as RunDepthRuleOptions, e as RunDurationRuleOptions, f as RunEventCountRuleOptions, g as RunStatusRuleOptions, h as RunTraceChecksOptions, S as SafetyFindingCategory, i as SafetyFindingConfidence, j as SafetyOversizedAttributeRuleOptions, k as SafetyRawContentRuleOptions, l as SafetyRedactionRuleOptions, m as SafetySecretPattern, n as SafetySecretPatternRuleOptions, o as StallDetectionRuleOptions, p as StructureIncompleteRuleOptions, q as StructureOrphanRuleOptions, r as StructureParallelWidthRuleOptions, s as StructureRelationshipRuleOptions, t as ToolFailureRuleOptions, u as ToolOrderingRuleOptions, v as ToolUsageRuleOptions, w as TraceCheckContext, x as TraceCheckDiagnostic, y as TraceCheckDiagnosticCode, z as TraceCheckEvidence, A as TraceCheckFacts, C as TraceCheckFinding, E as TraceCheckFindingStatus, F as TraceCheckRule, H as TraceCheckRuleCategory, I as TraceCheckRuleExecution, J as TraceCheckRuleExecutionStatus, K as TraceCheckSeverity, N as TraceCheckStatus, P as TraceCheckSummary, Q as TraceSignalRuleOptions, U as createBaselineRegressionRule, V as createDecisionRule, W as createGuardrailRule, X as createLlmUsageRule, Y as createMaxStepDurationRule, Z as createObservedOutcomeRule, _ as createRequireCompletedRule, $ as createRetrievalRule, a0 as createRunDepthRule, a1 as createRunDurationRule, a2 as createRunEventCountRule, a3 as createRunStatusRule, a4 as createSafetyOversizedAttributeRule, a5 as createSafetyRawContentRule, a6 as createSafetyRedactionRule, a7 as createSafetySecretPatternRule, a8 as createStallDetectionRule, a9 as createStructureCycleRule, aa as createStructureIncompleteRule, ab as createStructureOrphanRule, ac as createStructureParallelWidthRule, ad as createStructureRelationshipRule, ae as createToolFailureRule, af as createToolOrderingRule, ag as createToolUsageRule, ah as projectLogicalEvents, ai as resolveCanonicalToolName, aj as runTraceChecks } from './index-DlwbVqEs.js';
3
3
  export { PROGRAMMATIC_DIAGNOSTIC_SPECS, ProgrammaticDiagnosticCode, ProgrammaticDiagnosticSpec, formatProgrammaticDiagnostic } from './readers.js';
4
4
  import { T as TraceReadResult } from './index-B9ZGvUVL.js';
5
5
  import { P as PersistedInspectEvent } from './persisted-inspect-event-BVucFVrP.js';
@@ -66,6 +66,13 @@ interface TraceContractRunRules {
66
66
  maxDurationMs?: number;
67
67
  }
68
68
  interface TraceContractToolRules {
69
+ /**
70
+ * Unconditional tool presence invariant. Every named tool must appear at least
71
+ * once. Do not use for cache-hit or alternate-path shortcuts — prefer
72
+ * `observations.required` until `alternatives.anyOf` ships (planned 6.20.0).
73
+ *
74
+ * @see docs/TRACE-CONTRACTS.md
75
+ */
69
76
  required?: string[];
70
77
  /** Alias of `required` (TraceContract v2 normalization). */
71
78
  requiredTools?: string[];
@@ -74,6 +81,25 @@ interface TraceContractToolRules {
74
81
  forbiddenTools?: string[];
75
82
  allowed?: string[];
76
83
  maxCalls?: number;
84
+ /**
85
+ * Required tool order as adjacent first-occurrence pairs (start/encounter order).
86
+ *
87
+ * `[A, B, C]` expands to “A before B” and “B before C”, each comparing the
88
+ * first occurrence of the named tool. Unlisted intermediate tools are
89
+ * allowed. Later repetitions do not invalidate an earlier valid order.
90
+ *
91
+ * TraceContract `requiredOrder` **implies presence**: every listed name is
92
+ * added to the effective required-tool set. Low-level `createToolOrderingRule`
93
+ * alone may still pass vacuously when an endpoint is missing.
94
+ *
95
+ * This is **not** causal happens-before. Overlapping intervals emit a
96
+ * non-failing overlap warning. Planned modes (6.20.0, GitHub #308):
97
+ * `happens-before`, `all-occurrences`.
98
+ *
99
+ * @see docs/TRACE-CONTRACTS.md
100
+ * @beta Available through `agent-inspect/checks`. Additive changes may ship
101
+ * in minor releases; breaking changes require a future major.
102
+ */
77
103
  requiredOrder?: string[];
78
104
  }
79
105
  interface TraceContractLlmRules {
@@ -1,4 +1,4 @@
1
- export { buildTraceFacts, createBaselineRegressionRule, createDecisionRule, createGuardrailRule, createLlmUsageRule, createMaxStepDurationRule, createObservedOutcomeRule, createRequireCompletedRule, createRetrievalRule, createRunDepthRule, createRunDurationRule, createRunEventCountRule, createRunStatusRule, createSafetyOversizedAttributeRule, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createStallDetectionRule, createStructureCycleRule, createStructureIncompleteRule, createStructureOrphanRule, createStructureParallelWidthRule, createStructureRelationshipRule, createToolFailureRule, createToolOrderingRule, createToolUsageRule, defineTraceContract, evaluateTraceContract, evaluateTraceContractRead, projectLogicalEvents, resolveCanonicalToolName, runTraceChecks, summarizeSemanticParity } from './chunk-UFP54T7F.mjs';
1
+ export { buildTraceFacts, createBaselineRegressionRule, createDecisionRule, createGuardrailRule, createLlmUsageRule, createMaxStepDurationRule, createObservedOutcomeRule, createRequireCompletedRule, createRetrievalRule, createRunDepthRule, createRunDurationRule, createRunEventCountRule, createRunStatusRule, createSafetyOversizedAttributeRule, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createStallDetectionRule, createStructureCycleRule, createStructureIncompleteRule, createStructureOrphanRule, createStructureParallelWidthRule, createStructureRelationshipRule, createToolFailureRule, createToolOrderingRule, createToolUsageRule, defineTraceContract, evaluateTraceContract, evaluateTraceContractRead, projectLogicalEvents, resolveCanonicalToolName, runTraceChecks, summarizeSemanticParity } from './chunk-DIZPIPY2.mjs';
2
2
  import './chunk-VFO76UH3.mjs';
3
3
  import './chunk-ULCGIRTC.mjs';
4
4
  import './chunk-VU6O5QAH.mjs';
@@ -395,8 +395,11 @@ function buildTraceFacts(input) {
395
395
  }
396
396
 
397
397
  // packages/core/src/safety/sensitive-key.ts
398
+ function keyHasExplicitSeparator(value) {
399
+ return /[_\-.]/.test(value);
400
+ }
398
401
  function normalizeSensitiveKey(value) {
399
- return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
402
+ return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").toLowerCase().replace(/[^a-z0-9]+/g, "_").replace(/^_+|_+$/g, "");
400
403
  }
401
404
  var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
402
405
  [
@@ -448,6 +451,7 @@ function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSIT
448
451
  const normalized = normalizeSensitiveKey(key);
449
452
  if (!normalized) return false;
450
453
  if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
454
+ const allowPrefixCompound = keyHasExplicitSeparator(key);
451
455
  for (const sensitive of sensitiveKeys) {
452
456
  const s = normalizeSensitiveKey(sensitive);
453
457
  if (!s) continue;
@@ -456,7 +460,8 @@ function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSIT
456
460
  continue;
457
461
  }
458
462
  if (normalized === s) return true;
459
- if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
463
+ if (normalized.endsWith(`_${s}`)) return true;
464
+ if (allowPrefixCompound && normalized.startsWith(`${s}_`)) return true;
460
465
  }
461
466
  return false;
462
467
  }
@@ -554,10 +559,11 @@ function emptySummary() {
554
559
  passed: 0,
555
560
  failed: 0,
556
561
  warnings: 0,
557
- errors: 0
562
+ errors: 0,
563
+ rulesEvaluated: 0
558
564
  };
559
565
  }
560
- function errorResult(input, diagnostics, selectedRun) {
566
+ function errorResult(input, diagnostics, selectedRun, ruleExecutions = []) {
561
567
  return {
562
568
  ok: false,
563
569
  status: "error",
@@ -565,10 +571,12 @@ function errorResult(input, diagnostics, selectedRun) {
565
571
  ...selectedRun ? { runId: selectedRun.runId } : {},
566
572
  summary: {
567
573
  ...emptySummary(),
568
- errors: diagnostics.filter((item) => item.severity === "error").length
574
+ errors: diagnostics.filter((item) => item.severity === "error").length,
575
+ rulesEvaluated: ruleExecutions.length
569
576
  },
570
577
  findings: [],
571
- diagnostics: [...diagnostics]
578
+ diagnostics: [...diagnostics],
579
+ ruleExecutions: [...ruleExecutions]
572
580
  };
573
581
  }
574
582
  function flattenNodes(nodes) {
@@ -724,7 +732,7 @@ function normalizeFinding(rule, finding) {
724
732
  ...finding.action !== void 0 ? { action: finding.action } : {}
725
733
  };
726
734
  }
727
- function summarize(findings, diagnostics) {
735
+ function summarize(findings, diagnostics, rulesEvaluated) {
728
736
  return {
729
737
  passed: findings.filter((finding) => finding.status === "pass").length,
730
738
  failed: findings.filter(
@@ -733,9 +741,21 @@ function summarize(findings, diagnostics) {
733
741
  warnings: findings.filter(
734
742
  (finding) => finding.status === "warning" || finding.severity === "warning"
735
743
  ).length,
736
- errors: diagnostics.filter((item) => item.severity === "error").length
744
+ errors: diagnostics.filter((item) => item.severity === "error").length,
745
+ rulesEvaluated
737
746
  };
738
747
  }
748
+ function classifyRuleExecution(findings, threw) {
749
+ if (findings.some((finding) => finding.status === "fail" && finding.severity === "error")) {
750
+ return "fail";
751
+ }
752
+ if (findings.some(
753
+ (finding) => finding.status === "warning" || finding.severity === "warning"
754
+ )) {
755
+ return "warning";
756
+ }
757
+ return "pass";
758
+ }
739
759
  function stringAttr(event, keys) {
740
760
  for (const key of keys) {
741
761
  const value = event.attributes?.[key];
@@ -832,6 +852,9 @@ function finishedEvents(context, kind) {
832
852
  (event) => (kind === void 0 || event.kind === kind) && event.status !== "running"
833
853
  );
834
854
  }
855
+ function toolInvocationEvents(context) {
856
+ return semanticEvents(context).filter((event) => event.kind === "TOOL");
857
+ }
835
858
  function firstIndexByName(events) {
836
859
  const index = /* @__PURE__ */ new Map();
837
860
  for (const [position, event] of events.entries()) {
@@ -1279,7 +1302,7 @@ function createToolUsageRule(options) {
1279
1302
  category: "tool",
1280
1303
  defaultSeverity: "error",
1281
1304
  evaluate(context) {
1282
- const tools = finishedEvents(context, "TOOL");
1305
+ const tools = toolInvocationEvents(context);
1283
1306
  const names = tools.map(toolName);
1284
1307
  const nameSet = new Set(names);
1285
1308
  const findings = [];
@@ -1320,8 +1343,9 @@ function createToolUsageRule(options) {
1320
1343
  };
1321
1344
  }
1322
1345
  function createToolOrderingRule(options) {
1346
+ const ruleId = options.id ?? "tool.order";
1323
1347
  return {
1324
- id: "tool.order",
1348
+ id: ruleId,
1325
1349
  category: "tool",
1326
1350
  defaultSeverity: "error",
1327
1351
  evaluate(context) {
@@ -1329,18 +1353,42 @@ function createToolOrderingRule(options) {
1329
1353
  const index = firstIndexByName(tools);
1330
1354
  const beforeIndex = index.get(options.before);
1331
1355
  const afterIndex = index.get(options.after);
1332
- if (beforeIndex === void 0 || afterIndex === void 0 || beforeIndex < afterIndex) {
1356
+ if (beforeIndex === void 0 || afterIndex === void 0) {
1333
1357
  return [];
1334
1358
  }
1335
- return [
1336
- failFinding(
1337
- "tool.order",
1338
- `Tool ${options.before} must appear before ${options.after}.`,
1339
- [eventEvidence(tools[beforeIndex]), eventEvidence(tools[afterIndex])],
1340
- { before: options.before, after: options.after },
1341
- tools.map(toolName)
1342
- )
1343
- ];
1359
+ if (beforeIndex >= afterIndex) {
1360
+ return [
1361
+ failFinding(
1362
+ ruleId,
1363
+ `Tool ${options.before} must appear before ${options.after}.`,
1364
+ [eventEvidence(tools[beforeIndex]), eventEvidence(tools[afterIndex])],
1365
+ { before: options.before, after: options.after },
1366
+ tools.map(toolName)
1367
+ )
1368
+ ];
1369
+ }
1370
+ const beforeEvent = tools[beforeIndex];
1371
+ const afterEvent = tools[afterIndex];
1372
+ const beforeEnd = eventEndMs(beforeEvent);
1373
+ const afterStart = eventStartMs(afterEvent);
1374
+ if (beforeEnd !== void 0 && afterStart !== void 0 && beforeEnd > afterStart) {
1375
+ return [
1376
+ {
1377
+ ruleId,
1378
+ severity: "warning",
1379
+ status: "warning",
1380
+ message: `Tool order ${options.before} before ${options.after} satisfied start/encounter order, but intervals overlap so causal completion before the next tool was not established.`,
1381
+ expected: { before: options.before, after: options.after, mode: "first-occurrence" },
1382
+ actual: {
1383
+ code: "tool.order.overlap",
1384
+ beforeEndedAt: beforeEvent.endedAt,
1385
+ afterStartedAt: afterEvent.startedAt ?? afterEvent.timestamp
1386
+ },
1387
+ evidence: [eventEvidence(beforeEvent), eventEvidence(afterEvent)]
1388
+ }
1389
+ ];
1390
+ }
1391
+ return [];
1344
1392
  }
1345
1393
  };
1346
1394
  }
@@ -2137,12 +2185,24 @@ function createBaselineRegressionRule(options) {
2137
2185
  }
2138
2186
  function createObservedOutcomeRule(options = {}) {
2139
2187
  const failOn = options.failOn ?? ["failed"];
2188
+ const requireAny = options.requireAny === true;
2140
2189
  return {
2141
2190
  id: "outcome.status",
2142
2191
  category: "run",
2143
2192
  defaultSeverity: "error",
2144
2193
  evaluate(context) {
2145
2194
  const outcomes = extractOutcomesFromPersistedEvents(context.events);
2195
+ if (requireAny && outcomes.length === 0) {
2196
+ return [
2197
+ failFinding(
2198
+ "outcome.status",
2199
+ "Expected at least one observed outcome.",
2200
+ runEvidence(context.selectedRun),
2201
+ { requireAny: true, expected: "at least one observed outcome" },
2202
+ { code: "outcome.missing", actual: 0 }
2203
+ )
2204
+ ];
2205
+ }
2146
2206
  const matching = outcomesMatchingStatus(outcomes, failOn);
2147
2207
  if (matching.length === 0) return [];
2148
2208
  return [
@@ -2178,6 +2238,18 @@ function runTraceChecks(input, options = {}) {
2178
2238
  if (rules.diagnostics.length > 0) {
2179
2239
  return errorResult(input, rules.diagnostics, selected.run);
2180
2240
  }
2241
+ if (rules.rules.length === 0) {
2242
+ return errorResult(
2243
+ input,
2244
+ [
2245
+ diagnostic(
2246
+ "AI_CHECK_NO_RULES_EVALUATED",
2247
+ "No trace check rules were evaluated. Configure at least one rule, contract, or CLI check option."
2248
+ )
2249
+ ],
2250
+ selected.run
2251
+ );
2252
+ }
2181
2253
  const facts = buildFacts(input, selected.run);
2182
2254
  const context = {
2183
2255
  ...facts,
@@ -2186,22 +2258,38 @@ function runTraceChecks(input, options = {}) {
2186
2258
  };
2187
2259
  const diagnostics = [];
2188
2260
  const findings = [];
2261
+ const ruleExecutions = [];
2189
2262
  for (const rule of rules.rules) {
2190
2263
  try {
2191
- findings.push(...rule.evaluate(context).map((finding) => normalizeFinding(rule, finding)));
2264
+ const ruleFindings = rule.evaluate(context).map((finding) => normalizeFinding(rule, finding));
2265
+ findings.push(...ruleFindings);
2266
+ ruleExecutions.push({
2267
+ ruleId: rule.id,
2268
+ category: rule.category,
2269
+ status: classifyRuleExecution(ruleFindings, false),
2270
+ findingCount: ruleFindings.length,
2271
+ ...selected.run ? { runId: selected.run.runId } : {}
2272
+ });
2192
2273
  } catch (error) {
2193
2274
  const message = error instanceof Error ? error.message : String(error);
2194
2275
  diagnostics.push(
2195
2276
  diagnostic("AI_CHECK_INTERNAL_ERROR", `Rule ${rule.id} failed: ${message}`, rule.id)
2196
2277
  );
2278
+ ruleExecutions.push({
2279
+ ruleId: rule.id,
2280
+ category: rule.category,
2281
+ status: "error",
2282
+ findingCount: 0,
2283
+ ...selected.run ? { runId: selected.run.runId } : {}
2284
+ });
2197
2285
  }
2198
2286
  }
2199
2287
  if (diagnostics.length > 0) {
2200
- return errorResult(input, diagnostics, selected.run);
2288
+ return errorResult(input, diagnostics, selected.run, ruleExecutions);
2201
2289
  }
2202
2290
  const eventById = new Map(input.read.events.map((event) => [event.eventId, event]));
2203
2291
  const sortedFindings = findings.sort(compareFindings(eventById));
2204
- const summary = summarize(sortedFindings, diagnostics);
2292
+ const summary = summarize(sortedFindings, diagnostics, ruleExecutions.length);
2205
2293
  const status = summary.failed > 0 ? "fail" : "pass";
2206
2294
  return {
2207
2295
  ok: status === "pass",
@@ -2210,7 +2298,8 @@ function runTraceChecks(input, options = {}) {
2210
2298
  ...selected.run ? { runId: selected.run.runId } : {},
2211
2299
  summary,
2212
2300
  findings: sortedFindings,
2213
- diagnostics
2301
+ diagnostics,
2302
+ ruleExecutions
2214
2303
  };
2215
2304
  }
2216
2305
 
@@ -2305,9 +2394,13 @@ function contractToRules(contract) {
2305
2394
  rules.push(createStructureIncompleteRule({ requireEndedAtForStarted: true }));
2306
2395
  }
2307
2396
  if (contract.tools) {
2397
+ const order = contract.tools.requiredOrder ?? [];
2308
2398
  const required = [
2309
- ...contract.tools.required ?? [],
2310
- ...contract.tools.requiredTools ?? []
2399
+ .../* @__PURE__ */ new Set([
2400
+ ...contract.tools.required ?? [],
2401
+ ...contract.tools.requiredTools ?? [],
2402
+ ...order
2403
+ ])
2311
2404
  ];
2312
2405
  const forbidden = [
2313
2406
  ...contract.tools.forbidden ?? [],
@@ -2321,9 +2414,14 @@ function contractToRules(contract) {
2321
2414
  ...contract.tools.maxCalls !== void 0 ? { maxCount: contract.tools.maxCalls } : {}
2322
2415
  })
2323
2416
  );
2324
- const order = contract.tools.requiredOrder ?? [];
2325
2417
  for (let i = 0; i < order.length - 1; i += 1) {
2326
- rules.push(createToolOrderingRule({ before: order[i], after: order[i + 1] }));
2418
+ rules.push(
2419
+ createToolOrderingRule({
2420
+ before: order[i],
2421
+ after: order[i + 1],
2422
+ id: `contract.tool.order.${i}`
2423
+ })
2424
+ );
2327
2425
  }
2328
2426
  }
2329
2427
  if (contract.llm) {
@@ -2391,5 +2489,5 @@ function evaluateTraceContractRead(read, contract, options = {}) {
2391
2489
  }
2392
2490
 
2393
2491
  export { buildTraceFacts, createBaselineRegressionRule, createDecisionRule, createGuardrailRule, createLlmUsageRule, createMaxStepDurationRule, createObservedOutcomeRule, createRequireCompletedRule, createRetrievalRule, createRunDepthRule, createRunDurationRule, createRunEventCountRule, createRunStatusRule, createSafetyOversizedAttributeRule, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createStallDetectionRule, createStructureCycleRule, createStructureIncompleteRule, createStructureOrphanRule, createStructureParallelWidthRule, createStructureRelationshipRule, createToolFailureRule, createToolOrderingRule, createToolUsageRule, defineTraceContract, evaluateTraceContract, evaluateTraceContractRead, projectLogicalEvents, resolveCanonicalToolName, runTraceChecks, summarizeSemanticParity };
2394
- //# sourceMappingURL=chunk-UFP54T7F.mjs.map
2395
- //# sourceMappingURL=chunk-UFP54T7F.mjs.map
2492
+ //# sourceMappingURL=chunk-DIZPIPY2.mjs.map
2493
+ //# sourceMappingURL=chunk-DIZPIPY2.mjs.map