agent-inspect 6.14.0 → 6.14.2

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 (76) hide show
  1. package/CHANGELOG.md +22 -6
  2. package/README.md +47 -45
  3. package/docs/DEMO-SCRIPT.md +2 -2
  4. package/docs/GOLDEN-PATH.md +18 -18
  5. package/docs/KNOWN-ISSUES.md +2 -1
  6. package/docs/SUPPORT-LEVELS.md +2 -2
  7. package/docs/TRACE-CONTRACTS.md +13 -3
  8. package/package.json +15 -6
  9. package/packages/cli/dist/{chunk-MEO2Z3KE.mjs → chunk-AACUXCHT.mjs} +205 -35
  10. package/packages/cli/dist/chunk-AACUXCHT.mjs.map +1 -0
  11. package/packages/cli/dist/index.cjs +265 -35
  12. package/packages/cli/dist/index.cjs.map +1 -1
  13. package/packages/cli/dist/index.mjs +59 -6
  14. package/packages/cli/dist/index.mjs.map +1 -1
  15. package/packages/cli/dist/{src-6VZNGIF6.mjs → src-ABTS4GO4.mjs} +3 -3
  16. package/packages/cli/dist/{src-6VZNGIF6.mjs.map → src-ABTS4GO4.mjs.map} +1 -1
  17. package/packages/core/dist/advanced.cjs +156 -19
  18. package/packages/core/dist/advanced.cjs.map +1 -1
  19. package/packages/core/dist/advanced.d.cts +17 -9
  20. package/packages/core/dist/advanced.d.ts +17 -9
  21. package/packages/core/dist/advanced.mjs +6 -6
  22. package/packages/core/dist/checks.cjs +108 -18
  23. package/packages/core/dist/checks.cjs.map +1 -1
  24. package/packages/core/dist/checks.d.cts +4 -4
  25. package/packages/core/dist/checks.d.ts +4 -4
  26. package/packages/core/dist/checks.mjs +1 -1
  27. package/packages/core/dist/{chunk-CTA6XNDP.mjs → chunk-5N2OBM7S.mjs} +3 -3
  28. package/packages/core/dist/{chunk-CTA6XNDP.mjs.map → chunk-5N2OBM7S.mjs.map} +1 -1
  29. package/packages/core/dist/chunk-AK5EN4U2.mjs +174 -0
  30. package/packages/core/dist/chunk-AK5EN4U2.mjs.map +1 -0
  31. package/packages/core/dist/{chunk-BS2QCAJX.mjs → chunk-BHMXLDLK.mjs} +110 -20
  32. package/packages/core/dist/chunk-BHMXLDLK.mjs.map +1 -0
  33. package/packages/core/dist/{chunk-UOPVGCOB.mjs → chunk-NXQF73EC.mjs} +3 -3
  34. package/packages/core/dist/{chunk-UOPVGCOB.mjs.map → chunk-NXQF73EC.mjs.map} +1 -1
  35. package/packages/core/dist/{chunk-LFWZEO2L.mjs → chunk-SGL4JGCD.mjs} +3 -3
  36. package/packages/core/dist/{chunk-LFWZEO2L.mjs.map → chunk-SGL4JGCD.mjs.map} +1 -1
  37. package/packages/core/dist/{context-BHAgRjOe.d.cts → context-Ca5yK8Cs.d.cts} +3 -3
  38. package/packages/core/dist/{context-Blyjb5my.d.ts → context-D6cS4XIL.d.ts} +3 -3
  39. package/packages/core/dist/diff.d.cts +3 -3
  40. package/packages/core/dist/diff.d.ts +3 -3
  41. package/packages/core/dist/exporters.d.cts +3 -3
  42. package/packages/core/dist/exporters.d.ts +3 -3
  43. package/packages/core/dist/exporters.mjs +1 -1
  44. package/packages/core/dist/{index-CmXMS-MF.d.cts → index-BY6XZ5aG.d.cts} +3 -3
  45. package/packages/core/dist/{index-Bu_vOjql.d.ts → index-D9HBequ_.d.ts} +3 -3
  46. package/packages/core/dist/index.d.cts +6 -6
  47. package/packages/core/dist/index.d.ts +6 -6
  48. package/packages/core/dist/{inspect-event-DVg84S4v.d.cts → inspect-event-DRthdZlf.d.cts} +9 -0
  49. package/packages/core/dist/{inspect-event-DVg84S4v.d.ts → inspect-event-DRthdZlf.d.ts} +9 -0
  50. package/packages/core/dist/{log-config-BG1WmWf2.d.cts → log-config-CFlIJHTf.d.cts} +1 -1
  51. package/packages/core/dist/{log-config-Ck0aT_Ou.d.ts → log-config-OZRfpHED.d.ts} +1 -1
  52. package/packages/core/dist/logs.cjs +95 -15
  53. package/packages/core/dist/logs.cjs.map +1 -1
  54. package/packages/core/dist/logs.d.cts +3 -3
  55. package/packages/core/dist/logs.d.ts +3 -3
  56. package/packages/core/dist/logs.mjs +2 -2
  57. package/packages/core/dist/{persisted-inspect-event-ChE7pGb7.d.ts → persisted-inspect-event-BVucFVrP.d.ts} +1 -1
  58. package/packages/core/dist/{persisted-inspect-event-d-mSP8kd.d.cts → persisted-inspect-event-CVZWZldL.d.cts} +1 -1
  59. package/packages/core/dist/persisted.cjs +95 -15
  60. package/packages/core/dist/persisted.cjs.map +1 -1
  61. package/packages/core/dist/persisted.d.cts +5 -5
  62. package/packages/core/dist/persisted.d.ts +5 -5
  63. package/packages/core/dist/persisted.mjs +3 -3
  64. package/packages/core/dist/readers.cjs +95 -15
  65. package/packages/core/dist/readers.cjs.map +1 -1
  66. package/packages/core/dist/readers.d.cts +2 -2
  67. package/packages/core/dist/readers.d.ts +2 -2
  68. package/packages/core/dist/readers.mjs +3 -3
  69. package/packages/core/dist/{types-MuwXSJ4b.d.ts → types--ainI31J.d.ts} +1 -1
  70. package/packages/core/dist/{types-BLX3tiOW.d.cts → types-UnrNaTo2.d.cts} +1 -1
  71. package/packages/core/dist/writers.d.cts +2 -2
  72. package/packages/core/dist/writers.d.ts +2 -2
  73. package/packages/cli/dist/chunk-MEO2Z3KE.mjs.map +0 -1
  74. package/packages/core/dist/chunk-BS2QCAJX.mjs.map +0 -1
  75. package/packages/core/dist/chunk-T5MASTIW.mjs +0 -94
  76. package/packages/core/dist/chunk-T5MASTIW.mjs.map +0 -1
