agent-inspect 6.31.21 → 6.31.22

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 (47) hide show
  1. package/CHANGELOG.md +6 -0
  2. package/README.md +1 -1
  3. package/package.json +1 -1
  4. package/packages/cli/dist/{chunk-N5JN26MW.mjs → chunk-EMWA5EKU.mjs} +300 -31
  5. package/packages/cli/dist/chunk-EMWA5EKU.mjs.map +1 -0
  6. package/packages/cli/dist/index.cjs +379 -56
  7. package/packages/cli/dist/index.cjs.map +1 -1
  8. package/packages/cli/dist/index.mjs +75 -31
  9. package/packages/cli/dist/index.mjs.map +1 -1
  10. package/packages/cli/dist/{src-VMGRSTG7.mjs → src-VZHGOLTO.mjs} +3 -3
  11. package/packages/cli/dist/{src-VMGRSTG7.mjs.map → src-VZHGOLTO.mjs.map} +1 -1
  12. package/packages/core/dist/advanced.cjs +247 -5
  13. package/packages/core/dist/advanced.cjs.map +1 -1
  14. package/packages/core/dist/advanced.mjs +6 -5
  15. package/packages/core/dist/advanced.mjs.map +1 -1
  16. package/packages/core/dist/checks.cjs +160 -27
  17. package/packages/core/dist/checks.cjs.map +1 -1
  18. package/packages/core/dist/checks.mjs +2 -1
  19. package/packages/core/dist/chunk-GCZUWY47.mjs +182 -0
  20. package/packages/core/dist/chunk-GCZUWY47.mjs.map +1 -0
  21. package/packages/core/dist/{chunk-JE3TUFAQ.mjs → chunk-RBXD7BNX.mjs} +3 -3
  22. package/packages/core/dist/{chunk-JE3TUFAQ.mjs.map → chunk-RBXD7BNX.mjs.map} +1 -1
  23. package/packages/core/dist/{chunk-YU6XT5A2.mjs → chunk-S4NU55LU.mjs} +45 -3
  24. package/packages/core/dist/chunk-S4NU55LU.mjs.map +1 -0
  25. package/packages/core/dist/{chunk-EIP5CNEL.mjs → chunk-UPGBMRL4.mjs} +49 -3
  26. package/packages/core/dist/chunk-UPGBMRL4.mjs.map +1 -0
  27. package/packages/core/dist/{chunk-4CDX5GDS.mjs → chunk-ZOF6ON65.mjs} +104 -99
  28. package/packages/core/dist/chunk-ZOF6ON65.mjs.map +1 -0
  29. package/packages/core/dist/exporters.cjs +82 -27
  30. package/packages/core/dist/exporters.cjs.map +1 -1
  31. package/packages/core/dist/exporters.mjs +72 -27
  32. package/packages/core/dist/exporters.mjs.map +1 -1
  33. package/packages/core/dist/logs.cjs +197 -1
  34. package/packages/core/dist/logs.cjs.map +1 -1
  35. package/packages/core/dist/logs.mjs +3 -2
  36. package/packages/core/dist/logs.mjs.map +1 -1
  37. package/packages/core/dist/persisted.cjs +197 -1
  38. package/packages/core/dist/persisted.cjs.map +1 -1
  39. package/packages/core/dist/persisted.mjs +4 -3
  40. package/packages/core/dist/persisted.mjs.map +1 -1
  41. package/packages/core/dist/readers.cjs +243 -1
  42. package/packages/core/dist/readers.cjs.map +1 -1
  43. package/packages/core/dist/readers.mjs +4 -3
  44. package/packages/cli/dist/chunk-N5JN26MW.mjs.map +0 -1
  45. package/packages/core/dist/chunk-4CDX5GDS.mjs.map +0 -1
  46. package/packages/core/dist/chunk-EIP5CNEL.mjs.map +0 -1
  47. package/packages/core/dist/chunk-YU6XT5A2.mjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,11 @@
1
1
  # Changelog
2
2
 
