agent-inspect 6.19.1 → 6.20.0

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.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.20.0
4
+
5
+ ### Minor Changes
6
+
7
+ - 43a4481: Flexible deterministic contracts: selectable `requiredOrderMode` (`first-occurrence` | `happens-before` | `all-occurrences`), one-level `alternatives.anyOf`, and `lintTraceContract` / `explainTraceContract` helpers. Includes MCP expected-rejection and local Promptfoo use-together recipes.
8
+
3
9
  ## 6.19.1
4
10
 
5
11
  ### Patch 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.19.1** · persisted schema `1.0` · Node.js `>=20` · MIT.
215
+ **Current published baseline:** **6.20.0** · 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
 
@@ -10,6 +10,9 @@ Contracts compile to deterministic check rules for common cases:
10
10
 
11
11
  - run status / completion / max duration
12
12
  - tool required / forbidden / allowed / maxCalls / order (`requiredTools` / `forbiddenTools` aliases)
13
+ - selectable `requiredOrderMode` (`first-occurrence` | `happens-before` | `all-occurrences`)
14
+ - `alternatives.anyOf` for one level of legitimate alternate paths
15
+ - `lintTraceContract` / `explainTraceContract` for brittle-contract diagnostics
13
16
  - LLM maxCalls / maxTotalTokens / allowedModels
14
17
  - evidence-bearing findings on failures
15
18
  - evaluation over **logical** TraceFacts (raw events remain available)
@@ -24,13 +27,14 @@ Contracts compile to deterministic check rules for common cases:
24
27
  → contract.tool.order.1: B before C
