agent-inspect 6.28.0 → 6.29.1

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 (91) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/README.md +1 -1
  3. package/docs/CLI.md +19 -1
  4. package/docs/LIMITATIONS.md +2 -2
  5. package/docs/SAFE-TRACE-SHARING.md +1 -1
  6. package/docs/SCHEMA.md +1 -1
  7. package/docs/STANDARDS.md +1 -1
  8. package/package.json +2 -1
  9. package/packages/cli/dist/{chunk-JVQ4LTHR.mjs → chunk-UK4HD5M3.mjs} +181 -32
  10. package/packages/cli/dist/chunk-UK4HD5M3.mjs.map +1 -0
  11. package/packages/cli/dist/index.cjs +251 -103
  12. package/packages/cli/dist/index.cjs.map +1 -1
  13. package/packages/cli/dist/index.mjs +63 -72
  14. package/packages/cli/dist/index.mjs.map +1 -1
  15. package/packages/cli/dist/{src-M5J5YC5E.mjs → src-CMPIJGUE.mjs} +3 -3
  16. package/packages/cli/dist/{src-M5J5YC5E.mjs.map → src-CMPIJGUE.mjs.map} +1 -1
  17. package/packages/core/dist/advanced.cjs +153 -30
  18. package/packages/core/dist/advanced.cjs.map +1 -1
  19. package/packages/core/dist/advanced.d.cts +20 -7
  20. package/packages/core/dist/advanced.d.ts +20 -7
  21. package/packages/core/dist/advanced.mjs +114 -38
  22. package/packages/core/dist/advanced.mjs.map +1 -1
  23. package/packages/core/dist/checks.cjs +235 -34
  24. package/packages/core/dist/checks.cjs.map +1 -1
  25. package/packages/core/dist/checks.d.cts +5 -5
  26. package/packages/core/dist/checks.d.ts +5 -5
  27. package/packages/core/dist/checks.mjs +5 -5
  28. package/packages/core/dist/{chunk-NXQF73EC.mjs → chunk-5B4DNGFB.mjs} +9 -5
  29. package/packages/core/dist/chunk-5B4DNGFB.mjs.map +1 -0
  30. package/packages/core/dist/{chunk-JBNRJLIV.mjs → chunk-5RF7FYGL.mjs} +33 -7
  31. package/packages/core/dist/chunk-5RF7FYGL.mjs.map +1 -0
  32. package/packages/core/dist/{chunk-U25RHRSU.mjs → chunk-65LFRW2T.mjs} +13 -6
  33. package/packages/core/dist/chunk-65LFRW2T.mjs.map +1 -0
  34. package/packages/core/dist/{chunk-WGDSM37E.mjs → chunk-AQMJFKI6.mjs} +5 -5
  35. package/packages/core/dist/{chunk-WGDSM37E.mjs.map → chunk-AQMJFKI6.mjs.map} +1 -1
  36. package/packages/core/dist/{chunk-R4SSYU6D.mjs → chunk-COZPMOUF.mjs} +3 -3
  37. package/packages/core/dist/{chunk-R4SSYU6D.mjs.map → chunk-COZPMOUF.mjs.map} +1 -1
  38. package/packages/core/dist/{chunk-NDRMIL7Z.mjs → chunk-FKUTGUFG.mjs} +12 -4
  39. package/packages/core/dist/chunk-FKUTGUFG.mjs.map +1 -0
  40. package/packages/core/dist/{chunk-ME4WXYY3.mjs → chunk-GPGBKN7W.mjs} +238 -37
  41. package/packages/core/dist/chunk-GPGBKN7W.mjs.map +1 -0
  42. package/packages/core/dist/{chunk-P366CCL2.mjs → chunk-QJI52TH3.mjs} +4 -2
  43. package/packages/core/dist/chunk-QJI52TH3.mjs.map +1 -0
  44. package/packages/core/dist/{chunk-WRE4CNPF.mjs → chunk-SJ3C5RIS.mjs} +3 -3
  45. package/packages/core/dist/chunk-SJ3C5RIS.mjs.map +1 -0
  46. package/packages/core/dist/{context-DgcvkJ9t.d.ts → context-B8zzsmjX.d.ts} +2 -2
  47. package/packages/core/dist/{context-DGMqxFpz.d.cts → context-BhaVHtOT.d.cts} +2 -2
  48. package/packages/core/dist/diff.d.cts +1 -1
  49. package/packages/core/dist/diff.d.ts +1 -1
  50. package/packages/core/dist/exporters.cjs +39 -8
  51. package/packages/core/dist/exporters.cjs.map +1 -1
  52. package/packages/core/dist/exporters.d.cts +13 -3
  53. package/packages/core/dist/exporters.d.ts +13 -3
  54. package/packages/core/dist/exporters.mjs +15 -10
  55. package/packages/core/dist/exporters.mjs.map +1 -1
  56. package/packages/core/dist/{index-C6bCIbFO.d.cts → index-BT3KcO6-.d.cts} +1 -1
  57. package/packages/core/dist/{index-DVetZwGG.d.cts → index-C61p7wBR.d.cts} +3 -3
  58. package/packages/core/dist/{index-BOA1AeEU.d.ts → index-DTO2iGeq.d.ts} +3 -3
  59. package/packages/core/dist/{index-BzyNPfLm.d.ts → index-reskZCVW.d.ts} +1 -1
  60. package/packages/core/dist/index.cjs +10 -1
  61. package/packages/core/dist/index.cjs.map +1 -1
  62. package/packages/core/dist/index.d.cts +4 -4
  63. package/packages/core/dist/index.d.ts +4 -4
  64. package/packages/core/dist/index.mjs +6 -6
  65. package/packages/core/dist/{persisted-inspect-event-CbaRYpbw.d.ts → persisted-inspect-event-BMwvGIB8.d.ts} +5 -0
  66. package/packages/core/dist/{persisted-inspect-event-DiJ0I_vi.d.cts → persisted-inspect-event-DPaCiars.d.cts} +5 -0
  67. package/packages/core/dist/persisted.cjs +8 -2
  68. package/packages/core/dist/persisted.cjs.map +1 -1
  69. package/packages/core/dist/persisted.d.cts +3 -3
  70. package/packages/core/dist/persisted.d.ts +3 -3
  71. package/packages/core/dist/persisted.mjs +3 -3
  72. package/packages/core/dist/readers.cjs +16 -2
  73. package/packages/core/dist/readers.cjs.map +1 -1
  74. package/packages/core/dist/readers.d.cts +2 -2
  75. package/packages/core/dist/readers.d.ts +2 -2
  76. package/packages/core/dist/readers.mjs +4 -4
  77. package/packages/core/dist/{types-wXuxMUop.d.cts → types-BSzhK7Z1.d.cts} +9 -0
  78. package/packages/core/dist/{types-xv9bSgOK.d.ts → types-C5Y8Idle.d.ts} +9 -0
  79. package/packages/core/dist/writers.cjs +10 -1
  80. package/packages/core/dist/writers.cjs.map +1 -1
  81. package/packages/core/dist/writers.d.cts +1 -1
  82. package/packages/core/dist/writers.d.ts +1 -1
  83. package/packages/core/dist/writers.mjs +3 -3
  84. package/packages/cli/dist/chunk-JVQ4LTHR.mjs.map +0 -1
  85. package/packages/core/dist/chunk-JBNRJLIV.mjs.map +0 -1
  86. package/packages/core/dist/chunk-ME4WXYY3.mjs.map +0 -1
  87. package/packages/core/dist/chunk-NDRMIL7Z.mjs.map +0 -1
  88. package/packages/core/dist/chunk-NXQF73EC.mjs.map +0 -1
  89. package/packages/core/dist/chunk-P366CCL2.mjs.map +0 -1
  90. package/packages/core/dist/chunk-U25RHRSU.mjs.map +0 -1
  91. package/packages/core/dist/chunk-WRE4CNPF.mjs.map +0 -1