@@ -0,0 +1,174 @@
1
+ // packages/core/src/logs/tree-builder.ts
2
+ function inc(map, key) {
3
+ map[key] = (map[key] ?? 0) + 1;
4
+ }
5
+ function confidenceRank(confidence) {
6
+ switch (confidence) {
7
+ case "unknown":
8
+ return 0;
9
+ case "heuristic":
10
+ return 1;
11
+ case "correlated":
12
+ return 2;
13
+ case "explicit":
14
+ return 3;
15
+ default:
16
+ return 0;
17
+ }
18
+ }
19
+ function computeRunStatus(events) {
20
+ let runTerminal;
21
+ let sawRunEvent = false;
22
+ for (const e of events) {
23
+ if (e.kind !== "RUN") continue;
24
+ sawRunEvent = true;
25
+ if (e.status === "ok" || e.status === "error") {
26
+ runTerminal = e.status;
27
+ }
28
+ }
29
+ if (sawRunEvent) {
30
+ return runTerminal ?? "running";
31
+ }
32
+ let hasRunning = false;
33
+ for (const e of events) {
34
+ if (e.status === "error") return "error";
35
+ if (e.status === "running") hasRunning = true;
36
+ }
37
+ return hasRunning ? "running" : "ok";
38
+ }
39
+ function linkNodesVisibilityFirst(nodes) {
40
+ let selfParentCount = 0;
41
+ let unresolvedParentCount = 0;
42
+ let normalizedEdgeCount = 0;
43
+ let cycleCount = 0;
44
+ const pending = [];
45
+ for (const node of nodes.values()) {
46
+ const parentId = node.event.parentId;
47
+ if (!parentId) continue;
48
+ if (parentId === node.event.eventId) {
49
+ selfParentCount += 1;
50
+ normalizedEdgeCount += 1;
51
+ continue;
52
+ }
53
+ if (!nodes.has(parentId)) {
54
+ unresolvedParentCount += 1;
55
+ continue;
56
+ }
57
+ pending.push({
58
+ childId: node.event.eventId,
59
+ parentId,
60
+ childTimestamp: node.event.timestamp,
61
+ childConfidence: node.event.confidence
62
+ });
63
+ }
64
+ pending.sort((a, b) => {
65
+ const conf = confidenceRank(b.childConfidence) - confidenceRank(a.childConfidence);
66
+ if (conf !== 0) return conf;
67
+ return a.childTimestamp - b.childTimestamp;
68
+ });
69
+ const parentOf = /* @__PURE__ */ new Map();
70
+ for (const edge of pending) {
71
+ parentOf.set(edge.childId, edge.parentId);
72
+ let cursor = edge.parentId;
73
+ const seen = /* @__PURE__ */ new Set([edge.childId]);
74
+ let cyclic = false;
75
+ while (cursor) {
76
+ if (seen.has(cursor)) {
77
+ cyclic = true;
78
+ break;
79
+ }
80
+ seen.add(cursor);
81
+ cursor = parentOf.get(cursor);
82
+ }
83
+ if (cyclic) {
84
+ parentOf.delete(edge.childId);
85
+ cycleCount += 1;
86
+ normalizedEdgeCount += 1;
87
+ }
88
+ }
89
+ for (const [childId, parentId] of parentOf) {
90
+ nodes.get(parentId).children.push(nodes.get(childId));
91
+ }
92
+ const roots = [];
93
+ for (const node of nodes.values()) {
94
+ if (!parentOf.has(node.event.eventId)) {
95
+ roots.push(node);
96
+ }
97
+ }
98
+ const assignDepth = (n, depth, stack) => {
99
+ if (stack.has(n.event.eventId)) return;
100
+ n.depth = depth;
101
+ stack.add(n.event.eventId);
102
+ for (const c of n.children) assignDepth(c, depth + 1, stack);
103
+ stack.delete(n.event.eventId);
104
+ };
105
+ for (const r of roots) assignDepth(r, 0, /* @__PURE__ */ new Set());
106
+ return {
107
+ roots,
108
+ summary: {
109
+ rootCount: roots.length,
110
+ selfParentCount,
111
+ cycleCount,
112
+ unresolvedParentCount,
113
+ normalizedEdgeCount
114
+ }
115
+ };
116
+ }
117
+ var TreeBuilder = class {
118
+ constructor(options) {
119
+ void options?.config;
120
+ }
121
+ build(events) {
122
+ const byRun = /* @__PURE__ */ new Map();
123
+ for (const e of events) {
124
+ if (!byRun.has(e.runId)) byRun.set(e.runId, []);
125
+ byRun.get(e.runId).push(e);
126
+ }
127
+ const out = [];
128
+ for (const [runId, runEvents] of byRun.entries()) {
129
+ const sorted = [...runEvents].sort((a, b) => a.timestamp - b.timestamp);
130
+ const nodes = /* @__PURE__ */ new Map();
131
+ for (const e of sorted) {
132
+ nodes.set(e.eventId, { event: e, children: [], depth: 0 });
133
+ }
134
+ const { roots, summary } = linkNodesVisibilityFirst(nodes);
135
+ const confidenceBreakdown = {
136
+ explicit: 0,
137
+ correlated: 0,
138
+ heuristic: 0,
139
+ unknown: 0
140
+ };
141
+ const kinds = {};
142
+ for (const e of sorted) {
143
+ inc(confidenceBreakdown, e.confidence);
144
+ kinds[e.kind] = (kinds[e.kind] ?? 0) + 1;
145
+ }
146
+ const startedAt = sorted.length > 0 ? sorted[0].timestamp : void 0;
147
+ const endedAt = sorted.length > 0 ? sorted[sorted.length - 1].timestamp : void 0;
148
+ const status = computeRunStatus(sorted);
149
+ const durationMs = startedAt !== void 0 && endedAt !== void 0 && Number.isFinite(startedAt) && Number.isFinite(endedAt) && endedAt >= startedAt && status !== "running" ? endedAt - startedAt : void 0;
150
+ const name = sorted.find((e) => e.kind === "RUN")?.name;
151
+ out.push({
152
+ runId,
153
+ name,
154
+ status,
155
+ startedAt,
156
+ endedAt: status === "running" ? void 0 : endedAt,
157
+ durationMs,
158
+ children: roots,
159
+ metadata: {
160
+ totalEvents: sorted.length,
161
+ confidenceBreakdown,
162
+ kinds,
163
+ relationshipSummary: summary
164
+ }
165
+ });
166
+ }
167
+ out.sort((a, b) => (b.startedAt ?? 0) - (a.startedAt ?? 0));
168
+ return out;
169
+ }
170
+ };
171
+
172
+ export { TreeBuilder };
173
+ //# sourceMappingURL=chunk-AK5EN4U2.mjs.map
174
+ //# sourceMappingURL=chunk-AK5EN4U2.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/logs/tree-builder.ts"],"names":[],"mappings":"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","file":"chunk-AK5EN4U2.mjs","sourcesContent":["import type {\n InspectEvent,\n InspectNode,\n InspectRunTree,\n RelationshipSummary,\n} from \"../types/inspect-event.js\";\nimport type { LogIngestConfig } from \"../types/log-config.js\";\n\nexport interface TreeBuilderOptions {\n config?: LogIngestConfig;\n}\n\nfunction inc<T extends string>(map: Record<T, number>, key: T): void {\n map[key] = (map[key] ?? 0) + 1;\n}\n\nfunction confidenceRank(confidence: InspectEvent[\"confidence\"]): number {\n switch (confidence) {\n case \"unknown\":\n return 0;\n case \"heuristic\":\n return 1;\n case \"correlated\":\n return 2;\n case \"explicit\":\n return 3;\n default:\n return 0;\n }\n}\n\nfunction computeRunStatus(events: InspectEvent[]): InspectRunTree[\"status\"] {\n // Derive the run status from the RUN node lifecycle, matching\n // manualTraceEventsToRunTree and extractMetadata: a run is \"running\" only\n // until its RUN completion is recorded. The v0.1 bridge writes each node as a\n // \"started\" event (status \"running\") followed by a \"completed\" event, so a\n // finished run still carries \"running\" started rows; those must not force the\n // whole run back to \"running\". Events arrive timestamp-sorted, so the last\n // terminal RUN status wins.\n let runTerminal: \"ok\" | \"error\" | undefined;\n let sawRunEvent = false;\n for (const e of events) {\n if (e.kind !== \"RUN\") continue;\n sawRunEvent = true;\n if (e.status === \"ok\" || e.status === \"error\") {\n runTerminal = e.status;\n }\n }\n if (sawRunEvent) {\n return runTerminal ?? \"running\";\n }\n\n // Fallback for traces with no RUN node (e.g. log-only ingestion).\n let hasRunning = false;\n for (const e of events) {\n if (e.status === \"error\") return \"error\";\n if (e.status === \"running\") hasRunning = true;\n }\n return hasRunning ? \"running\" : \"ok\";\n}\n\ninterface PendingEdge {\n childId: string;\n parentId: string;\n childTimestamp: number;\n childConfidence: InspectEvent[\"confidence\"];\n}\n\n/**\n * Link children to parents without self-edges or cycles. Broken edges become roots.\n */\nexport function linkNodesVisibilityFirst(\n nodes: Map<string, InspectNode>,\n): { roots: InspectNode[]; summary: RelationshipSummary } {\n let selfParentCount = 0;\n let unresolvedParentCount = 0;\n let normalizedEdgeCount = 0;\n let cycleCount = 0;\n\n const pending: PendingEdge[] = [];\n for (const node of nodes.values()) {\n const parentId = node.event.parentId;\n if (!parentId) continue;\n if (parentId === node.event.eventId) {\n selfParentCount += 1;\n normalizedEdgeCount += 1;\n continue;\n }\n if (!nodes.has(parentId)) {\n unresolvedParentCount += 1;\n continue;\n }\n pending.push({\n childId: node.event.eventId,\n parentId,\n childTimestamp: node.event.timestamp,\n childConfidence: node.event.confidence,\n });\n }\n\n // Prefer keeping higher-confidence / earlier edges; break the weakest last edge in a cycle.\n pending.sort((a, b) => {\n const conf = confidenceRank(b.childConfidence) - confidenceRank(a.childConfidence);\n if (conf !== 0) return conf;\n return a.childTimestamp - b.childTimestamp;\n });\n\n const parentOf = new Map<string, string>();\n for (const edge of pending) {\n parentOf.set(edge.childId, edge.parentId);\n // Detect if accepting this edge creates a cycle (walk from parent toward roots).\n let cursor: string | undefined = edge.parentId;\n const seen = new Set<string>([edge.childId]);\n let cyclic = false;\n while (cursor) {\n if (seen.has(cursor)) {\n cyclic = true;\n break;\n }\n seen.add(cursor);\n cursor = parentOf.get(cursor);\n }\n if (cyclic) {\n parentOf.delete(edge.childId);\n cycleCount += 1;\n normalizedEdgeCount += 1;\n }\n }\n\n for (const [childId, parentId] of parentOf) {\n nodes.get(parentId)!.children.push(nodes.get(childId)!);\n }\n\n const roots: InspectNode[] = [];\n for (const node of nodes.values()) {\n if (!parentOf.has(node.event.eventId)) {\n roots.push(node);\n }\n }\n\n const assignDepth = (n: InspectNode, depth: number, stack: Set<string>) => {\n if (stack.has(n.event.eventId)) return;\n n.depth = depth;\n stack.add(n.event.eventId);\n for (const c of n.children) assignDepth(c, depth + 1, stack);\n stack.delete(n.event.eventId);\n };\n for (const r of roots) assignDepth(r, 0, new Set());\n\n return {\n roots,\n summary: {\n rootCount: roots.length,\n selfParentCount,\n cycleCount,\n unresolvedParentCount,\n normalizedEdgeCount,\n },\n };\n}\n\nexport class TreeBuilder {\n constructor(options?: TreeBuilderOptions) {\n void options?.config;\n }\n\n build(events: InspectEvent[]): InspectRunTree[] {\n const byRun = new Map<string, InspectEvent[]>();\n for (const e of events) {\n if (!byRun.has(e.runId)) byRun.set(e.runId, []);\n byRun.get(e.runId)!.push(e);\n }\n\n const out: InspectRunTree[] = [];\n for (const [runId, runEvents] of byRun.entries()) {\n const sorted = [...runEvents].sort((a, b) => a.timestamp - b.timestamp);\n\n const nodes = new Map<string, InspectNode>();\n for (const e of sorted) {\n nodes.set(e.eventId, { event: e, children: [], depth: 0 });\n }\n\n const { roots, summary } = linkNodesVisibilityFirst(nodes);\n\n // metadata\n const confidenceBreakdown = {\n explicit: 0,\n correlated: 0,\n heuristic: 0,\n unknown: 0,\n } as Record<InspectEvent[\"confidence\"], number>;\n const kinds = {} as Record<InspectEvent[\"kind\"], number>;\n for (const e of sorted) {\n inc(confidenceBreakdown, e.confidence);\n (kinds as any)[e.kind] = ((kinds as any)[e.kind] ?? 0) + 1;\n }\n\n const startedAt = sorted.length > 0 ? sorted[0]!.timestamp : undefined;\n const endedAt = sorted.length > 0 ? sorted[sorted.length - 1]!.timestamp : undefined;\n const status = computeRunStatus(sorted);\n const durationMs =\n startedAt !== undefined &&\n endedAt !== undefined &&\n Number.isFinite(startedAt) &&\n Number.isFinite(endedAt) &&\n endedAt >= startedAt &&\n status !== \"running\"\n ? endedAt - startedAt\n : undefined;\n\n const name = sorted.find((e) => e.kind === \"RUN\")?.name;\n\n out.push({\n runId,\n name,\n status,\n startedAt,\n endedAt: status === \"running\" ? undefined : endedAt,\n durationMs,\n children: roots,\n metadata: {\n totalEvents: sorted.length,\n confidenceBreakdown,\n kinds,\n relationshipSummary: summary,\n },\n });\n }\n\n // newest first for stable display\n out.sort((a, b) => (b.startedAt ?? 0) - (a.startedAt ?? 0));\n return out;\n }\n}\n"]}
@@ -195,6 +195,23 @@ function projectLogicalEvents(events) {
195
195
  }
