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
package/CHANGELOG.md CHANGED
@@ -1,5 +1,17 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.29.1
4
+
5
+ ### Patch Changes
6
+
7
+ - d723406: Post-6.29 hardening: regex-free redaction policy, OTLP GenAI declared-vs-emitted honesty, recovery fail-closed contracts, AI SDK overlap/close terminalization (open rows only), Evidence refuse unsafe expected/oneOf values with bind-before-HTML packaging, and CLI/recipe DX for anyOf vs retry paths.
8
+
9
+ ## 6.29.0
10
+
11
+ ### Minor Changes
12
+
13
+ - 0e5732e: Provider usage fidelity: preserve cache-read (`cached`), cache-write (`cacheWrite`), and reasoning token fields across core normalization and adapters. Add isolated AI SDK peer matrix (`ai@^6` required; AI SDK 7 soft-blocked pending telemetry API migration). No pricing engine; root Node remains `>=20`.
14
+
3
15
  ## 6.28.0
4
16
 
5
17
  ### Minor Changes
package/README.md CHANGED
@@ -212,7 +212,7 @@ The root package is enough for custom capture, the CLI, checks, and Evidence wor
212
212
 
213
213
  ## Status and documentation
214
214
 
215
- **Current published baseline:** **6.28.0** · persisted schema `1.0` · Node.js `>=20` · MIT.
215
+ **Current published baseline:** **6.29.1** · persisted schema `1.0` · Node.js `>=20` · MIT.
216
216
 
217
217
  Legacy v0.1 and v0.2 traces remain readable. Check the npm badge and [changelog](CHANGELOG.md) for the current published version.
218
218
 
package/docs/CLI.md CHANGED
@@ -49,6 +49,24 @@ Core commands:
49
49
  - `report` — markdown or HTML inspection report for a single run
50
50
  - `explain` — deterministic local facts/inferences for a trace, with dry-run payloads
51
51
 
52
+ ## 1.1 CLI vs TraceContract decision table (6.29.3)
53
+
54
+ Use this table when choosing between CLI check shorthands and TraceContract rules.
55
+ No new CLI commands were added for branching paths.
56
+
57
+ | Need | Prefer |
58
+ | ---- | ------ |
59
+ | One tool must always run | CLI `--required-tool` / contract `tools.required` |
60
+ | Tool must never run | CLI `--forbidden-tool` / contract `tools.forbidden` |
61
+ | Legitimate alternate paths (OR) | TraceContract `alternatives.anyOf` (not CLI flags) |
62
+ | Causal order between tools | TraceContract `requiredOrder` + `requiredOrderMode` |
63
+ | Read recovery vs write fail-closed | TraceContract `retry.operations` + `sideEffectClass` |
64
+ | Sensitive expected literals in Evidence | Contract binding safety (`unavailable` on credential-like expected); never silent complete packaging |
65
+ | Share-safe offline review package | CLI `bundle` / Evidence CI helpers |
66
+
67
+ See [TRACE-CONTRACTS.md](./TRACE-CONTRACTS.md) and recipe
68
+ [sensitive-read-outbound-write-anyof](../examples/recipes/sensitive-read-outbound-write-anyof/).
69
+
52
70
  ## 2. Environment variables
53
71
 
54
72
  - **`AGENT_INSPECT_TRACE_DIR`**: default directory for manual trace files (`.jsonl`) when not passed via `--dir` (or API options).
@@ -446,7 +464,7 @@ Options:
446
464
  - `--profile <local|share|strict>`: redaction profile (default `share`)
447
465
  - `-o, --output <path>`: write redacted content to a file
448
466
  - `--json`: print deterministic JSON wrapper with findings
449
- - `--policy <path>`: local JSON redaction policy (`extraKeys` + bounded `literal` / `prefix` / `typed` patterns). No remote fetch; no secrets on argv. See [SAFETY-POLICY.md](SAFETY-POLICY.md).
467
+ - `--policy <path>`: local JSON redaction policy (`extraKeys` + bounded `literal` / `prefix` patterns; no user regex since 6.29.1). No remote fetch; no secrets on argv. See [SAFETY-POLICY.md](SAFETY-POLICY.md).
450
468
  - `--fail-on-residual`: opt-in non-zero exit when residual safety is `UNSAFE` or `UNKNOWN` (default exit codes unchanged)
451
469
 
452
470
  After redaction, the command surfaces a **residual safety assessment** using the same local detector pipeline as `verify-safe`. Human mode prints a concise stderr warning when residual status is not `SAFE`. JSON mode adds an additive `residualAssessment` field (`status`, finding counts, codes only — never matched secret values). Residual status uses `SAFE` | `SAFE_WITH_WARNINGS` | `UNSAFE` | `UNKNOWN`. Supported AgentInspect traces get a full assessment; arbitrary JSON that is not a supported trace yields `UNKNOWN`. Redact never certifies safe sharing — finish with `verify-safe` before publishing.
