agent-inspect 6.29.6 → 6.31.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.
Files changed (29) hide show
  1. package/CHANGELOG.md +17 -0
  2. package/README.md +1 -1
  3. package/docs/CLI.md +26 -4
  4. package/docs/TRACE-CONTRACTS.md +25 -0
  5. package/package.json +1 -1
  6. package/packages/cli/dist/{chunk-DBRMI7TC.mjs → chunk-Y5Z4BXUO.mjs} +2422 -101
  7. package/packages/cli/dist/chunk-Y5Z4BXUO.mjs.map +1 -0
  8. package/packages/cli/dist/index.cjs +10313 -7195
  9. package/packages/cli/dist/index.cjs.map +1 -1
  10. package/packages/cli/dist/index.mjs +866 -59
  11. package/packages/cli/dist/index.mjs.map +1 -1
  12. package/packages/cli/dist/{src-6CET2GW2.mjs → src-WTTH5G33.mjs} +3 -3
  13. package/packages/cli/dist/{src-6CET2GW2.mjs.map → src-WTTH5G33.mjs.map} +1 -1
  14. package/packages/core/dist/advanced.cjs +12 -1
  15. package/packages/core/dist/advanced.cjs.map +1 -1
  16. package/packages/core/dist/advanced.d.cts +2 -2
  17. package/packages/core/dist/advanced.d.ts +2 -2
  18. package/packages/core/dist/advanced.mjs +2 -2
  19. package/packages/core/dist/checks.cjs +172 -43
  20. package/packages/core/dist/checks.cjs.map +1 -1
  21. package/packages/core/dist/checks.d.cts +2 -2
  22. package/packages/core/dist/checks.d.ts +2 -2
  23. package/packages/core/dist/checks.mjs +1 -1
  24. package/packages/core/dist/{chunk-OOX25GTH.mjs → chunk-VEQKLWGJ.mjs} +174 -46
  25. package/packages/core/dist/chunk-VEQKLWGJ.mjs.map +1 -0
  26. package/packages/core/dist/{index-7hG_qggp.d.ts → index-CgOAGuM5.d.ts} +111 -1
  27. package/packages/core/dist/{index-CQJUNPPe.d.cts → index-EQihlEei.d.cts} +111 -1
  28. package/packages/cli/dist/chunk-DBRMI7TC.mjs.map +0 -1
  29. package/packages/core/dist/chunk-OOX25GTH.mjs.map +0 -1
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- import { ATTRIBUTION_CONFIDENCES, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createSafetyOversizedAttributeRule, resolveTraceDir, parseDuration, buildSessionIndex, resolveBundleRunIds, getTraceFilePath, openTrace, sha256Hex, collectTraceSchemaVersions, aggregateBundleSafeStatus, bundleFailsOnSafety, bundleRunAssetRelativePath, buildPlaceholderArtifact, EVIDENCE_HTML_FILENAME, EVIDENCE_MANIFEST_FILENAME, buildBundleMetadata, buildBundleSummaryMarkdown, buildEvidenceHtmlShell, buildEvidenceProvenanceViewHtml, EVIDENCE_FORMAT_VERSION, inferEvidenceFileRole, buildEvidenceSafetyViewHtml, buildEvidenceDiffViewHtml, buildEvidenceCircuitViewHtml, buildEvidenceOutcomesViewHtml, buildEvidenceContractsViewHtml, buildEvidenceToolsLlmViewHtml, buildEvidenceCausalFailureViewHtml, buildEvidenceTimelineViewHtml, buildEvidenceTreeViewHtml, buildEvidenceManifest, serializeEvidenceManifest, buildZipArchive, assertBundlePathContained, enrichSessionRunRecord, normalizeBundleOutputPath, sanitizeBundleRunId, defaultBundleOutputPath, runTraceChecks, assertEvidenceRelativePath, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, TraceReadError, resolveRedactionProfile, applyProfileMetadataCaps, Redactor, flattenTree, escapeHtml, safeString, compactAttributes, stableJson, escapeMarkdown, truncateStringForProfile, extractMetadata, filterTraces, truncateName, buildRunSummary, formatDuration, formatTimestamp, renderErrorLine, isAgentInspectTrace, filterMetasBySessionScope, aggregateSessionCheckResults, createBaselineRegressionRule, summarizeSemanticParity, buildEvidenceCiPackage, verifyEvidenceDirectory, diffTraceEvents, renderRunDiff, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, formatStepLabel, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, resolveSuiteTemplate, defaultSuiteConfigTemplate, loadSuiteConfig, validateSuiteConfig, runSuite, renderSuiteReport, analyzeCohort, renderCohortReport, gateHasThresholds, runGate, renderGateReport, persistedInspectEventsToTraceEvents, renderStepLine, getIndent, TreeBuilder, zeroKinds, validateEvent, traceEventToPersistedInspectEvent, isPersistedInspectEvent, createRunStatusRule, createStructureOrphanRule, createStructureCycleRule, createRunDurationRule, createMaxStepDurationRule, createRequireCompletedRule, createStallDetectionRule, createObservedOutcomeRule, createRunDepthRule, createToolUsageRule, createLlmUsageRule, createStructureRelationshipRule, createStructureParallelWidthRule, projectLogicalEvents, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, DEFAULT_SUITE_ARTIFACTS_DIR, parseCohortMetricList, COHORT_METRIC_IDS, parseGateList, nanoid, isAttributionConfidence, diffRuns, manualTraceEventsToComparableRun } from './chunk-DBRMI7TC.mjs';
2
+ import { ATTRIBUTION_CONFIDENCES, createSafetyRawContentRule, createSafetyRedactionRule, createSafetySecretPatternRule, createSafetyOversizedAttributeRule, resolveTraceDir, parseDuration, buildSessionIndex, resolveBundleRunIds, getTraceFilePath, openTrace, sha256Hex, collectTraceSchemaVersions, aggregateBundleSafeStatus, bundleFailsOnSafety, bundleRunAssetRelativePath, buildPlaceholderArtifact, EVIDENCE_HTML_FILENAME, EVIDENCE_MANIFEST_FILENAME, buildBundleMetadata, buildBundleSummaryMarkdown, buildEvidenceHtmlShell, buildEvidenceProvenanceViewHtml, EVIDENCE_FORMAT_VERSION, inferEvidenceFileRole, buildEvidenceSafetyViewHtml, buildEvidenceDiffViewHtml, buildEvidenceCircuitViewHtml, buildEvidenceOutcomesViewHtml, buildEvidenceContractsViewHtml, buildEvidenceToolsLlmViewHtml, buildEvidenceCausalFailureViewHtml, buildEvidenceTimelineViewHtml, buildEvidenceTreeViewHtml, buildEvidenceManifest, serializeEvidenceManifest, buildZipArchive, assertBundlePathContained, enrichSessionRunRecord, normalizeBundleOutputPath, sanitizeBundleRunId, defaultBundleOutputPath, runTraceChecks, assertEvidenceRelativePath, TraceDirectory, loadTraceMetadataList, loadSessionRunRecords, TraceReadError, resolveRedactionProfile, applyProfileMetadataCaps, Redactor, flattenTree, escapeHtml, safeString, compactAttributes, stableJson, escapeMarkdown, truncateStringForProfile, extractMetadata, filterTraces, truncateName, buildRunSummary, formatDuration, formatTimestamp, renderErrorLine, isAgentInspectTrace, defineTraceContract, filterMetasBySessionScope, evaluateTraceContract, aggregateSessionCheckResults, createBaselineRegressionRule, summarizeSemanticParity, buildEvidenceCiPackage, verifyEvidenceDirectory, diffTraceEvents, renderRunDiff, buildRunTimeline, renderTimeline, buildTraceStats, renderTraceStats, parseDurationFilter, searchTraces, formatStepLabel, buildActivitySummary, renderActivitySummaryHuman, buildRunWhatSummary, renderRunWhat, buildLocalExplanation, resolveSuiteTemplate, defaultSuiteConfigTemplate, loadSuiteConfig, validateSuiteConfig, runSuite, renderSuiteReport, analyzeCohort, renderCohortReport, gateHasThresholds, runGate, renderGateReport, persistedInspectEventsToTraceEvents, renderStepLine, getIndent, TreeBuilder, zeroKinds, validateEvent, traceEventToPersistedInspectEvent, isPersistedInspectEvent, createRunStatusRule, createStructureOrphanRule, createStructureCycleRule, createRunDurationRule, createMaxStepDurationRule, createRequireCompletedRule, createStallDetectionRule, createObservedOutcomeRule, createRunDepthRule, createToolUsageRule, createLlmUsageRule, createStructureRelationshipRule, createStructureParallelWidthRule, projectLogicalEvents, summarizeObservedOutcomes, extractOutcomesFromTraceEvents, renderObservedOutcomesMarkdown, renderObservedOutcomesHtml, DEFAULT_SUITE_ARTIFACTS_DIR, parseCohortMetricList, COHORT_METRIC_IDS, parseGateList, nanoid, isAttributionConfidence, diffRuns, manualTraceEventsToComparableRun } from './chunk-Y5Z4BXUO.mjs';
3
3
  import { realpathSync, constants as constants$1, existsSync, readFileSync } from 'fs';