@@ -165,8 +165,31 @@ var init_redactor = __esm({
165
165
  });
166
166
 
167
167
  // packages/core/src/safety/credential-value-patterns.ts
168
+ function stringContainsHighConfidenceCredential(value) {
169
+ for (const pattern of HIGH_CONFIDENCE_CREDENTIAL_PATTERNS) {
170
+ pattern.lastIndex = 0;
171
+ if (pattern.test(value)) {
172
+ pattern.lastIndex = 0;
173
+ return true;
174
+ }
175
+ }
176
+ return false;
177
+ }
178
+ var KEY_VALUE_SECRET_PATTERN, HIGH_CONFIDENCE_CREDENTIAL_PATTERNS;
168
179
  var init_credential_value_patterns = __esm({
169
180
  "packages/core/src/safety/credential-value-patterns.ts"() {
181
+ KEY_VALUE_SECRET_PATTERN = /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=([^\s"'\\]{8,})/i;
182
+ HIGH_CONFIDENCE_CREDENTIAL_PATTERNS = [
183
+ /^(?:basic|bearer|digest|apikey)\s+[a-z0-9._~+/=-]+$/i,
184
+ /\bbearer\s+[a-z0-9._~+/=-]{12,}\b/i,
185
+ /\b[a-z0-9_.-]+=[^;\s]+(?:;\s*[a-z0-9_.-]+=[^;\s]+)+/i,
186
+ /\beyJ[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\b/,
187
+ /\b(?:sk-(?:proj-)?[a-zA-Z0-9_-]{16,}|sk-ant-[a-zA-Z0-9_-]{16,}|AIza[0-9A-Za-z_-]{20,})\b/,
188
+ /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\b/,
189
+ /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/,
190
+ /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*-----END [A-Z ]*PRIVATE KEY-----/,
191
+ KEY_VALUE_SECRET_PATTERN
192
+ ];
170
193
  }
171
194
  });
172
195
 
@@ -358,6 +381,8 @@ function isPersistedTokenUsage(value) {
358
381
  if (!isOptionalNonNegativeNumber(value.output)) return false;
359
382
  if (!isOptionalNonNegativeNumber(value.total)) return false;
360
383
  if (!isOptionalNonNegativeNumber(value.cached)) return false;
384
+ if (!isOptionalNonNegativeNumber(value.cacheWrite)) return false;
385
+ if (!isOptionalNonNegativeNumber(value.reasoning)) return false;
361
386
  return true;
362
387
  }
363
388
  function isPersistedTraceContext(value) {
@@ -2136,7 +2161,13 @@ function buildRunSummary(events) {
2136
2161
  tokensInput: isNonNegativeFiniteNumber(s.metadata?.tokens?.input) ? s.metadata.tokens.input : void 0,
2137
2162
  tokensOutput: isNonNegativeFiniteNumber(s.metadata?.tokens?.output) ? s.metadata.tokens.output : void 0,
2138
2163
  tokensTotal: isNonNegativeFiniteNumber(s.metadata?.tokens?.total) ? s.metadata.tokens.total : void 0,
2139
- tokensCached: isNonNegativeFiniteNumber(s.metadata?.tokens?.cached) ? s.metadata.tokens.cached : void 0
2164
+ tokensCached: isNonNegativeFiniteNumber(s.metadata?.tokens?.cached) ? s.metadata.tokens.cached : void 0,
2165
+ tokensCacheWrite: isNonNegativeFiniteNumber(
2166
+ s.metadata?.tokens?.cacheWrite
2167
+ ) ? s.metadata.tokens.cacheWrite : void 0,
2168
+ tokensReasoning: isNonNegativeFiniteNumber(
2169
+ s.metadata?.tokens?.reasoning
2170
+ ) ? s.metadata.tokens.reasoning : void 0
2140
2171
  });
2141
2172
  }
2142
2173
  }
@@ -2160,9 +2191,13 @@ function buildRunSummary(events) {
2160
2191
  let totalTokensOutput = 0;
2161
2192
  let totalTokensTotal = 0;
2162
2193
  let totalTokensCached = 0;
2194
+ let totalTokensCacheWrite = 0;
2195
+ let totalTokensReasoning = 0;
2163
2196
  let tokenBearingSteps = 0;
2164
2197
  let stepsWithKnownTotal = 0;
2165
2198
  let hasCachedTokens = false;
2199
+ let hasCacheWriteTokens = false;
2200
+ let hasReasoningTokens = false;
2166
2201
  const depthCache = /* @__PURE__ */ new Map();
2167
2202
  for (const [id, s] of steps.entries()) {
2168
2203
  totalSteps += 1;
@@ -2177,7 +2212,7 @@ function buildRunSummary(events) {
2177
2212
  longestStep = { name: s.name, durationMs: s.durationMs, type: s.type };
2178
2213
  }
2179
2214
  }
2180
- if (s.tokensInput !== void 0 || s.tokensOutput !== void 0 || s.tokensTotal !== void 0 || s.tokensCached !== void 0) {
2215
+ if (s.tokensInput !== void 0 || s.tokensOutput !== void 0 || s.tokensTotal !== void 0 || s.tokensCached !== void 0 || s.tokensCacheWrite !== void 0 || s.tokensReasoning !== void 0) {
2181
2216
  tokenBearingSteps += 1;
2182
2217
  if (s.tokensInput !== void 0) totalTokensInput += s.tokensInput;
2183
2218
  if (s.tokensOutput !== void 0) totalTokensOutput += s.tokensOutput;
@@ -2192,6 +2227,14 @@ function buildRunSummary(events) {
2192
2227
  totalTokensCached += s.tokensCached;
2193
2228
  hasCachedTokens = true;
2194
2229
  }
2230
+ if (s.tokensCacheWrite !== void 0) {
2231
+ totalTokensCacheWrite += s.tokensCacheWrite;
2232
+ hasCacheWriteTokens = true;
2233
+ }
2234
+ if (s.tokensReasoning !== void 0) {
2235
+ totalTokensReasoning += s.tokensReasoning;
2236
+ hasReasoningTokens = true;
2237
+ }
2195
2238
  }
2196
2239
  }
2197
2240
  const summary = {
@@ -2211,7 +2254,9 @@ function buildRunSummary(events) {
2211
2254
  input: totalTokensInput,
2212
2255
  output: totalTokensOutput,
2213
2256
  ...stepsWithKnownTotal === tokenBearingSteps ? { total: totalTokensTotal } : {},
2214
- ...hasCachedTokens ? { cached: totalTokensCached } : {}
2257
+ ...hasCachedTokens ? { cached: totalTokensCached } : {},
2258
+ ...hasCacheWriteTokens ? { cacheWrite: totalTokensCacheWrite } : {},
2259
+ ...hasReasoningTokens ? { reasoning: totalTokensReasoning } : {}
2215
2260
  }
2216
2261
  } : {}
2217
2262
  };
@@ -2751,6 +2796,12 @@ function renderRunWhat(summary, options = {}) {
2751
2796
  if (summary.totalTokens.cached !== void 0) {
2752
2797
  tokenParts.push(`${summary.totalTokens.cached} cached`);
2753
2798
  }
2799
+ if (summary.totalTokens.cacheWrite !== void 0) {
2800
+ tokenParts.push(`${summary.totalTokens.cacheWrite} cache-write`);
2801
+ }
2802
+ if (summary.totalTokens.reasoning !== void 0) {
2803
+ tokenParts.push(`${summary.totalTokens.reasoning} reasoning`);
2804
+ }
2754
2805
  lines.push(`Tokens: ${tokenParts.join(" / ")}`);
2755
2806
  }
2756
2807
  if (showCorrelation && summary.correlation) {
@@ -6896,6 +6947,9 @@ var init_checks2 = __esm({
6896
6947
  "output",
6897
6948
  "total",
6898
6949
  "cached",
6950
+ "cachewrite",
6951
+ "cache_write",
6952
+ "reasoning",
6899
6953
  "input_tokens",
6900
6954
  "inputtokens",
6901
6955
  "output_tokens",
@@ -6905,7 +6959,13 @@ var init_checks2 = __esm({
6905
6959
  "prompt_tokens",
6906
6960
  "prompttokens",
6907
6961
  "completion_tokens",
6908
- "completiontokens"
6962
+ "completiontokens",
6963
+ "cache_read",
6964
+ "cacheread",
6965
+ "cache_creation",
6966
+ "cachecreation",
6967
+ "reasoning_tokens",
6968
+ "reasoningtokens"
6909
6969
  ]);
6910
6970
  DEFAULT_SECRET_PATTERNS = [
6911
6971
  { id: "bearer-token", pattern: /Bearer\s+[A-Za-z0-9._~+/-]{12,}=*/ },
@@ -6935,9 +6995,16 @@ var init_control_rules = __esm({
6935
6995
  }
6936
6996
  });
6937
6997
 
6998
+ // packages/core/src/checks/canonical-equality.ts
6999
+ var init_canonical_equality = __esm({
7000
+ "packages/core/src/checks/canonical-equality.ts"() {
7001
+ }
7002
+ });
7003
+
6938
7004
  // packages/core/src/checks/tool-arguments.ts
6939
7005
  var init_tool_arguments = __esm({
6940
7006
  "packages/core/src/checks/tool-arguments.ts"() {
7007
+ init_canonical_equality();
6941
7008
  }
6942
7009
  });
6943
7010
 
@@ -6952,6 +7019,7 @@ var init_retry_safety = __esm({
6952
7019
  // packages/core/src/checks/recovery-operations.ts
6953
7020
  var init_recovery_operations = __esm({
6954
7021
  "packages/core/src/checks/recovery-operations.ts"() {
7022
+ init_canonical_equality();
6955
7023
  init_logical_events();
6956
7024
  init_tool_arguments();
6957
7025
  init_retry_safety();
@@ -7159,6 +7227,38 @@ var init_contract = __esm({
7159
7227
  });
7160
7228
 
7161
7229
  // packages/core/src/evidence/contract-binding.ts
7230
+ function contractContainsUnsafeExpectedValues(value) {
7231
+ return scanForExpectedFields(value, 0);
7232
+ }
7233
+ function scanForExpectedFields(value, depth) {
7234
+ if (depth > 32) return false;
7235
+ if (Array.isArray(value)) {
7236
+ return value.some((item) => scanForExpectedFields(item, depth + 1));
7237
+ }
7238
+ if (value === null || typeof value !== "object") return false;
7239
+ const record = value;
7240
+ for (const [key, child] of Object.entries(record)) {
7241
+ if (key === "expected" || key === "oneOf") {
7242
+ if (valueTreeContainsCredential(child, depth + 1)) return true;
7243
+ continue;
7244
+ }
7245
+ if (scanForExpectedFields(child, depth + 1)) return true;
7246
+ }
7247
+ return false;
7248
+ }
7249
+ function valueTreeContainsCredential(value, depth) {
7250
+ if (depth > 32) return false;
7251
+ if (typeof value === "string") {
7252
+ return stringContainsHighConfidenceCredential(value);
7253
+ }
7254
+ if (Array.isArray(value)) {
7255
+ return value.some((item) => valueTreeContainsCredential(item, depth + 1));
7256
+ }
7257
+ if (value === null || typeof value !== "object") return false;
7258
+ return Object.values(value).some(
7259
+ (child) => valueTreeContainsCredential(child, depth + 1)
7260
+ );
7261
+ }
7162
7262
  function serializeCanonicalJson(value) {
7163
7263
  return `${JSON.stringify(stableValue(value), null, 2)}
7164
7264
  `;
@@ -7292,6 +7392,32 @@ function buildEvidenceContractPackage(input3) {
7292
7392
  if (unsupported.length > 0) {
7293
7393
  ruleIds = sortedUniqueStrings([...ruleIds, ...unsupported]);
7294
7394
  }
7395
+ if (contractContainsUnsafeExpectedValues(resolved)) {
7396
+ return {
7397
+ binding: {
7398
+ status: "unavailable",
7399
+ source: input3.source,
7400
+ ...input3.contractId !== void 0 ? { contractId: input3.contractId } : {},
7401
+ ...input3.contractVersion !== void 0 ? { contractVersion: input3.contractVersion } : {},
7402
+ canonicalizationVersion: EVIDENCE_CONTRACT_CANONICALIZATION_VERSION,
7403
+ engineVersion: input3.engineVersion,
7404
+ ruleIds,
7405
+ ...unsupported.length > 0 ? { unsupportedRuleIds: unsupported } : {},
7406
+ note: input3.note ?? EVIDENCE_CONTRACT_UNSAFE_NOTE
7407
+ },
7408
+ checkBinding: {
7409
+ canonicalizationVersion: EVIDENCE_CONTRACT_CANONICALIZATION_VERSION,
7410
+ engineVersion: input3.engineVersion,
7411
+ evaluatedRuleIds: ruleIds,
7412
+ bindingStatus: "unavailable",
7413
+ ...unsupported.length > 0 ? { unsupportedRuleIds: unsupported } : {},
7414
+ origin: {
7415
+ source: input3.source,
7416
+ ...input3.preset?.name ? { preset: input3.preset.name } : {}
7417
+ }
7418
+ }
7419
+ };
7420
+ }
7295
7421
  const document = {
7296
7422
  canonicalizationVersion: EVIDENCE_CONTRACT_CANONICALIZATION_VERSION,
7297
7423
  kind,
@@ -7431,16 +7557,18 @@ function verifyEvidenceContractBinding(parts) {
7431
7557
  }
7432
7558
  return issues;
7433
7559
  }
7434
- var EVIDENCE_CONTRACT_CANONICALIZATION_VERSION, EVIDENCE_CONTRACT_PARTIAL_NOTE, EVIDENCE_CONTRACT_UNAVAILABLE_NOTE, EVIDENCE_CONTRACT_ASSURANCE_NOTE;
7560
+ var EVIDENCE_CONTRACT_CANONICALIZATION_VERSION, EVIDENCE_CONTRACT_PARTIAL_NOTE, EVIDENCE_CONTRACT_UNAVAILABLE_NOTE, EVIDENCE_CONTRACT_ASSURANCE_NOTE, EVIDENCE_CONTRACT_UNSAFE_NOTE;
7435
7561
  var init_contract_binding = __esm({
7436
7562
  "packages/core/src/evidence/contract-binding.ts"() {
7437
7563
  init_contract();
7564
+ init_credential_value_patterns();
7438
7565
  init_hash();
7439
7566
  init_types4();
7440
7567
  EVIDENCE_CONTRACT_CANONICALIZATION_VERSION = "1";
7441
7568
  EVIDENCE_CONTRACT_PARTIAL_NOTE = "Custom or programmatic rules are not serializable; Evidence records rule IDs only and does not claim complete reviewer replay.";
7442
7569
  EVIDENCE_CONTRACT_UNAVAILABLE_NOTE = "No resolved TraceContract or check preset was packaged with this Evidence artifact.";
7443
7570
  EVIDENCE_CONTRACT_ASSURANCE_NOTE = "Contract binding verifies packaged digest integrity only; it does not prove producer identity, trusted time, source completeness, semantic truth, or external acceptance.";
7571
+ EVIDENCE_CONTRACT_UNSAFE_NOTE = "Resolved TraceContract contains high-confidence credential-like expected values; Evidence refuses complete packaging rather than silently redacting evaluated expectations.";
7444
7572
  }
7445
7573
  });
7446
7574
 
@@ -7789,7 +7917,15 @@ function buildEmbeddedPayload(input3) {
7789
7917
  redactionProfile: input3.redactionProfile,
7790
7918
  verificationPolicy: input3.verificationPolicy
7791
7919
  },
7792
- checkSummary: input3.checkSummary
7920
+ checkSummary: input3.checkSummary,
7921
+ ...input3.contractBinding !== void 0 ? {
7922
+ contract: {
7923
+ status: input3.contractBinding.status,
7924
+ ...input3.contractBinding.sha256 !== void 0 ? { sha256: input3.contractBinding.sha256 } : {},
7925
+ ...input3.contractBinding.ruleCount !== void 0 ? { ruleCount: input3.contractBinding.ruleCount } : {},
7926
+ ...input3.contractBinding.note !== void 0 ? { note: input3.contractBinding.note } : {}
7927
+ }
7928
+ } : {}
7793
7929
  };
7794
7930
  }
7795
7931
  function buildEvidenceHtmlShell(input3) {
@@ -7887,6 +8023,7 @@ ${nav}
7887
8023
  <p>Artifact status: <span class="badge ${statusClass(input3.assessmentStatus)}">${escapeHtml(input3.assessmentStatus)}</span>
7888
8024
  ${input3.sourceStatus !== void 0 ? ` \xB7 Source status: <span class="badge ${statusClass(input3.sourceStatus)}">${escapeHtml(input3.sourceStatus)}</span>` : ""}</p>
7889
8025
  <p>Profile: <code>${escapeHtml(input3.redactionProfile)}</code> \xB7 Verification: <code>${escapeHtml(input3.verificationPolicy)}</code></p>
8026
+ ${input3.contractBinding !== void 0 ? `<p>Contract binding: <code>${escapeHtml(input3.contractBinding.status)}</code>${input3.contractBinding.ruleCount !== void 0 ? ` \xB7 Rules: <code>${escapeHtml(String(input3.contractBinding.ruleCount))}</code>` : ""}${input3.contractBinding.sha256 !== void 0 ? ` \xB7 Digest: <code>${escapeHtml(input3.contractBinding.sha256.slice(0, 16))}\u2026</code>` : ""}</p>${input3.contractBinding.note !== void 0 && input3.contractBinding.note.trim() !== "" ? `<p class="muted">${escapeHtml(input3.contractBinding.note)}</p>` : ""}` : ""}
7890
8027
  <p>Generator: <code>${escapeHtml(input3.generatorName)}@${escapeHtml(input3.generatorVersion)}</code>
7891
8028
  ${input3.createdAt ? ` \xB7 Created: <code>${escapeHtml(input3.createdAt)}</code>` : ""}</p>
7892
8029
  <h3>Runs</h3>
@@ -8978,29 +9115,6 @@ function buildEvidenceCiPackage(input3) {
8978
9115
  schemaVersions.add(version2);
8979
9116
  }
8980
9117
  const createdAt = input3.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
8981
- const evidenceHtml = buildEvidenceHtmlShell({
8982
- title: "AgentInspect evidence",
8983
- runIds: input3.runIds,
8984
- assessmentStatus: input3.assessmentStatus,
8985
- sourceStatus: input3.sourceStatus,
8986
- redactionProfile: input3.redactionProfile,
8987
- verificationPolicy: input3.redactionProfile,
8988
- generatorName: "agent-inspect",
8989
- generatorVersion: input3.generatorVersion,
8990
- createdAt,
8991
- summaryText: input3.summaryText,
8992
- checkSummary: {
8993
- aggregateStatus: input3.assessmentStatus,
8994
- runs: input3.runIds.map((runId) => ({
8995
- runId,
8996
- status: input3.assessmentStatus,
8997
- sourceStatus: input3.sourceStatus,
8998
- errors: input3.assessmentStatus === "UNSAFE" || input3.assessmentStatus === "UNKNOWN" ? 1 : 0,
8999
- warnings: input3.assessmentStatus === "SAFE WITH WARNINGS" ? 1 : 0,
9000
- findings: 0
9001
- }))
9002
- }
9003
- });
9004
9118
  let checkResultsJson = input3.checkResultsJson;
9005
9119
  let contractBinding;
9006
9120
  let contractFileContent;
@@ -9023,6 +9137,37 @@ function buildEvidenceCiPackage(input3) {
9023
9137
  bindCheckResultsToContract(parsed, packaged2.checkBinding)
9024
9138
  );
9025
9139
  }
9140
+ const evidenceHtml = buildEvidenceHtmlShell({
9141
+ title: "AgentInspect evidence",
9142
+ runIds: input3.runIds,
9143
+ assessmentStatus: input3.assessmentStatus,
9144
+ sourceStatus: input3.sourceStatus,
9145
+ redactionProfile: input3.redactionProfile,
9146
+ verificationPolicy: input3.redactionProfile,
9147
+ generatorName: "agent-inspect",
9148
+ generatorVersion: input3.generatorVersion,
9149
+ createdAt,
9150
+ summaryText: input3.summaryText,
9151
+ checkSummary: {
9152
+ aggregateStatus: input3.assessmentStatus,
9153
+ runs: input3.runIds.map((runId) => ({
9154
+ runId,
9155
+ status: input3.assessmentStatus,
9156
+ sourceStatus: input3.sourceStatus,
9157
+ errors: input3.assessmentStatus === "UNSAFE" || input3.assessmentStatus === "UNKNOWN" ? 1 : 0,
9158
+ warnings: input3.assessmentStatus === "SAFE WITH WARNINGS" ? 1 : 0,
9159
+ findings: 0
9160
+ }))
9161
+ },
9162
+ ...contractBinding !== void 0 ? {
9163
+ contractBinding: {
9164
+ status: contractBinding.status,
9165
+ ...contractBinding.sha256 !== void 0 ? { sha256: contractBinding.sha256 } : {},
9166
+ ...contractBinding.note !== void 0 ? { note: contractBinding.note } : {},
9167
+ ruleCount: contractBinding.ruleIds.length
9168
+ }
9169
+ } : {}
9170
+ });
9026
9171
  const packaged = [
9027
9172
  { path: EVIDENCE_HTML_FILENAME, content: evidenceHtml },
9028
9173
  { path: "check-results.json", content: checkResultsJson },
@@ -9424,16 +9569,20 @@ function normalizeTokenUsage(value) {
9424
9569
  const output2 = nonNegativeFinite(value.output);
9425
9570
  const suppliedTotal = nonNegativeFinite(value.total);
9426
9571
  const cached2 = nonNegativeFinite(value.cached);
9572
+ const cacheWrite = nonNegativeFinite(value.cacheWrite);
9573
+ const reasoning = nonNegativeFinite(value.reasoning);
9427
9574
  const derivedTotal = input3 !== void 0 && output2 !== void 0 && Number.isFinite(input3 + output2) ? input3 + output2 : void 0;
9428
9575
  const total = suppliedTotal ?? derivedTotal;
9429
- if (input3 === void 0 && output2 === void 0 && total === void 0 && cached2 === void 0) {
9576
+ if (input3 === void 0 && output2 === void 0 && total === void 0 && cached2 === void 0 && cacheWrite === void 0 && reasoning === void 0) {
9430
9577
  return void 0;
9431
9578
  }
9432
9579
  return {
9433
9580
  ...input3 !== void 0 ? { input: input3 } : {},
9434
9581
  ...output2 !== void 0 ? { output: output2 } : {},
9435
9582
  ...total !== void 0 ? { total } : {},
9436
- ...cached2 !== void 0 ? { cached: cached2 } : {}
9583
+ ...cached2 !== void 0 ? { cached: cached2 } : {},
9584
+ ...cacheWrite !== void 0 ? { cacheWrite } : {},
9585
+ ...reasoning !== void 0 ? { reasoning } : {}
9437
9586
  };
9438
9587
  }
9439
9588
  var init_token_usage = __esm({
@@ -10545,6 +10694,8 @@ function readOpenInferenceTokenUsage(attributes) {
10545
10694
  const completion = attributes["llm.token_count.completion"];
10546
10695
  const total = attributes["llm.token_count.total"];
10547
10696
  const cached2 = attributes["llm.token_count.prompt_details.cache_read"];
10697
+ const cacheWrite = attributes["llm.token_count.prompt_details.cache_write"] ?? attributes["llm.token_count.prompt_details.cache_creation"];
10698
+ const reasoning = attributes["llm.token_count.completion_details.reasoning"] ?? attributes["llm.token_count.completion_details.reasoning_tokens"];
10548
10699
  const usage = {};
10549
10700
  if (typeof prompt === "number" && Number.isFinite(prompt) && prompt >= 0) {
10550
10701
  usage.input = prompt;
@@ -10558,6 +10709,12 @@ function readOpenInferenceTokenUsage(attributes) {
10558
10709
  if (typeof cached2 === "number" && Number.isFinite(cached2) && cached2 >= 0) {
10559
10710
  usage.cached = cached2;
10560
10711
  }
10712
+ if (typeof cacheWrite === "number" && Number.isFinite(cacheWrite) && cacheWrite >= 0) {
10713
+ usage.cacheWrite = cacheWrite;
10714
+ }
10715
+ if (typeof reasoning === "number" && Number.isFinite(reasoning) && reasoning >= 0) {
10716
+ usage.reasoning = reasoning;
10717
+ }
10561
10718
  if (usage.total === void 0 && usage.input !== void 0 && usage.output !== void 0) {
10562
10719
  usage.total = usage.input + usage.output;
10563
10720
  }
@@ -13599,7 +13756,7 @@ var init_src = __esm({
13599
13756
  });
13600
13757
 
13601
13758
  // package.json
13602
- var version = "6.28.0";
13759
+ var version = "6.29.1";
13603
13760
 
13604
13761
  // packages/cli/src/list.ts
13605
13762
  init_advanced();
@@ -17592,13 +17749,13 @@ function isCredentialSensitiveKey2(key, sensitiveKeys) {
17592
17749
 
17593
17750
  // packages/redact/src/key-value-secret.ts
17594
17751
  var KEY_VALUE_SECRET_PATTERN_SOURCE = String.raw`\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=([^\s"'\\]{8,})`;
17595
- var KEY_VALUE_SECRET_PATTERN = new RegExp(
17752
+ var KEY_VALUE_SECRET_PATTERN2 = new RegExp(
17596
17753
  KEY_VALUE_SECRET_PATTERN_SOURCE,
17597
17754
  "i"
17598
17755
  );
17599
17756
  function valueContainsKeyValueSecret(value) {
17600
- KEY_VALUE_SECRET_PATTERN.lastIndex = 0;
17601
- return KEY_VALUE_SECRET_PATTERN.test(value);
17757
+ KEY_VALUE_SECRET_PATTERN2.lastIndex = 0;
17758
+ return KEY_VALUE_SECRET_PATTERN2.test(value);
17602
17759
  }
17603
17760
 
17604
17761
  // packages/redact/src/index.ts
@@ -18067,15 +18224,14 @@ var REDACTION_POLICY_LIMITS = {
18067
18224
  maxPatterns: 32,
18068
18225
  maxPatternLength: 128,
18069
18226
  maxPatternIdLength: 64,
18070
- maxTypedQuantifier: 64
18227
+ /** Maximum policy file size before parse (bytes). */
18228
+ maxPolicyFileBytes: 64 * 1024
18071
18229
  };
18072
- var SAFE_TYPED_PATTERN = /^[A-Za-z0-9_@./:=<>\-[\]()|+*?{},\\\s^$]+$/;
18230
+ var ALLOWED_TOP_LEVEL = /* @__PURE__ */ new Set(["version", "extraKeys", "patterns"]);
18231
+ var ALLOWED_PATTERN_FIELDS = /* @__PURE__ */ new Set(["id", "type", "value", "severity"]);
18073
18232
  function isRecord17(value) {
18074
18233
  return value !== null && typeof value === "object" && !Array.isArray(value);
18075
18234
  }
18076
- function escapeRegExp(value) {
18077
- return value.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
18078
- }
18079
18235
  function rejectRemotePolicyPath(policyPath) {
18080
18236
  const trimmed = policyPath.trim();
18081
18237
  if (/^[a-z][a-z0-9+.-]*:/i.test(trimmed)) {
@@ -18104,43 +18260,23 @@ function validateExtraKey(key, index) {
18104
18260
  }
18105
18261
  return key;
18106
18262
  }
18107
- function assertBoundedTypedPattern(pattern, label) {
18108
- if (pattern.length === 0) throw new Error(`${label} must be non-empty.`);
18109
- if (pattern.length > REDACTION_POLICY_LIMITS.maxPatternLength) {
18110
- throw new Error(
18111
- `${label} exceeds max length ${REDACTION_POLICY_LIMITS.maxPatternLength}.`
18112
- );
18113
- }
18114
- if (!SAFE_TYPED_PATTERN.test(pattern)) {
18115
- throw new Error(
18116
- `${label} contains unsupported characters for bounded typed patterns.`
18117
- );
18118
- }
18119
- if (/\(\?/.test(pattern) || /\\[1-9]/.test(pattern)) {
18120
- throw new Error(
18121
- `${label} rejects lookaround, backreferences, and nested quantifiers.`
18122
- );
18123
- }
18124
- if (/\([^)]*[+*{][^)]*\)[+*{]/.test(pattern) || /\[[^\]]*[+*{][^\]]*\][+*{]/.test(pattern)) {
18125
- throw new Error(`${label} rejects nested quantifiers.`);
18126
- }
18127
- if (/\.[*+]/.test(pattern) || /[*+]\{/.test(pattern)) {
18128
- throw new Error(`${label} rejects unbounded .* / .+ style quantifiers.`);
18129
- }
18130
- for (const match of pattern.matchAll(/\{(\d+)(?:,(\d*))?\}/g)) {
18131
- const min = Number(match[1]);
18132
- const maxRaw = match[2];
18133
- const max = maxRaw === void 0 || maxRaw === "" ? min : Number(maxRaw);
18134
- if (!Number.isFinite(min) || !Number.isFinite(max) || min > REDACTION_POLICY_LIMITS.maxTypedQuantifier || max > REDACTION_POLICY_LIMITS.maxTypedQuantifier) {
18135
- throw new Error(
18136
- `${label} quantifiers must be <= ${REDACTION_POLICY_LIMITS.maxTypedQuantifier}.`
18137
- );
18263
+ function rejectUnknownFields(record, allowed, label) {
18264
+ for (const key of Object.keys(record)) {
18265
+ if (!allowed.has(key)) {
18266
+ throw new Error(`${label} rejects unknown field "${key}".`);
18138
18267
  }
18139
18268
  }
18140
18269
  }
18141
18270
  function compilePatternDetector(input3, index) {
18142
18271
  const label = `patterns[${index}]`;
18143
18272
  if (!isRecord17(input3)) throw new Error(`${label} must be an object.`);
18273
+ const typeEarly = input3.type;
18274
+ if (typeEarly === "typed") {
18275
+ throw new Error(
18276
+ `${label}.type "typed" is no longer supported (removed in 6.29.1). Use type "literal" or "prefix" with a fixed value; arbitrary regex patterns are not accepted.`
18277
+ );
18278
+ }
18279
+ rejectUnknownFields(input3, ALLOWED_PATTERN_FIELDS, label);
18144
18280
  const idRaw = input3.id;
18145
18281
  if (typeof idRaw !== "string" || idRaw.trim() === "") {
18146
18282
  throw new Error(`${label}.id must be a non-empty string.`);
@@ -18155,48 +18291,35 @@ function compilePatternDetector(input3, index) {
18155
18291
  throw new Error(`${label}.id must be an identifier-like detector id.`);
18156
18292
  }
18157
18293
  const type = input3.type;
18158
- if (type !== "literal" && type !== "prefix" && type !== "typed") {
18159
- throw new Error(`${label}.type must be literal, prefix, or typed.`);
18294
+ if (type !== "literal" && type !== "prefix") {
18295
+ throw new Error(`${label}.type must be literal or prefix.`);
18296
+ }
18297
+ if (input3.pattern !== void 0) {
18298
+ throw new Error(
18299
+ `${label}.pattern is not accepted; use .value with type literal or prefix.`
18300
+ );
18160
18301
  }
18161
18302
  const severity = parseSeverity(input3.severity, label);
18162
- let source;
18163
- if (type === "typed") {
18164
- if (typeof input3.pattern !== "string") {
18165
- throw new Error(`${label}.pattern must be a string for typed patterns.`);
18166
- }
18167
- assertBoundedTypedPattern(input3.pattern, `${label}.pattern`);
18168
- source = input3.pattern;
18169
- } else {
18170
- if (typeof input3.value !== "string") {
18171
- throw new Error(`${label}.value must be a string for ${type} patterns.`);
18172
- }
18173
- if (input3.value.length === 0) {
18174
- throw new Error(`${label}.value must be non-empty.`);
18175
- }
18176
- if (input3.value.length > REDACTION_POLICY_LIMITS.maxPatternLength) {
18177
- throw new Error(
18178
- `${label}.value exceeds max length ${REDACTION_POLICY_LIMITS.maxPatternLength}.`
18179
- );
18180
- }
18181
- const escaped = escapeRegExp(input3.value);
18182
- source = type === "prefix" ? `^${escaped}` : escaped;
18303
+ if (typeof input3.value !== "string") {
18304
+ throw new Error(`${label}.value must be a string for ${type} patterns.`);
18183
18305
  }
18184
- let regex;
18185
- try {
18186
- regex = new RegExp(source);
18187
- } catch (error) {
18306
+ if (input3.value.length === 0) {
18307
+ throw new Error(`${label}.value must be non-empty.`);
18308
+ }
18309
+ if (input3.value.length > REDACTION_POLICY_LIMITS.maxPatternLength) {
18188
18310
  throw new Error(
18189
- `${label} failed to compile: ${error instanceof Error ? error.message : String(error)}`
18311
+ `${label}.value exceeds max length ${REDACTION_POLICY_LIMITS.maxPatternLength}.`
18190
18312
  );
18191
18313
  }
18314
+ const needle = input3.value;
18315
+ const match = type === "prefix" ? (haystack) => haystack.startsWith(needle) : (haystack) => haystack.includes(needle);
18192
18316
  return {
18193
18317
  id: `policy.${id}`,
18194
18318
  severity,
18195
18319
  matchKind: "custom",
18196
18320
  detect({ value }) {
18197
18321
  if (typeof value !== "string") return [];
18198
- regex.lastIndex = 0;
18199
- return regex.test(value) ? [{ action: "replace", severity, matchKind: "custom" }] : [];
18322
+ return match(value) ? [{ action: "replace", severity, matchKind: "custom" }] : [];
18200
18323
  }
18201
18324
  };
18202
18325
  }
@@ -18204,6 +18327,7 @@ function compileRedactionPolicy(raw, policyPath) {
18204
18327
  if (!isRecord17(raw)) {
18205
18328
  throw new Error(`Redaction policy must be a JSON object (${policyPath}).`);
18206
18329
  }
18330
+ rejectUnknownFields(raw, ALLOWED_TOP_LEVEL, "Redaction policy");
18207
18331
  const diagnostics = [];
18208
18332
  if (raw.version !== void 0 && raw.version !== 1) {
18209
18333
  throw new Error(`Unsupported redaction policy version (supported: 1).`);
@@ -18267,14 +18391,38 @@ function compileRedactionPolicy(raw, policyPath) {
18267
18391
  async function loadRedactionPolicy(policyPath) {
18268
18392
  rejectRemotePolicyPath(policyPath);
18269
18393
  const resolved = path33__default.default.resolve(policyPath);
18270
- let text;
18394
+ let fileStat;
18395
+ try {
18396
+ fileStat = await promises.stat(resolved);
18397
+ } catch (error) {
18398
+ throw new Error(
18399
+ `Failed to read --policy file "${resolved}": ${error instanceof Error ? error.message : String(error)}`
18400
+ );
18401
+ }
18402
+ if (!fileStat.isFile()) {
18403
+ throw new Error(
18404
+ `--policy must be a regular local JSON file (not a directory or special file): "${resolved}".`
18405
+ );
18406
+ }
18407
+ if (fileStat.size > REDACTION_POLICY_LIMITS.maxPolicyFileBytes) {
18408
+ throw new Error(
18409
+ `--policy file exceeds max size ${REDACTION_POLICY_LIMITS.maxPolicyFileBytes} bytes.`
18410
+ );
18411
+ }
18412
+ let buffer;
18271
18413
  try {
18272
- text = await promises.readFile(resolved, "utf-8");
18414
+ buffer = await promises.readFile(resolved);
18273
18415
  } catch (error) {
18274
18416
  throw new Error(
18275
18417
  `Failed to read --policy file "${resolved}": ${error instanceof Error ? error.message : String(error)}`
18276
18418
  );
18277
18419
  }
18420
+ if (buffer.byteLength > REDACTION_POLICY_LIMITS.maxPolicyFileBytes) {
18421
+ throw new Error(
18422
+ `--policy file exceeds max size ${REDACTION_POLICY_LIMITS.maxPolicyFileBytes} bytes.`
18423
+ );
18424
+ }
18425
+ const text = buffer.toString("utf-8");
18278
18426
  let parsed;
18279
18427
  try {
18280
18428
  parsed = JSON.parse(text);