@@ -26,7 +26,7 @@ This document states what AgentInspect **does not** provide today. It complement
26
26
  - **Subpath APIs:** `agent-inspect/writers`, `agent-inspect/readers`, and advanced helpers are available for local adoption from their owning subpaths. `createInspector()` is part of the small root API.
27
27
  - **Explicit writer ownership:** `createInspector()` does not print terminal lifecycle output or implicitly choose a disk writer. Use `fileWriter()` / `bufferedFileWriter()` / custom writers when persistence is desired.
28
28
  - **Diagnostic evidence, not an event-sourced runtime:** AgentInspect traces are local diagnostic evidence of what an agent did. They are **not** a write-ahead log, durable-before-effect journal, or application event-sourcing runtime. Buffered writers may lose a bounded tail of events on abrupt process termination. Call `flush()` / `close()` according to writer docs when you need the queue drained before exit; that lifecycle is deterministic and idempotent, but it is **not** an fsync / crash-durability guarantee.
29
- - **No standards upload:** OpenInference and OTLP JSON support is local read/export compatibility only. There is no OTLP gRPC/HTTP streaming sink, collector client, or hosted ingestion behavior.
29
+ - **No standards upload:** OpenInference and OTLP JSON support is local read/export compatibility only. There is no OTLP gRPC/HTTP streaming sink, collector client, or hosted ingestion behavior. OTLP GenAI export is metadata/token-oriented (`OTEL_GEN_AI_SEMCONV_PIN`); it does not emit `gen_ai.prompt` / `gen_ai.completion` bodies.
30
30
  - **Conservative detection:** `agent-inspect open` does not silently accept arbitrary JSON. Unsupported or ambiguous inputs produce errors/warnings rather than guessed traces.
31
31
  - **Large inputs:** reader inputs are bounded and read into local memory. This is not a database index or production log warehouse.
32
32
 
@@ -81,7 +81,7 @@ This document states what AgentInspect **does not** provide today. It complement
81
81
 
82
82
  ## Economics
83
83
 
84
- - **No cost engine**: no pricing tables, invoice-grade usage, or provider billing reconciliation.
84
+ - **No cost engine**: no pricing tables, invoice-grade usage, or provider billing reconciliation. Usage fidelity may preserve cache-read (`cached`), cache-write (`cacheWrite`), and reasoning token counts when providers report them; those fields are observational only.
85
85
  - **Token usage is supplied metadata only**: AgentInspect may display `input`, `output`, `total`, and `cached` counts when callers/adapters provide them; core does not count tokens or infer provider billing.
86
86
 
87
87
  ## Local observability commands (v1.4.0)
@@ -6,7 +6,7 @@ AgentInspect traces, log-ingest outputs, and exports are local files. They may s
6
6
 
7
7
  This guide is practical sharing guidance, not a guarantee that any artifact is safe to publish. Redaction profiles are **best-effort transformation**, not compliance-grade DLP or a safety certification. Always finish with `verify-safe` before sharing.
8
8
 
9
- Built-in profiles redact high-confidence credential forms (provider keys, JWTs, bearer tokens, and bounded `token=` / `api_key=` / `internal_token=` style key/value secrets). Broad or context-sensitive findings—such as private filesystem paths—may still appear under `verify-safe` and as residual status after `redact`. Org-specific patterns can use a local CLI `--policy` JSON file (`extraKeys` plus bounded literal/prefix/typed patterns) or programmatic custom detectors.
9
+ Built-in profiles redact high-confidence credential forms (provider keys, JWTs, bearer tokens, and bounded `token=` / `api_key=` / `internal_token=` style key/value secrets). Broad or context-sensitive findings—such as private filesystem paths—may still appear under `verify-safe` and as residual status after `redact`. Org-specific patterns can use a local CLI `--policy` JSON file (`extraKeys` plus bounded literal/prefix patterns; no user regex) or programmatic custom detectors.
10
10
 
11
11
  `strict` is a stricter **rule set** (more keys), not a promise that every input produces bytes different from `share`.
12
12
 