3
+ ## 6.31.22
4
+
5
+ ### Patch Changes
6
+
7
+ - 3f02b61: Treat native eventIds as opaque for retry redelivery fingerprints, retain conflicting same-ID evidence through tree/export, and surface direct vs nested identity disagreements on OTLP round-trip so source and OTLP strict retry gates agree (Prompt A / #484).
8
+
3
9
  ## 6.31.21
4
10
 
5
11
  ### Patch Changes
package/README.md CHANGED
@@ -213,7 +213,7 @@ The root package is enough for custom capture, the CLI, checks, and Evidence wor
213
213
 
214
214
  ## Status and documentation
215
215
 
216
- **Current published baseline:** **6.31.21** · persisted schema `1.0` · Node.js `>=20` · MIT.
216
+ **Current published baseline:** **6.31.22** · persisted schema `1.0` · Node.js `>=20` · MIT.
217
217
 
218
218
  Legacy v0.1 and v0.2 traces remain readable. Check the npm badge and [changelog](CHANGELOG.md) for the current published version.
219
219
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "agent-inspect",
3
- "version": "6.31.21",
3
+ "version": "6.31.22",
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",
@@ -5685,6 +5685,115 @@ function evaluateToolArgumentValue(value, check, evidencePresent) {
5685
5685
  };
5686
5686
  }
5687
5687
 
