agent-inspect 6.29.0 → 6.29.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 (54) hide show
  1. package/CHANGELOG.md +18 -0
  2. package/README.md +1 -1
  3. package/docs/API.md +4 -0
  4. package/docs/CLI.md +21 -1
  5. package/docs/LIMITATIONS.md +2 -1
  6. package/docs/NETWORK-BEHAVIOR.md +8 -0
  7. package/docs/SAFE-TRACE-SHARING.md +1 -1
  8. package/docs/STANDARDS.md +1 -1
  9. package/docs/TRACE-CONTRACTS.md +11 -0
  10. package/package.json +2 -2
  11. package/packages/cli/dist/{chunk-D7PT6TXM.mjs → chunk-UK4HD5M3.mjs} +126 -26
  12. package/packages/cli/dist/chunk-UK4HD5M3.mjs.map +1 -0
  13. package/packages/cli/dist/index.cjs +240 -106
  14. package/packages/cli/dist/index.cjs.map +1 -1
  15. package/packages/cli/dist/index.mjs +108 -82
  16. package/packages/cli/dist/index.mjs.map +1 -1
  17. package/packages/cli/dist/{src-QONEBW2F.mjs → src-CMPIJGUE.mjs} +3 -3
  18. package/packages/cli/dist/{src-QONEBW2F.mjs.map → src-CMPIJGUE.mjs.map} +1 -1
  19. package/packages/core/dist/advanced.cjs +138 -25
  20. package/packages/core/dist/advanced.cjs.map +1 -1
  21. package/packages/core/dist/advanced.d.cts +13 -2
  22. package/packages/core/dist/advanced.d.ts +13 -2
  23. package/packages/core/dist/advanced.mjs +109 -33
  24. package/packages/core/dist/advanced.mjs.map +1 -1
  25. package/packages/core/dist/checks.cjs +240 -35
  26. package/packages/core/dist/checks.cjs.map +1 -1
  27. package/packages/core/dist/checks.d.cts +2 -2
  28. package/packages/core/dist/checks.d.ts +2 -2
  29. package/packages/core/dist/checks.mjs +3 -3
  30. package/packages/core/dist/{chunk-TNOPL75V.mjs → chunk-5RF7FYGL.mjs} +3 -3
  31. package/packages/core/dist/{chunk-TNOPL75V.mjs.map → chunk-5RF7FYGL.mjs.map} +1 -1
  32. package/packages/core/dist/{chunk-3B24355S.mjs → chunk-65LFRW2T.mjs} +3 -3
  33. package/packages/core/dist/{chunk-3B24355S.mjs.map → chunk-65LFRW2T.mjs.map} +1 -1
  34. package/packages/core/dist/{chunk-MVRZ7JBH.mjs → chunk-COZPMOUF.mjs} +3 -3
  35. package/packages/core/dist/{chunk-MVRZ7JBH.mjs.map → chunk-COZPMOUF.mjs.map} +1 -1
  36. package/packages/core/dist/{chunk-LGTPSHH2.mjs → chunk-QZIXYP7U.mjs} +243 -38
  37. package/packages/core/dist/chunk-QZIXYP7U.mjs.map +1 -0
  38. package/packages/core/dist/{chunk-TIGBAVED.mjs → chunk-XRI3GB6I.mjs} +42 -5
  39. package/packages/core/dist/chunk-XRI3GB6I.mjs.map +1 -0
  40. package/packages/core/dist/exporters.cjs +10 -5
  41. package/packages/core/dist/exporters.cjs.map +1 -1
  42. package/packages/core/dist/exporters.d.cts +12 -2
  43. package/packages/core/dist/exporters.d.ts +12 -2
  44. package/packages/core/dist/exporters.mjs +13 -8
  45. package/packages/core/dist/exporters.mjs.map +1 -1
  46. package/packages/core/dist/{index-C61p7wBR.d.cts → index-BaQ48jrq.d.cts} +9 -1
  47. package/packages/core/dist/{index-DTO2iGeq.d.ts → index-CrnEOoRu.d.ts} +9 -1
  48. package/packages/core/dist/index.cjs +38 -1
  49. package/packages/core/dist/index.cjs.map +1 -1
  50. package/packages/core/dist/index.mjs +4 -4
  51. package/packages/core/dist/writers.mjs +1 -1
  52. package/packages/cli/dist/chunk-D7PT6TXM.mjs.map +0 -1
  53. package/packages/core/dist/chunk-LGTPSHH2.mjs.map +0 -1
  54. package/packages/core/dist/chunk-TIGBAVED.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,23 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.29.2