196
196
  }
197
197
  if (!remapped) {
198
+ if (originalParentId === event.eventId) {
199
+ diagnostics.push({
200
+ code: "AI_LOGICAL_SELF_PARENT_REMOVED",
201
+ message: `Removed self-parent edge on ${event.eventId}.`,
202
+ eventIds: [event.eventId]
203
+ });
204
+ const { parentId: _drop, ...rest } = event;
205
+ normalized.push({
206
+ ...rest,
207
+ projection: {
208
+ ...event.projection,
209
+ parentNormalized: true,
210
+ originalParentId
211
+ }
212
+ });
213
+ continue;
214
+ }
198
215
  if (!logicalById.has(originalParentId) && !logicalByRawId.has(originalParentId)) {
199
216
  const mapping = event.attributes?.parentMapping;
200
217
  const unresolved = mapping === "unresolved" || event.attributes?.parentUnresolved === true || event.attributes?.unresolvedParent === true || // LangGraph/framework scaffolding sentinel labels are not event ids.
@@ -210,6 +227,23 @@ function projectLogicalEvents(events) {
210
227
  normalized.push(event);
211
228
  continue;
212
229
  }
230
+ if (nextParent === event.eventId) {
231
+ diagnostics.push({
232
+ code: "AI_LOGICAL_SELF_PARENT_REMOVED",
233
+ message: `Removed self-parent edge on ${event.eventId} (was ${originalParentId}).`,
234
+ eventIds: [event.eventId]
235
+ });
236
+ const { parentId: _drop, ...rest } = event;
237
+ normalized.push({
238
+ ...rest,
239
+ projection: {
240
+ ...event.projection,
241
+ parentNormalized: true,
242
+ originalParentId
243
+ }
244
+ });
245
+ continue;
246
+ }
213
247
  diagnostics.push({
214
248
  code: "AI_LOGICAL_PARENT_REMAPPED",
215
249
  message: `Remapped parent ${originalParentId} \u2192 ${nextParent} for ${event.eventId}.`,
@@ -315,6 +349,73 @@ function buildTraceFacts(events) {
315
349
  };
316
350
  }
317
351
 
352
+ // packages/core/src/safety/sensitive-key.ts
353
+ function normalizeSensitiveKey(value) {
354
+ return value.toLowerCase().replace(/[^a-z0-9_]/g, "");
355
+ }
356
+ var NON_CREDENTIAL_TOKEN_CONFIG_KEYS = new Set(
357
+ [
358
+ "tokens",
359
+ "max_tokens",
360
+ "min_tokens",
361
+ "ls_max_tokens",
362
+ "token_count",
363
+ "token_limit",
364
+ "token_budget",
365
+ "input_tokens",
366
+ "output_tokens",
367
+ "total_tokens",
368
+ "cached_tokens",
369
+ "prompt_tokens",
370
+ "completion_tokens"
371
+ ].map(normalizeSensitiveKey)
372
+ );
373
+ var DEFAULT_CREDENTIAL_SENSITIVE_KEYS = [
374
+ "authorization",
375
+ "cookie",
376
+ "token",
377
+ "access_token",
378
+ "accesstoken",
379
+ "auth_token",
380
+ "authtoken",
381
+ "refresh_token",
382
+ "refreshtoken",
383
+ "id_token",
384
+ "idtoken",
385
+ "bearer_token",
386
+ "bearertoken",
387
+ "api_token",
388
+ "apitoken",
389
+ "apikey",
390
+ "api_key",
391
+ "password",
392
+ "secret",
393
+ "email"
394
+ ];
395
+ function isTokenCredentialKey(normalized) {
396
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
397
+ if (normalized === "token") return true;
398
+ if (normalized.endsWith("tokens")) return false;
399
+ return normalized.endsWith("token");
400
+ }
401
+ function isCredentialSensitiveKey(key, sensitiveKeys = DEFAULT_CREDENTIAL_SENSITIVE_KEYS) {
402
+ if (!key) return false;
403
+ const normalized = normalizeSensitiveKey(key);
404
+ if (!normalized) return false;
405
+ if (NON_CREDENTIAL_TOKEN_CONFIG_KEYS.has(normalized)) return false;
406
+ for (const sensitive of sensitiveKeys) {
407
+ const s = normalizeSensitiveKey(sensitive);
408
+ if (!s) continue;
409
+ if (s === "token") {
410
+ if (isTokenCredentialKey(normalized)) return true;
411
+ continue;
412
+ }
413
+ if (normalized === s) return true;
414
+ if (normalized.endsWith(`_${s}`) || normalized.startsWith(`${s}_`)) return true;
415
+ }
416
+ return false;
417
+ }
418
+
318
419
  // packages/core/src/checks/index.ts
319
420
  var SEVERITY_RANK = {
320
421
  error: 0,
@@ -332,16 +433,7 @@ var CONFIDENCE_RANK = {
332
433
  correlated: 2,
333
434
  explicit: 3
334
435
  };
335
- var DEFAULT_SENSITIVE_KEYS = [
336
- "authorization",
337
- "cookie",
338
- "token",
339
- "apikey",
340
- "api_key",
341
- "password",
342
- "secret",
343
- "email"
344
- ];
436
+ var DEFAULT_SENSITIVE_KEYS = DEFAULT_CREDENTIAL_SENSITIVE_KEYS;
345
437
  var DEFAULT_RAW_CONTENT_KEYS = [
346
438
  "body",
347
439
  "headers",
@@ -774,9 +866,7 @@ function hasRedactionMarker(value, markers) {
774
866
  return markers.some((marker) => value.includes(marker)) || /^\[HASH:[A-Za-z0-9_-]+\]$/.test(value);
775
867
  }
776
868
  function isSensitiveKey(key, sensitiveKeys) {
777
- if (!key) return false;
778
- const normalized = normalizedKey(key);
779
- return sensitiveKeys.some((sensitive) => normalized.includes(normalizedKey(sensitive)));
869
+ return isCredentialSensitiveKey(key, sensitiveKeys);
780
870
  }
781
871
  function isRawContentKey(key, forbiddenKeys) {
782
872
  if (!key) return false;
@@ -1135,7 +1225,7 @@ function createToolUsageRule(options) {
1135
1225
  }
1136
1226
  }
1137
1227
  const forbidden = new Set(options.forbidden ?? []);
1138
- const allowed = options.allowed ? new Set(options.allowed) : void 0;
1228
+ const allowed = options.allowed?.length ? new Set(options.allowed) : void 0;
1139
1229
  for (const event of tools) {
1140
1230
  const name = toolName(event);
1141
1231
  if (forbidden.has(name)) {
@@ -1235,9 +1325,9 @@ function createLlmUsageRule(options) {
1235
1325
  evaluate(context) {
1236
1326
  const llms = finishedEvents(context, "LLM");
1237
1327
  const findings = [];
1238
- const allowedModels = options.allowedModels ? new Set(options.allowedModels) : void 0;
1239
- const allowedProviders = options.allowedProviders ? new Set(options.allowedProviders) : void 0;
1240
- const finishReasons = options.finishReasons ? new Set(options.finishReasons) : void 0;
1328
+ const allowedModels = options.allowedModels?.length ? new Set(options.allowedModels) : void 0;
1329
+ const allowedProviders = options.allowedProviders?.length ? new Set(options.allowedProviders) : void 0;
1330
+ const finishReasons = options.finishReasons?.length ? new Set(options.finishReasons) : void 0;
1241
1331
  if (options.maxCalls !== void 0 && llms.length > options.maxCalls) {
1242
1332
  findings.push(
1243
1333
  failFinding(
@@ -1578,7 +1668,7 @@ function createSignalRule(ruleId, label, options, selectEvents, nameForEvent) {
1578
1668
  }
1579
1669
  }
1580
1670
  const forbidden = new Set(options.forbidden ?? []);
1581
- const allowed = options.allowed ? new Set(options.allowed) : void 0;
1671
+ const allowed = options.allowed?.length ? new Set(options.allowed) : void 0;
1582
1672
  for (const event of events) {
1583
1673
  const name = nameForEvent(event);
1584
1674
  if (forbidden.has(name)) {
@@ -2232,5 +2322,5 @@ function evaluateTraceContract(input, contract, options = {}) {
2232
2322
  }
2233
2323
 
2234
2324
  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, projectLogicalEvents, resolveCanonicalToolName, runTraceChecks, summarizeSemanticParity };
2235
- //# sourceMappingURL=chunk-BS2QCAJX.mjs.map
2236
- //# sourceMappingURL=chunk-BS2QCAJX.mjs.map
2325
+ //# sourceMappingURL=chunk-BHMXLDLK.mjs.map
2326
+ //# sourceMappingURL=chunk-BHMXLDLK.mjs.map