5688
+ // packages/core/src/persisted/delivery-identity.ts
5689
+ var DELIVERY_CONFLICT_ATTR = "agent_inspect.delivery_conflict";
5690
+ var IDENTITY_CONFLICT_ATTR = {
5691
+ operationId: "agent_inspect.identity_conflict.operation_id",
5692
+ attemptId: "agent_inspect.identity_conflict.attempt_id",
5693
+ retryOf: "agent_inspect.identity_conflict.retry_of",
5694
+ attemptNumber: "agent_inspect.identity_conflict.attempt_number"
5695
+ };
5696
+ var SYNTHETIC_DELIVERY_ID = /^(?:manual|inspect):[A-Za-z0-9_-]+:[A-Za-z0-9_-]+:[A-Za-z0-9_-]+:\d+$/;
5697
+ function stripReaderDeliveryDiscriminator(eventId) {
5698
+ if (!SYNTHETIC_DELIVERY_ID.test(eventId)) return eventId;
5699
+ return eventId.replace(/:\d+$/, "");
5700
+ }
5701
+ function canonicalDigest(value) {
5702
+ if (value === void 0) return null;
5703
+ const encoded = encodeCanonicalStructured(value);
5704
+ return encoded.ok ? encoded.value : `unencodable:${encoded.code}`;
5705
+ }
5706
+ function capturedContentDigest(attributes) {
5707
+ if (!attributes || typeof attributes !== "object") {
5708
+ return { args: null, result: null };
5709
+ }
5710
+ const nested = attributes.metadata && typeof attributes.metadata === "object" ? attributes.metadata : void 0;
5711
+ const args = attributes.arguments ?? attributes.args ?? attributes.input ?? nested?.arguments ?? nested?.args ?? nested?.input;
5712
+ const result = attributes.result ?? attributes.output ?? attributes.response ?? nested?.result ?? nested?.output ?? nested?.response;
5713
+ return {
5714
+ args: args === void 0 ? null : canonicalDigest(args),
5715
+ result: result === void 0 ? null : canonicalDigest(result)
5716
+ };
5717
+ }
5718
+ function timeKey(fields) {
5719
+ if (typeof fields.startedAt === "string" && fields.startedAt.trim() !== "") {
5720
+ return fields.startedAt;
5721
+ }
5722
+ if (typeof fields.timestamp === "string" && fields.timestamp.trim() !== "") {
5723
+ return fields.timestamp;
5724
+ }
5725
+ if (typeof fields.timestamp === "number" && Number.isFinite(fields.timestamp)) {
5726
+ return String(fields.timestamp);
5727
+ }
5728
+ return null;
5729
+ }
5730
+ function deliverySemanticFingerprint(fields) {
5731
+ const content = capturedContentDigest(fields.attributes);
5732
+ return JSON.stringify({
5733
+ stableEventId: stripReaderDeliveryDiscriminator(fields.eventId),
5734
+ runId: fields.runId,
5735
+ kind: fields.kind,
5736
+ name: fields.name,
5737
+ status: fields.status ?? null,
5738
+ parentId: fields.parentId ?? null,
5739
+ sourceType: fields.sourceType ?? null,
5740
+ time: timeKey(fields),
5741
+ operationId: fields.operationId ?? null,
5742
+ attemptId: fields.attemptId ?? null,
5743
+ attemptNumber: fields.attemptNumber ?? null,
5744
+ retryOf: fields.retryOf ?? null,
5745
+ argsDigest: content.args,
5746
+ resultDigest: content.result
5747
+ });
5748
+ }
5749
+ function identityFieldsFromAttributes(attributes) {
5750
+ if (!attributes || typeof attributes !== "object") {
5751
+ return {
5752
+ operationId: null,
5753
+ attemptId: null,
5754
+ attemptNumber: null,
5755
+ retryOf: null
5756
+ };
5757
+ }
5758
+ const nested = attributes.metadata && typeof attributes.metadata === "object" && !Array.isArray(attributes.metadata) ? attributes.metadata : void 0;
5759
+ const pickString3 = (key) => {
5760
+ const direct = attributes[key];
5761
+ if (typeof direct === "string" && direct.trim() !== "") return direct.trim();
5762
+ const nestedValue = nested?.[key];
5763
+ if (typeof nestedValue === "string" && nestedValue.trim() !== "") {
5764
+ return nestedValue.trim();
5765
+ }
5766
+ return null;
5767
+ };
5768
+ const pickNumber2 = () => {
5769
+ const direct = attributes.attemptNumber ?? attributes.attempt;
5770
+ if (typeof direct === "number" && Number.isFinite(direct)) return direct;
5771
+ const nestedValue = nested?.attemptNumber ?? nested?.attempt;
5772
+ if (typeof nestedValue === "number" && Number.isFinite(nestedValue)) {
5773
+ return nestedValue;
5774
+ }
5775
+ return null;
5776
+ };
5777
+ return {
5778
+ operationId: pickString3("operationId"),
5779
+ attemptId: pickString3("attemptId"),
5780
+ retryOf: pickString3("retryOf"),
5781
+ attemptNumber: pickNumber2()
5782
+ };
5783
+ }
5784
+ function hasDeliveryConflictMarker(attributes) {
5785
+ return attributes?.[DELIVERY_CONFLICT_ATTR] === true;
5786
+ }
5787
+ function stampDeliveryConflict(event) {
5788
+ return {
5789
+ ...event,
5790
+ attributes: {
5791
+ ...event.attributes ?? {},
5792
+ [DELIVERY_CONFLICT_ATTR]: true
5793
+ }
5794
+ };
5795
+ }
5796
+
5688
5797
  // packages/core/src/checks/retry-safety.ts