4
+
5
+ ### Patch Changes
6
+
7
+ - 555052d: Published runtime and fidelity patches for the post-6.29.1 adoption train:
8
+
9
+ - Externalize `agent-inspect` from `@agent-inspect/mcp` so packed ESM/CJS consumers share the application `inspectRun` context (#413).
10
+ - Refuse `suite init` overwrite of an existing suite config (#411 / #412).
11
+ - Recognize nested manual `attributes.metadata.arguments|input|toolArguments` in tool-argument checks (#414).
12
+ - Persist bounded safe thrown error codes from manual instrumentation (#415).
13
+ - Normalize OpenAI Agents cached tokens from `input_tokens_details.cached_tokens` (#416).
14
+
15
+ ## 6.29.1
16
+
17
+ ### Patch Changes
18
+
19
+ - 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.
20
+
3
21
  ## 6.29.0
4
22
 
5
23
  ### 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.29.0** · persisted schema `1.0` · Node.js `>=20` · MIT.
215
+ **Current published baseline:** **6.29.2** · 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/API.md CHANGED
@@ -474,6 +474,10 @@ Public methods:
474
474
 
475
475
  `capture` is explicit and metadata-only. `onSuccess: "metadata-only"` records safe type/length/key-count summaries in `outputSummary`; `onError: "metadata-only"` records thrown-value type/name summaries. It does not store raw return values, prompts, outputs, or thrown objects. Use `"none"` to disable a capture side.
476
476
 
477
+ Persisted step/run errors keep `name` and `message`. When present, a **bounded safe** `code` is also retained: finite numeric `code`/`status` values (for example HTTP `404`) or short strings matching letters, digits, underscore, hyphen, dot, and colon (max 128 characters). Response bodies, headers, multiline values, and arbitrary enumerable error properties are not persisted.
478
+
479
+ Pass structured tool arguments for contracts via step `metadata.arguments` / `metadata.input` / `metadata.toolArguments` (or top-level attributes with the same keys). TraceContract tool-argument checks read those locations; they do not enable default raw capture.
480
+
477
481
  `traceDir` and `silent` on `createInspector()` are context metadata for compatibility with existing helpers. They do not configure persistence or terminal output. Prefer writer-owned output configuration such as `fileWriter({ dir })` or `fileWriter({ filePath })`.
478
482
 
479
483
  `createInspectorRuntime()` is available from `agent-inspect/advanced` as the low-level isolation primitive. Most users should prefer `createInspector()` and `inspector.getDiagnostics()`.
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.
@@ -961,6 +979,8 @@ Options (shared):
961
979
 
962
980
  - `--template <name>` — PM/QA template (v5.4+): `customer-support-agent`, `refund-agent`, `sales-assistant`, `browser-task-agent`, `mcp-tool-agent`, `workflow-agent`, `rag-answer-agent`, `human-approval-agent`
963
981
 
982
+ `suite init` creates a new `agent-inspect.suite.json` and **refuses to overwrite** an existing file (valid, malformed, or empty). Edit or delete the existing config explicitly before recreating it. There is no `--force` flag.
983
+
964
984
  `run` also supports:
965
985
 
966
986
  - `-o, --output <dir>` — write JSON run artifact (default: `.agent-inspect/suite-runs`)
@@ -9,6 +9,7 @@ This document states what AgentInspect **does not** provide today. It complement
9
9
  - **No vendor upload pipeline**: no built-in Langfuse/Braintrust/New Relic/Datadog direct exporters as live sinks.
10
10
  - **No automatic universal instrumentation** of every framework: integration is explicit (manual traces, log ingest, optional adapters).
11
11
  - **No retry execution engine:** TraceContract `retry` rules (including additive `retry.operations[]` recovery oracles in 6.27) evaluate attempt identity and evidence only. AgentInspect does not retry tools, remediates nothing, and does not treat a client `idempotencyKey` as proof of exactly-once writes. Write-tool timeout/unknown completion is unevaluable without authoritative idempotency evidence; write-retry is not safe by default.
12
+ - **Transport facts are source-boundary only:** HTTP status, server-advertised retry delay, selected delay, and their sources must be captured at the transport/fetch boundary. An MCP wrapper cannot recover facts already collapsed into an SDK error message.
12
13
  - **Omitted-payload digests** (`createOmittedPayloadCommitment`) are bounded (1 MiB preflight). Digests prove omitted bytes existed; they are not redaction or authorization.
13
14
 
14
15
  ## Correlation metadata (v1.3.0)
@@ -26,7 +27,7 @@ This document states what AgentInspect **does not** provide today. It complement
26
27
  - **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
28
  - **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
29
  - **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.
30
+ - **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
31
  - **Conservative detection:** `agent-inspect open` does not silently accept arbitrary JSON. Unsupported or ambiguous inputs produce errors/warnings rather than guessed traces.
31
32
  - **Large inputs:** reader inputs are bounded and read into local memory. This is not a database index or production log warehouse.
32
33
 
@@ -27,6 +27,14 @@ AgentInspect is **local-first**. Core tracing writes local files and does **not*
27
27
  4. Prefer **redact / verify-safe** before any share or ingest path.
28
28
  5. Redaction is best-effort, not certification.
29
29
 
30
+ ## Transport evidence (HTTP / fetch / MCP)
31
+
32
+ Capture **HTTP status**, **server-advertised retry delay**, **selected delay**, and their **sources** at the transport or fetch boundary that observes them.
33
+
34
+ An MCP client wrapper or SDK error string cannot recover facts already collapsed into a message such as `"fetch failed"` or `"429 Too Many Requests"`. If the application needs TraceFacts or contracts over status/retry behavior, instrument the fetch/transport layer (or an observer that reads response headers before they are discarded).
35
+
36
+ AgentInspect does not invent transport facts from error message text.
37
+
30
38
  ## Enabling Studio ingest
31
39
 
32
40
  See [SELF-HOSTING.md](./SELF-HOSTING.md) and [`@agent-inspect/studio`](https://github.com/rajudandigam/agent-inspect/tree/main/packages/studio). HTTP ingest remains off until you configure token and binding.
@@ -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/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
 
@@ -229,11 +229,22 @@ defineTraceContract({
229
229
 
230
230
  Missing structured argument evidence fails closed (`AI_CHECK_TOOL_ARGUMENT_EVIDENCE_UNAVAILABLE`). Findings never include full actual inputs.
231
231
 
232
+ Manual instrumentation stores caller metadata under `attributes.metadata`. Tool-argument checks therefore also accept structured object/array evidence at:
233
+
234
+ ```text
235
+ attributes.metadata.arguments
236
+ attributes.metadata.input
237
+ attributes.metadata.toolArguments
238
+ ```
239
+
240
+ Precedence: top-level `attributes.arguments|input|toolArguments`, then nested metadata keys, then structured `inputSummary`. Preview strings are never parsed as JSON. This does not enable default raw argument capture.
241
+
232
242
  ### Capture capability matrix (tool-argument evidence)
233
243
 
234
244
  | Source | Structured input | Preview only | Digest only | Unavailable |
235
245
  | --- | :---: | :---: | :---: | :---: |
236
246
  | Manual `attributes.arguments` / `attributes.input` (object) | yes | — | — | — |
247
+ | Manual `attributes.metadata.arguments` / `input` / `toolArguments` (object/array) | yes | — | — | — |
237
248
  | Manual `inputSummary` string | — | yes | — | for pointer checks |
238
249
  | AI SDK / LangChain metadata-only default | — | sometimes | — | typical |
239
250
  | OpenAI Agents metadata-only | — | sometimes | — | typical |
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-inspect",
3
- "version": "6.29.0",
3
+ "version": "6.29.2",
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",
@@ -235,7 +235,7 @@
235
235
  "test:all": "pnpm run typecheck && pnpm run linked-versions:check && pnpm run build && pnpm run test && pnpm run size",
236
236
  "prepublish:checks": "pnpm run typecheck && pnpm run test && pnpm run test:coverage && pnpm run build && pnpm run fixtures:check && pnpm run recipes:check && pnpm run size && pnpm run linked-versions:check && pnpm run repo:health && pnpm run pack:smoke",
237
237
  "pack:dry-run": "pnpm run build && npm pack --dry-run",
238
- "pack:smoke": "pnpm run build && node scripts/package-smoke.mjs && node scripts/packed-openai-agents-e2e.mjs && node scripts/packed-ai-sdk-e2e.mjs && node scripts/packed-quickstart-e2e.mjs && node scripts/packed-semantic-loop-e2e.mjs && node scripts/packed-swarm-loop-e2e.mjs && node scripts/evidence-ci-golden-paths.mjs",
238
+ "pack:smoke": "pnpm run build && node scripts/package-smoke.mjs && node scripts/packed-openai-agents-e2e.mjs && node scripts/packed-ai-sdk-e2e.mjs && node scripts/packed-mcp-e2e.mjs && node scripts/packed-quickstart-e2e.mjs && node scripts/packed-semantic-loop-e2e.mjs && node scripts/packed-swarm-loop-e2e.mjs && node scripts/evidence-ci-golden-paths.mjs",
239
239
  "linked-versions:check": "node scripts/check-linked-versions.mjs",
240
240
  "docs:commands": "node scripts/validate-doc-commands.mjs",
241
241
  "docs:links": "node scripts/validate-doc-links.mjs",
@@ -841,6 +841,30 @@ var Redactor = class {
841
841
  }
842
842
  };
843
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
+
844
868
  // packages/core/src/redaction-profiles.ts
845
869
  var SHARE_PROFILE_EXTRA_KEYS = [
846
870
  "userEmail",
@@ -7074,7 +7098,15 @@ function buildEmbeddedPayload(input) {
7074
7098
  redactionProfile: input.redactionProfile,
7075
7099
  verificationPolicy: input.verificationPolicy
7076
7100
  },
7077
- 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
+ } : {}
7078
7110
  };
7079
7111
  }
7080
7112
  function buildEvidenceHtmlShell(input) {
@@ -7172,6 +7204,7 @@ ${nav}
7172
7204
  <p>Artifact status: <span class="badge ${statusClass(input.assessmentStatus)}">${escapeHtml(input.assessmentStatus)}</span>
7173
7205
  ${input.sourceStatus !== void 0 ? ` \xB7 Source status: <span class="badge ${statusClass(input.sourceStatus)}">${escapeHtml(input.sourceStatus)}</span>` : ""}</p>
7174
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>` : ""}` : ""}
7175
7208
  <p>Generator: <code>${escapeHtml(input.generatorName)}@${escapeHtml(input.generatorVersion)}</code>
7176
7209
  ${input.createdAt ? ` \xB7 Created: <code>${escapeHtml(input.createdAt)}</code>` : ""}</p>
7177
7210
  <h3>Runs</h3>
@@ -7964,6 +7997,39 @@ var EVIDENCE_CONTRACT_CANONICALIZATION_VERSION = "1";
7964
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.";
7965
7998
  var EVIDENCE_CONTRACT_UNAVAILABLE_NOTE = "No resolved TraceContract or check preset was packaged with this Evidence artifact.";
7966
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
+ }
7967
8033
  function serializeCanonicalJson(value) {
7968
8034
  return `${JSON.stringify(stableValue(value), null, 2)}
7969
8035
  `;
@@ -8097,6 +8163,32 @@ function buildEvidenceContractPackage(input) {
8097
8163
  if (unsupported.length > 0) {
8098
8164
  ruleIds = sortedUniqueStrings([...ruleIds, ...unsupported]);
8099
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
+ }
8100
8192
  const document = {
8101
8193
  canonicalizationVersion: EVIDENCE_CONTRACT_CANONICALIZATION_VERSION,
8102
8194
  kind,
@@ -8469,29 +8561,6 @@ function buildEvidenceCiPackage(input) {
8469
8561
  schemaVersions.add(version);
8470
8562
  }
8471
8563
  const createdAt = input.createdAt ?? (/* @__PURE__ */ new Date()).toISOString();
8472
- const evidenceHtml = buildEvidenceHtmlShell({
8473
- title: "AgentInspect evidence",
8474
- runIds: input.runIds,
8475
- assessmentStatus: input.assessmentStatus,
8476
- sourceStatus: input.sourceStatus,
8477
- redactionProfile: input.redactionProfile,
8478
- verificationPolicy: input.redactionProfile,
8479
- generatorName: "agent-inspect",
8480
- generatorVersion: input.generatorVersion,
8481
- createdAt,
8482
- summaryText: input.summaryText,
8483
- checkSummary: {
8484
- aggregateStatus: input.assessmentStatus,
8485
- runs: input.runIds.map((runId) => ({
8486
- runId,
8487
- status: input.assessmentStatus,
8488
- sourceStatus: input.sourceStatus,
8489
- errors: input.assessmentStatus === "UNSAFE" || input.assessmentStatus === "UNKNOWN" ? 1 : 0,
8490
- warnings: input.assessmentStatus === "SAFE WITH WARNINGS" ? 1 : 0,
8491
- findings: 0
8492
- }))
8493
- }
8494
- });
8495
8564
  let checkResultsJson = input.checkResultsJson;
8496
8565
  let contractBinding;
8497
8566
  let contractFileContent;
@@ -8514,6 +8583,37 @@ function buildEvidenceCiPackage(input) {
8514
8583
  bindCheckResultsToContract(parsed, packaged2.checkBinding)
8515
8584
  );
8516
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
+ });
8517
8617
  const packaged = [
8518
8618
  { path: EVIDENCE_HTML_FILENAME, content: evidenceHtml },
8519
8619
  { path: "check-results.json", content: checkResultsJson },
@@ -12386,5 +12486,5 @@ function renderGateReport(result, options = {}) {
12386
12486
  }
12387
12487
 
12388
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 };
12389
- //# sourceMappingURL=chunk-D7PT6TXM.mjs.map
12390
- //# sourceMappingURL=chunk-D7PT6TXM.mjs.map
12489
+ //# sourceMappingURL=chunk-UK4HD5M3.mjs.map
12490
+ //# sourceMappingURL=chunk-UK4HD5M3.mjs.map