25
28
  ```
26
29
 
27
- Each pair compares the **first occurrence** (start/encounter order in the evaluated event stream):
30
+ `requiredOrderMode` selects one ordering relation for every generated pair:
28
31
 
29
32
  - unlisted intermediate tools are allowed;
30
- - later repetitions do not invalidate an earlier valid first-occurrence order;
31
33
  - TraceContract `requiredOrder` **implies presence** — every listed name is added to the effective required-tool set;
32
- - this is **not** causal happens-before; overlapping intervals emit a non-failing `tool.order.overlap` warning;
33
- - combine ordering with `maxCalls` or custom rules when repeated calls matter.
34
+ - `first-occurrence` (default when omitted) compares first occurrences in start/encounter order; later repetitions do not invalidate an earlier valid order, and interval overlap emits a non-failing `tool.order.overlap` warning;
35
+ - `happens-before` requires the first `before` occurrence to finish before the first `after` occurrence starts;
36
+ - `all-occurrences` requires every `before` occurrence to finish before every `after` occurrence starts (`max(before.end) <= min(after.start)`);
37
+ - causal modes fail when a required interval boundary cannot be resolved instead of falling back to encounter order.
34
38
 
35
39
  Examples for `requiredOrder: ["retrieve", "generate"]`:
36
40
 
@@ -38,12 +42,16 @@ Examples for `requiredOrder: ["retrieve", "generate"]`:
38
42
  | --- | --- |
39
43
  | `retrieve → generate` | PASS |
40
44
  | `retrieve → rerank → generate` | PASS |
41
- | `retrieve → generate → retrieve` | PASS (first-occurrence) |
45
+ | `retrieve → generate → retrieve` | PASS under omitted / `first-occurrence`; FAIL under `all-occurrences` |
42
46
  | `generate → retrieve` | FAIL (order) |
43
47
  | `cache_lookup → generate` | FAIL (missing `retrieve` via implied presence) |
44
48
 
45
49
  Low-level `createToolOrderingRule({ before, after })` alone may still pass when an endpoint is missing (compositional). TraceContract `requiredOrder` does not.
46
50
 
51
+ For overlapping first calls, omitted / `first-occurrence` warns while `happens-before` fails.
52
+
53
+ Immediate or positional `all-pairs` matching is not implemented.
54
+
47
55
  ### Experimental Vitest / Jest matchers (shipped)
48
56
 
49
57
  | Package | Export | Matchers |
@@ -55,7 +63,7 @@ These are **Experimental** — API names may evolve. There is no `expectTrace(..
55
63
 
56
64
  See [API.md](./API.md), [TRACE-FACTS.md](./TRACE-FACTS.md), and `packages/core/src/checks/contract.ts`.
57
65
 
58
- ## Rule kinds (shipped vs planned)
66
+ ## Rule kinds
59
67
 
60
68
  TraceContract rules fall into distinct categories. Mixing them incorrectly is a common source of false failures (see GitHub #308 and #309).
61
69
 
@@ -65,65 +73,68 @@ Unconditional path invariant: every named tool must appear **at least once** in
65
73
 
66
74
  - Use when the tool is always part of a valid execution path.
67
75
  - **Do not** use for steps that legitimate shortcuts may skip (for example cache hits that bypass `retrieve`).
68
- - When a shortcut is valid but you still need evidence of the outcome, prefer `observations.required` until `alternatives.anyOf` ships (6.20.0).
76
+ - Prefer `alternatives.anyOf` or `observations.required` when a shortcut is valid.
69
77
 
70
- ### `tools.requiredOrder` (shipped — first-occurrence / start-encounter)
78
+ ### `tools.requiredOrder` (shipped — selectable ordering modes)
71
79
 
72
- Legacy first-start / encounter ordering. The evaluator walks the trace and checks that each listed tool's **first occurrence** appears after the previous tool's first occurrence.
80
+ The evaluator expands each list into adjacent pairs and applies one `requiredOrderMode` to every pair.
73
81
 
74
82
  - TraceContract `requiredOrder` **implies presence** of every listed tool (unioned into `tools.required`).
75
- - Default mode is **first-occurrence** start/encounter order **not** causal happens-before.
76
- - Overlapping intervals that still satisfy start order emit a non-failing overlap warning.
77
- - **Planned (6.20.0, GitHub #308):**
78
- - `requiredOrderMode: "happens-before"` first before must **end** before first after **starts**
79
- - `requiredOrderMode: "all-occurrences"` — every before must end before every after starts
80
-
81
- ### `observations.required` (shipped)
82
-
83
- Requires externally observed or effect evidence (for example HTTP status, file write, cache key) rather than a specific tool call. Prefer this when the invariant is about **outcome** rather than **which tool ran**.
84
-
85
- ### Planned (6.20.0 — not shipped)
86
-
87
- Document only; **do not** use these fields in contracts today:
83
+ - `requiredOrderMode: "first-occurrence"` is the default first-occurrence start/encounter relation; overlapping intervals emit a non-failing warning.
84
+ - `requiredOrderMode: "happens-before"` requires the first before to **end** before the first after **starts**; overlap fails.
85
+ - `requiredOrderMode: "all-occurrences"` requires every before to end before every after starts; any cross-boundary overlap or later before fails.
86
+ - Missing interval boundaries fail closed in the two causal modes.
87
+
88
+ ### `alternatives.anyOf` (shipped)
89
+
90
+ One level of named deterministic branches. Base rules always apply. At least one complete branch must pass.
91
+
92
+ ```ts
93
+ defineTraceContract({
94
+ run: { requireCompleted: true },
95
+ tools: { required: ["generate"] },
96
+ alternatives: {
97
+ anyOf: [
98
+ {
99
+ id: "cache-hit",
100
+ contract: {
101
+ tools: { required: ["cache_lookup"], forbidden: ["retrieve"] },
102
+ observations: { required: ["cache-hit-valid"] },
103
+ },
104
+ },
105
+ {
106
+ id: "retrieve",
107
+ contract: {
108
+ tools: { required: ["retrieve"], requiredOrder: ["retrieve", "generate"] },
109
+ observations: { required: ["retrieval-context-valid"] },
110
+ },
111
+ },
112
+ ],
113
+ },
114
+ });
115
+ ```
88
116
 
89
- | Planned field | Purpose | GitHub |
90
- |---------------|---------|--------|
91
- | `alternatives.anyOf` | One of several deterministic valid paths (one level, no nested groups, no predicates) | #309 |
92
- | `requiredOrderMode: "happens-before"` | Causal completion-before-start ordering | #308 |
93
- | `requiredOrderMode: "all-occurrences"` | Strict ordering across all tool occurrences | #308 |
117
+ Constraints:
94
118
 
95
- API shape for both requires maintainer approval before external PR lands. @HsienW volunteered on #308 for `requiredOrderMode` implementation.
119
+ - unique branch ids
120
+ - no nested `alternatives`
121
+ - no predicates / runtime DSL
122
+ - unused failed branches do not fail the contract when another branch passes
123
+ - if none pass → `contract.alternatives.none-satisfied`
96
124
 
97
- ## Workaround until 6.20.0
125
+ ### `observations.required` (shipped)
98
126
 
99
- When a legitimate shortcut skips a tool you would otherwise require:
127
+ Requires externally observed or effect evidence (for example HTTP status, file write, cache key) rather than a specific tool call. Prefer this when the invariant is about **outcome** rather than **which tool ran**.
100
128
 
101
- 1. **Remove** unconditional `tools.required` for that step.
102
- 2. **Express** the verified outcome via `observations.required` when possible.
103
- 3. **Document** the cache-hit or alternate path in contract comments for reviewers.
129
+ ### Lint and explain (shipped)
104
130
 
105
- Example matching GitHub #309 (cache hit skips second `retrieve`):
131
+ ```ts
132
+ import { lintTraceContract, explainTraceContract } from "agent-inspect/checks";
106
133
 
107
- ```yaml
108
- contract:
109
- tools:
110
- required: [generate] # not retrieve — cache may skip it
111
- requiredOrder: [generate] # ordering only among tools that ran
112
- observations:
113
- required: [cache_hit_or_retrieve_evidence]
134
+ lintTraceContract(contract); // brittle / invalid shape diagnostics
135
+ explainTraceContract(contract); // human-readable intent lines
114
136
  ```
115
137
 
116
- With first-occurrence ordering, `retrieve → generate → retrieve` still **passes** when both retrieves are present (see worked example below).
117
-
118
- ## What is not shipped (yet)
119
-
120
- Do **not** document these as available:
121
-
122
- - `expectTrace(...).toSatisfyTraceContract` (different API shape than the shipped matchers)
123
- - Full workflow handoff / approval / MCP protocol contract rules
124
- - Per-tool argument schema / regex validators on the contract surface
125
- - Every structure rule (orphan/cycle/depth) exposed on the contract API (many exist as standalone check rules)
126
-
127
138
  ## CLI relationship
128
139
 
129
140
  ```bash
@@ -137,3 +148,4 @@ Suites and gates can consume check results; see [SUITES-COHORTS-GATES.md](./SUIT
137
148
  - Experimental/Beta API — may evolve in minors
138
149
  - Contract tests are smoke-level; prefer check-engine tests for deep rule coverage
139
150
  - Always review findings before treating a green check as product proof
151
+ - No nested alternatives, all-pairs matching, or general temporal DSL
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-inspect",
3
- "version": "6.19.1",
3
+ "version": "6.20.0",
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",
@@ -11781,5 +11781,5 @@ function renderGateReport(result, options = {}) {
11781
11781
  }
11782
11782
 
11783
11783
  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 };
11784
- //# sourceMappingURL=chunk-QDYVK4MF.mjs.map
11785
- //# sourceMappingURL=chunk-QDYVK4MF.mjs.map
11784
+ //# sourceMappingURL=chunk-QPRJUVLH.mjs.map
11785
+ //# sourceMappingURL=chunk-QPRJUVLH.mjs.map