agent-inspect 6.20.0 → 6.21.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 +6 -0
- package/README.md +1 -1
- package/docs/TRACE-CONTRACTS.md +39 -0
- package/package.json +1 -1
- package/packages/cli/dist/{chunk-QPRJUVLH.mjs → chunk-CRUHIL5J.mjs} +16 -2
- package/packages/cli/dist/chunk-CRUHIL5J.mjs.map +1 -0
- package/packages/cli/dist/index.cjs +22 -3
- package/packages/cli/dist/index.cjs.map +1 -1
- package/packages/cli/dist/index.mjs +4 -4
- package/packages/cli/dist/index.mjs.map +1 -1
- package/packages/cli/dist/{src-6W5ZR3I7.mjs → src-MNJFYW3W.mjs} +3 -3
- package/packages/cli/dist/{src-6W5ZR3I7.mjs.map → src-MNJFYW3W.mjs.map} +1 -1
- package/packages/core/dist/advanced.cjs +3 -0
- package/packages/core/dist/advanced.cjs.map +1 -1
- package/packages/core/dist/advanced.d.cts +6 -156
- package/packages/core/dist/advanced.d.ts +6 -156
- package/packages/core/dist/advanced.mjs +6 -60
- package/packages/core/dist/advanced.mjs.map +1 -1
- package/packages/core/dist/checks.cjs +558 -25
- package/packages/core/dist/checks.cjs.map +1 -1
- package/packages/core/dist/checks.d.cts +81 -3
- package/packages/core/dist/checks.d.ts +81 -3
- package/packages/core/dist/checks.mjs +2 -2
- package/packages/core/dist/{chunk-G47KQB42.mjs → chunk-43SHIPZM.mjs} +556 -29
- package/packages/core/dist/chunk-43SHIPZM.mjs.map +1 -0
- package/packages/core/dist/{chunk-3XS5O4JI.mjs → chunk-R4SSYU6D.mjs} +3 -3
- package/packages/core/dist/chunk-R4SSYU6D.mjs.map +1 -0
- package/packages/core/dist/{chunk-5YFJJFXU.mjs → chunk-WGDSM37E.mjs} +3 -3
- package/packages/core/dist/{chunk-5YFJJFXU.mjs.map → chunk-WGDSM37E.mjs.map} +1 -1
- package/packages/core/dist/{context-C5ye_xcS.d.cts → context-DOOT9GZ-.d.cts} +1 -1
- package/packages/core/dist/{context-CNsNSgE2.d.ts → context-DOX2-RjH.d.ts} +1 -1
- package/packages/core/dist/diff.d.cts +1 -1
- package/packages/core/dist/diff.d.ts +1 -1
- package/packages/core/dist/exporters.d.cts +1 -1
- package/packages/core/dist/exporters.d.ts +1 -1
- package/packages/core/dist/exporters.mjs +1 -1
- package/packages/core/dist/{index-rVpX5PPh.d.cts → index-BG-ZBESI.d.cts} +153 -1
- package/packages/core/dist/{index-Bg9ZdsdS.d.ts → index-xevIlqdd.d.ts} +153 -1
- package/packages/core/dist/index.d.cts +3 -3
- package/packages/core/dist/index.d.ts +3 -3
- package/packages/core/dist/index.mjs +3 -3
- package/packages/core/dist/persisted.d.cts +1 -1
- package/packages/core/dist/persisted.d.ts +1 -1
- package/packages/core/dist/{types--ainI31J.d.ts → types-Bx3mEZ04.d.ts} +1 -1
- package/packages/core/dist/{types-UnrNaTo2.d.cts → types-VzKihKQo.d.cts} +1 -1
- package/packages/cli/dist/chunk-QPRJUVLH.mjs.map +0 -1
- package/packages/core/dist/chunk-3XS5O4JI.mjs.map +0 -1
- package/packages/core/dist/chunk-G47KQB42.mjs.map +0 -1
|
@@ -64,6 +64,17 @@ function formatProgrammaticDiagnostic(code, detail) {
|
|
|
64
64
|
}
|
|
65
65
|
|
|
66
66
|
// packages/core/src/outcomes/types.ts
|
|
67
|
+
var OBSERVED_OUTCOME_METHODS = [
|
|
68
|
+
"dom",
|
|
69
|
+
"accessibility",
|
|
70
|
+
"snapshot",
|
|
71
|
+
"network",
|
|
72
|
+
"storage",
|
|
73
|
+
"filesystem",
|
|
74
|
+
"database",
|
|
75
|
+
"queue",
|
|
76
|
+
"custom"
|
|
77
|
+
];
|
|
67
78
|
var OUTCOME_ATTRIBUTE_STATUS_KEY = "outcomeStatus";
|
|
68
79
|
var OUTCOME_ATTRIBUTE_EXPECTATION_KEY = "expectation";
|
|
69
80
|
var OUTCOME_ATTRIBUTE_METHOD_KEY = "method";
|
|
@@ -910,6 +921,248 @@ function buildTraceFacts(input) {
|
|
|
910
921
|
};
|
|
911
922
|
}
|
|
912
923
|
|
|
924
|
+
// packages/core/src/sessions/metadata.ts
|
|
925
|
+
function isNonEmptyString(value) {
|
|
926
|
+
return typeof value === "string" && value.trim() !== "";
|
|
927
|
+
}
|
|
928
|
+
function finitePositiveInt(value) {
|
|
929
|
+
if (typeof value !== "number" || !Number.isFinite(value) || value < 1) {
|
|
930
|
+
return void 0;
|
|
931
|
+
}
|
|
932
|
+
return Math.trunc(value);
|
|
933
|
+
}
|
|
934
|
+
function extractSessionWorkflowMetadata(record) {
|
|
935
|
+
if (!record) return void 0;
|
|
936
|
+
const out = {};
|
|
937
|
+
let found = false;
|
|
938
|
+
const assignString = (key, value) => {
|
|
939
|
+
if (isNonEmptyString(value)) {
|
|
940
|
+
out[key] = value.trim();
|
|
941
|
+
found = true;
|
|
942
|
+
}
|
|
943
|
+
};
|
|
944
|
+
assignString("sessionId", record.sessionId);
|
|
945
|
+
assignString("conversationId", record.conversationId);
|
|
946
|
+
assignString("groupId", record.groupId);
|
|
947
|
+
assignString("parentGroupId", record.parentGroupId);
|
|
948
|
+
assignString("retryOf", record.retryOf);
|
|
949
|
+
assignString("retryReason", record.retryReason);
|
|
950
|
+
assignString("handoffFrom", record.handoffFrom);
|
|
951
|
+
assignString("handoffTo", record.handoffTo);
|
|
952
|
+
assignString("subAgentId", record.subAgentId);
|
|
953
|
+
assignString("subAgentName", record.subAgentName);
|
|
954
|
+
assignString("jobId", record.jobId);
|
|
955
|
+
assignString("queueName", record.queueName);
|
|
956
|
+
assignString("workflowName", record.workflowName);
|
|
957
|
+
assignString("workflowStep", record.workflowStep);
|
|
958
|
+
assignString("toolCallId", record.toolCallId);
|
|
959
|
+
assignString("mcpToolCallId", record.mcpToolCallId);
|
|
960
|
+
assignString("linkedStepId", record.linkedStepId);
|
|
961
|
+
assignString("correlationId", record.correlationId);
|
|
962
|
+
assignString("requestId", record.requestId);
|
|
963
|
+
assignString("decisionId", record.decisionId);
|
|
964
|
+
const attempt = finitePositiveInt(record.attempt);
|
|
965
|
+
if (attempt !== void 0) {
|
|
966
|
+
out.attempt = attempt;
|
|
967
|
+
found = true;
|
|
968
|
+
}
|
|
969
|
+
return found ? out : void 0;
|
|
970
|
+
}
|
|
971
|
+
|
|
972
|
+
// packages/core/src/checks/contract-scope.ts
|
|
973
|
+
function diagnostic(code, message, ruleId) {
|
|
974
|
+
return {
|
|
975
|
+
code,
|
|
976
|
+
message,
|
|
977
|
+
severity: "error",
|
|
978
|
+
...ruleId !== void 0 ? { ruleId } : {}
|
|
979
|
+
};
|
|
980
|
+
}
|
|
981
|
+
function isNonEmptyString2(value) {
|
|
982
|
+
return typeof value === "string" && value.trim() !== "";
|
|
983
|
+
}
|
|
984
|
+
function scopeEntries(scope) {
|
|
985
|
+
const out = [];
|
|
986
|
+
if (isNonEmptyString2(scope.runId)) out.push(["runId", scope.runId.trim()]);
|
|
987
|
+
if (isNonEmptyString2(scope.subAgentId)) out.push(["subAgentId", scope.subAgentId.trim()]);
|
|
988
|
+
if (isNonEmptyString2(scope.groupId)) out.push(["groupId", scope.groupId.trim()]);
|
|
989
|
+
if (isNonEmptyString2(scope.workflowStep)) {
|
|
990
|
+
out.push(["workflowStep", scope.workflowStep.trim()]);
|
|
991
|
+
}
|
|
992
|
+
if (isNonEmptyString2(scope.rootEventId)) {
|
|
993
|
+
out.push(["rootEventId", scope.rootEventId.trim()]);
|
|
994
|
+
}
|
|
995
|
+
return out;
|
|
996
|
+
}
|
|
997
|
+
function mergeWorkflowMeta(into, from) {
|
|
998
|
+
if (!from) return;
|
|
999
|
+
for (const [key, value] of Object.entries(from)) {
|
|
1000
|
+
if (value === void 0) continue;
|
|
1001
|
+
if (into[key] === void 0) {
|
|
1002
|
+
into[key] = value;
|
|
1003
|
+
}
|
|
1004
|
+
}
|
|
1005
|
+
}
|
|
1006
|
+
function workflowMetadataForRun(events, runId) {
|
|
1007
|
+
const preferred = {};
|
|
1008
|
+
const fallback = {};
|
|
1009
|
+
for (const event of events) {
|
|
1010
|
+
if (event.runId !== runId) continue;
|
|
1011
|
+
const attrs = event.attributes;
|
|
1012
|
+
if (!attrs || typeof attrs !== "object") continue;
|
|
1013
|
+
const direct = extractSessionWorkflowMetadata(attrs);
|
|
1014
|
+
const nested = attrs.metadata && typeof attrs.metadata === "object" ? extractSessionWorkflowMetadata(attrs.metadata) : void 0;
|
|
1015
|
+
const bag = {};
|
|
1016
|
+
mergeWorkflowMeta(bag, direct);
|
|
1017
|
+
mergeWorkflowMeta(bag, nested);
|
|
1018
|
+
if (event.kind === "RUN") {
|
|
1019
|
+
mergeWorkflowMeta(preferred, bag);
|
|
1020
|
+
} else {
|
|
1021
|
+
mergeWorkflowMeta(fallback, bag);
|
|
1022
|
+
}
|
|
1023
|
+
}
|
|
1024
|
+
mergeWorkflowMeta(preferred, fallback);
|
|
1025
|
+
return preferred;
|
|
1026
|
+
}
|
|
1027
|
+
function flattenNodes(nodes) {
|
|
1028
|
+
return nodes.flatMap((node) => [node, ...flattenNodes(node.children)]);
|
|
1029
|
+
}
|
|
1030
|
+
function collectSubtreeEventIds(run, rootEventId) {
|
|
1031
|
+
const nodes = flattenNodes(run.children);
|
|
1032
|
+
const byId = new Map(nodes.map((node) => [node.event.eventId, node]));
|
|
1033
|
+
const root = byId.get(rootEventId);
|
|
1034
|
+
if (!root) return void 0;
|
|
1035
|
+
const ids = /* @__PURE__ */ new Set();
|
|
1036
|
+
const visit = (node) => {
|
|
1037
|
+
ids.add(node.event.eventId);
|
|
1038
|
+
for (const child of node.children) visit(child);
|
|
1039
|
+
};
|
|
1040
|
+
visit(root);
|
|
1041
|
+
return ids;
|
|
1042
|
+
}
|
|
1043
|
+
function filterTree(nodes, keep) {
|
|
1044
|
+
const out = [];
|
|
1045
|
+
for (const node of nodes) {
|
|
1046
|
+
if (!keep.has(node.event.eventId)) continue;
|
|
1047
|
+
out.push({
|
|
1048
|
+
...node,
|
|
1049
|
+
children: filterTree(node.children, keep)
|
|
1050
|
+
});
|
|
1051
|
+
}
|
|
1052
|
+
return out;
|
|
1053
|
+
}
|
|
1054
|
+
function projectInput(input, run, eventIds) {
|
|
1055
|
+
const runEvents = input.read.events.filter((event) => event.runId === run.runId);
|
|
1056
|
+
const projectedEvents = eventIds === void 0 ? runEvents : runEvents.filter((event) => eventIds.has(event.eventId) || event.kind === "RUN");
|
|
1057
|
+
const projectedChildren = eventIds === void 0 ? run.children : filterTree(run.children, eventIds);
|
|
1058
|
+
const projectedRun = {
|
|
1059
|
+
...run,
|
|
1060
|
+
children: projectedChildren,
|
|
1061
|
+
metadata: {
|
|
1062
|
+
...run.metadata,
|
|
1063
|
+
totalEvents: flattenNodes(projectedChildren).length
|
|
1064
|
+
}
|
|
1065
|
+
};
|
|
1066
|
+
return {
|
|
1067
|
+
evidenceEventCount: projectedEvents.length,
|
|
1068
|
+
input: {
|
|
1069
|
+
...input,
|
|
1070
|
+
selectedRun: projectedRun,
|
|
1071
|
+
read: {
|
|
1072
|
+
...input.read,
|
|
1073
|
+
runs: [projectedRun],
|
|
1074
|
+
events: projectedEvents
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1077
|
+
};
|
|
1078
|
+
}
|
|
1079
|
+
function resolveTraceContractScope(input, scope) {
|
|
1080
|
+
if (scope === void 0) {
|
|
1081
|
+
return { diagnostics: [] };
|
|
1082
|
+
}
|
|
1083
|
+
const entries = scopeEntries(scope);
|
|
1084
|
+
if (entries.length === 0) {
|
|
1085
|
+
return {
|
|
1086
|
+
diagnostics: [
|
|
1087
|
+
diagnostic(
|
|
1088
|
+
"AI_CHECK_INVALID_CONFIG",
|
|
1089
|
+
"TraceContract scope requires at least one explicit selector (runId, subAgentId, groupId, workflowStep, or rootEventId).",
|
|
1090
|
+
"contract.scope.empty"
|
|
1091
|
+
)
|
|
1092
|
+
]
|
|
1093
|
+
};
|
|
1094
|
+
}
|
|
1095
|
+
const matchedSelectors = Object.fromEntries(entries);
|
|
1096
|
+
const actorKeys = entries.filter(([key]) => key !== "rootEventId");
|
|
1097
|
+
const rootEventId = matchedSelectors.rootEventId;
|
|
1098
|
+
let candidates = [...input.read.runs];
|
|
1099
|
+
if (matchedSelectors.runId) {
|
|
1100
|
+
candidates = candidates.filter((run2) => run2.runId === matchedSelectors.runId);
|
|
1101
|
+
}
|
|
1102
|
+
for (const [key, value] of actorKeys) {
|
|
1103
|
+
if (key === "runId") continue;
|
|
1104
|
+
candidates = candidates.filter((run2) => {
|
|
1105
|
+
const meta = workflowMetadataForRun(input.read.events, run2.runId);
|
|
1106
|
+
const actual = meta[key];
|
|
1107
|
+
return actual === value;
|
|
1108
|
+
});
|
|
1109
|
+
}
|
|
1110
|
+
if (rootEventId && actorKeys.length === 0) {
|
|
1111
|
+
candidates = candidates.filter(
|
|
1112
|
+
(run2) => flattenNodes(run2.children).some((node) => node.event.eventId === rootEventId)
|
|
1113
|
+
);
|
|
1114
|
+
}
|
|
1115
|
+
if (candidates.length === 0) {
|
|
1116
|
+
return {
|
|
1117
|
+
diagnostics: [
|
|
1118
|
+
diagnostic(
|
|
1119
|
+
"AI_CHECK_RUN_SELECTION_REQUIRED",
|
|
1120
|
+
`TraceContract scope matched zero actors for ${JSON.stringify(matchedSelectors)}. Missing actor metadata does not fall back to the whole session.`,
|
|
1121
|
+
"contract.scope.zero-match"
|
|
1122
|
+
)
|
|
1123
|
+
]
|
|
1124
|
+
};
|
|
1125
|
+
}
|
|
1126
|
+
if (candidates.length > 1) {
|
|
1127
|
+
return {
|
|
1128
|
+
diagnostics: [
|
|
1129
|
+
diagnostic(
|
|
1130
|
+
"AI_CHECK_RUN_SELECTION_REQUIRED",
|
|
1131
|
+
`TraceContract scope matched ${candidates.length} actors for ${JSON.stringify(matchedSelectors)} (runIds: ${candidates.map((run2) => run2.runId).sort().join(", ")}). Singular actor selectors must resolve to exactly one run.`,
|
|
1132
|
+
"contract.scope.ambiguous"
|
|
1133
|
+
)
|
|
1134
|
+
]
|
|
1135
|
+
};
|
|
1136
|
+
}
|
|
1137
|
+
const run = candidates[0];
|
|
1138
|
+
let eventIds;
|
|
1139
|
+
if (rootEventId) {
|
|
1140
|
+
eventIds = collectSubtreeEventIds(run, rootEventId);
|
|
1141
|
+
if (eventIds === void 0) {
|
|
1142
|
+
return {
|
|
1143
|
+
diagnostics: [
|
|
1144
|
+
diagnostic(
|
|
1145
|
+
"AI_CHECK_INVALID_ARGUMENTS",
|
|
1146
|
+
`TraceContract scope rootEventId ${rootEventId} was not found in run ${run.runId}.`,
|
|
1147
|
+
"contract.scope.root-missing"
|
|
1148
|
+
)
|
|
1149
|
+
]
|
|
1150
|
+
};
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
const projected = projectInput(input, run, eventIds);
|
|
1154
|
+
return {
|
|
1155
|
+
resolved: {
|
|
1156
|
+
runId: run.runId,
|
|
1157
|
+
...rootEventId !== void 0 ? { rootEventId } : {},
|
|
1158
|
+
matchedSelectors,
|
|
1159
|
+
evidenceEventCount: projected.evidenceEventCount,
|
|
1160
|
+
input: projected.input
|
|
1161
|
+
},
|
|
1162
|
+
diagnostics: []
|
|
1163
|
+
};
|
|
1164
|
+
}
|
|
1165
|
+
|
|
913
1166
|
// packages/core/src/checks/contract.ts
|
|
914
1167
|
function contractFailFinding(ruleId, message, evidence, expected, actual) {
|
|
915
1168
|
return {
|
|
@@ -933,12 +1186,141 @@ function cloneBody(body) {
|
|
|
933
1186
|
...body.run ? { run: { ...body.run } } : {},
|
|
934
1187
|
...body.tools ? { tools: { ...body.tools } } : {},
|
|
935
1188
|
...body.llm ? { llm: { ...body.llm } } : {},
|
|
936
|
-
...body.observations ? {
|
|
1189
|
+
...body.observations ? {
|
|
1190
|
+
observations: {
|
|
1191
|
+
...body.observations,
|
|
1192
|
+
...body.observations.requireProvenance ? { requireProvenance: { ...body.observations.requireProvenance } } : {}
|
|
1193
|
+
}
|
|
1194
|
+
} : {}
|
|
937
1195
|
};
|
|
938
1196
|
}
|
|
939
1197
|
function bodyHasRules(body) {
|
|
940
1198
|
return body.run !== void 0 || body.tools !== void 0 || body.llm !== void 0 || body.observations !== void 0;
|
|
941
1199
|
}
|
|
1200
|
+
var MAX_EVIDENCE_EVENT_IDS = 16;
|
|
1201
|
+
var METHOD_VOCABULARY = new Set(OBSERVED_OUTCOME_METHODS);
|
|
1202
|
+
function parseEvidenceEventIds(evidence) {
|
|
1203
|
+
if (evidence === void 0 || evidence === null) {
|
|
1204
|
+
return { status: "missing" };
|
|
1205
|
+
}
|
|
1206
|
+
if (typeof evidence === "string") {
|
|
1207
|
+
const trimmed = evidence.trim();
|
|
1208
|
+
if (trimmed === "") {
|
|
1209
|
+
return { status: "invalid", reason: "empty evidence string" };
|
|
1210
|
+
}
|
|
1211
|
+
return { status: "ok", eventIds: [trimmed] };
|
|
1212
|
+
}
|
|
1213
|
+
if (typeof evidence !== "object" || Array.isArray(evidence)) {
|
|
1214
|
+
return {
|
|
1215
|
+
status: "invalid",
|
|
1216
|
+
reason: "evidence must be a string event id or { eventId } / { eventIds }"
|
|
1217
|
+
};
|
|
1218
|
+
}
|
|
1219
|
+
const record = evidence;
|
|
1220
|
+
if (typeof record.eventId === "string") {
|
|
1221
|
+
const trimmed = record.eventId.trim();
|
|
1222
|
+
if (trimmed === "") {
|
|
1223
|
+
return { status: "invalid", reason: "empty evidence.eventId" };
|
|
1224
|
+
}
|
|
1225
|
+
return { status: "ok", eventIds: [trimmed] };
|
|
1226
|
+
}
|
|
1227
|
+
if (Array.isArray(record.eventIds)) {
|
|
1228
|
+
if (record.eventIds.length === 0) {
|
|
1229
|
+
return { status: "invalid", reason: "empty evidence.eventIds" };
|
|
1230
|
+
}
|
|
1231
|
+
if (record.eventIds.length > MAX_EVIDENCE_EVENT_IDS) {
|
|
1232
|
+
return {
|
|
1233
|
+
status: "invalid",
|
|
1234
|
+
reason: `evidence.eventIds exceeds bound of ${MAX_EVIDENCE_EVENT_IDS}`
|
|
1235
|
+
};
|
|
1236
|
+
}
|
|
1237
|
+
const eventIds = [];
|
|
1238
|
+
for (const item of record.eventIds) {
|
|
1239
|
+
if (typeof item !== "string" || item.trim() === "") {
|
|
1240
|
+
return { status: "invalid", reason: "evidence.eventIds contains a non-string id" };
|
|
1241
|
+
}
|
|
1242
|
+
eventIds.push(item.trim());
|
|
1243
|
+
}
|
|
1244
|
+
return { status: "ok", eventIds };
|
|
1245
|
+
}
|
|
1246
|
+
return {
|
|
1247
|
+
status: "invalid",
|
|
1248
|
+
reason: "evidence must include eventId or eventIds"
|
|
1249
|
+
};
|
|
1250
|
+
}
|
|
1251
|
+
function provenanceFindingsForOutcome(outcome, requireProvenance, knownEventIds) {
|
|
1252
|
+
const findings = [];
|
|
1253
|
+
const evidenceBase = [
|
|
1254
|
+
{
|
|
1255
|
+
runId: outcome.runId,
|
|
1256
|
+
eventId: outcome.outcomeId,
|
|
1257
|
+
kind: "OUTCOME",
|
|
1258
|
+
name: outcome.name,
|
|
1259
|
+
path: `outcome.${outcome.name}`
|
|
1260
|
+
}
|
|
1261
|
+
];
|
|
1262
|
+
if (requireProvenance.method) {
|
|
1263
|
+
if (outcome.method === void 0 || outcome.method.trim() === "") {
|
|
1264
|
+
findings.push(
|
|
1265
|
+
contractFailFinding(
|
|
1266
|
+
"contract.observation.provenance.method",
|
|
1267
|
+
`Observation ${outcome.name} is missing a structural method.`,
|
|
1268
|
+
evidenceBase,
|
|
1269
|
+
{ method: true },
|
|
1270
|
+
{ name: outcome.name, method: outcome.method ?? null }
|
|
1271
|
+
)
|
|
1272
|
+
);
|
|
1273
|
+
} else if (!METHOD_VOCABULARY.has(outcome.method)) {
|
|
1274
|
+
findings.push(
|
|
1275
|
+
contractFailFinding(
|
|
1276
|
+
"contract.observation.provenance.method",
|
|
1277
|
+
`Observation ${outcome.name} method ${outcome.method} is outside the bounded ObservedOutcomeMethod vocabulary.`,
|
|
1278
|
+
evidenceBase,
|
|
1279
|
+
{ methodVocabulary: [...OBSERVED_OUTCOME_METHODS] },
|
|
1280
|
+
{ name: outcome.name, method: outcome.method }
|
|
1281
|
+
)
|
|
1282
|
+
);
|
|
1283
|
+
}
|
|
1284
|
+
}
|
|
1285
|
+
if (requireProvenance.evidence || requireProvenance.sameRunEventReference) {
|
|
1286
|
+
const parsed = parseEvidenceEventIds(outcome.evidence);
|
|
1287
|
+
if (parsed.status === "missing") {
|
|
1288
|
+
findings.push(
|
|
1289
|
+
contractFailFinding(
|
|
1290
|
+
"contract.observation.provenance.evidence",
|
|
1291
|
+
`Observation ${outcome.name} is missing bounded evidence references.`,
|
|
1292
|
+
evidenceBase,
|
|
1293
|
+
{ evidence: true },
|
|
1294
|
+
{ name: outcome.name, evidence: null }
|
|
1295
|
+
)
|
|
1296
|
+
);
|
|
1297
|
+
} else if (parsed.status === "invalid") {
|
|
1298
|
+
findings.push(
|
|
1299
|
+
contractFailFinding(
|
|
1300
|
+
"contract.observation.provenance.evidence",
|
|
1301
|
+
`Observation ${outcome.name} evidence is not a bounded event reference (${parsed.reason}).`,
|
|
1302
|
+
evidenceBase,
|
|
1303
|
+
{ evidence: true },
|
|
1304
|
+
{ name: outcome.name, reason: parsed.reason }
|
|
1305
|
+
)
|
|
1306
|
+
);
|
|
1307
|
+
} else if (requireProvenance.sameRunEventReference) {
|
|
1308
|
+
const missing = parsed.eventIds.filter((eventId) => !knownEventIds.has(eventId));
|
|
1309
|
+
if (missing.length > 0) {
|
|
1310
|
+
findings.push(
|
|
1311
|
+
contractFailFinding(
|
|
1312
|
+
"contract.observation.provenance.same-run",
|
|
1313
|
+
`Observation ${outcome.name} references event ids missing from the same run: ${missing.join(", ")}.`,
|
|
1314
|
+
evidenceBase,
|
|
1315
|
+
{ sameRunEventReference: true, eventIds: parsed.eventIds },
|
|
1316
|
+
{ name: outcome.name, missing }
|
|
1317
|
+
)
|
|
1318
|
+
);
|
|
1319
|
+
}
|
|
1320
|
+
}
|
|
1321
|
+
}
|
|
1322
|
+
return findings;
|
|
1323
|
+
}
|
|
942
1324
|
function contractToRules(contract) {
|
|
943
1325
|
const rules = [];
|
|
944
1326
|
const allowedStatuses = contract.run?.allowedStatuses ?? [];
|
|
@@ -1086,9 +1468,71 @@ function contractToRules(contract) {
|
|
|
1086
1468
|
})
|
|
1087
1469
|
);
|
|
1088
1470
|
}
|
|
1471
|
+
const requireProvenance = contract.observations.requireProvenance;
|
|
1472
|
+
if (requireProvenance && (requireProvenance.method || requireProvenance.evidence || requireProvenance.sameRunEventReference)) {
|
|
1473
|
+
rules.push({
|
|
1474
|
+
id: "contract.observation.provenance",
|
|
1475
|
+
category: "run",
|
|
1476
|
+
defaultSeverity: "error",
|
|
1477
|
+
evaluate(context) {
|
|
1478
|
+
const outcomes = extractOutcomesFromPersistedEvents(context.events);
|
|
1479
|
+
const knownEventIds = new Set(context.events.map((event) => event.eventId));
|
|
1480
|
+
const targets = required.length > 0 ? outcomes.filter((outcome) => required.includes(outcome.name)) : outcomes;
|
|
1481
|
+
return targets.flatMap(
|
|
1482
|
+
(outcome) => provenanceFindingsForOutcome(outcome, requireProvenance, knownEventIds)
|
|
1483
|
+
);
|
|
1484
|
+
}
|
|
1485
|
+
});
|
|
1486
|
+
}
|
|
1089
1487
|
}
|
|
1090
1488
|
return rules;
|
|
1091
1489
|
}
|
|
1490
|
+
function validateScopeShape(scope) {
|
|
1491
|
+
if (scope === void 0) return [];
|
|
1492
|
+
const hasSelector = typeof scope.runId === "string" && scope.runId.trim() !== "" || typeof scope.subAgentId === "string" && scope.subAgentId.trim() !== "" || typeof scope.groupId === "string" && scope.groupId.trim() !== "" || typeof scope.workflowStep === "string" && scope.workflowStep.trim() !== "" || typeof scope.rootEventId === "string" && scope.rootEventId.trim() !== "";
|
|
1493
|
+
if (!hasSelector) {
|
|
1494
|
+
return [
|
|
1495
|
+
{
|
|
1496
|
+
code: "contract.scope.empty",
|
|
1497
|
+
severity: "error",
|
|
1498
|
+
message: "scope requires at least one explicit selector (runId, subAgentId, groupId, workflowStep, or rootEventId).",
|
|
1499
|
+
path: "scope"
|
|
1500
|
+
}
|
|
1501
|
+
];
|
|
1502
|
+
}
|
|
1503
|
+
return [];
|
|
1504
|
+
}
|
|
1505
|
+
function validateProvenanceShape(observations) {
|
|
1506
|
+
const diagnostics = [];
|
|
1507
|
+
const provenance = observations?.requireProvenance;
|
|
1508
|
+
if (!provenance) return diagnostics;
|
|
1509
|
+
const enabled = provenance.method === true || provenance.evidence === true || provenance.sameRunEventReference === true;
|
|
1510
|
+
if (!enabled) {
|
|
1511
|
+
diagnostics.push({
|
|
1512
|
+
code: "contract.observation.provenance.empty",
|
|
1513
|
+
severity: "warning",
|
|
1514
|
+
message: "observations.requireProvenance is set but no flags are enabled.",
|
|
1515
|
+
path: "observations.requireProvenance"
|
|
1516
|
+
});
|
|
1517
|
+
}
|
|
1518
|
+
if (provenance.sameRunEventReference === true && provenance.evidence !== true) {
|
|
1519
|
+
diagnostics.push({
|
|
1520
|
+
code: "contract.observation.provenance.same-run-without-evidence",
|
|
1521
|
+
severity: "info",
|
|
1522
|
+
message: "sameRunEventReference implies evidence checking; set requireProvenance.evidence: true for clarity.",
|
|
1523
|
+
path: "observations.requireProvenance.sameRunEventReference"
|
|
1524
|
+
});
|
|
1525
|
+
}
|
|
1526
|
+
if (enabled && (observations?.required?.length ?? 0) === 0) {
|
|
1527
|
+
diagnostics.push({
|
|
1528
|
+
code: "contract.observation.provenance.without-required",
|
|
1529
|
+
severity: "warning",
|
|
1530
|
+
message: "requireProvenance without observations.required applies to every observed outcome in scope.",
|
|
1531
|
+
path: "observations.requireProvenance"
|
|
1532
|
+
});
|
|
1533
|
+
}
|
|
1534
|
+
return diagnostics;
|
|
1535
|
+
}
|
|
1092
1536
|
function validateAlternativesShape(alternatives) {
|
|
1093
1537
|
const diagnostics = [];
|
|
1094
1538
|
if (alternatives === void 0) return diagnostics;
|
|
@@ -1195,9 +1639,11 @@ function evaluateBody(input, body, options = {}) {
|
|
|
1195
1639
|
});
|
|
1196
1640
|
}
|
|
1197
1641
|
function defineTraceContract(input) {
|
|
1198
|
-
const shapeErrors =
|
|
1199
|
-
(
|
|
1200
|
-
|
|
1642
|
+
const shapeErrors = [
|
|
1643
|
+
...validateAlternativesShape(input.alternatives),
|
|
1644
|
+
...validateScopeShape(input.scope),
|
|
1645
|
+
...validateProvenanceShape(input.observations)
|
|
1646
|
+
].filter((item) => item.severity === "error");
|
|
1201
1647
|
if (shapeErrors.length > 0) {
|
|
1202
1648
|
throw new TypeError(shapeErrors.map((item) => item.message).join(" "));
|
|
1203
1649
|
}
|
|
@@ -1209,15 +1655,25 @@ function defineTraceContract(input) {
|
|
|
1209
1655
|
contract: cloneBody(branch.contract)
|
|
1210
1656
|
}))
|
|
1211
1657
|
} : void 0;
|
|
1658
|
+
const scope = input.scope ? {
|
|
1659
|
+
...input.scope.runId !== void 0 ? { runId: input.scope.runId } : {},
|
|
1660
|
+
...input.scope.subAgentId !== void 0 ? { subAgentId: input.scope.subAgentId } : {},
|
|
1661
|
+
...input.scope.groupId !== void 0 ? { groupId: input.scope.groupId } : {},
|
|
1662
|
+
...input.scope.workflowStep !== void 0 ? { workflowStep: input.scope.workflowStep } : {},
|
|
1663
|
+
...input.scope.rootEventId !== void 0 ? { rootEventId: input.scope.rootEventId } : {}
|
|
1664
|
+
} : void 0;
|
|
1212
1665
|
return {
|
|
1213
1666
|
...body,
|
|
1667
|
+
...scope ? { scope } : {},
|
|
1214
1668
|
...alternatives ? { alternatives } : {}
|
|
1215
1669
|
};
|
|
1216
1670
|
}
|
|
1217
1671
|
function evaluateTraceContract(input, contract, options = {}) {
|
|
1218
|
-
const shapeErrors =
|
|
1219
|
-
(
|
|
1220
|
-
|
|
1672
|
+
const shapeErrors = [
|
|
1673
|
+
...validateAlternativesShape(contract.alternatives),
|
|
1674
|
+
...validateScopeShape(contract.scope),
|
|
1675
|
+
...validateProvenanceShape(contract.observations)
|
|
1676
|
+
].filter((item) => item.severity === "error");
|
|
1221
1677
|
if (shapeErrors.length > 0) {
|
|
1222
1678
|
return {
|
|
1223
1679
|
ok: false,
|
|
@@ -1241,13 +1697,58 @@ function evaluateTraceContract(input, contract, options = {}) {
|
|
|
1241
1697
|
ruleExecutions: []
|
|
1242
1698
|
};
|
|
1243
1699
|
}
|
|
1244
|
-
const
|
|
1700
|
+
const scoped = resolveTraceContractScope(input, contract.scope);
|
|
1701
|
+
if (scoped.diagnostics.length > 0) {
|
|
1702
|
+
return {
|
|
1703
|
+
ok: false,
|
|
1704
|
+
status: "error",
|
|
1705
|
+
format: input.read.format,
|
|
1706
|
+
...options.runId !== void 0 ? { runId: options.runId } : {},
|
|
1707
|
+
...scoped.resolved?.runId !== void 0 ? { runId: scoped.resolved.runId } : {},
|
|
1708
|
+
summary: {
|
|
1709
|
+
passed: 0,
|
|
1710
|
+
failed: 0,
|
|
1711
|
+
warnings: 0,
|
|
1712
|
+
errors: scoped.diagnostics.length,
|
|
1713
|
+
rulesEvaluated: 0
|
|
1714
|
+
},
|
|
1715
|
+
findings: [],
|
|
1716
|
+
diagnostics: scoped.diagnostics,
|
|
1717
|
+
ruleExecutions: []
|
|
1718
|
+
};
|
|
1719
|
+
}
|
|
1720
|
+
const effectiveInput = scoped.resolved?.input ?? input;
|
|
1721
|
+
const effectiveRunId = scoped.resolved?.runId ?? options.runId;
|
|
1722
|
+
const base = evaluateBody(effectiveInput, contract, {
|
|
1723
|
+
...effectiveRunId !== void 0 ? { runId: effectiveRunId } : {}
|
|
1724
|
+
});
|
|
1725
|
+
const scopeFinding = scoped.resolved ? {
|
|
1726
|
+
ruleId: "contract.scope.selected",
|
|
1727
|
+
severity: "info",
|
|
1728
|
+
status: "pass",
|
|
1729
|
+
message: `Selected actor ${scoped.resolved.runId} with ${scoped.resolved.evidenceEventCount} evidence event(s).`,
|
|
1730
|
+
expected: scoped.resolved.matchedSelectors,
|
|
1731
|
+
actual: {
|
|
1732
|
+
runId: scoped.resolved.runId,
|
|
1733
|
+
evidenceEventCount: scoped.resolved.evidenceEventCount,
|
|
1734
|
+
...scoped.resolved.rootEventId !== void 0 ? { rootEventId: scoped.resolved.rootEventId } : {}
|
|
1735
|
+
},
|
|
1736
|
+
evidence: [
|
|
1737
|
+
{
|
|
1738
|
+
runId: scoped.resolved.runId,
|
|
1739
|
+
kind: "RUN",
|
|
1740
|
+
path: "scope"
|
|
1741
|
+
}
|
|
1742
|
+
]
|
|
1743
|
+
} : void 0;
|
|
1245
1744
|
const branches = contract.alternatives?.anyOf ?? [];
|
|
1246
1745
|
if (branches.length === 0) {
|
|
1247
|
-
return base;
|
|
1746
|
+
return scopeFinding ? mergeContractResults(effectiveInput, [base], [scopeFinding]) : base;
|
|
1248
1747
|
}
|
|
1249
1748
|
const branchEvaluations = branches.map((branch) => {
|
|
1250
|
-
const result = evaluateBody(
|
|
1749
|
+
const result = evaluateBody(effectiveInput, branch.contract, {
|
|
1750
|
+
...effectiveRunId !== void 0 ? { runId: effectiveRunId } : {}
|
|
1751
|
+
});
|
|
1251
1752
|
return { branch, result };
|
|
1252
1753
|
});
|
|
1253
1754
|
const satisfied = branchEvaluations.filter((item) => item.result.ok && item.result.status === "pass").map((item) => item.branch.id);
|
|
@@ -1267,7 +1768,11 @@ function evaluateTraceContract(input, contract, options = {}) {
|
|
|
1267
1768
|
},
|
|
1268
1769
|
evidence: []
|
|
1269
1770
|
};
|
|
1270
|
-
return mergeContractResults(
|
|
1771
|
+
return mergeContractResults(
|
|
1772
|
+
effectiveInput,
|
|
1773
|
+
[base],
|
|
1774
|
+
[...scopeFinding ? [scopeFinding] : [], passFinding]
|
|
1775
|
+
);
|
|
1271
1776
|
}
|
|
1272
1777
|
const noneFinding = {
|
|
1273
1778
|
ruleId: "contract.alternatives.none-satisfied",
|
|
@@ -1294,13 +1799,21 @@ function evaluateTraceContract(input, contract, options = {}) {
|
|
|
1294
1799
|
ruleId: `contract.alternatives.${item.branch.id}.${finding.ruleId}`
|
|
1295
1800
|
}))
|
|
1296
1801
|
);
|
|
1297
|
-
return mergeContractResults(
|
|
1802
|
+
return mergeContractResults(
|
|
1803
|
+
effectiveInput,
|
|
1804
|
+
[base],
|
|
1805
|
+
[...scopeFinding ? [scopeFinding] : [], noneFinding, ...prefixedBranchFindings]
|
|
1806
|
+
);
|
|
1298
1807
|
}
|
|
1299
1808
|
function evaluateTraceContractRead(read, contract, options = {}) {
|
|
1300
1809
|
return evaluateTraceContract({ read }, contract, options);
|
|
1301
1810
|
}
|
|
1302
1811
|
function lintTraceContract(contract) {
|
|
1303
|
-
const diagnostics =
|
|
1812
|
+
const diagnostics = [
|
|
1813
|
+
...validateAlternativesShape(contract.alternatives),
|
|
1814
|
+
...validateScopeShape(contract.scope),
|
|
1815
|
+
...validateProvenanceShape(contract.observations)
|
|
1816
|
+
];
|
|
1304
1817
|
const branches = contract.alternatives?.anyOf ?? [];
|
|
1305
1818
|
if (branches.length === 1) {
|
|
1306
1819
|
diagnostics.push({
|
|
@@ -1335,6 +1848,12 @@ function lintTraceContract(contract) {
|
|
|
1335
1848
|
}
|
|
1336
1849
|
function explainTraceContract(contract) {
|
|
1337
1850
|
const lines = [];
|
|
1851
|
+
if (contract.scope) {
|
|
1852
|
+
const parts = Object.entries(contract.scope).filter(([, value]) => typeof value === "string" && value.trim() !== "").map(([key, value]) => `${key}=${value}`);
|
|
1853
|
+
if (parts.length > 0) {
|
|
1854
|
+
lines.push(`Scope: select actor by [${parts.join(", ")}] before evaluation.`);
|
|
1855
|
+
}
|
|
1856
|
+
}
|
|
1338
1857
|
if (contract.run?.requireCompleted !== false) {
|
|
1339
1858
|
lines.push("Base: run must complete (no running events).");
|
|
1340
1859
|
}
|
|
@@ -1386,6 +1905,18 @@ function explainTraceContract(contract) {
|
|
|
1386
1905
|
if (contract.observations?.failOn?.length) {
|
|
1387
1906
|
lines.push(`Base: fail on observations [${contract.observations.failOn.join(", ")}].`);
|
|
1388
1907
|
}
|
|
1908
|
+
if (contract.observations?.requireProvenance) {
|
|
1909
|
+
const flags = [
|
|
1910
|
+
contract.observations.requireProvenance.method ? "method" : void 0,
|
|
1911
|
+
contract.observations.requireProvenance.evidence ? "evidence" : void 0,
|
|
1912
|
+
contract.observations.requireProvenance.sameRunEventReference ? "sameRunEventReference" : void 0
|
|
1913
|
+
].filter((item) => item !== void 0);
|
|
1914
|
+
if (flags.length > 0) {
|
|
1915
|
+
lines.push(
|
|
1916
|
+
`Base: require structural observation provenance [${flags.join(", ")}] (not semantic truth).`
|
|
1917
|
+
);
|
|
1918
|
+
}
|
|
1919
|
+
}
|
|
1389
1920
|
const branches = contract.alternatives?.anyOf ?? [];
|
|
1390
1921
|
if (branches.length > 0) {
|
|
1391
1922
|
lines.push(
|
|
@@ -1486,7 +2017,7 @@ var DEFAULT_SECRET_PATTERNS = [
|
|
|
1486
2017
|
function compareStrings(a, b) {
|
|
1487
2018
|
return (a ?? "").localeCompare(b ?? "");
|
|
1488
2019
|
}
|
|
1489
|
-
function
|
|
2020
|
+
function diagnostic2(code, message, ruleId) {
|
|
1490
2021
|
return {
|
|
1491
2022
|
code,
|
|
1492
2023
|
message,
|
|
@@ -1519,14 +2050,14 @@ function errorResult(input, diagnostics, selectedRun, ruleExecutions = []) {
|
|
|
1519
2050
|
ruleExecutions: [...ruleExecutions]
|
|
1520
2051
|
};
|
|
1521
2052
|
}
|
|
1522
|
-
function
|
|
1523
|
-
return nodes.flatMap((node) => [node, ...
|
|
2053
|
+
function flattenNodes2(nodes) {
|
|
2054
|
+
return nodes.flatMap((node) => [node, ...flattenNodes2(node.children)]);
|
|
1524
2055
|
}
|
|
1525
2056
|
function buildFacts(input, selectedRun) {
|
|
1526
2057
|
const scopedRuns = selectedRun ? [selectedRun] : input.read.runs;
|
|
1527
2058
|
const scopedRunIds = new Set(scopedRuns.map((run) => run.runId));
|
|
1528
2059
|
const scopedEvents = selectedRun === void 0 ? input.read.events : input.read.events.filter((event) => scopedRunIds.has(event.runId));
|
|
1529
|
-
const nodes =
|
|
2060
|
+
const nodes = flattenNodes2(scopedRuns.flatMap((run) => run.children));
|
|
1530
2061
|
const nodesByEventId = /* @__PURE__ */ new Map();
|
|
1531
2062
|
const childrenByParentId = /* @__PURE__ */ new Map();
|
|
1532
2063
|
for (const node of nodes) {
|
|
@@ -1558,7 +2089,7 @@ function resolveSelectedRun(input, runId) {
|
|
|
1558
2089
|
if (runId && input.selectedRun.runId !== runId) {
|
|
1559
2090
|
return {
|
|
1560
2091
|
diagnostics: [
|
|
1561
|
-
|
|
2092
|
+
diagnostic2(
|
|
1562
2093
|
"AI_CHECK_INVALID_ARGUMENTS",
|
|
1563
2094
|
`Selected run ${input.selectedRun.runId} does not match requested run ${runId}.`
|
|
1564
2095
|
)
|
|
@@ -1572,7 +2103,7 @@ function resolveSelectedRun(input, runId) {
|
|
|
1572
2103
|
if (!run) {
|
|
1573
2104
|
return {
|
|
1574
2105
|
diagnostics: [
|
|
1575
|
-
|
|
2106
|
+
diagnostic2("AI_CHECK_RUN_SELECTION_REQUIRED", `Run not found: ${runId}.`)
|
|
1576
2107
|
]
|
|
1577
2108
|
};
|
|
1578
2109
|
}
|
|
@@ -1584,7 +2115,7 @@ function resolveSelectedRun(input, runId) {
|
|
|
1584
2115
|
if (input.read.runs.length === 0) {
|
|
1585
2116
|
return {
|
|
1586
2117
|
diagnostics: [
|
|
1587
|
-
|
|
2118
|
+
diagnostic2(
|
|
1588
2119
|
"AI_CHECK_RUN_SELECTION_REQUIRED",
|
|
1589
2120
|
formatProgrammaticDiagnostic(
|
|
1590
2121
|
"AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED",
|
|
@@ -1596,7 +2127,7 @@ function resolveSelectedRun(input, runId) {
|
|
|
1596
2127
|
}
|
|
1597
2128
|
return {
|
|
1598
2129
|
diagnostics: [
|
|
1599
|
-
|
|
2130
|
+
diagnostic2(
|
|
1600
2131
|
"AI_CHECK_RUN_SELECTION_REQUIRED",
|
|
1601
2132
|
formatProgrammaticDiagnostic("AI_TRACE_CONTRACT_RUN_SELECTION_REQUIRED")
|
|
1602
2133
|
)
|
|
@@ -1609,7 +2140,7 @@ function selectRules(rules, selectedIds) {
|
|
|
1609
2140
|
for (const rule of rules) {
|
|
1610
2141
|
if (byId.has(rule.id)) {
|
|
1611
2142
|
diagnostics.push(
|
|
1612
|
-
|
|
2143
|
+
diagnostic2("AI_CHECK_INVALID_CONFIG", `Duplicate trace check rule id: ${rule.id}.`, rule.id)
|
|
1613
2144
|
);
|
|
1614
2145
|
continue;
|
|
1615
2146
|
}
|
|
@@ -1620,7 +2151,7 @@ function selectRules(rules, selectedIds) {
|
|
|
1620
2151
|
for (const id of selected) {
|
|
1621
2152
|
if (!byId.has(id)) {
|
|
1622
2153
|
diagnostics.push(
|
|
1623
|
-
|
|
2154
|
+
diagnostic2("AI_CHECK_INVALID_CONFIG", `Unknown trace check rule id: ${id}.`, id)
|
|
1624
2155
|
);
|
|
1625
2156
|
}
|
|
1626
2157
|
}
|
|
@@ -3307,7 +3838,7 @@ function runTraceChecks(input, options = {}) {
|
|
|
3307
3838
|
return errorResult(
|
|
3308
3839
|
input,
|
|
3309
3840
|
[
|
|
3310
|
-
|
|
3841
|
+
diagnostic2(
|
|
3311
3842
|
"AI_CHECK_NO_RULES_EVALUATED",
|
|
3312
3843
|
"No trace check rules were evaluated. Configure at least one rule, contract, or CLI check option."
|
|
3313
3844
|
)
|
|
@@ -3338,7 +3869,7 @@ function runTraceChecks(input, options = {}) {
|
|
|
3338
3869
|
} catch (error) {
|
|
3339
3870
|
const message = error instanceof Error ? error.message : String(error);
|
|
3340
3871
|
diagnostics.push(
|
|
3341
|
-
|
|
3872
|
+
diagnostic2("AI_CHECK_INTERNAL_ERROR", `Rule ${rule.id} failed: ${message}`, rule.id)
|
|
3342
3873
|
);
|
|
3343
3874
|
ruleExecutions.push({
|
|
3344
3875
|
ruleId: rule.id,
|
|
@@ -3404,7 +3935,9 @@ exports.formatProgrammaticDiagnostic = formatProgrammaticDiagnostic;
|
|
|
3404
3935
|
exports.lintTraceContract = lintTraceContract;
|
|
3405
3936
|
exports.projectLogicalEvents = projectLogicalEvents;
|
|
3406
3937
|
exports.resolveCanonicalToolName = resolveCanonicalToolName;
|
|
3938
|
+
exports.resolveTraceContractScope = resolveTraceContractScope;
|
|
3407
3939
|
exports.runTraceChecks = runTraceChecks;
|
|
3408
3940
|
exports.summarizeSemanticParity = summarizeSemanticParity;
|
|
3941
|
+
exports.workflowMetadataForRun = workflowMetadataForRun;
|
|
3409
3942
|
//# sourceMappingURL=checks.cjs.map
|
|
3410
3943
|
//# sourceMappingURL=checks.cjs.map
|