5689
5798
  function fail2(ruleId, message, evidence, expected, actual) {
5690
5799
  return {
@@ -5740,7 +5849,7 @@ function attemptIdOf(event) {
5740
5849
  }
5741
5850
  function countOperationAttempts(members) {
5742
5851
  const identified = /* @__PURE__ */ new Set();
5743
- let unidentified = 0;
5852
+ const unidentifiedFingerprints = /* @__PURE__ */ new Set();
5744
5853
  for (const event of members) {
5745
5854
  if (event.kind !== "TOOL" && event.kind !== "LLM") continue;
5746
5855
  const id = attemptIdOf(event);
@@ -5748,13 +5857,13 @@ function countOperationAttempts(members) {
5748
5857
  identified.add(id);
5749
5858
  continue;
5750
5859
  }
5751
- unidentified += 1;
5860
+ unidentifiedFingerprints.add(redeliveryFingerprint(event));
5752
5861
  }
5753
5862
  if (identified.size > 0) {
5754
- return identified.size + unidentified;
5863
+ return identified.size + unidentifiedFingerprints.size;
5755
5864
  }
5756
5865
  const numbered = /* @__PURE__ */ new Set();
5757
- let unnumbered = 0;
5866
+ const unnumberedFingerprints = /* @__PURE__ */ new Set();
5758
5867
  for (const event of members) {
5759
5868
  if (event.kind !== "TOOL" && event.kind !== "LLM") continue;
5760
5869
  const num = attemptNumberOf(event);
@@ -5762,12 +5871,12 @@ function countOperationAttempts(members) {
5762
5871
  numbered.add(num);
5763
5872
  continue;
5764
5873
  }
5765
- unnumbered += 1;
5874
+ unnumberedFingerprints.add(redeliveryFingerprint(event));
5766
5875
  }
5767
5876
  if (numbered.size > 0) {
5768
- return numbered.size + unnumbered;
5877
+ return numbered.size + unnumberedFingerprints.size;
5769
5878
  }
5770
- return unnumbered;
5879
+ return unnumberedFingerprints.size;
5771
5880
  }
5772
5881
  function classifyRetryAttempt(event, priorOrdered, allMembers) {
5773
5882
  const workflow = workflowFor(event);
@@ -5819,19 +5928,49 @@ function classifyRetryAttempt(event, priorOrdered, allMembers) {
5819
5928
  }
5820
5929
  function redeliveryFingerprint(event) {
5821
5930
  const workflow = workflowFor(event);
5822
- const stableEventId = (event.eventId ?? "").replace(/:\d+$/, "");
5823
- return JSON.stringify({
5824
- stableEventId,
5931
+ return deliverySemanticFingerprint({
5932
+ eventId: event.eventId ?? "",
5825
5933
  runId: event.runId,
5826
5934
  kind: event.kind,
5827
5935
  name: event.name,
5828
5936
  status: event.status,
5937
+ parentId: event.parentId,
5938
+ timestamp: event.timestamp,
5939
+ startedAt: event.startedAt,
5940
+ sourceType: event.source?.type,
5941
+ attributes: event.attributes && typeof event.attributes === "object" ? event.attributes : void 0,
5829
5942
  operationId: workflow.operationId ?? null,
5830
5943
  attemptId: workflow.attemptId ?? null,
5831
5944
  attemptNumber: workflow.attemptNumber ?? null,
5832
5945
  retryOf: workflow.retryOf ?? null
5833
5946
  });
5834
5947
  }
5948
+ var IDENTITY_KEYS = ["operationId", "attemptId", "retryOf", "attemptNumber"];
5949
+ function identityValuesEqual(a, b) {
5950
+ if (typeof a === "number" && typeof b === "number") {
5951
+ return Number.isFinite(a) && Number.isFinite(b) && a === b;
5952
+ }
5953
+ if (typeof a === "string" && typeof b === "string") {
5954
+ return a.trim() === b.trim();
5955
+ }
5956
+ return a === b;
5957
+ }
5958
+ function directNestedIdentityConflicts(event) {
5959
+ const attrs = event.attributes;
5960
+ if (!attrs || typeof attrs !== "object") return [];
5961
+ const nested = attrs.metadata && typeof attrs.metadata === "object" && !Array.isArray(attrs.metadata) ? attrs.metadata : void 0;
5962
+ if (!nested) return [];
5963
+ const conflicts = [];
5964
+ for (const key of IDENTITY_KEYS) {
5965
+ const direct = attrs[key];
5966
+ const nestedValue = nested[key];
5967
+ if (direct === void 0 || nestedValue === void 0) continue;
5968
+ if (!identityValuesEqual(direct, nestedValue)) {
5969
+ conflicts.push(key);
5970
+ }
5971
+ }
5972
+ return conflicts;
5973
+ }
5835
5974
  function hasConflictingAttemptIdReuse(members) {
5836
5975
  const byAttempt = /* @__PURE__ */ new Map();
5837
5976
  for (const event of members) {
@@ -5847,6 +5986,31 @@ function hasConflictingAttemptIdReuse(members) {
5847
5986
  }
5848
5987
  return false;
5849
5988
  }
5989
+ function hasConflictingEventIdReuse(members) {
5990
+ const byEventId = /* @__PURE__ */ new Map();
5991
+ for (const event of members) {
5992
+ if (event.kind !== "TOOL" && event.kind !== "LLM") continue;
5993
+ const eventId = event.eventId;
5994
+ if (!eventId) continue;
5995
+ if (hasDeliveryConflictMarker(event.attributes)) {
5996
+ return true;
5997
+ }
5998
+ const fingerprints = byEventId.get(eventId) ?? /* @__PURE__ */ new Set();
5999
+ fingerprints.add(redeliveryFingerprint(event));
6000
+ byEventId.set(eventId, fingerprints);
6001
+ }
6002
+ for (const fingerprints of byEventId.values()) {
6003
+ if (fingerprints.size > 1) return true;
6004
+ }
6005
+ return false;
6006
+ }
6007
+ function hasIdentityRepresentationConflict(members) {
6008
+ for (const event of members) {
6009
+ if (event.kind !== "TOOL" && event.kind !== "LLM") continue;
6010
+ if (directNestedIdentityConflicts(event).length > 0) return true;
6011
+ }
6012
+ return false;
6013
+ }
5850
6014
  function evaluateRetrySafetyRules(events, rules, _runEvidence) {
5851
6015
  const findings = [];
5852
6016
  const byOperation = /* @__PURE__ */ new Map();
@@ -5854,13 +6018,14 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
5854
6018
  const workflow = workflowFor(event);
5855
6019
  const operationId = workflow.operationId;
5856
6020
  if (!operationId) continue;
5857
- const list = byOperation.get(operationId) ?? [];
5858
- list.push(event);
5859
- byOperation.set(operationId, list);
6021
+ const key = `${event.runId}\0${operationId}`;
6022
+ const group = byOperation.get(key) ?? { operationId, members: [] };
6023
+ group.members.push(event);
6024
+ byOperation.set(key, group);
5860
6025
  }
5861
6026
  if (rules.maxAttempts !== void 0) {
5862
- for (const [operationId, members] of byOperation) {
5863
- if (hasConflictingAttemptIdReuse(members)) {
6027
+ for (const { operationId, members } of byOperation.values()) {
6028
+ if (hasConflictingAttemptIdReuse(members) || hasConflictingEventIdReuse(members)) {
5864
6029
  findings.push(
5865
6030
  fail2(
5866
6031
  "contract.retry.duplicate-attempt-id",
@@ -5871,6 +6036,31 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
5871
6036
  )
5872
6037
  );
5873
6038
  }
6039
+ if (hasIdentityRepresentationConflict(members)) {
6040
+ findings.push(
6041
+ fail2(
6042
+ "contract.retry.ambiguous-identity",
6043
+ `Operation ${operationId} has conflicting direct vs nested identity fields; strict identity cannot pass.`,
6044
+ members.slice(0, 4).map(eventEvidence),
6045
+ "agreeing identity representation",
6046
+ "direct/nested conflict"
6047
+ )
6048
+ );
6049
+ }
6050
+ const toolish = members.filter((event) => event.kind === "TOOL" || event.kind === "LLM");
6051
+ const hasAttemptId = toolish.some((event) => attemptIdOf(event) !== void 0);
6052
+ const missingAttemptId = toolish.some((event) => attemptIdOf(event) === void 0);
6053
+ if (hasAttemptId && missingAttemptId) {
6054
+ findings.push(
6055
+ fail2(
6056
+ "contract.retry.ambiguous-identity",
6057
+ `Operation ${operationId} has partial attempt identity; strict identity conformance cannot pass.`,
6058
+ members.slice(0, 4).map(eventEvidence),
6059
+ "complete attempt identity",
6060
+ "partial attemptId coverage"
6061
+ )
6062
+ );
6063
+ }
5874
6064
  const count = countOperationAttempts(members);
5875
6065
  if (count > rules.maxAttempts) {
5876
6066
  findings.push(
@@ -5886,7 +6076,7 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
5886
6076
  }
5887
6077
  }
5888
6078
  if (rules.requireTerminalResult) {
5889
- for (const [operationId, members] of byOperation) {
6079
+ for (const { operationId, members } of byOperation.values()) {
5890
6080
  const hasTerminal = members.some((event) => event.status === "ok" || event.status === "error");
5891
6081
  if (!hasTerminal) {
5892
6082
  findings.push(
@@ -5906,7 +6096,7 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
5906
6096
  const workflow = workflowFor(event);
5907
6097
  const fallbackOf = workflow.fallbackOf;
5908
6098
  if (!fallbackOf) continue;
5909
- const prior = byOperation.get(fallbackOf) ?? [];
6099
+ const prior = byOperation.get(`${event.runId}\0${fallbackOf}`)?.members ?? [];
5910
6100
  const fallbackStart = eventTime(event);
5911
6101
  const earlierFailure = prior.some(
5912
6102
  (candidate) => candidate.status === "error" && eventTime(candidate) !== "" && fallbackStart !== "" && eventTime(candidate) < fallbackStart
@@ -5933,7 +6123,7 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
5933
6123
  for (const event of toolEvents) {
5934
6124
  const name = resolveCanonicalToolName(event);
5935
6125
  const workflow = workflowFor(event);
5936
- const key = `${workflow.operationId ?? name}::${name}`;
6126
+ const key = `${event.runId}::${workflow.operationId ?? name}::${name}`;
5937
6127
  const list = byToolOp.get(key) ?? [];
5938
6128
  list.push(event);
5939
6129
  byToolOp.set(key, list);
@@ -5991,7 +6181,7 @@ function evaluateRetrySafetyRules(events, rules, _runEvidence) {
5991
6181
  }
5992
6182
  }
5993
6183
  if (rules.requireRecoveredFailureVisible) {
5994
- for (const [operationId, members] of byOperation) {
6184
+ for (const { operationId, members } of byOperation.values()) {
5995
6185
  const ordered = sortByTime(members);
5996
6186
  const toolish = ordered.filter(
5997
6187
  (event) => (event.kind === "TOOL" || event.kind === "LLM") && (event.status === "ok" || event.status === "error")
@@ -6250,14 +6440,7 @@ function attemptIdOf2(event) {
6250
6440
  return typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
6251
6441
  }
6252
6442
  function hasDuplicateAttemptIds(members) {
6253
- const seen = /* @__PURE__ */ new Set();
6254
- for (const event of members) {
6255
- const id = attemptIdOf2(event);
6256
- if (!id) continue;
6257
- if (seen.has(id)) return true;
6258
- seen.add(id);
6259
- }
6260
- return false;
6443
+ return hasConflictingAttemptIdReuse(members) || hasConflictingEventIdReuse(members);
6261
6444
  }
6262
6445
  function findRetryTarget(members, retryOf) {
6263
6446
  return members.find(
@@ -12200,7 +12383,47 @@ var TreeBuilder = class {
12200
12383
  const sorted = [...runEvents].sort((a, b) => a.timestamp - b.timestamp);
12201
12384
  const nodes = /* @__PURE__ */ new Map();
12202
12385
  for (const e of sorted) {
12203
- nodes.set(e.eventId, { event: e, children: [], depth: 0 });
12386
+ const existing = nodes.get(e.eventId);
12387
+ if (!existing) {
12388
+ nodes.set(e.eventId, { event: e, children: [], depth: 0 });
12389
+ continue;
12390
+ }
12391
+ const existingAttrs = existing.event.attributes && typeof existing.event.attributes === "object" ? existing.event.attributes : void 0;
12392
+ const nextAttrs = e.attributes && typeof e.attributes === "object" ? e.attributes : void 0;
12393
+ const existingIdentity = identityFieldsFromAttributes(existingAttrs);
12394
+ const nextIdentity = identityFieldsFromAttributes(nextAttrs);
12395
+ const existingFp = deliverySemanticFingerprint({
12396
+ eventId: existing.event.eventId,
12397
+ runId: existing.event.runId,
12398
+ kind: existing.event.kind,
12399
+ name: existing.event.name,
12400
+ status: existing.event.status,
12401
+ parentId: existing.event.parentId,
12402
+ timestamp: existing.event.timestamp,
12403
+ sourceType: existing.event.source?.type,
12404
+ attributes: existingAttrs,
12405
+ ...existingIdentity
12406
+ });
12407
+ const nextFp = deliverySemanticFingerprint({
12408
+ eventId: e.eventId,
12409
+ runId: e.runId,
12410
+ kind: e.kind,
12411
+ name: e.name,
12412
+ status: e.status,
12413
+ parentId: e.parentId,
12414
+ timestamp: e.timestamp,
12415
+ sourceType: e.source?.type,
12416
+ attributes: nextAttrs,
12417
+ ...nextIdentity
12418
+ });
12419
+ if (existingFp === nextFp) {
12420
+ continue;
12421
+ }
12422
+ nodes.set(e.eventId, {
12423
+ event: stampDeliveryConflict(e),
12424
+ children: [],
12425
+ depth: 0
12426
+ });
12204
12427
  }
12205
12428
  const { roots, summary } = linkNodesVisibilityFirst(nodes);
12206
12429
  const confidenceBreakdown = {
@@ -13665,6 +13888,12 @@ function promoteAgentInspectWorkflowIdentity(attributes, pathPrefix) {
13665
13888
  ["agent_inspect.retry_of", "retryOf", "string"],
13666
13889
  ["agent_inspect.attempt_number", "attemptNumber", "int"]
13667
13890
  ];
13891
+ const conflictMapping = [
13892
+ ["agent_inspect.identity_conflict.operation_id", "operationId", "string"],
13893
+ ["agent_inspect.identity_conflict.attempt_id", "attemptId", "string"],
13894
+ ["agent_inspect.identity_conflict.retry_of", "retryOf", "string"],
13895
+ ["agent_inspect.identity_conflict.attempt_number", "attemptNumber", "int"]
13896
+ ];
13668
13897
  const metadata = attributes.metadata && typeof attributes.metadata === "object" && !Array.isArray(attributes.metadata) ? { ...attributes.metadata } : {};
13669
13898
  for (const [dotted, camel, kind] of mapping) {
13670
13899
  const raw = attributes[dotted];
@@ -13716,6 +13945,46 @@ function promoteAgentInspectWorkflowIdentity(attributes, pathPrefix) {
13716
13945
  if (direct === void 0) attributes[camel] = promoted;
13717
13946
  if (nested === void 0) metadata[camel] = promoted;
13718
13947
  }
13948
+ for (const [dotted, camel, kind] of conflictMapping) {
13949
+ const raw = attributes[dotted];
13950
+ if (raw === void 0 || raw === null) continue;
13951
+ let alternate;
13952
+ if (kind === "int") {
13953
+ const n = typeof raw === "number" ? raw : typeof raw === "string" ? Number(raw) : NaN;
13954
+ if (!Number.isFinite(n) || n < 1) {
13955
+ warnings.push({
13956
+ code: "otlp_identity_invalid",
13957
+ message: `Ignoring invalid ${dotted} identity conflict value.`,
13958
+ severity: "warning",
13959
+ field: `${pathPrefix}.${dotted}`
13960
+ });
13961
+ continue;
13962
+ }
13963
+ alternate = Math.trunc(n);
13964
+ } else if (typeof raw === "string" && raw.trim() !== "") {
13965
+ alternate = raw.trim();
13966
+ } else {
13967
+ warnings.push({
13968
+ code: "otlp_identity_invalid",
13969
+ message: `Ignoring non-string ${dotted} identity conflict value.`,
13970
+ severity: "warning",
13971
+ field: `${pathPrefix}.${dotted}`
13972
+ });
13973
+ continue;
13974
+ }
13975
+ const preferred = attributes[camel];
13976
+ if (preferred !== void 0 && preferred !== alternate) {
13977
+ metadata[camel] = alternate;
13978
+ warnings.push({
13979
+ code: "otlp_identity_conflict",
13980
+ message: `Conflicting ${camel}: attributes.${camel} vs nested alternate from ${dotted}; retaining both.`,
13981
+ severity: "warning",
13982
+ field: `${pathPrefix}.${dotted}`
13983
+ });
13984
+ } else if (preferred === void 0) {
13985
+ metadata[camel] = alternate;
13986
+ }
13987
+ }
13719
13988
  if (Object.keys(metadata).length > 0) {
13720
13989
  attributes.metadata = metadata;
13721
13990
  }
@@ -15696,6 +15965,6 @@ function renderGateReport(result, options = {}) {
15696
15965
  return renderGateSummaryMarkdown(result);
15697
15966
  }
15698
15967
 
15699
- export { ATTRIBUTION_CONFIDENCES, COHORT_METRIC_IDS, DEFAULT_REDACT_KEYS, 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, defineTraceContract, diffRuns, diffTraceEvents, enrichSessionRunRecord, escapeHtml, escapeMarkdown, evaluateTraceContract, extractMetadata, extractOutcomesFromTraceEvents, filterMetasBySessionScope, filterTraces, flattenTree, formatDuration2 as formatDuration, formatStepLabel, formatTimestamp, gateHasThresholds, getIndent, getTraceFilePath, inferEvidenceFileRole, isAgentInspectTrace, isAttributionConfidence, isCredentialSensitiveKey, isPersistedInspectEvent, loadSessionRunRecords, loadSuiteConfig, loadTraceMetadataList, manualTraceEventsToComparableRun, nanoid, normalizeBundleOutputPath, openTrace, parseCohortMetricList, parseDuration, parseDurationFilter, parseGateList, parseTraceJsonl, persistedInspectEventsToRunTrees, persistedInspectEventsToTraceEvents, projectLogicalEvents, 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, stringContainsHighConfidenceCredential, summarizeObservedOutcomes, summarizeSemanticParity, traceEventToPersistedInspectEvent, truncateName, truncateStringForProfile, validateEvent, validateSuiteConfig, verifyEvidenceDirectory, zeroKinds };
15700
- //# sourceMappingURL=chunk-N5JN26MW.mjs.map
15701
- //# sourceMappingURL=chunk-N5JN26MW.mjs.map
15968
+ export { ATTRIBUTION_CONFIDENCES, COHORT_METRIC_IDS, DEFAULT_REDACT_KEYS, DEFAULT_SUITE_ARTIFACTS_DIR, DELIVERY_CONFLICT_ATTR, EVIDENCE_FORMAT_VERSION, EVIDENCE_HTML_FILENAME, EVIDENCE_MANIFEST_FILENAME, IDENTITY_CONFLICT_ATTR, 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, defineTraceContract, diffRuns, diffTraceEvents, enrichSessionRunRecord, escapeHtml, escapeMarkdown, evaluateTraceContract, extractMetadata, extractOutcomesFromTraceEvents, filterMetasBySessionScope, filterTraces, flattenTree, formatDuration2 as formatDuration, formatStepLabel, formatTimestamp, gateHasThresholds, getIndent, getTraceFilePath, inferEvidenceFileRole, isAgentInspectTrace, isAttributionConfidence, isCredentialSensitiveKey, isPersistedInspectEvent, loadSessionRunRecords, loadSuiteConfig, loadTraceMetadataList, manualTraceEventsToComparableRun, nanoid, normalizeBundleOutputPath, openTrace, parseCohortMetricList, parseDuration, parseDurationFilter, parseGateList, parseTraceJsonl, persistedInspectEventsToRunTrees, persistedInspectEventsToTraceEvents, projectLogicalEvents, 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, stringContainsHighConfidenceCredential, summarizeObservedOutcomes, summarizeSemanticParity, traceEventToPersistedInspectEvent, truncateName, truncateStringForProfile, validateEvent, validateSuiteConfig, verifyEvidenceDirectory, zeroKinds };
15969
+ //# sourceMappingURL=chunk-EMWA5EKU.mjs.map
15970
+ //# sourceMappingURL=chunk-EMWA5EKU.mjs.map