package/docs/SCHEMA.md CHANGED
@@ -264,7 +264,7 @@ Canonical samples: `fixtures/traces-v0.2/*.jsonl` (validated by `pnpm fixtures:c
264
264
  | `attributes` | no | Shallow metadata bag (redaction-ready) |
265
265
  | `inputSummary` / `outputSummary` | no | Truncated previews when explicitly captured |
266
266
  | `error` | no | `{ name?, message, code? }` when `status: "error"` |
267
- | `tokenUsage` | no | `{ input?, output?, total?, cached? }` when supplied/known |
267
+ | `tokenUsage` | no | `{ input?, output?, total?, cached?, cacheWrite?, reasoning? }` when supplied/known. `cached` is cache-read; `cacheWrite` / `reasoning` are informational and are never added to `total`. No pricing fields. |
268
268
  | `trace` | no | Optional `{ traceId?, spanId?, parentSpanId? }` for future OTel alignment |
269
269
 
270
270
  Programmatic helpers: see [API.md](./API.md) §13 (experimental persisted-event foundation).
package/docs/STANDARDS.md CHANGED
@@ -29,7 +29,7 @@ The fixture's top-level `version` is an **AgentInspect reference fixture revisio
29
29
  npx agent-inspect export <run-id> --format otlp-json --profile share
30
30
  ```
31
31
 
32
- GenAI attribute mapping follows `OTEL_GEN_AI_SEMCONV_PIN` (see exporters API). No gRPC collector included.
32
+ GenAI attribute mapping follows `OTEL_GEN_AI_SEMCONV_PIN` (see exporters API). The pin lists only attributes the exporter may emit (operation name, request model, usage tokens). AgentInspect does **not** export `gen_ai.prompt` / `gen_ai.completion` bodies. No gRPC collector included.
33
33
 
34
34
  Fixture: [fixtures/standards/otlp-basic.json](../fixtures/standards/otlp-basic.json)
35
35
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-inspect",
3
- "version": "6.28.0",
3
+ "version": "6.29.1",
4
4
  "license": "MIT",
5
5
  "type": "module",
6
6
  "description": "Local evidence debugger and trajectory-test toolkit for TypeScript AI agents — execution trees, TraceContract checks, Evidence v2, and read-only MCP",
@@ -250,6 +250,7 @@
250
250
  "demo:generate": "node scripts/demo-generate.mjs",
251
251
  "demo:verify": "node scripts/demo-verify.mjs",
252
252
  "compat:smoke": "node scripts/compat-smoke.mjs",
253
+ "compat:ai-sdk-matrix": "node scripts/ai-sdk-peer-matrix.mjs",
253
254
  "fixtures:check": "node scripts/validate-fixtures.mjs",
254
255
  "recipes:check": "node scripts/validate-recipes.mjs",
255
256
  "perf:baseline": "node scripts/performance-baseline.mjs",
@@ -94,6 +94,8 @@ function isPersistedTokenUsage(value) {
94
94
  if (!isOptionalNonNegativeNumber(value.output)) return false;
95
95
  if (!isOptionalNonNegativeNumber(value.total)) return false;
96
96
  if (!isOptionalNonNegativeNumber(value.cached)) return false;
97
+ if (!isOptionalNonNegativeNumber(value.cacheWrite)) return false;
98
+ if (!isOptionalNonNegativeNumber(value.reasoning)) return false;
97
99
  return true;
98
100
  }
99
101
  function isPersistedTraceContext(value) {
@@ -839,6 +841,30 @@ var Redactor = class {
839
841
  }
840
842
  };
841
843
 
844
+ // packages/core/src/safety/credential-value-patterns.ts
845
+ var KEY_VALUE_SECRET_PATTERN = /\b(?:api[_-]?key|internal[_-]?token|access[_-]?token|auth[_-]?token|password|secret|token)=([^\s"'\\]{8,})/i;
846
+ var HIGH_CONFIDENCE_CREDENTIAL_PATTERNS = [
847
+ /^(?:basic|bearer|digest|apikey)\s+[a-z0-9._~+/=-]+$/i,
848
+ /\bbearer\s+[a-z0-9._~+/=-]{12,}\b/i,
849
+ /\b[a-z0-9_.-]+=[^;\s]+(?:;\s*[a-z0-9_.-]+=[^;\s]+)+/i,
850
+ /\beyJ[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\.[a-zA-Z0-9_-]{8,}\b/,
851
+ /\b(?:sk-(?:proj-)?[a-zA-Z0-9_-]{16,}|sk-ant-[a-zA-Z0-9_-]{16,}|AIza[0-9A-Za-z_-]{20,})\b/,
852
+ /\b(?:ghp|gho|ghu|ghs|ghr)_[A-Za-z0-9_]{20,}\b/,
853
+ /\b(?:AKIA|ASIA)[A-Z0-9]{16}\b/,
854
+ /-----BEGIN [A-Z ]*PRIVATE KEY-----[\s\S]*-----END [A-Z ]*PRIVATE KEY-----/,
855
+ KEY_VALUE_SECRET_PATTERN
856
+ ];
857
+ function stringContainsHighConfidenceCredential(value) {
858
+ for (const pattern of HIGH_CONFIDENCE_CREDENTIAL_PATTERNS) {
859
+ pattern.lastIndex = 0;
860
+ if (pattern.test(value)) {
861
+ pattern.lastIndex = 0;
862
+ return true;
863
+ }
864
+ }
865
+ return false;
866
+ }
867
+
842
868
  // packages/core/src/redaction-profiles.ts
843
869
  var SHARE_PROFILE_EXTRA_KEYS = [
844
870
  "userEmail",
@@ -1796,7 +1822,13 @@ function buildRunSummary(events) {
1796
1822
  tokensInput: isNonNegativeFiniteNumber(s.metadata?.tokens?.input) ? s.metadata.tokens.input : void 0,
1797
1823
  tokensOutput: isNonNegativeFiniteNumber(s.metadata?.tokens?.output) ? s.metadata.tokens.output : void 0,
1798
1824
  tokensTotal: isNonNegativeFiniteNumber(s.metadata?.tokens?.total) ? s.metadata.tokens.total : void 0,
1799
- tokensCached: isNonNegativeFiniteNumber(s.metadata?.tokens?.cached) ? s.metadata.tokens.cached : void 0
1825
+ tokensCached: isNonNegativeFiniteNumber(s.metadata?.tokens?.cached) ? s.metadata.tokens.cached : void 0,
1826
+ tokensCacheWrite: isNonNegativeFiniteNumber(
1827
+ s.metadata?.tokens?.cacheWrite
1828
+ ) ? s.metadata.tokens.cacheWrite : void 0,
1829
+ tokensReasoning: isNonNegativeFiniteNumber(
1830
+ s.metadata?.tokens?.reasoning
1831
+ ) ? s.metadata.tokens.reasoning : void 0
1800
1832
  });
1801
1833
  }
1802
1834
  }
@@ -1820,9 +1852,13 @@ function buildRunSummary(events) {
1820
1852
  let totalTokensOutput = 0;
1821
1853
  let totalTokensTotal = 0;
1822
1854
  let totalTokensCached = 0;
1855
+ let totalTokensCacheWrite = 0;
1856
+ let totalTokensReasoning = 0;
1823
1857
  let tokenBearingSteps = 0;
1824
1858
  let stepsWithKnownTotal = 0;
1825
1859
  let hasCachedTokens = false;
1860
+ let hasCacheWriteTokens = false;
1861
+ let hasReasoningTokens = false;
1826
1862
  const depthCache = /* @__PURE__ */ new Map();
1827
1863
  for (const [id, s] of steps.entries()) {
1828
1864
  totalSteps += 1;
@@ -1837,7 +1873,7 @@ function buildRunSummary(events) {
1837
1873
  longestStep = { name: s.name, durationMs: s.durationMs, type: s.type };
1838
1874
  }
1839
1875
  }
1840
- if (s.tokensInput !== void 0 || s.tokensOutput !== void 0 || s.tokensTotal !== void 0 || s.tokensCached !== void 0) {
1876
+ 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) {
1841
1877
  tokenBearingSteps += 1;
1842
1878
  if (s.tokensInput !== void 0) totalTokensInput += s.tokensInput;
1843
1879
  if (s.tokensOutput !== void 0) totalTokensOutput += s.tokensOutput;
@@ -1852,6 +1888,14 @@ function buildRunSummary(events) {
1852
1888
  totalTokensCached += s.tokensCached;
1853
1889
  hasCachedTokens = true;
1854
1890
  }
1891
+ if (s.tokensCacheWrite !== void 0) {
1892
+ totalTokensCacheWrite += s.tokensCacheWrite;
1893
+ hasCacheWriteTokens = true;
1894
+ }
1895
+ if (s.tokensReasoning !== void 0) {
1896
+ totalTokensReasoning += s.tokensReasoning;
1897
+ hasReasoningTokens = true;
1898
+ }
1855
1899
  }
1856
1900
  }
1857
1901
  const summary = {
@@ -1871,7 +1915,9 @@ function buildRunSummary(events) {
1871
1915
  input: totalTokensInput,
1872
1916
  output: totalTokensOutput,
1873
1917
  ...stepsWithKnownTotal === tokenBearingSteps ? { total: totalTokensTotal } : {},
1874
- ...hasCachedTokens ? { cached: totalTokensCached } : {}
1918
+ ...hasCachedTokens ? { cached: totalTokensCached } : {},
1919
+ ...hasCacheWriteTokens ? { cacheWrite: totalTokensCacheWrite } : {},
1920
+ ...hasReasoningTokens ? { reasoning: totalTokensReasoning } : {}
1875
1921
  }
1876
1922
  } : {}
1877
1923
  };
@@ -2384,6 +2430,12 @@ function renderRunWhat(summary, options = {}) {
2384
2430
  if (summary.totalTokens.cached !== void 0) {
2385
2431
  tokenParts.push(`${summary.totalTokens.cached} cached`);
2386
2432
  }
2433
+ if (summary.totalTokens.cacheWrite !== void 0) {
2434
+ tokenParts.push(`${summary.totalTokens.cacheWrite} cache-write`);
2435
+ }
2436
+ if (summary.totalTokens.reasoning !== void 0) {
2437
+ tokenParts.push(`${summary.totalTokens.reasoning} reasoning`);
2438
+ }
2387
2439
  lines.push(`Tokens: ${tokenParts.join(" / ")}`);
2388
2440
  }
2389
2441
  if (showCorrelation && summary.correlation) {
@@ -5186,6 +5238,9 @@ var SAFE_USAGE_LEAF_KEYS = /* @__PURE__ */ new Set([
5186
5238
  "output",
5187
5239
  "total",
5188
5240
  "cached",
5241
+ "cachewrite",
5242
+ "cache_write",
5243
+ "reasoning",
5189
5244
  "input_tokens",
5190
5245
  "inputtokens",
5191
5246
  "output_tokens",
@@ -5195,7 +5250,13 @@ var SAFE_USAGE_LEAF_KEYS = /* @__PURE__ */ new Set([
5195
5250
  "prompt_tokens",
5196
5251
  "prompttokens",
5197
5252
  "completion_tokens",
5198
- "completiontokens"
5253
+ "completiontokens",
5254
+ "cache_read",
5255
+ "cacheread",
5256
+ "cache_creation",
5257
+ "cachecreation",
5258
+ "reasoning_tokens",
5259
+ "reasoningtokens"
5199
5260
  ]);
5200
5261
  var DEFAULT_SECRET_PATTERNS = [
5201
5262
  { id: "bearer-token", pattern: /Bearer\s+[A-Za-z0-9._~+/-]{12,}=*/ },
@@ -7037,7 +7098,15 @@ function buildEmbeddedPayload(input) {
7037
7098
  redactionProfile: input.redactionProfile,
7038
7099
  verificationPolicy: input.verificationPolicy
7039
7100
  },
7040
- checkSummary: input.checkSummary
7101
+ checkSummary: input.checkSummary,
7102
+ ...input.contractBinding !== void 0 ? {
7103
+ contract: {
7104
+ status: input.contractBinding.status,
7105
+ ...input.contractBinding.sha256 !== void 0 ? { sha256: input.contractBinding.sha256 } : {},
7106
+ ...input.contractBinding.ruleCount !== void 0 ? { ruleCount: input.contractBinding.ruleCount } : {},
7107
+ ...input.contractBinding.note !== void 0 ? { note: input.contractBinding.note } : {}
7108
+ }
7109
+ } : {}
7041
7110
  };
7042
7111
  }
7043
7112
  function buildEvidenceHtmlShell(input) {
@@ -7135,6 +7204,7 @@ ${nav}
7135
7204
  <p>Artifact status: <span class="badge ${statusClass(input.assessmentStatus)}">${escapeHtml(input.assessmentStatus)}</span>
7136
7205
  ${input.sourceStatus !== void 0 ? ` \xB7 Source status: <span class="badge ${statusClass(input.sourceStatus)}">${escapeHtml(input.sourceStatus)}</span>` : ""}</p>
7137
7206
  <p>Profile: <code>${escapeHtml(input.redactionProfile)}</code> \xB7 Verification: <code>${escapeHtml(input.verificationPolicy)}</code></p>
7207
+ ${input.contractBinding !== void 0 ? `<p>Contract binding: <code>${escapeHtml(input.contractBinding.status)}</code>${input.contractBinding.ruleCount !== void 0 ? ` \xB7 Rules: <code>${escapeHtml(String(input.contractBinding.ruleCount))}</code>` : ""}${input.contractBinding.sha256 !== void 0 ? ` \xB7 Digest: <code>${escapeHtml(input.contractBinding.sha256.slice(0, 16))}\u2026</code>` : ""}</p>${input.contractBinding.note !== void 0 && input.contractBinding.note.trim() !== "" ? `<p class="muted">${escapeHtml(input.contractBinding.note)}</p>` : ""}` : ""}
7138
7208
  <p>Generator: <code>${escapeHtml(input.generatorName)}@${escapeHtml(input.generatorVersion)}</code>
7139
7209
  ${input.createdAt ? ` \xB7 Created: <code>${escapeHtml(input.createdAt)}</code>` : ""}</p>
7140
7210
  <h3>Runs</h3>
@@ -7927,6 +7997,39 @@ var EVIDENCE_CONTRACT_CANONICALIZATION_VERSION = "1";
7927
7997
  var EVIDENCE_CONTRACT_PARTIAL_NOTE = "Custom or programmatic rules are not serializable; Evidence records rule IDs only and does not claim complete reviewer replay.";
7928
7998
  var EVIDENCE_CONTRACT_UNAVAILABLE_NOTE = "No resolved TraceContract or check preset was packaged with this Evidence artifact.";
7929
7999
  var 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.";
8000
+ var EVIDENCE_CONTRACT_UNSAFE_NOTE = "Resolved TraceContract contains high-confidence credential-like expected values; Evidence refuses complete packaging rather than silently redacting evaluated expectations.";
8001
+ function contractContainsUnsafeExpectedValues(value) {
8002
+ return scanForExpectedFields(value, 0);
8003
+ }
8004
+ function scanForExpectedFields(value, depth) {
8005
+ if (depth > 32) return false;
8006
+ if (Array.isArray(value)) {
8007
+ return value.some((item) => scanForExpectedFields(item, depth + 1));
8008
+ }
8009
+ if (value === null || typeof value !== "object") return false;
8010
+ const record = value;
8011
+ for (const [key, child] of Object.entries(record)) {
8012
+ if (key === "expected" || key === "oneOf") {
8013
+ if (valueTreeContainsCredential(child, depth + 1)) return true;
8014
+ continue;
8015
+ }
8016
+ if (scanForExpectedFields(child, depth + 1)) return true;
8017
+ }
8018
+ return false;
8019
+ }
8020
+ function valueTreeContainsCredential(value, depth) {
8021
+ if (depth > 32) return false;
8022
+ if (typeof value === "string") {
8023
+ return stringContainsHighConfidenceCredential(value);
8024
+ }
8025
+ if (Array.isArray(value)) {
8026
+ return value.some((item) => valueTreeContainsCredential(item, depth + 1));
8027
+ }
8028
+ if (value === null || typeof value !== "object") return false;
8029
+ return Object.values(value).some(
8030
+ (child) => valueTreeContainsCredential(child, depth + 1)
8031
+ );
8032
+ }
7930
8033
  function serializeCanonicalJson(value) {
7931
8034
  return `${JSON.stringify(stableValue(value), null, 2)}
7932
8035
  `;
@@ -8060,6 +8163,32 @@ function buildEvidenceContractPackage(input) {
8060
8163
  if (unsupported.length > 0) {
8061
8164
  ruleIds = sortedUniqueStrings([...ruleIds, ...unsupported]);
8062
8165
  }
8166
+ if (contractContainsUnsafeExpectedValues(resolved)) {
8167
+ return {
8168
+ binding: {
8169
+ status: "unavailable",
8170
+ source: input.source,
8171
+ ...input.contractId !== void 0 ? { contractId: input.contractId } : {},
8172
+ ...input.contractVersion !== void 0 ? { contractVersion: input.contractVersion } : {},
8173
+ canonicalizationVersion: EVIDENCE_CONTRACT_CANONICALIZATION_VERSION,
8174
+ engineVersion: input.engineVersion,
8175
+ ruleIds,
8176
+ ...unsupported.length > 0 ? { unsupportedRuleIds: unsupported } : {},
8177
+ note: input.note ?? EVIDENCE_CONTRACT_UNSAFE_NOTE
8178
+ },
8179
+ checkBinding: {
8180
+ canonicalizationVersion: EVIDENCE_CONTRACT_CANONICALIZATION_VERSION,
8181
+ engineVersion: input.engineVersion,
8182
+ evaluatedRuleIds: ruleIds,
8183
+ bindingStatus: "unavailable",
8184
+ ...unsupported.length > 0 ? { unsupportedRuleIds: unsupported } : {},
8185
+ origin: {
8186
+ source: input.source,
8187
+ ...input.preset?.name ? { preset: input.preset.name } : {}
8188
+ }
8189
+ }
8190
+ };
8191
+ }
8063
8192
  const document = {
8064
8193
  canonicalizationVersion: EVIDENCE_CONTRACT_CANONICALIZATION_VERSION,
8065
8194
  kind,
@@ -8432,29 +8561,6 @@ function buildEvidenceCiPackage(input) {
8432
8561
  schemaVersions.add(version);
8433
8562
  }
8434
8563
  const createdAt = input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
8435
- const evidenceHtml = buildEvidenceHtmlShell({
8436
- title: "AgentInspect evidence",
8437
- runIds: input.runIds,
8438
- assessmentStatus: input.assessmentStatus,
8439
- sourceStatus: input.sourceStatus,
8440
- redactionProfile: input.redactionProfile,
8441
- verificationPolicy: input.redactionProfile,
8442
- generatorName: "agent-inspect",
8443
- generatorVersion: input.generatorVersion,
8444
- createdAt,
8445
- summaryText: input.summaryText,
8446
- checkSummary: {
8447
- aggregateStatus: input.assessmentStatus,
8448
- runs: input.runIds.map((runId) => ({
8449
- runId,
8450
- status: input.assessmentStatus,
8451
- sourceStatus: input.sourceStatus,
8452
- errors: input.assessmentStatus === "UNSAFE" || input.assessmentStatus === "UNKNOWN" ? 1 : 0,
8453
- warnings: input.assessmentStatus === "SAFE WITH WARNINGS" ? 1 : 0,
8454
- findings: 0
8455
- }))
8456
- }
8457
- });
8458
8564
  let checkResultsJson = input.checkResultsJson;
8459
8565
  let contractBinding;
8460
8566
  let contractFileContent;
@@ -8477,6 +8583,37 @@ function buildEvidenceCiPackage(input) {
8477
8583
  bindCheckResultsToContract(parsed, packaged2.checkBinding)
8478
8584
  );
8479
8585
  }
8586
+ const evidenceHtml = buildEvidenceHtmlShell({
8587
+ title: "AgentInspect evidence",
8588
+ runIds: input.runIds,
8589
+ assessmentStatus: input.assessmentStatus,
8590
+ sourceStatus: input.sourceStatus,
8591
+ redactionProfile: input.redactionProfile,
8592
+ verificationPolicy: input.redactionProfile,
8593
+ generatorName: "agent-inspect",
8594
+ generatorVersion: input.generatorVersion,
8595
+ createdAt,
8596
+ summaryText: input.summaryText,
8597
+ checkSummary: {
8598
+ aggregateStatus: input.assessmentStatus,
8599
+ runs: input.runIds.map((runId) => ({
8600
+ runId,
8601
+ status: input.assessmentStatus,
8602
+ sourceStatus: input.sourceStatus,
8603
+ errors: input.assessmentStatus === "UNSAFE" || input.assessmentStatus === "UNKNOWN" ? 1 : 0,
8604
+ warnings: input.assessmentStatus === "SAFE WITH WARNINGS" ? 1 : 0,
8605
+ findings: 0
8606
+ }))
8607
+ },
8608
+ ...contractBinding !== void 0 ? {
8609
+ contractBinding: {
8610
+ status: contractBinding.status,
8611
+ ...contractBinding.sha256 !== void 0 ? { sha256: contractBinding.sha256 } : {},
8612
+ ...contractBinding.note !== void 0 ? { note: contractBinding.note } : {},
8613
+ ruleCount: contractBinding.ruleIds.length
8614
+ }
8615
+ } : {}
8616
+ });
8480
8617
  const packaged = [
8481
8618
  { path: EVIDENCE_HTML_FILENAME, content: evidenceHtml },
8482
8619
  { path: "check-results.json", content: checkResultsJson },
@@ -8792,16 +8929,20 @@ function normalizeTokenUsage(value) {
8792
8929
  const output = nonNegativeFinite(value.output);
8793
8930
  const suppliedTotal = nonNegativeFinite(value.total);
8794
8931
  const cached = nonNegativeFinite(value.cached);
8932
+ const cacheWrite = nonNegativeFinite(value.cacheWrite);
8933
+ const reasoning = nonNegativeFinite(value.reasoning);
8795
8934
  const derivedTotal = input !== void 0 && output !== void 0 && Number.isFinite(input + output) ? input + output : void 0;
8796
8935
  const total = suppliedTotal ?? derivedTotal;
8797
- if (input === void 0 && output === void 0 && total === void 0 && cached === void 0) {
8936
+ if (input === void 0 && output === void 0 && total === void 0 && cached === void 0 && cacheWrite === void 0 && reasoning === void 0) {
8798
8937
  return void 0;
8799
8938
  }
8800
8939
  return {
8801
8940
  ...input !== void 0 ? { input } : {},
8802
8941
  ...output !== void 0 ? { output } : {},
8803
8942
  ...total !== void 0 ? { total } : {},
8804
- ...cached !== void 0 ? { cached } : {}
8943
+ ...cached !== void 0 ? { cached } : {},
8944
+ ...cacheWrite !== void 0 ? { cacheWrite } : {},
8945
+ ...reasoning !== void 0 ? { reasoning } : {}
8805
8946
  };
8806
8947
  }
8807
8948
 
@@ -9960,6 +10101,8 @@ function readOpenInferenceTokenUsage(attributes) {
9960
10101
  const completion = attributes["llm.token_count.completion"];
9961
10102
  const total = attributes["llm.token_count.total"];
9962
10103
  const cached = attributes["llm.token_count.prompt_details.cache_read"];
10104
+ const cacheWrite = attributes["llm.token_count.prompt_details.cache_write"] ?? attributes["llm.token_count.prompt_details.cache_creation"];
10105
+ const reasoning = attributes["llm.token_count.completion_details.reasoning"] ?? attributes["llm.token_count.completion_details.reasoning_tokens"];
9963
10106
  const usage = {};
9964
10107
  if (typeof prompt === "number" && Number.isFinite(prompt) && prompt >= 0) {
9965
10108
  usage.input = prompt;
@@ -9973,6 +10116,12 @@ function readOpenInferenceTokenUsage(attributes) {
9973
10116
  if (typeof cached === "number" && Number.isFinite(cached) && cached >= 0) {
9974
10117
  usage.cached = cached;
9975
10118
  }
10119
+ if (typeof cacheWrite === "number" && Number.isFinite(cacheWrite) && cacheWrite >= 0) {
10120
+ usage.cacheWrite = cacheWrite;
10121
+ }
10122
+ if (typeof reasoning === "number" && Number.isFinite(reasoning) && reasoning >= 0) {
10123
+ usage.reasoning = reasoning;
10124
+ }
9976
10125
  if (usage.total === void 0 && usage.input !== void 0 && usage.output !== void 0) {
9977
10126
  usage.total = usage.input + usage.output;
9978
10127
  }
@@ -12337,5 +12486,5 @@ function renderGateReport(result, options = {}) {
12337
12486
  }
12338
12487
 
12339
12488
  export { COHORT_METRIC_IDS, DEFAULT_SUITE_ARTIFACTS_DIR, EVIDENCE_FORMAT_VERSION, EVIDENCE_HTML_FILENAME, EVIDENCE_MANIFEST_FILENAME, Redactor, TraceDirectory, TraceReadError, TreeBuilder, aggregateBundleSafeStatus, aggregateSessionCheckResults, analyzeCohort, applyProfileMetadataCaps, assertBundlePathContained, assertEvidenceRelativePath, buildActivitySummary, buildBundleMetadata, buildBundleSummaryMarkdown, buildEvidenceCausalFailureViewHtml, buildEvidenceCiPackage, buildEvidenceCircuitViewHtml, buildEvidenceContractsViewHtml, buildEvidenceDiffViewHtml, buildEvidenceHtmlShell, buildEvidenceManifest, buildEvidenceOutcomesViewHtml, buildEvidenceProvenanceViewHtml, buildEvidenceSafetyViewHtml, buildEvidenceTimelineViewHtml, buildEvidenceToolsLlmViewHtml, buildEvidenceTreeViewHtml, buildLocalExplanation, buildPlaceholderArtifact, buildRunSummary, buildRunTimeline, buildRunWhatSummary, buildSessionIndex, buildTraceStats, buildZipArchive, bundleFailsOnSafety, bundleRunAssetRelativePath, collectTraceSchemaVersions, compactAttributes, createBaselineRegressionRule, createLlmUsageRule, createMaxStepDurationRule, createObservedOutcomeRule, createRequireCompletedRule, createRunDepthRule, createRunDurationRule, createRunStatusRule, createSafetyOversizedAttributeRule, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createStallDetectionRule, createStructureCycleRule, createStructureOrphanRule, createStructureParallelWidthRule, createStructureRelationshipRule, createToolUsageRule, defaultBundleOutputPath, defaultSuiteConfigTemplate, diffRuns, diffTraceEvents, enrichSessionRunRecord, escapeHtml, escapeMarkdown, extractMetadata, extractOutcomesFromTraceEvents, filterMetasBySessionScope, filterTraces, flattenTree, formatDuration2 as formatDuration, formatStepLabel, formatTimestamp, gateHasThresholds, getIndent, getTraceFilePath, inferEvidenceFileRole, isAgentInspectTrace, isPersistedInspectEvent, loadSessionRunRecords, loadSuiteConfig, loadTraceMetadataList, manualTraceEventsToComparableRun, nanoid, normalizeBundleOutputPath, openTrace, parseCohortMetricList, parseDuration, parseDurationFilter, parseGateList, parseTraceJsonl, persistedInspectEventsToTraceEvents, renderActivitySummaryHuman, renderCohortReport, renderErrorLine, renderGateReport, renderObservedOutcomesHtml, renderObservedOutcomesMarkdown, renderRunDiff, renderRunWhat, renderStepLine, renderSuiteReport, renderTimeline, renderTraceStats, resolveBundleRunIds, resolveRedactionProfile, resolveSuiteTemplate, resolveTraceDir, runGate, runSuite, runTraceChecks, safeString, sanitizeBundleRunId, searchTraces, serializeEvidenceManifest, sha256Hex, stableJson, summarizeObservedOutcomes, summarizeSemanticParity, traceEventToPersistedInspectEvent, truncateName, truncateStringForProfile, validateEvent, validateSuiteConfig, verifyEvidenceDirectory, zeroKinds };
12340
- //# sourceMappingURL=chunk-JVQ4LTHR.mjs.map
12341
- //# sourceMappingURL=chunk-JVQ4LTHR.mjs.map
12489
+ //# sourceMappingURL=chunk-UK4HD5M3.mjs.map
12490
+ //# sourceMappingURL=chunk-UK4HD5M3.mjs.map