4
4
  import path19 from 'path';
5
5
  import { fileURLToPath, pathToFileURL } from 'url';
@@ -13,7 +13,7 @@ import { createServer } from 'http';
13
13
  import { createRequire } from 'module';
14
14
 
15
15
  // package.json
16
- var version = "6.29.6";
16
+ var version = "6.31.0";
17
17
 
18
18
  // packages/cli/src/trace-dir-scale.ts
19
19
  var TRACE_COUNT_WARN = 1e3;
@@ -3397,7 +3397,7 @@ async function newestTraceMtimeMs(traceDir) {
3397
3397
  }
3398
3398
  async function loadSessionRuns(traceDir) {
3399
3399
  try {
3400
- const mod = await import('./src-6CET2GW2.mjs');
3400
+ const mod = await import('./src-WTTH5G33.mjs');
3401
3401
  const dbPath = mod.resolveIndexDbPath(traceDir);
3402
3402
  const status = mod.indexStatus(dbPath);
3403
3403
  if (!status.healthy) {
@@ -5855,7 +5855,8 @@ async function writeLocalEvidence(input3) {
5855
5855
  redactionProfile: profile,
5856
5856
  assessmentStatus,
5857
5857
  checkResultsJson: input3.checkResultsJson,
5858
- ...input3.summaryText !== void 0 ? { summaryText: input3.summaryText } : {}
5858
+ ...input3.summaryText !== void 0 ? { summaryText: input3.summaryText } : {},
5859
+ ...input3.contractPackage !== void 0 ? { contractPackage: input3.contractPackage } : {}
5859
5860
  });
5860
5861
  const files = [
5861
5862
  ["evidence.html", evidencePackage["evidence.html"]],
@@ -5863,6 +5864,10 @@ async function writeLocalEvidence(input3) {
5863
5864
  ["check-results.json", evidencePackage["check-results.json"]],
5864
5865
  ["trace.jsonl", evidencePackage["trace.jsonl"]]
5865
5866
  ];
5867
+ const resolvedContract = evidencePackage["contract.resolved.json"];
5868
+ if (resolvedContract !== void 0) {
5869
+ files.push(["contract.resolved.json", resolvedContract]);
5870
+ }
5866
5871
  const expected = createEvidenceCiArtifacts({
5867
5872
  redactionProfile: profile
5868
5873
  }).map((a) => a.path);
@@ -6824,6 +6829,142 @@ function asStringArray(value) {
6824
6829
  return value;
6825
6830
  }
6826
6831
  var CHECKS_KEYS = /* @__PURE__ */ new Set(["select", "run", "tool", "llm", "structure", "safety"]);
6832
+ var ROOT_CONFIG_KEYS = /* @__PURE__ */ new Set(["checks", "contract"]);
6833
+ var CONTRACT_KEYS = /* @__PURE__ */ new Set([
6834
+ "run",
6835
+ "tools",
6836
+ "llm",
6837
+ "steps",
6838
+ "observations",
6839
+ "scope",
6840
+ "alternatives",
6841
+ "controls",
6842
+ "retry"
6843
+ ]);
6844
+ var CONTRACT_BODY_KEYS = /* @__PURE__ */ new Set([
6845
+ "run",
6846
+ "tools",
6847
+ "llm",
6848
+ "steps",
6849
+ "observations",
6850
+ "controls",
6851
+ "retry"
6852
+ ]);
6853
+ var CONTRACT_SCOPE_KEYS = /* @__PURE__ */ new Set([
6854
+ "runId",
6855
+ "subAgentId",
6856
+ "groupId",
6857
+ "workflowStep",
6858
+ "rootEventId"
6859
+ ]);
6860
+ var CONTRACT_RUN_KEYS = /* @__PURE__ */ new Set(["requireCompleted", "allowedStatuses", "maxDurationMs"]);
6861
+ var CONTRACT_TOOLS_KEYS = /* @__PURE__ */ new Set([
6862
+ "required",
6863
+ "requiredTools",
6864
+ "forbidden",
6865
+ "forbiddenTools",
6866
+ "allowed",
6867
+ "maxCalls",
6868
+ "requiredOrder",
6869
+ "requiredOrderMode",
6870
+ "arguments",
6871
+ "orderRules",
6872
+ "defaultOccurrenceMode"
6873
+ ]);
6874
+ var CONTRACT_LLM_KEYS = /* @__PURE__ */ new Set(["maxCalls", "maxTotalTokens", "allowedModels"]);
6875
+ var CONTRACT_OBSERVATION_KEYS = /* @__PURE__ */ new Set(["required", "failOn", "requireProvenance"]);
6876
+ var CONTRACT_PROVENANCE_KEYS = /* @__PURE__ */ new Set(["method", "evidence", "sameRunEventReference"]);
6877
+ var CONTRACT_CONTROLS_KEYS = /* @__PURE__ */ new Set([
6878
+ "declaredTools",
6879
+ "enforcedTools",
6880
+ "declaredToolsAttribute",
6881
+ "enforcedToolsAttribute",
6882
+ "requireDeclaredMatchesEnforced",
6883
+ "requireObservedWithinEnforced",
6884
+ "requireObservedWithinDeclared",
6885
+ "requiredStages"
6886
+ ]);
6887
+ var CONTRACT_CONTROL_STAGES = /* @__PURE__ */ new Set([
6888
+ "declared",
6889
+ "presented",
6890
+ "validated",
6891
+ "enforced",
6892
+ "observed",
6893
+ "accepted"
6894
+ ]);
6895
+ var CONTRACT_CONTROL_STAGE_KEYS = /* @__PURE__ */ new Set(["stage", "observation"]);
6896
+ var CONTRACT_RETRY_KEYS = /* @__PURE__ */ new Set([
6897
+ "maxAttempts",
6898
+ "requireTerminalResult",
6899
+ "fallbackOnlyAfterFailure",
6900
+ "nonIdempotentTools",
6901
+ "requireIdempotencyEvidenceForRetry",
6902
+ "requireRecoveredFailureVisible",
6903
+ "operations"
6904
+ ]);
6905
+ var CONTRACT_OPERATION_KEYS = /* @__PURE__ */ new Set([
6906
+ "tool",
6907
+ "maxAttempts",
6908
+ "retryableErrors",
6909
+ "requireFailureBeforeRetry",
6910
+ "requireSameArguments",
6911
+ "requireTerminalSuccess",
6912
+ "requireRecoveredFailureVisible",
6913
+ "successfulResultDependency",
6914
+ "sideEffectClass"
6915
+ ]);
6916
+ var CONTRACT_RETRYABLE_ERRORS_KEYS = /* @__PURE__ */ new Set(["codes"]);
6917
+ var CONTRACT_RESULT_DEP_KEYS = /* @__PURE__ */ new Set(["consumerKind", "requireExplicitReference"]);
6918
+ var CONTRACT_ALT_KEYS = /* @__PURE__ */ new Set(["anyOf"]);
6919
+ var CONTRACT_ALT_BRANCH_KEYS = /* @__PURE__ */ new Set(["id", "description", "contract"]);
6920
+ var CONTRACT_ORDER_RULE_KEYS = /* @__PURE__ */ new Set([
6921
+ "before",
6922
+ "after",
6923
+ "occurrenceMode",
6924
+ "requireEndpoints"
6925
+ ]);
6926
+ var CONTRACT_STEPS_KEYS = /* @__PURE__ */ new Set(["orderRelations"]);
6927
+ var CONTRACT_STEP_ORDER_RELATION_KEYS = /* @__PURE__ */ new Set([
6928
+ "before",
6929
+ "after",
6930
+ "mode",
6931
+ "requireEndpoints"
6932
+ ]);
6933
+ var CONTRACT_STEP_REF_KEYS = /* @__PURE__ */ new Set(["kind", "name"]);
6934
+ var CONTRACT_STEP_KINDS = /* @__PURE__ */ new Set(["TOOL", "LLM"]);
6935
+ var CONTRACT_ARGUMENT_KEYS = /* @__PURE__ */ new Set([
6936
+ "tool",
6937
+ "path",
6938
+ "operator",
6939
+ "occurrence",
6940
+ "expected",
6941
+ "oneOf",
6942
+ "type"
6943
+ ]);
6944
+ var CONTRACT_ARGUMENT_OPERATORS = /* @__PURE__ */ new Set(["exists", "type", "equals", "oneOf"]);
6945
+ var CONTRACT_ARGUMENT_OCCURRENCES = /* @__PURE__ */ new Set(["first", "last", "any", "all"]);
6946
+ var CONTRACT_ARGUMENT_TYPES = /* @__PURE__ */ new Set([
6947
+ "string",
6948
+ "number",
6949
+ "boolean",
6950
+ "object",
6951
+ "array",
6952
+ "null"
6953
+ ]);
6954
+ var CONTRACT_ORDER_MODES = /* @__PURE__ */ new Set([
6955
+ "first-occurrence",
6956
+ "happens-before",
6957
+ "all-occurrences"
6958
+ ]);
6959
+ var CONTRACT_FAIL_ON = /* @__PURE__ */ new Set(["failed", "unknown", "skipped"]);
6960
+ var CONTRACT_SIDE_EFFECT_CLASSES = /* @__PURE__ */ new Set(["read", "write"]);
6961
+ var CONTRACT_MAX_STRING_LIST = 64;
6962
+ var CONTRACT_MAX_ARGUMENTS = 32;
6963
+ var CONTRACT_MAX_ORDER_RULES = 32;
6964
+ var CONTRACT_MAX_ANY_OF = 16;
6965
+ var CONTRACT_MAX_OPERATIONS = 32;
6966
+ var CONTRACT_MAX_REQUIRED_STAGES = 16;
6967
+ var CONTRACT_MAX_ONE_OF = 32;
6827
6968
  var RUN_KEYS = /* @__PURE__ */ new Set(["expected", "allowIncomplete", "maxDurationMs", "maxDepth"]);
6828
6969
  var TOOL_KEYS = /* @__PURE__ */ new Set(["required", "forbidden", "allowed", "minCount", "maxCount"]);
6829
6970
  var LLM_KEYS = /* @__PURE__ */ new Set([
@@ -6930,6 +7071,49 @@ function requireBoolean(value, pathPrefix) {
6930
7071
  }
6931
7072
  return value;
6932
7073
  }
7074
+ function requireNonEmptyString(value, pathPrefix) {
7075
+ if (typeof value !== "string" || value.trim() === "") {
7076
+ throw new CheckConfigError(
7077
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7078
+ `${pathPrefix} must be a non-empty string.`
7079
+ );
7080
+ }
7081
+ return value;
7082
+ }
7083
+ function requireBoundedArray(value, pathPrefix, max) {
7084
+ if (!Array.isArray(value)) {
7085
+ throw new CheckConfigError(
7086
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7087
+ `${pathPrefix} must be an array.`
7088
+ );
7089
+ }
7090
+ if (value.length > max) {
7091
+ throw new CheckConfigError(
7092
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7093
+ `${pathPrefix} exceeds bound of ${max} items.`
7094
+ );
7095
+ }
7096
+ return value;
7097
+ }
7098
+ function requireBoundedStringArray(value, pathPrefix, max = CONTRACT_MAX_STRING_LIST) {
7099
+ const items = requireBoundedArray(value, pathPrefix, max);
7100
+ if (items.some((item) => typeof item !== "string" || item.trim() === "")) {
7101
+ throw new CheckConfigError(
7102
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7103
+ `${pathPrefix} must be an array of non-empty strings.`
7104
+ );
7105
+ }
7106
+ return items;
7107
+ }
7108
+ function requireOrderMode(value, pathPrefix) {
7109
+ if (typeof value !== "string" || !CONTRACT_ORDER_MODES.has(value)) {
7110
+ throw new CheckConfigError(
7111
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7112
+ `${pathPrefix} must be one of: "first-occurrence", "happens-before", "all-occurrences".`
7113
+ );
7114
+ }
7115
+ return value;
7116
+ }
6933
7117
  function parseRunSection(value) {
6934
7118
  const record = requireObject(value, "checks.run");
6935
7119
  rejectUnknownKeys(record, RUN_KEYS, "checks.run");
@@ -7062,6 +7246,7 @@ function sectionHasEffect(section) {
7062
7246
  return Object.keys(section).length > 0;
7063
7247
  }
7064
7248
  function checkConfigHasEffect(config) {
7249
+ if (contractConfigHasEffect(config.contract)) return true;
7065
7250
  const checks2 = config.checks;
7066
7251
  if (checks2 === void 0) return false;
7067
7252
  if ((checks2.select?.length ?? 0) > 0) return true;
@@ -7072,43 +7257,651 @@ function checkConfigHasEffect(config) {
7072
7257
  if (sectionHasEffect(checks2.safety)) return true;
7073
7258
  return false;
7074
7259
  }
7260
+ function contractConfigHasEffect(contract) {
7261
+ if (contract === void 0) return false;
7262
+ if (sectionHasEffect(contract.run)) return true;
7263
+ if (sectionHasEffect(contract.tools)) return true;
7264
+ if (sectionHasEffect(contract.llm)) return true;
7265
+ if (sectionHasEffect(contract.steps)) return true;
7266
+ if (sectionHasEffect(contract.observations)) {
7267
+ return true;
7268
+ }
7269
+ if (sectionHasEffect(contract.controls)) return true;
7270
+ if (sectionHasEffect(contract.retry)) return true;
7271
+ if ((contract.alternatives?.anyOf?.length ?? 0) > 0) return true;
7272
+ return false;
7273
+ }
7274
+ function parseContractRunSection(value, pathPrefix = "contract.run") {
7275
+ const record = requireObject(value, pathPrefix);
7276
+ rejectUnknownKeys(record, CONTRACT_RUN_KEYS, pathPrefix);
7277
+ const out = {};
7278
+ if (record.requireCompleted !== void 0) {
7279
+ out.requireCompleted = requireBoolean(
7280
+ record.requireCompleted,
7281
+ `${pathPrefix}.requireCompleted`
7282
+ );
7283
+ }
7284
+ if (record.allowedStatuses !== void 0) {
7285
+ out.allowedStatuses = requireBoundedStringArray(
7286
+ record.allowedStatuses,
7287
+ `${pathPrefix}.allowedStatuses`
7288
+ );
7289
+ }
7290
+ if (record.maxDurationMs !== void 0) {
7291
+ out.maxDurationMs = requireNonNegativeNumber(
7292
+ record.maxDurationMs,
7293
+ `${pathPrefix}.maxDurationMs`
7294
+ );
7295
+ }
7296
+ return out;
7297
+ }
7298
+ function parseToolArgumentCheck(value, pathPrefix) {
7299
+ const record = requireObject(value, pathPrefix);
7300
+ rejectUnknownKeys(record, CONTRACT_ARGUMENT_KEYS, pathPrefix);
7301
+ const tool = requireNonEmptyString(record.tool, `${pathPrefix}.tool`);
7302
+ if (typeof record.path !== "string") {
7303
+ throw new CheckConfigError(
7304
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7305
+ `${pathPrefix}.path must be a string JSON Pointer ("" or start with "/").`
7306
+ );
7307
+ }
7308
+ const pathValue = record.path;
7309
+ if (typeof record.operator !== "string" || !CONTRACT_ARGUMENT_OPERATORS.has(record.operator)) {
7310
+ throw new CheckConfigError(
7311
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7312
+ `${pathPrefix}.operator must be one of: "exists", "type", "equals", "oneOf".`
7313
+ );
7314
+ }
7315
+ const operator = record.operator;
7316
+ const out = { tool, path: pathValue, operator };
7317
+ if (record.occurrence !== void 0) {
7318
+ if (typeof record.occurrence !== "string" || !CONTRACT_ARGUMENT_OCCURRENCES.has(record.occurrence)) {
7319
+ throw new CheckConfigError(
7320
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7321
+ `${pathPrefix}.occurrence must be one of: "first", "last", "any", "all".`
7322
+ );
7323
+ }
7324
+ out.occurrence = record.occurrence;
7325
+ }
7326
+ if (record.expected !== void 0) {
7327
+ out.expected = record.expected;
7328
+ }
7329
+ if (record.oneOf !== void 0) {
7330
+ out.oneOf = requireBoundedArray(record.oneOf, `${pathPrefix}.oneOf`, CONTRACT_MAX_ONE_OF);
7331
+ }
7332
+ if (record.type !== void 0) {
7333
+ if (typeof record.type !== "string" || !CONTRACT_ARGUMENT_TYPES.has(record.type)) {
7334
+ throw new CheckConfigError(
7335
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7336
+ `${pathPrefix}.type must be one of: "string", "number", "boolean", "object", "array", "null".`
7337
+ );
7338
+ }
7339
+ out.type = record.type;
7340
+ }
7341
+ return out;
7342
+ }
7343
+ function parseOrderRule(value, pathPrefix) {
7344
+ const record = requireObject(value, pathPrefix);
7345
+ rejectUnknownKeys(record, CONTRACT_ORDER_RULE_KEYS, pathPrefix);
7346
+ const out = {
7347
+ before: requireNonEmptyString(record.before, `${pathPrefix}.before`),
7348
+ after: requireNonEmptyString(record.after, `${pathPrefix}.after`)
7349
+ };
7350
+ if (record.occurrenceMode !== void 0) {
7351
+ out.occurrenceMode = requireOrderMode(record.occurrenceMode, `${pathPrefix}.occurrenceMode`);
7352
+ }
7353
+ if (record.requireEndpoints !== void 0) {
7354
+ out.requireEndpoints = requireBoolean(
7355
+ record.requireEndpoints,
7356
+ `${pathPrefix}.requireEndpoints`
7357
+ );
7358
+ }
7359
+ return out;
7360
+ }
7361
+ function parseContractToolsSection(value, pathPrefix = "contract.tools") {
7362
+ const record = requireObject(value, pathPrefix);
7363
+ rejectUnknownKeys(record, CONTRACT_TOOLS_KEYS, pathPrefix);
7364
+ const out = {};
7365
+ if (record.required !== void 0) {
7366
+ out.required = requireBoundedStringArray(record.required, `${pathPrefix}.required`);
7367
+ }
7368
+ if (record.requiredTools !== void 0) {
7369
+ out.requiredTools = requireBoundedStringArray(
7370
+ record.requiredTools,
7371
+ `${pathPrefix}.requiredTools`
7372
+ );
7373
+ }
7374
+ if (record.forbidden !== void 0) {
7375
+ out.forbidden = requireBoundedStringArray(record.forbidden, `${pathPrefix}.forbidden`);
7376
+ }
7377
+ if (record.forbiddenTools !== void 0) {
7378
+ out.forbiddenTools = requireBoundedStringArray(
7379
+ record.forbiddenTools,
7380
+ `${pathPrefix}.forbiddenTools`
7381
+ );
7382
+ }
7383
+ if (record.allowed !== void 0) {
7384
+ out.allowed = requireBoundedStringArray(record.allowed, `${pathPrefix}.allowed`);
7385
+ }
7386
+ if (record.maxCalls !== void 0) {
7387
+ out.maxCalls = requireNonNegativeNumber(record.maxCalls, `${pathPrefix}.maxCalls`);
7388
+ }
7389
+ if (record.requiredOrder !== void 0) {
7390
+ out.requiredOrder = requireBoundedStringArray(
7391
+ record.requiredOrder,
7392
+ `${pathPrefix}.requiredOrder`
7393
+ );
7394
+ }
7395
+ if (record.requiredOrderMode !== void 0) {
7396
+ out.requiredOrderMode = requireOrderMode(
7397
+ record.requiredOrderMode,
7398
+ `${pathPrefix}.requiredOrderMode`
7399
+ );
7400
+ }
7401
+ if (record.defaultOccurrenceMode !== void 0) {
7402
+ out.defaultOccurrenceMode = requireOrderMode(
7403
+ record.defaultOccurrenceMode,
7404
+ `${pathPrefix}.defaultOccurrenceMode`
7405
+ );
7406
+ }
7407
+ if (record.arguments !== void 0) {
7408
+ const items = requireBoundedArray(
7409
+ record.arguments,
7410
+ `${pathPrefix}.arguments`,
7411
+ CONTRACT_MAX_ARGUMENTS
7412
+ );
7413
+ out.arguments = items.map(
7414
+ (item, index) => parseToolArgumentCheck(item, `${pathPrefix}.arguments[${index}]`)
7415
+ );
7416
+ }
7417
+ if (record.orderRules !== void 0) {
7418
+ const items = requireBoundedArray(
7419
+ record.orderRules,
7420
+ `${pathPrefix}.orderRules`,
7421
+ CONTRACT_MAX_ORDER_RULES
7422
+ );
7423
+ out.orderRules = items.map(
7424
+ (item, index) => parseOrderRule(item, `${pathPrefix}.orderRules[${index}]`)
7425
+ );
7426
+ }
7427
+ return out;
7428
+ }
7429
+ function parseContractLlmSection(value, pathPrefix = "contract.llm") {
7430
+ const record = requireObject(value, pathPrefix);
7431
+ rejectUnknownKeys(record, CONTRACT_LLM_KEYS, pathPrefix);
7432
+ const out = {};
7433
+ if (record.maxCalls !== void 0) {
7434
+ out.maxCalls = requireNonNegativeNumber(record.maxCalls, `${pathPrefix}.maxCalls`);
7435
+ }
7436
+ if (record.maxTotalTokens !== void 0) {
7437
+ out.maxTotalTokens = requireNonNegativeNumber(
7438
+ record.maxTotalTokens,
7439
+ `${pathPrefix}.maxTotalTokens`
7440
+ );
7441
+ }
7442
+ if (record.allowedModels !== void 0) {
7443
+ out.allowedModels = requireBoundedStringArray(
7444
+ record.allowedModels,
7445
+ `${pathPrefix}.allowedModels`
7446
+ );
7447
+ }
7448
+ return out;
7449
+ }
7450
+ function parseStepRef(value, pathPrefix) {
7451
+ const record = requireObject(value, pathPrefix);
7452
+ rejectUnknownKeys(record, CONTRACT_STEP_REF_KEYS, pathPrefix);
7453
+ if (typeof record.kind !== "string" || !CONTRACT_STEP_KINDS.has(record.kind)) {
7454
+ throw new CheckConfigError(
7455
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7456
+ `${pathPrefix}.kind must be "TOOL" or "LLM".`
7457
+ );
7458
+ }
7459
+ return {
7460
+ kind: record.kind,
7461
+ name: requireNonEmptyString(record.name, `${pathPrefix}.name`)
7462
+ };
7463
+ }
7464
+ function parseStepOrderRelation(value, pathPrefix) {
7465
+ const record = requireObject(value, pathPrefix);
7466
+ rejectUnknownKeys(record, CONTRACT_STEP_ORDER_RELATION_KEYS, pathPrefix);
7467
+ if (record.before === void 0) {
7468
+ throw new CheckConfigError(
7469
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7470
+ `${pathPrefix}.before is required.`
7471
+ );
7472
+ }
7473
+ if (record.after === void 0) {
7474
+ throw new CheckConfigError(
7475
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7476
+ `${pathPrefix}.after is required.`
7477
+ );
7478
+ }
7479
+ const out = {
7480
+ before: parseStepRef(record.before, `${pathPrefix}.before`),
7481
+ after: parseStepRef(record.after, `${pathPrefix}.after`)
7482
+ };
7483
+ if (record.mode !== void 0) {
7484
+ out.mode = requireOrderMode(record.mode, `${pathPrefix}.mode`);
7485
+ }
7486
+ if (record.requireEndpoints !== void 0) {
7487
+ out.requireEndpoints = requireBoolean(
7488
+ record.requireEndpoints,
7489
+ `${pathPrefix}.requireEndpoints`
7490
+ );
7491
+ }
7492
+ return out;
7493
+ }
7494
+ function parseContractStepsSection(value, pathPrefix = "contract.steps") {
7495
+ const record = requireObject(value, pathPrefix);
7496
+ rejectUnknownKeys(record, CONTRACT_STEPS_KEYS, pathPrefix);
7497
+ const out = {};
7498
+ if (record.orderRelations !== void 0) {
7499
+ const items = requireBoundedArray(
7500
+ record.orderRelations,
7501
+ `${pathPrefix}.orderRelations`,
7502
+ CONTRACT_MAX_ORDER_RULES
7503
+ );
7504
+ out.orderRelations = items.map(
7505
+ (item, index) => parseStepOrderRelation(item, `${pathPrefix}.orderRelations[${index}]`)
7506
+ );
7507
+ }
7508
+ return out;
7509
+ }
7510
+ function parseRequireProvenance(value, pathPrefix) {
7511
+ const record = requireObject(value, pathPrefix);
7512
+ rejectUnknownKeys(record, CONTRACT_PROVENANCE_KEYS, pathPrefix);
7513
+ const out = {};
7514
+ if (record.method !== void 0) {
7515
+ out.method = requireBoolean(record.method, `${pathPrefix}.method`);
7516
+ }
7517
+ if (record.evidence !== void 0) {
7518
+ out.evidence = requireBoolean(record.evidence, `${pathPrefix}.evidence`);
7519
+ }
7520
+ if (record.sameRunEventReference !== void 0) {
7521
+ out.sameRunEventReference = requireBoolean(
7522
+ record.sameRunEventReference,
7523
+ `${pathPrefix}.sameRunEventReference`
7524
+ );
7525
+ }
7526
+ return out;
7527
+ }
7528
+ function parseContractObservationsSection(value, pathPrefix = "contract.observations") {
7529
+ const record = requireObject(value, pathPrefix);
7530
+ rejectUnknownKeys(record, CONTRACT_OBSERVATION_KEYS, pathPrefix);
7531
+ const out = {};
7532
+ if (record.required !== void 0) {
7533
+ out.required = requireBoundedStringArray(record.required, `${pathPrefix}.required`);
7534
+ }
7535
+ if (record.failOn !== void 0) {
7536
+ const items = requireBoundedArray(record.failOn, `${pathPrefix}.failOn`, CONTRACT_MAX_STRING_LIST);
7537
+ for (const item of items) {
7538
+ if (typeof item !== "string" || !CONTRACT_FAIL_ON.has(item)) {
7539
+ throw new CheckConfigError(
7540
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7541
+ `${pathPrefix}.failOn values must be "failed", "unknown", or "skipped".`
7542
+ );
7543
+ }
7544
+ }
7545
+ out.failOn = items;
7546
+ }
7547
+ if (record.requireProvenance !== void 0) {
7548
+ out.requireProvenance = parseRequireProvenance(
7549
+ record.requireProvenance,
7550
+ `${pathPrefix}.requireProvenance`
7551
+ );
7552
+ }
7553
+ return out;
7554
+ }
7555
+ function parseControlRequiredStage(value, pathPrefix) {
7556
+ const record = requireObject(value, pathPrefix);
7557
+ rejectUnknownKeys(record, CONTRACT_CONTROL_STAGE_KEYS, pathPrefix);
7558
+ if (typeof record.stage !== "string" || !CONTRACT_CONTROL_STAGES.has(record.stage)) {
7559
+ throw new CheckConfigError(
7560
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7561
+ `${pathPrefix}.stage must be one of: declared, presented, validated, enforced, observed, accepted.`
7562
+ );
7563
+ }
7564
+ const out = {
7565
+ stage: record.stage
7566
+ };
7567
+ if (record.observation !== void 0) {
7568
+ out.observation = requireNonEmptyString(record.observation, `${pathPrefix}.observation`);
7569
+ }
7570
+ return out;
7571
+ }
7572
+ function parseContractControlsSection(value, pathPrefix = "contract.controls") {
7573
+ const record = requireObject(value, pathPrefix);
7574
+ rejectUnknownKeys(record, CONTRACT_CONTROLS_KEYS, pathPrefix);
7575
+ const out = {};
7576
+ if (record.declaredTools !== void 0) {
7577
+ out.declaredTools = requireBoundedStringArray(
7578
+ record.declaredTools,
7579
+ `${pathPrefix}.declaredTools`
7580
+ );
7581
+ }
7582
+ if (record.enforcedTools !== void 0) {
7583
+ out.enforcedTools = requireBoundedStringArray(
7584
+ record.enforcedTools,
7585
+ `${pathPrefix}.enforcedTools`
7586
+ );
7587
+ }
7588
+ if (record.declaredToolsAttribute !== void 0) {
7589
+ out.declaredToolsAttribute = requireNonEmptyString(
7590
+ record.declaredToolsAttribute,
7591
+ `${pathPrefix}.declaredToolsAttribute`
7592
+ );
7593
+ }
7594
+ if (record.enforcedToolsAttribute !== void 0) {
7595
+ out.enforcedToolsAttribute = requireNonEmptyString(
7596
+ record.enforcedToolsAttribute,
7597
+ `${pathPrefix}.enforcedToolsAttribute`
7598
+ );
7599
+ }
7600
+ if (record.requireDeclaredMatchesEnforced !== void 0) {
7601
+ out.requireDeclaredMatchesEnforced = requireBoolean(
7602
+ record.requireDeclaredMatchesEnforced,
7603
+ `${pathPrefix}.requireDeclaredMatchesEnforced`
7604
+ );
7605
+ }
7606
+ if (record.requireObservedWithinEnforced !== void 0) {
7607
+ out.requireObservedWithinEnforced = requireBoolean(
7608
+ record.requireObservedWithinEnforced,
7609
+ `${pathPrefix}.requireObservedWithinEnforced`
7610
+ );
7611
+ }
7612
+ if (record.requireObservedWithinDeclared !== void 0) {
7613
+ out.requireObservedWithinDeclared = requireBoolean(
7614
+ record.requireObservedWithinDeclared,
7615
+ `${pathPrefix}.requireObservedWithinDeclared`
7616
+ );
7617
+ }
7618
+ if (record.requiredStages !== void 0) {
7619
+ const items = requireBoundedArray(
7620
+ record.requiredStages,
7621
+ `${pathPrefix}.requiredStages`,
7622
+ CONTRACT_MAX_REQUIRED_STAGES
7623
+ );
7624
+ out.requiredStages = items.map(
7625
+ (item, index) => parseControlRequiredStage(item, `${pathPrefix}.requiredStages[${index}]`)
7626
+ );
7627
+ }
7628
+ return out;
7629
+ }
7630
+ function parseRecoveryOperation(value, pathPrefix) {
7631
+ const record = requireObject(value, pathPrefix);
7632
+ rejectUnknownKeys(record, CONTRACT_OPERATION_KEYS, pathPrefix);
7633
+ const out = {
7634
+ tool: requireNonEmptyString(record.tool, `${pathPrefix}.tool`)
7635
+ };
7636
+ if (record.maxAttempts !== void 0) {
7637
+ out.maxAttempts = requireNonNegativeNumber(record.maxAttempts, `${pathPrefix}.maxAttempts`);
7638
+ }
7639
+ if (record.retryableErrors !== void 0) {
7640
+ const errors = requireObject(record.retryableErrors, `${pathPrefix}.retryableErrors`);
7641
+ rejectUnknownKeys(errors, CONTRACT_RETRYABLE_ERRORS_KEYS, `${pathPrefix}.retryableErrors`);
7642
+ const retryableErrors = {};
7643
+ if (errors.codes !== void 0) {
7644
+ retryableErrors.codes = requireBoundedStringArray(
7645
+ errors.codes,
7646
+ `${pathPrefix}.retryableErrors.codes`
7647
+ );
7648
+ }
7649
+ out.retryableErrors = retryableErrors;
7650
+ }
7651
+ if (record.requireFailureBeforeRetry !== void 0) {
7652
+ out.requireFailureBeforeRetry = requireBoolean(
7653
+ record.requireFailureBeforeRetry,
7654
+ `${pathPrefix}.requireFailureBeforeRetry`
7655
+ );
7656
+ }
7657
+ if (record.requireSameArguments !== void 0) {
7658
+ if (record.requireSameArguments === true || record.requireSameArguments === false) {
7659
+ out.requireSameArguments = record.requireSameArguments;
7660
+ } else if (record.requireSameArguments === "structured-or-digest") {
7661
+ out.requireSameArguments = "structured-or-digest";
7662
+ } else {
7663
+ throw new CheckConfigError(
7664
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7665
+ `${pathPrefix}.requireSameArguments must be a boolean or "structured-or-digest".`
7666
+ );
7667
+ }
7668
+ }
7669
+ if (record.requireTerminalSuccess !== void 0) {
7670
+ out.requireTerminalSuccess = requireBoolean(
7671
+ record.requireTerminalSuccess,
7672
+ `${pathPrefix}.requireTerminalSuccess`
7673
+ );
7674
+ }
7675
+ if (record.requireRecoveredFailureVisible !== void 0) {
7676
+ out.requireRecoveredFailureVisible = requireBoolean(
7677
+ record.requireRecoveredFailureVisible,
7678
+ `${pathPrefix}.requireRecoveredFailureVisible`
7679
+ );
7680
+ }
7681
+ if (record.successfulResultDependency !== void 0) {
7682
+ const dep = requireObject(
7683
+ record.successfulResultDependency,
7684
+ `${pathPrefix}.successfulResultDependency`
7685
+ );
7686
+ rejectUnknownKeys(dep, CONTRACT_RESULT_DEP_KEYS, `${pathPrefix}.successfulResultDependency`);
7687
+ if (dep.consumerKind !== "LLM") {
7688
+ throw new CheckConfigError(
7689
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7690
+ `${pathPrefix}.successfulResultDependency.consumerKind must be "LLM".`
7691
+ );
7692
+ }
7693
+ const dependency = { consumerKind: "LLM" };
7694
+ if (dep.requireExplicitReference !== void 0) {
7695
+ dependency.requireExplicitReference = requireBoolean(
7696
+ dep.requireExplicitReference,
7697
+ `${pathPrefix}.successfulResultDependency.requireExplicitReference`
7698
+ );
7699
+ }
7700
+ out.successfulResultDependency = dependency;
7701
+ }
7702
+ if (record.sideEffectClass !== void 0) {
7703
+ if (typeof record.sideEffectClass !== "string" || !CONTRACT_SIDE_EFFECT_CLASSES.has(record.sideEffectClass)) {
7704
+ throw new CheckConfigError(
7705
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7706
+ `${pathPrefix}.sideEffectClass must be "read" or "write".`
7707
+ );
7708
+ }
7709
+ out.sideEffectClass = record.sideEffectClass;
7710
+ }
7711
+ return out;
7712
+ }
7713
+ function parseContractRetrySection(value, pathPrefix = "contract.retry") {
7714
+ const record = requireObject(value, pathPrefix);
7715
+ rejectUnknownKeys(record, CONTRACT_RETRY_KEYS, pathPrefix);
7716
+ const out = {};
7717
+ if (record.maxAttempts !== void 0) {
7718
+ out.maxAttempts = requireNonNegativeNumber(record.maxAttempts, `${pathPrefix}.maxAttempts`);
7719
+ }
7720
+ if (record.requireTerminalResult !== void 0) {
7721
+ out.requireTerminalResult = requireBoolean(
7722
+ record.requireTerminalResult,
7723
+ `${pathPrefix}.requireTerminalResult`
7724
+ );
7725
+ }
7726
+ if (record.fallbackOnlyAfterFailure !== void 0) {
7727
+ out.fallbackOnlyAfterFailure = requireBoolean(
7728
+ record.fallbackOnlyAfterFailure,
7729
+ `${pathPrefix}.fallbackOnlyAfterFailure`
7730
+ );
7731
+ }
7732
+ if (record.nonIdempotentTools !== void 0) {
7733
+ out.nonIdempotentTools = requireBoundedStringArray(
7734
+ record.nonIdempotentTools,
7735
+ `${pathPrefix}.nonIdempotentTools`
7736
+ );
7737
+ }
7738
+ if (record.requireIdempotencyEvidenceForRetry !== void 0) {
7739
+ out.requireIdempotencyEvidenceForRetry = requireBoolean(
7740
+ record.requireIdempotencyEvidenceForRetry,
7741
+ `${pathPrefix}.requireIdempotencyEvidenceForRetry`
7742
+ );
7743
+ }
7744
+ if (record.requireRecoveredFailureVisible !== void 0) {
7745
+ out.requireRecoveredFailureVisible = requireBoolean(
7746
+ record.requireRecoveredFailureVisible,
7747
+ `${pathPrefix}.requireRecoveredFailureVisible`
7748
+ );
7749
+ }
7750
+ if (record.operations !== void 0) {
7751
+ const items = requireBoundedArray(
7752
+ record.operations,
7753
+ `${pathPrefix}.operations`,
7754
+ CONTRACT_MAX_OPERATIONS
7755
+ );
7756
+ out.operations = items.map(
7757
+ (item, index) => parseRecoveryOperation(item, `${pathPrefix}.operations[${index}]`)
7758
+ );
7759
+ }
7760
+ return out;
7761
+ }
7762
+ function parseContractScopeSection(value) {
7763
+ const record = requireObject(value, "contract.scope");
7764
+ rejectUnknownKeys(record, CONTRACT_SCOPE_KEYS, "contract.scope");
7765
+ const out = {};
7766
+ if (record.runId !== void 0) {
7767
+ out.runId = requireNonEmptyString(record.runId, "contract.scope.runId");
7768
+ }
7769
+ if (record.subAgentId !== void 0) {
7770
+ out.subAgentId = requireNonEmptyString(record.subAgentId, "contract.scope.subAgentId");
7771
+ }
7772
+ if (record.groupId !== void 0) {
7773
+ out.groupId = requireNonEmptyString(record.groupId, "contract.scope.groupId");
7774
+ }
7775
+ if (record.workflowStep !== void 0) {
7776
+ out.workflowStep = requireNonEmptyString(
7777
+ record.workflowStep,
7778
+ "contract.scope.workflowStep"
7779
+ );
7780
+ }
7781
+ if (record.rootEventId !== void 0) {
7782
+ out.rootEventId = requireNonEmptyString(record.rootEventId, "contract.scope.rootEventId");
7783
+ }
7784
+ return out;
7785
+ }
7786
+ function parseContractBodySection(value, pathPrefix) {
7787
+ const record = requireObject(value, pathPrefix);
7788
+ rejectUnknownKeys(record, CONTRACT_BODY_KEYS, pathPrefix);
7789
+ const out = {};
7790
+ if (record.run !== void 0) out.run = parseContractRunSection(record.run, `${pathPrefix}.run`);
7791
+ if (record.tools !== void 0) {
7792
+ out.tools = parseContractToolsSection(record.tools, `${pathPrefix}.tools`);
7793
+ }
7794
+ if (record.llm !== void 0) out.llm = parseContractLlmSection(record.llm, `${pathPrefix}.llm`);
7795
+ if (record.steps !== void 0) {
7796
+ out.steps = parseContractStepsSection(record.steps, `${pathPrefix}.steps`);
7797
+ }
7798
+ if (record.observations !== void 0) {
7799
+ out.observations = parseContractObservationsSection(
7800
+ record.observations,
7801
+ `${pathPrefix}.observations`
7802
+ );
7803
+ }
7804
+ if (record.controls !== void 0) {
7805
+ out.controls = parseContractControlsSection(record.controls, `${pathPrefix}.controls`);
7806
+ }
7807
+ if (record.retry !== void 0) {
7808
+ out.retry = parseContractRetrySection(record.retry, `${pathPrefix}.retry`);
7809
+ }
7810
+ return out;
7811
+ }
7812
+ function parseContractAlternativesSection(value) {
7813
+ const record = requireObject(value, "contract.alternatives");
7814
+ rejectUnknownKeys(record, CONTRACT_ALT_KEYS, "contract.alternatives");
7815
+ if (record.anyOf === void 0) {
7816
+ throw new CheckConfigError(
7817
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7818
+ "contract.alternatives.anyOf is required."
7819
+ );
7820
+ }
7821
+ const items = requireBoundedArray(
7822
+ record.anyOf,
7823
+ "contract.alternatives.anyOf",
7824
+ CONTRACT_MAX_ANY_OF
7825
+ );
7826
+ const anyOf = items.map((item, index) => {
7827
+ const pathPrefix = `contract.alternatives.anyOf[${index}]`;
7828
+ const branch = requireObject(item, pathPrefix);
7829
+ rejectUnknownKeys(branch, CONTRACT_ALT_BRANCH_KEYS, pathPrefix);
7830
+ const id = requireNonEmptyString(branch.id, `${pathPrefix}.id`);
7831
+ if (branch.contract === void 0) {
7832
+ throw new CheckConfigError(
7833
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7834
+ `${pathPrefix}.contract is required.`
7835
+ );
7836
+ }
7837
+ const out = {
7838
+ id,
7839
+ contract: parseContractBodySection(branch.contract, `${pathPrefix}.contract`)
7840
+ };
7841
+ if (branch.description !== void 0) {
7842
+ out.description = requireNonEmptyString(branch.description, `${pathPrefix}.description`);
7843
+ }
7844
+ return out;
7845
+ });
7846
+ return { anyOf };
7847
+ }
7848
+ function parseContractSection(value) {
7849
+ const record = requireObject(value, "contract");
7850
+ rejectUnknownKeys(record, CONTRACT_KEYS, "contract");
7851
+ const bodyOnly = {};
7852
+ for (const key of Object.keys(record)) {
7853
+ if (CONTRACT_BODY_KEYS.has(key)) bodyOnly[key] = record[key];
7854
+ }
7855
+ const out = { ...parseContractBodySection(bodyOnly, "contract") };
7856
+ if (record.scope !== void 0) out.scope = parseContractScopeSection(record.scope);
7857
+ if (record.alternatives !== void 0) {
7858
+ out.alternatives = parseContractAlternativesSection(record.alternatives);
7859
+ }
7860
+ return out;
7861
+ }
7075
7862
  function parseCheckConfig(value) {
7076
7863
  if (value === void 0 || value === null) return {};
7077
7864
  if (typeof value !== "object" || Array.isArray(value)) {
7078
7865
  throw new CheckConfigError("AI_CHECK_CONFIG_INVALID_VALUE", "Config must export an object.");
7079
7866
  }
7080
7867
  const root = value;
7081
- if ("contract" in root) {
7082
- throw new CheckConfigError(
7083
- "AI_CHECK_CONFIG_UNKNOWN_KEY",
7084
- 'Top-level "contract" is not supported by `agent-inspect check --config`. Use the TraceContract TypeScript API (`defineTraceContract` / `evaluateTraceContract` from `agent-inspect/checks`), or express tool/run/llm rules under `checks`.'
7085
- );
7086
- }
7087
7868
  const rootKeys = Object.keys(root);
7088
7869
  for (const key of rootKeys) {
7089
- if (key === "checks") continue;
7090
- const suggestion = closestKey(key, ["checks"]);
7870
+ if (ROOT_CONFIG_KEYS.has(key)) continue;
7871
+ const suggestion = closestKey(key, [...ROOT_CONFIG_KEYS]);
7091
7872
  const hint = suggestion ? ` Did you mean "${suggestion}"?` : "";
7092
7873
  throw new CheckConfigError(
7093
7874
  "AI_CHECK_CONFIG_UNKNOWN_KEY",
7094
- `Unknown top-level check config key "${key}". Allowed: checks.${hint}`
7875
+ `Unknown top-level check config key "${key}". Allowed: checks, contract.${hint}`
7095
7876
  );
7096
7877
  }
7097
- if (!("checks" in root)) return {};
7098
- const checksRecord = requireObject(root.checks, "checks");
7099
- rejectUnknownKeys(checksRecord, CHECKS_KEYS, "checks");
7100
- const checks2 = {};
7101
- if (checksRecord.select !== void 0) {
7102
- checks2.select = requireStringArray(checksRecord.select, "checks.select");
7878
+ const out = {};
7879
+ if ("checks" in root) {
7880
+ const checksRecord = requireObject(root.checks, "checks");
7881
+ rejectUnknownKeys(checksRecord, CHECKS_KEYS, "checks");
7882
+ const checks2 = {};
7883
+ if (checksRecord.select !== void 0) {
7884
+ checks2.select = requireStringArray(checksRecord.select, "checks.select");
7885
+ }
7886
+ if (checksRecord.run !== void 0) checks2.run = parseRunSection(checksRecord.run);
7887
+ if (checksRecord.tool !== void 0) checks2.tool = parseToolSection(checksRecord.tool);
7888
+ if (checksRecord.llm !== void 0) checks2.llm = parseLlmSection(checksRecord.llm);
7889
+ if (checksRecord.structure !== void 0) {
7890
+ checks2.structure = parseStructureSection(checksRecord.structure);
7891
+ }
7892
+ if (checksRecord.safety !== void 0) checks2.safety = parseSafetySection(checksRecord.safety);
7893
+ out.checks = checks2;
7894
+ }
7895
+ if ("contract" in root) {
7896
+ out.contract = parseContractSection(root.contract);
7103
7897
  }
7104
- if (checksRecord.run !== void 0) checks2.run = parseRunSection(checksRecord.run);
7105
- if (checksRecord.tool !== void 0) checks2.tool = parseToolSection(checksRecord.tool);
7106
- if (checksRecord.llm !== void 0) checks2.llm = parseLlmSection(checksRecord.llm);
7107
- if (checksRecord.structure !== void 0) {
7108
- checks2.structure = parseStructureSection(checksRecord.structure);
7898
+ if (out.contract !== void 0 && contractConfigHasEffect(out.contract) && checkConfigHasEffect({ checks: out.checks })) {
7899
+ throw new CheckConfigError(
7900
+ "AI_CHECK_CONFIG_INVALID_VALUE",
7901
+ 'Config cannot combine top-level "checks" and "contract". Use one vocabulary per config file.'
7902
+ );
7109
7903
  }
7110
- if (checksRecord.safety !== void 0) checks2.safety = parseSafetySection(checksRecord.safety);
7111
- return { checks: checks2 };
7904
+ return out;
7112
7905
  }
7113
7906
  async function loadConfig(configPath) {
7114
7907
  if (configPath === void 0) return {};
@@ -7436,6 +8229,7 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
7436
8229
  let evidenceRead;
7437
8230
  let evidenceRunIds = [];
7438
8231
  let evidenceSourceContents;
8232
+ let evidenceContract;
7439
8233
  const sessionId = options.session?.trim();
7440
8234
  const groupId = options.group?.trim();
7441
8235
  const useSessionScope = Boolean(sessionId || groupId);
@@ -7444,7 +8238,7 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
7444
8238
  if (options.config !== void 0 && !checkConfigHasEffect(config)) {
7445
8239
  result = errorResult(
7446
8240
  "AI_CHECK_CONFIG_NO_EFFECTIVE_RULES",
7447
- "Explicit --config has no effective check rules. Configure checks.select, checks.run, checks.tool, checks.llm, checks.structure, or checks.safety."
8241
+ "Explicit --config has no effective check rules. Configure checks.select, checks.run, checks.tool, checks.llm, checks.structure, checks.safety, or contract."
7448
8242
  );
7449
8243
  if (options.json) printJson2(result);
7450
8244
  else printHuman2(result, options);
@@ -7452,7 +8246,11 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
7452
8246
  return;
7453
8247
  }
7454
8248
  let effectiveOptions = options;
7455
- const resolved = resolvePreset(options.preset, {
8249
+ const useContract = config.contract !== void 0 && contractConfigHasEffect(config.contract);
8250
+ if (useContract) {
8251
+ evidenceContract = defineTraceContract(config.contract);
8252
+ }
8253
+ const resolved = useContract ? void 0 : resolvePreset(options.preset, {
7456
8254
  hasToolRules: hasToolRulesConfigured(config, options)
7457
8255
  });
7458
8256
  if (resolved !== void 0) {
@@ -7460,7 +8258,7 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
7460
8258
  config = applied.config;
7461
8259
  effectiveOptions = applied.options;
7462
8260
  }
7463
- const built = buildRules(config, effectiveOptions, resolved?.select ?? []);
8261
+ const built = useContract ? { rules: [], select: [], diagnostics: [] } : buildRules(config, effectiveOptions, resolved?.select ?? []);
7464
8262
  if (built.diagnostics.some((item) => item.severity === "error")) {
7465
8263
  result = errorResult("AI_CHECK_INVALID_CONFIG", "Invalid check configuration.");
7466
8264
  result.diagnostics = [...built.diagnostics];
@@ -7482,6 +8280,7 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
7482
8280
  });
7483
8281
  const perRun = [];
7484
8282
  const sourceContents = /* @__PURE__ */ new Map();
8283
+ const definedContract = evidenceContract;
7485
8284
  for (const meta of scoped.metas) {
7486
8285
  const read = await openTrace(
7487
8286
  { type: "file", path: meta.filePath },
@@ -7498,23 +8297,20 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
7498
8297
  `
7499
8298
  );
7500
8299
  }
8300
+ const base = definedContract ? evaluateTraceContract({ read }, definedContract, { runId: meta.runId }) : runTraceChecks(
8301
+ { read },
8302
+ {
8303
+ rules: built.rules,
8304
+ select: built.select,
8305
+ runId: meta.runId
8306
+ }
8307
+ );
7501
8308
  perRun.push(
7502
- mergeSafetyExtensions(
7503
- runTraceChecks(
7504
- { read },
7505
- {
7506
- rules: built.rules,
7507
- select: built.select,
7508
- runId: meta.runId
7509
- }
7510
- ),
7511
- read,
7512
- {
7513
- ...options.guardrails ? { guardrails: options.guardrails } : {},
7514
- ...options.circuit ? { circuits: options.circuit } : {},
7515
- runId: meta.runId
7516
- }
7517
- )
8309
+ mergeSafetyExtensions(base, read, {
8310
+ ...options.guardrails ? { guardrails: options.guardrails } : {},
8311
+ ...options.circuit ? { circuits: options.circuit } : {},
8312
+ runId: meta.runId
8313
+ })
7518
8314
  );
7519
8315
  }
7520
8316
  evidenceRunIds = scoped.runIds;
@@ -7553,22 +8349,25 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
7553
8349
  ])
7554
8350
  );
7555
8351
  }
7556
- result = mergeSafetyExtensions(
7557
- runTraceChecks(
7558
- { read },
7559
- {
7560
- rules: built.rules,
7561
- select: built.select,
7562
- ...options.run !== void 0 ? { runId: options.run } : {}
7563
- }
7564
- ),
7565
- read,
8352
+ const base = useContract && evidenceContract !== void 0 ? evaluateTraceContract(
8353
+ { read },
8354
+ evidenceContract,
7566
8355
  {
7567
- ...options.guardrails ? { guardrails: options.guardrails } : {},
7568
- ...options.circuit ? { circuits: options.circuit } : {},
8356
+ ...options.run !== void 0 ? { runId: options.run } : {}
8357
+ }
8358
+ ) : runTraceChecks(
8359
+ { read },
8360
+ {
8361
+ rules: built.rules,
8362
+ select: built.select,
7569
8363
  ...options.run !== void 0 ? { runId: options.run } : {}
7570
8364
  }
7571
8365
  );
8366
+ result = mergeSafetyExtensions(base, read, {
8367
+ ...options.guardrails ? { guardrails: options.guardrails } : {},
8368
+ ...options.circuit ? { circuits: options.circuit } : {},
8369
+ ...options.run !== void 0 ? { runId: options.run } : {}
8370
+ });
7572
8371
  }
7573
8372
  } catch (error) {
7574
8373
  if (phase === "config") {
@@ -7612,7 +8411,15 @@ async function checkCommand(target, options = {}, stdin = process.stdin) {
7612
8411
  checkResultsJson: checkResultToEvidenceJson(result, runIds),
7613
8412
  summaryText: `Check status: ${result.status}`,
7614
8413
  redactionProfile,
7615
- format: evidenceFormat
8414
+ format: evidenceFormat,
8415
+ ...evidenceContract !== void 0 ? {
8416
+ contractPackage: {
8417
+ engineVersion: "",
8418
+ source: "file",
8419
+ contract: evidenceContract,
8420
+ ...options.config !== void 0 ? { path: options.config } : {}
8421
+ }
8422
+ } : {}
7616
8423
  });
7617
8424
  if (!options.json) {
7618
8425
  console.log(`Evidence: ${written}`);
@@ -12173,7 +12980,7 @@ function isModuleNotFound4(e) {
12173
12980
  }
12174
12981
  async function loadIndexSqlite() {
12175
12982
  try {
12176
- return await import('./src-6CET2GW2.mjs');
12983
+ return await import('./src-WTTH5G33.mjs');
12177
12984
  } catch (e) {
12178
12985
  if (isModuleNotFound4(e)) {
12179
12986
  console.error(