autotel-schema 11.0.1 → 13.0.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/dist/index.cjs CHANGED
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
  const require_snapshot = require('./snapshot-BJmrOlMK.cjs');
3
- const require_processor = require('./processor-C9NmN0wQ.cjs');
3
+ const require_processor = require('./processor-DQvVwsvP.cjs');
4
4
  const require_diff = require('./diff.cjs');
5
5
 
6
6
  //#region src/completeness.ts
@@ -43,7 +43,7 @@ function score(field, points, detail) {
43
43
  * Pass every span of one trace — the tree and count checks are meaningless on a
44
44
  * partial slice.
45
45
  */
46
- function scoreGenAiCompleteness(spans) {
46
+ function scoreGenAiCompleteness(spans, options = {}) {
47
47
  const fields = [];
48
48
  fields.push(anySpanHas(spans, "gen_ai.input.messages") ? score("llm_input", 1, "gen_ai.input.messages present") : score("llm_input", 0, "no span carries gen_ai.input.messages"));
49
49
  fields.push(anySpanHas(spans, "gen_ai.output.messages") ? score("llm_output", 1, "gen_ai.output.messages present") : score("llm_output", 0, "no span carries gen_ai.output.messages"));
@@ -81,18 +81,34 @@ function scoreGenAiCompleteness(spans) {
81
81
  if (spans.length >= 2) fields.push(score("span_count", 1, `${spans.length} spans`));
82
82
  else if (spans.length === 1) fields.push(score("span_count", .5, "single-span trace"));
83
83
  else fields.push(score("span_count", 0, "no spans"));
84
+ const blind = new Set(options.notCapturable);
85
+ for (const field of fields) if (blind.has(field.field)) field.notCapturable = true;
86
+ const scored = fields.filter((f) => !f.notCapturable);
87
+ const missing = scored.filter((f) => f.points === 0).map((f) => f.field);
88
+ const partial = scored.filter((f) => f.points === .5).map((f) => f.field);
89
+ const notCapturable = fields.filter((f) => f.notCapturable).map((f) => f.field);
84
90
  return {
85
- score: fields.reduce((sum, f) => sum + f.points, 0),
86
- max: GENAI_COMPLETENESS_FIELDS.length,
91
+ score: scored.reduce((sum, f) => sum + f.points, 0),
92
+ max: scored.length,
87
93
  fields,
88
- missing: fields.filter((f) => f.points === 0).map((f) => f.field),
89
- partial: fields.filter((f) => f.points === .5).map((f) => f.field)
94
+ missing,
95
+ partial,
96
+ notCapturable,
97
+ verdict: verdictFor(spans.length, notCapturable.length, missing.length + partial.length)
90
98
  };
91
99
  }
100
+ function verdictFor(spanCount, blindSpots, gaps) {
101
+ if (spanCount === 0) return "invalid";
102
+ if (blindSpots > 0) return "unknown";
103
+ if (gaps > 0) return "partial";
104
+ return "healthy";
105
+ }
92
106
  /** One line per field, for a CLI or a failed assertion. */
93
107
  function formatCompleteness(result) {
94
- return [`GenAI trace completeness: ${result.score}/${result.max}`, ...result.fields.map((f) => {
95
- return ` ${f.points === 1 ? "✓" : f.points === .5 ? "~" : "✗"} ${f.field} — ${f.detail}`;
108
+ return [`GenAI trace completeness: ${result.score}/${result.max} (${result.verdict})`, ...result.fields.map((f) => {
109
+ const mark = f.notCapturable ? "?" : f.points === 1 ? "✓" : f.points === .5 ? "~" : "✗";
110
+ const reason = f.notCapturable ? `not capturable here — ${f.detail}` : f.detail;
111
+ return ` ${mark} ${f.field} — ${reason}`;
96
112
  })].join("\n");
97
113
  }
98
114
 
@@ -188,6 +204,11 @@ const AGENT_SECURITY_TELEMETRY_CONTRACT = require_processor.defineContract({
188
204
  "revoked"
189
205
  ]
190
206
  },
207
+ "agent.consent.evidence": {
208
+ ...stringAttr,
209
+ enum: ["observed", "inferred"],
210
+ description: "Whether the consent outcome was witnessed or reconstructed. Defaults to inferred: no runtime reports the human click, so an approval deduced from the tool having run must never be cited as a human decision."
211
+ },
191
212
  "agent.scope.active": { ...stringArrayAttr },
192
213
  "agent.memory.operation": {
193
214
  ...stringAttr,
@@ -237,6 +258,65 @@ const AGENT_SECURITY_TELEMETRY_CONTRACT = require_processor.defineContract({
237
258
  "malicious"
238
259
  ]
239
260
  },
261
+ "detection.correlation_id": {
262
+ ...stringAttr,
263
+ highCardinality: true,
264
+ description: "Session the detection belongs to"
265
+ },
266
+ "detection.rule_id": {
267
+ ...stringAttr,
268
+ description: "Sequence rule that fired"
269
+ },
270
+ "detection.severity": {
271
+ ...stringAttr,
272
+ enum: [
273
+ "low",
274
+ "medium",
275
+ "high",
276
+ "critical"
277
+ ],
278
+ description: "Severity of the rule that fired"
279
+ },
280
+ "detection.first_at": {
281
+ ...numberAttr,
282
+ description: "Epoch ms of the first step matched by the rule"
283
+ },
284
+ "detection.last_at": {
285
+ ...numberAttr,
286
+ description: "Epoch ms of the last step matched by the rule"
287
+ },
288
+ "detection.steps": {
289
+ ...numberAttr,
290
+ description: "How many ordered steps the rule matched"
291
+ },
292
+ "detection.disposition.status": {
293
+ ...stringAttr,
294
+ enum: [
295
+ "new",
296
+ "acknowledged",
297
+ "in_progress",
298
+ "resolved",
299
+ "false_positive",
300
+ "risk_accepted"
301
+ ],
302
+ description: "Triage decision recorded against a detection"
303
+ },
304
+ "detection.disposition.note": {
305
+ ...stringAttr,
306
+ description: "Why the finding was closed. Required for false_positive and risk_accepted."
307
+ },
308
+ "detection.disposition.supersedes": {
309
+ ...stringAttr,
310
+ enum: [
311
+ "new",
312
+ "acknowledged",
313
+ "in_progress",
314
+ "resolved",
315
+ "false_positive",
316
+ "risk_accepted"
317
+ ],
318
+ description: "Status this decision replaces — dispositions are appended, never edited, so a reversal survives."
319
+ },
240
320
  "security.event": { ...stringAttr },
241
321
  "security.category": { ...stringAttr },
242
322
  "security.outcome": { ...stringAttr },
@@ -276,6 +356,7 @@ exports.AGENT_SECURITY_TELEMETRY_CONTRACT = AGENT_SECURITY_TELEMETRY_CONTRACT;
276
356
  exports.ATTRIBUTE_TYPES = require_processor.ATTRIBUTE_TYPES;
277
357
  exports.GENAI_COMPLETENESS_FIELDS = GENAI_COMPLETENESS_FIELDS;
278
358
  exports.SCHEMA_ATTRS = require_snapshot.SCHEMA_ATTRS;
359
+ exports.SCHEMA_VIOLATION_ATTRS = require_processor.SCHEMA_VIOLATION_ATTRS;
279
360
  exports.SNAPSHOT_SPEC = require_snapshot.SNAPSHOT_SPEC;
280
361
  exports.STABILITIES = require_processor.STABILITIES;
281
362
  exports.SchemaValidationSpanProcessor = require_processor.SchemaValidationSpanProcessor;
package/dist/index.d.cts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as diffSnapshots, c as ContractSnapshot, d as contractToSnapshot, f as parseSnapshot, g as SchemaAttributeKey, h as SNAPSHOT_SPEC, i as SnapshotDiff, l as SnapshotAttribute, m as SCHEMA_ATTRS, n as ChangeType, o as formatDiff, p as serializeSnapshot, r as SnapshotChange, s as hasBreakingChanges, t as ChangeKind, u as SnapshotSpan } from "./diff-B9GL_E28.cjs";
2
2
  import { A as validateScenarioSpec, C as ScenarioViolationCode, D as isScenarioClosed, E as formatScenarioResult, F as ViolationCode, I as ViolationSeverity, L as formatViolation, M as EmittedSpan, N as SchemaViolation, O as parseCardinality, P as ValidateOptions, R as hasErrors, S as ScenarioViolation, T as evaluateScenario, _ as ScenarioOutcome, a as SpanSpec, b as ScenarioSpan, c as allowsAdditionalAttributes, d as Cardinality, f as CheckScenarioOptions, g as ScenarioEventSpec, h as ScenarioAddition, i as STABILITIES, j as EmittedAttributeValue, k as proposeScenario, l as defineContract, m as EvaluateScenarioOptions, n as AttributeSpec, o as Stability, p as CompletionBoundary, r as AttributeType, s as TelemetryContract, t as ATTRIBUTE_TYPES, u as resolveAttributeSpec, v as ScenarioProposal, w as checkScenario, x as ScenarioSpec, y as ScenarioResult, z as validateSpan } from "./contract-CfOaZcD0.cjs";
3
- import { OtelContext, ReadableSpanLike, SchemaProcessorMode, SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, SpanLike, SpanProcessorLike, createSchemaValidationProcessor } from "./processor.cjs";
3
+ import { OtelContext, ReadableSpanLike, SCHEMA_VIOLATION_ATTRS, SchemaProcessorMode, SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, SpanLike, SpanProcessorLike, createSchemaValidationProcessor } from "./processor.cjs";
4
4
  //#region src/completeness.d.ts
5
5
  /** The ten fields a GenAI trace is scored on. */
6
6
  declare const GENAI_COMPLETENESS_FIELDS: readonly ["llm_input", "llm_output", "model_name", "token_usage", "cost_usd", "latency_per_span", "tool_call_args", "tool_call_results", "span_tree", "span_count"];
@@ -11,16 +11,49 @@ interface FieldScore {
11
11
  points: 0 | 0.5 | 1;
12
12
  /** Why the field scored what it did — shown to whoever has to fix it. */
13
13
  detail: string;
14
+ /**
15
+ * The deployment declared it cannot capture this field. Excluded from both
16
+ * `score` and `max`: scoring a blind spot as a failure tells the reader to go
17
+ * fix instrumentation that was never able to see it.
18
+ */
19
+ notCapturable?: true;
20
+ }
21
+ /**
22
+ * How much of a story this trace can support.
23
+ *
24
+ * - `invalid` — no spans. Nothing here supports any claim.
25
+ * - `unknown` — a capture blind spot was declared, so the record cannot account
26
+ * for its own gaps whatever else it scored.
27
+ * - `partial` — everything observable was observable, and some of it is absent.
28
+ * - `healthy` — every capturable field landed, and no blind spot was declared.
29
+ *
30
+ * `unknown` outranks `partial` deliberately: knowing what you missed is a
31
+ * stronger position than not knowing what you missed.
32
+ */
33
+ type CompletenessVerdict = 'healthy' | 'partial' | 'unknown' | 'invalid';
34
+ interface CompletenessOptions {
35
+ /**
36
+ * Fields this deployment cannot capture at all — a provider that never
37
+ * returns token counts, a runtime with no way to see tool results.
38
+ *
39
+ * Derive it from the `autotel.coverage.unobserved` resource attribute, or
40
+ * declare it in the test that asserts on the trace.
41
+ */
42
+ notCapturable?: readonly GenAiCompletenessField[];
14
43
  }
15
44
  interface CompletenessResult {
16
- /** Total points, 0–10. */
45
+ /** Points earned across the capturable fields. */
17
46
  score: number;
47
+ /** Points available: ten, less the fields declared not capturable. */
18
48
  max: number;
19
49
  fields: FieldScore[];
20
- /** Fields that scored 0. */
50
+ /** Capturable fields that scored 0. */
21
51
  missing: GenAiCompletenessField[];
22
- /** Fields that scored 0.5. */
52
+ /** Capturable fields that scored 0.5. */
23
53
  partial: GenAiCompletenessField[];
54
+ /** Fields excluded from scoring because the deployment cannot see them. */
55
+ notCapturable: GenAiCompletenessField[];
56
+ verdict: CompletenessVerdict;
24
57
  }
25
58
  /**
26
59
  * Score a single trace's spans against the ten-field checklist.
@@ -28,7 +61,7 @@ interface CompletenessResult {
28
61
  * Pass every span of one trace — the tree and count checks are meaningless on a
29
62
  * partial slice.
30
63
  */
31
- declare function scoreGenAiCompleteness(spans: ScenarioSpan[]): CompletenessResult;
64
+ declare function scoreGenAiCompleteness(spans: ScenarioSpan[], options?: CompletenessOptions): CompletenessResult;
32
65
  /** One line per field, for a CLI or a failed assertion. */
33
66
  declare function formatCompleteness(result: CompletenessResult): string;
34
67
  //#endregion
@@ -66,4 +99,4 @@ declare function isHighCardinalityKey(contract: TelemetryContract, key: string):
66
99
  */
67
100
  declare const AGENT_SECURITY_TELEMETRY_CONTRACT: TelemetryContract;
68
101
  //#endregion
69
- export { AGENT_SECURITY_TELEMETRY_CONTRACT, ATTRIBUTE_TYPES, type AttributeSpec, type AttributeType, type Cardinality, type ChangeKind, type ChangeType, type CheckScenarioOptions, type CompletenessResult, type CompletionBoundary, type ContractSnapshot, type EmittedAttributeValue, type EmittedSpan, type EvaluateScenarioOptions, type FieldScore, GENAI_COMPLETENESS_FIELDS, type GenAiCompletenessField, type OtelContext, type ReadableSpanLike, SCHEMA_ATTRS, SNAPSHOT_SPEC, STABILITIES, type ScenarioAddition, type ScenarioEventSpec, type ScenarioOutcome, type ScenarioProposal, type ScenarioResult, type ScenarioSpan, type ScenarioSpec, type ScenarioViolation, type ScenarioViolationCode, type SchemaAttributeKey, type SchemaProcessorMode, type SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, type SchemaViolation, type SnapshotAttribute, type SnapshotChange, type SnapshotDiff, type SnapshotSpan, type SpanLike, type SpanProcessorLike, type SpanSpec, type Stability, type TelemetryContract, type ValidateOptions, type ViolationCode, type ViolationSeverity, allowsAdditionalAttributes, checkScenario, contractToSnapshot, createSchemaValidationProcessor, defineContract, diffSnapshots, evaluateScenario, formatCompleteness, formatDiff, formatScenarioResult, formatViolation, hasBreakingChanges, hasErrors, highCardinalityKeys, isHighCardinalityKey, isScenarioClosed, parseCardinality, parseSnapshot, proposeScenario, resolveAttributeSpec, scoreGenAiCompleteness, serializeSnapshot, validateScenarioSpec, validateSpan };
102
+ export { AGENT_SECURITY_TELEMETRY_CONTRACT, ATTRIBUTE_TYPES, type AttributeSpec, type AttributeType, type Cardinality, type ChangeKind, type ChangeType, type CheckScenarioOptions, type CompletenessOptions, type CompletenessResult, type CompletenessVerdict, type CompletionBoundary, type ContractSnapshot, type EmittedAttributeValue, type EmittedSpan, type EvaluateScenarioOptions, type FieldScore, GENAI_COMPLETENESS_FIELDS, type GenAiCompletenessField, type OtelContext, type ReadableSpanLike, SCHEMA_ATTRS, SCHEMA_VIOLATION_ATTRS, SNAPSHOT_SPEC, STABILITIES, type ScenarioAddition, type ScenarioEventSpec, type ScenarioOutcome, type ScenarioProposal, type ScenarioResult, type ScenarioSpan, type ScenarioSpec, type ScenarioViolation, type ScenarioViolationCode, type SchemaAttributeKey, type SchemaProcessorMode, type SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, type SchemaViolation, type SnapshotAttribute, type SnapshotChange, type SnapshotDiff, type SnapshotSpan, type SpanLike, type SpanProcessorLike, type SpanSpec, type Stability, type TelemetryContract, type ValidateOptions, type ViolationCode, type ViolationSeverity, allowsAdditionalAttributes, checkScenario, contractToSnapshot, createSchemaValidationProcessor, defineContract, diffSnapshots, evaluateScenario, formatCompleteness, formatDiff, formatScenarioResult, formatViolation, hasBreakingChanges, hasErrors, highCardinalityKeys, isHighCardinalityKey, isScenarioClosed, parseCardinality, parseSnapshot, proposeScenario, resolveAttributeSpec, scoreGenAiCompleteness, serializeSnapshot, validateScenarioSpec, validateSpan };
package/dist/index.d.ts CHANGED
@@ -1,6 +1,6 @@
1
1
  import { a as diffSnapshots, c as ContractSnapshot, d as contractToSnapshot, f as parseSnapshot, g as SchemaAttributeKey, h as SNAPSHOT_SPEC, i as SnapshotDiff, l as SnapshotAttribute, m as SCHEMA_ATTRS, n as ChangeType, o as formatDiff, p as serializeSnapshot, r as SnapshotChange, s as hasBreakingChanges, t as ChangeKind, u as SnapshotSpan } from "./diff-DenUg42T.js";
2
2
  import { A as validateScenarioSpec, C as ScenarioViolationCode, D as isScenarioClosed, E as formatScenarioResult, F as ViolationCode, I as ViolationSeverity, L as formatViolation, M as EmittedSpan, N as SchemaViolation, O as parseCardinality, P as ValidateOptions, R as hasErrors, S as ScenarioViolation, T as evaluateScenario, _ as ScenarioOutcome, a as SpanSpec, b as ScenarioSpan, c as allowsAdditionalAttributes, d as Cardinality, f as CheckScenarioOptions, g as ScenarioEventSpec, h as ScenarioAddition, i as STABILITIES, j as EmittedAttributeValue, k as proposeScenario, l as defineContract, m as EvaluateScenarioOptions, n as AttributeSpec, o as Stability, p as CompletionBoundary, r as AttributeType, s as TelemetryContract, t as ATTRIBUTE_TYPES, u as resolveAttributeSpec, v as ScenarioProposal, w as checkScenario, x as ScenarioSpec, y as ScenarioResult, z as validateSpan } from "./contract-CfOaZcD0.js";
3
- import { OtelContext, ReadableSpanLike, SchemaProcessorMode, SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, SpanLike, SpanProcessorLike, createSchemaValidationProcessor } from "./processor.js";
3
+ import { OtelContext, ReadableSpanLike, SCHEMA_VIOLATION_ATTRS, SchemaProcessorMode, SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, SpanLike, SpanProcessorLike, createSchemaValidationProcessor } from "./processor.js";
4
4
  //#region src/completeness.d.ts
5
5
  /** The ten fields a GenAI trace is scored on. */
6
6
  declare const GENAI_COMPLETENESS_FIELDS: readonly ["llm_input", "llm_output", "model_name", "token_usage", "cost_usd", "latency_per_span", "tool_call_args", "tool_call_results", "span_tree", "span_count"];
@@ -11,16 +11,49 @@ interface FieldScore {
11
11
  points: 0 | 0.5 | 1;
12
12
  /** Why the field scored what it did — shown to whoever has to fix it. */
13
13
  detail: string;
14
+ /**
15
+ * The deployment declared it cannot capture this field. Excluded from both
16
+ * `score` and `max`: scoring a blind spot as a failure tells the reader to go
17
+ * fix instrumentation that was never able to see it.
18
+ */
19
+ notCapturable?: true;
20
+ }
21
+ /**
22
+ * How much of a story this trace can support.
23
+ *
24
+ * - `invalid` — no spans. Nothing here supports any claim.
25
+ * - `unknown` — a capture blind spot was declared, so the record cannot account
26
+ * for its own gaps whatever else it scored.
27
+ * - `partial` — everything observable was observable, and some of it is absent.
28
+ * - `healthy` — every capturable field landed, and no blind spot was declared.
29
+ *
30
+ * `unknown` outranks `partial` deliberately: knowing what you missed is a
31
+ * stronger position than not knowing what you missed.
32
+ */
33
+ type CompletenessVerdict = 'healthy' | 'partial' | 'unknown' | 'invalid';
34
+ interface CompletenessOptions {
35
+ /**
36
+ * Fields this deployment cannot capture at all — a provider that never
37
+ * returns token counts, a runtime with no way to see tool results.
38
+ *
39
+ * Derive it from the `autotel.coverage.unobserved` resource attribute, or
40
+ * declare it in the test that asserts on the trace.
41
+ */
42
+ notCapturable?: readonly GenAiCompletenessField[];
14
43
  }
15
44
  interface CompletenessResult {
16
- /** Total points, 0–10. */
45
+ /** Points earned across the capturable fields. */
17
46
  score: number;
47
+ /** Points available: ten, less the fields declared not capturable. */
18
48
  max: number;
19
49
  fields: FieldScore[];
20
- /** Fields that scored 0. */
50
+ /** Capturable fields that scored 0. */
21
51
  missing: GenAiCompletenessField[];
22
- /** Fields that scored 0.5. */
52
+ /** Capturable fields that scored 0.5. */
23
53
  partial: GenAiCompletenessField[];
54
+ /** Fields excluded from scoring because the deployment cannot see them. */
55
+ notCapturable: GenAiCompletenessField[];
56
+ verdict: CompletenessVerdict;
24
57
  }
25
58
  /**
26
59
  * Score a single trace's spans against the ten-field checklist.
@@ -28,7 +61,7 @@ interface CompletenessResult {
28
61
  * Pass every span of one trace — the tree and count checks are meaningless on a
29
62
  * partial slice.
30
63
  */
31
- declare function scoreGenAiCompleteness(spans: ScenarioSpan[]): CompletenessResult;
64
+ declare function scoreGenAiCompleteness(spans: ScenarioSpan[], options?: CompletenessOptions): CompletenessResult;
32
65
  /** One line per field, for a CLI or a failed assertion. */
33
66
  declare function formatCompleteness(result: CompletenessResult): string;
34
67
  //#endregion
@@ -66,4 +99,4 @@ declare function isHighCardinalityKey(contract: TelemetryContract, key: string):
66
99
  */
67
100
  declare const AGENT_SECURITY_TELEMETRY_CONTRACT: TelemetryContract;
68
101
  //#endregion
69
- export { AGENT_SECURITY_TELEMETRY_CONTRACT, ATTRIBUTE_TYPES, type AttributeSpec, type AttributeType, type Cardinality, type ChangeKind, type ChangeType, type CheckScenarioOptions, type CompletenessResult, type CompletionBoundary, type ContractSnapshot, type EmittedAttributeValue, type EmittedSpan, type EvaluateScenarioOptions, type FieldScore, GENAI_COMPLETENESS_FIELDS, type GenAiCompletenessField, type OtelContext, type ReadableSpanLike, SCHEMA_ATTRS, SNAPSHOT_SPEC, STABILITIES, type ScenarioAddition, type ScenarioEventSpec, type ScenarioOutcome, type ScenarioProposal, type ScenarioResult, type ScenarioSpan, type ScenarioSpec, type ScenarioViolation, type ScenarioViolationCode, type SchemaAttributeKey, type SchemaProcessorMode, type SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, type SchemaViolation, type SnapshotAttribute, type SnapshotChange, type SnapshotDiff, type SnapshotSpan, type SpanLike, type SpanProcessorLike, type SpanSpec, type Stability, type TelemetryContract, type ValidateOptions, type ViolationCode, type ViolationSeverity, allowsAdditionalAttributes, checkScenario, contractToSnapshot, createSchemaValidationProcessor, defineContract, diffSnapshots, evaluateScenario, formatCompleteness, formatDiff, formatScenarioResult, formatViolation, hasBreakingChanges, hasErrors, highCardinalityKeys, isHighCardinalityKey, isScenarioClosed, parseCardinality, parseSnapshot, proposeScenario, resolveAttributeSpec, scoreGenAiCompleteness, serializeSnapshot, validateScenarioSpec, validateSpan };
102
+ export { AGENT_SECURITY_TELEMETRY_CONTRACT, ATTRIBUTE_TYPES, type AttributeSpec, type AttributeType, type Cardinality, type ChangeKind, type ChangeType, type CheckScenarioOptions, type CompletenessOptions, type CompletenessResult, type CompletenessVerdict, type CompletionBoundary, type ContractSnapshot, type EmittedAttributeValue, type EmittedSpan, type EvaluateScenarioOptions, type FieldScore, GENAI_COMPLETENESS_FIELDS, type GenAiCompletenessField, type OtelContext, type ReadableSpanLike, SCHEMA_ATTRS, SCHEMA_VIOLATION_ATTRS, SNAPSHOT_SPEC, STABILITIES, type ScenarioAddition, type ScenarioEventSpec, type ScenarioOutcome, type ScenarioProposal, type ScenarioResult, type ScenarioSpan, type ScenarioSpec, type ScenarioViolation, type ScenarioViolationCode, type SchemaAttributeKey, type SchemaProcessorMode, type SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, type SchemaViolation, type SnapshotAttribute, type SnapshotChange, type SnapshotDiff, type SnapshotSpan, type SpanLike, type SpanProcessorLike, type SpanSpec, type Stability, type TelemetryContract, type ValidateOptions, type ViolationCode, type ViolationSeverity, allowsAdditionalAttributes, checkScenario, contractToSnapshot, createSchemaValidationProcessor, defineContract, diffSnapshots, evaluateScenario, formatCompleteness, formatDiff, formatScenarioResult, formatViolation, hasBreakingChanges, hasErrors, highCardinalityKeys, isHighCardinalityKey, isScenarioClosed, parseCardinality, parseSnapshot, proposeScenario, resolveAttributeSpec, scoreGenAiCompleteness, serializeSnapshot, validateScenarioSpec, validateSpan };
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { a as SNAPSHOT_SPEC, i as SCHEMA_ATTRS, n as parseSnapshot, r as serializeSnapshot, t as contractToSnapshot } from "./snapshot-BFIxChH0.js";
2
- import { _ as validateScenarioSpec, a as validateSpan, c as allowsAdditionalAttributes, d as checkScenario, f as evaluateScenario, g as proposeScenario, h as parseCardinality, i as hasErrors, l as defineContract, m as isScenarioClosed, n as createSchemaValidationProcessor, o as ATTRIBUTE_TYPES, p as formatScenarioResult, r as formatViolation, s as STABILITIES, t as SchemaValidationSpanProcessor, u as resolveAttributeSpec } from "./processor-Cn0HNUvw.js";
2
+ import { _ as proposeScenario, a as hasErrors, c as STABILITIES, d as resolveAttributeSpec, f as checkScenario, g as parseCardinality, h as isScenarioClosed, i as formatViolation, l as allowsAdditionalAttributes, m as formatScenarioResult, n as SchemaValidationSpanProcessor, o as validateSpan, p as evaluateScenario, r as createSchemaValidationProcessor, s as ATTRIBUTE_TYPES, t as SCHEMA_VIOLATION_ATTRS, u as defineContract, v as validateScenarioSpec } from "./processor-PQss56h3.js";
3
3
  import { diffSnapshots, formatDiff, hasBreakingChanges } from "./diff.js";
4
4
 
5
5
  //#region src/completeness.ts
@@ -42,7 +42,7 @@ function score(field, points, detail) {
42
42
  * Pass every span of one trace — the tree and count checks are meaningless on a
43
43
  * partial slice.
44
44
  */
45
- function scoreGenAiCompleteness(spans) {
45
+ function scoreGenAiCompleteness(spans, options = {}) {
46
46
  const fields = [];
47
47
  fields.push(anySpanHas(spans, "gen_ai.input.messages") ? score("llm_input", 1, "gen_ai.input.messages present") : score("llm_input", 0, "no span carries gen_ai.input.messages"));
48
48
  fields.push(anySpanHas(spans, "gen_ai.output.messages") ? score("llm_output", 1, "gen_ai.output.messages present") : score("llm_output", 0, "no span carries gen_ai.output.messages"));
@@ -80,18 +80,34 @@ function scoreGenAiCompleteness(spans) {
80
80
  if (spans.length >= 2) fields.push(score("span_count", 1, `${spans.length} spans`));
81
81
  else if (spans.length === 1) fields.push(score("span_count", .5, "single-span trace"));
82
82
  else fields.push(score("span_count", 0, "no spans"));
83
+ const blind = new Set(options.notCapturable);
84
+ for (const field of fields) if (blind.has(field.field)) field.notCapturable = true;
85
+ const scored = fields.filter((f) => !f.notCapturable);
86
+ const missing = scored.filter((f) => f.points === 0).map((f) => f.field);
87
+ const partial = scored.filter((f) => f.points === .5).map((f) => f.field);
88
+ const notCapturable = fields.filter((f) => f.notCapturable).map((f) => f.field);
83
89
  return {
84
- score: fields.reduce((sum, f) => sum + f.points, 0),
85
- max: GENAI_COMPLETENESS_FIELDS.length,
90
+ score: scored.reduce((sum, f) => sum + f.points, 0),
91
+ max: scored.length,
86
92
  fields,
87
- missing: fields.filter((f) => f.points === 0).map((f) => f.field),
88
- partial: fields.filter((f) => f.points === .5).map((f) => f.field)
93
+ missing,
94
+ partial,
95
+ notCapturable,
96
+ verdict: verdictFor(spans.length, notCapturable.length, missing.length + partial.length)
89
97
  };
90
98
  }
99
+ function verdictFor(spanCount, blindSpots, gaps) {
100
+ if (spanCount === 0) return "invalid";
101
+ if (blindSpots > 0) return "unknown";
102
+ if (gaps > 0) return "partial";
103
+ return "healthy";
104
+ }
91
105
  /** One line per field, for a CLI or a failed assertion. */
92
106
  function formatCompleteness(result) {
93
- return [`GenAI trace completeness: ${result.score}/${result.max}`, ...result.fields.map((f) => {
94
- return ` ${f.points === 1 ? "✓" : f.points === .5 ? "~" : "✗"} ${f.field} — ${f.detail}`;
107
+ return [`GenAI trace completeness: ${result.score}/${result.max} (${result.verdict})`, ...result.fields.map((f) => {
108
+ const mark = f.notCapturable ? "?" : f.points === 1 ? "✓" : f.points === .5 ? "~" : "✗";
109
+ const reason = f.notCapturable ? `not capturable here — ${f.detail}` : f.detail;
110
+ return ` ${mark} ${f.field} — ${reason}`;
95
111
  })].join("\n");
96
112
  }
97
113
 
@@ -187,6 +203,11 @@ const AGENT_SECURITY_TELEMETRY_CONTRACT = defineContract({
187
203
  "revoked"
188
204
  ]
189
205
  },
206
+ "agent.consent.evidence": {
207
+ ...stringAttr,
208
+ enum: ["observed", "inferred"],
209
+ description: "Whether the consent outcome was witnessed or reconstructed. Defaults to inferred: no runtime reports the human click, so an approval deduced from the tool having run must never be cited as a human decision."
210
+ },
190
211
  "agent.scope.active": { ...stringArrayAttr },
191
212
  "agent.memory.operation": {
192
213
  ...stringAttr,
@@ -236,6 +257,65 @@ const AGENT_SECURITY_TELEMETRY_CONTRACT = defineContract({
236
257
  "malicious"
237
258
  ]
238
259
  },
260
+ "detection.correlation_id": {
261
+ ...stringAttr,
262
+ highCardinality: true,
263
+ description: "Session the detection belongs to"
264
+ },
265
+ "detection.rule_id": {
266
+ ...stringAttr,
267
+ description: "Sequence rule that fired"
268
+ },
269
+ "detection.severity": {
270
+ ...stringAttr,
271
+ enum: [
272
+ "low",
273
+ "medium",
274
+ "high",
275
+ "critical"
276
+ ],
277
+ description: "Severity of the rule that fired"
278
+ },
279
+ "detection.first_at": {
280
+ ...numberAttr,
281
+ description: "Epoch ms of the first step matched by the rule"
282
+ },
283
+ "detection.last_at": {
284
+ ...numberAttr,
285
+ description: "Epoch ms of the last step matched by the rule"
286
+ },
287
+ "detection.steps": {
288
+ ...numberAttr,
289
+ description: "How many ordered steps the rule matched"
290
+ },
291
+ "detection.disposition.status": {
292
+ ...stringAttr,
293
+ enum: [
294
+ "new",
295
+ "acknowledged",
296
+ "in_progress",
297
+ "resolved",
298
+ "false_positive",
299
+ "risk_accepted"
300
+ ],
301
+ description: "Triage decision recorded against a detection"
302
+ },
303
+ "detection.disposition.note": {
304
+ ...stringAttr,
305
+ description: "Why the finding was closed. Required for false_positive and risk_accepted."
306
+ },
307
+ "detection.disposition.supersedes": {
308
+ ...stringAttr,
309
+ enum: [
310
+ "new",
311
+ "acknowledged",
312
+ "in_progress",
313
+ "resolved",
314
+ "false_positive",
315
+ "risk_accepted"
316
+ ],
317
+ description: "Status this decision replaces — dispositions are appended, never edited, so a reversal survives."
318
+ },
239
319
  "security.event": { ...stringAttr },
240
320
  "security.category": { ...stringAttr },
241
321
  "security.outcome": { ...stringAttr },
@@ -271,4 +351,4 @@ const AGENT_SECURITY_TELEMETRY_CONTRACT = defineContract({
271
351
  });
272
352
 
273
353
  //#endregion
274
- export { AGENT_SECURITY_TELEMETRY_CONTRACT, ATTRIBUTE_TYPES, GENAI_COMPLETENESS_FIELDS, SCHEMA_ATTRS, SNAPSHOT_SPEC, STABILITIES, SchemaValidationSpanProcessor, allowsAdditionalAttributes, checkScenario, contractToSnapshot, createSchemaValidationProcessor, defineContract, diffSnapshots, evaluateScenario, formatCompleteness, formatDiff, formatScenarioResult, formatViolation, hasBreakingChanges, hasErrors, highCardinalityKeys, isHighCardinalityKey, isScenarioClosed, parseCardinality, parseSnapshot, proposeScenario, resolveAttributeSpec, scoreGenAiCompleteness, serializeSnapshot, validateScenarioSpec, validateSpan };
354
+ export { AGENT_SECURITY_TELEMETRY_CONTRACT, ATTRIBUTE_TYPES, GENAI_COMPLETENESS_FIELDS, SCHEMA_ATTRS, SCHEMA_VIOLATION_ATTRS, SNAPSHOT_SPEC, STABILITIES, SchemaValidationSpanProcessor, allowsAdditionalAttributes, checkScenario, contractToSnapshot, createSchemaValidationProcessor, defineContract, diffSnapshots, evaluateScenario, formatCompleteness, formatDiff, formatScenarioResult, formatViolation, hasBreakingChanges, hasErrors, highCardinalityKeys, isHighCardinalityKey, isScenarioClosed, parseCardinality, parseSnapshot, proposeScenario, resolveAttributeSpec, scoreGenAiCompleteness, serializeSnapshot, validateScenarioSpec, validateSpan };
@@ -566,6 +566,20 @@ function formatViolation(v) {
566
566
  * but `enabledInProduction` is there if you want a sampled canary in prod.
567
567
  */
568
568
  const DEFAULT_WARN_INTERVAL_MS = 6e4;
569
+ /**
570
+ * How many violation codes a single span carries.
571
+ *
572
+ * The count attribute stays exact, so trimming the list loses detail but never
573
+ * misleads about scale. Without a cap, one span against a wide contract could
574
+ * carry hundreds of strings into every exporter downstream.
575
+ */
576
+ const MAX_STAMPED_CODES = 20;
577
+ /** Attributes written onto a span carrying contract violations. */
578
+ const SCHEMA_VIOLATION_ATTRS = {
579
+ count: "autotel.schema.violations",
580
+ severity: "autotel.schema.violation.severity",
581
+ codes: "autotel.schema.violation.codes"
582
+ };
569
583
  function isProduction() {
570
584
  return process.env.NODE_ENV === "production";
571
585
  }
@@ -600,12 +614,30 @@ var SchemaValidationSpanProcessor = class {
600
614
  } catch {
601
615
  return;
602
616
  }
617
+ if (this.opts.stampViolations) this.stamp(span, violations);
603
618
  for (const violation of violations) {
604
619
  this.violationCount++;
605
620
  this.opts.onViolation?.(violation, span);
606
621
  this.handle(violation);
607
622
  }
608
623
  }
624
+ /**
625
+ * Record the violations on the span itself.
626
+ *
627
+ * A conforming span is left alone rather than marked with a zero: the
628
+ * presence of the attribute is what a reader filters on, and stamping every
629
+ * span would make `autotel.schema.violations` mean nothing while costing
630
+ * payload on the spans that are fine.
631
+ */
632
+ stamp(span, violations) {
633
+ if (violations.length === 0) return;
634
+ try {
635
+ const worst = violations.some((v) => v.severity === "error") ? "error" : "warning";
636
+ span.attributes[SCHEMA_VIOLATION_ATTRS.count] = violations.length;
637
+ span.attributes[SCHEMA_VIOLATION_ATTRS.severity] = worst;
638
+ span.attributes[SCHEMA_VIOLATION_ATTRS.codes] = violations.slice(0, MAX_STAMPED_CODES).map((v) => v.attribute ? `${v.code}:${v.attribute}` : v.code);
639
+ } catch {}
640
+ }
609
641
  handle(violation) {
610
642
  const mode = this.opts.mode ?? "warn";
611
643
  if (mode === "silent") return;
@@ -638,6 +670,12 @@ Object.defineProperty(exports, 'ATTRIBUTE_TYPES', {
638
670
  return ATTRIBUTE_TYPES;
639
671
  }
640
672
  });
673
+ Object.defineProperty(exports, 'SCHEMA_VIOLATION_ATTRS', {
674
+ enumerable: true,
675
+ get: function () {
676
+ return SCHEMA_VIOLATION_ATTRS;
677
+ }
678
+ });
641
679
  Object.defineProperty(exports, 'STABILITIES', {
642
680
  enumerable: true,
643
681
  get: function () {
@@ -565,6 +565,20 @@ function formatViolation(v) {
565
565
  * but `enabledInProduction` is there if you want a sampled canary in prod.
566
566
  */
567
567
  const DEFAULT_WARN_INTERVAL_MS = 6e4;
568
+ /**
569
+ * How many violation codes a single span carries.
570
+ *
571
+ * The count attribute stays exact, so trimming the list loses detail but never
572
+ * misleads about scale. Without a cap, one span against a wide contract could
573
+ * carry hundreds of strings into every exporter downstream.
574
+ */
575
+ const MAX_STAMPED_CODES = 20;
576
+ /** Attributes written onto a span carrying contract violations. */
577
+ const SCHEMA_VIOLATION_ATTRS = {
578
+ count: "autotel.schema.violations",
579
+ severity: "autotel.schema.violation.severity",
580
+ codes: "autotel.schema.violation.codes"
581
+ };
568
582
  function isProduction() {
569
583
  return process.env.NODE_ENV === "production";
570
584
  }
@@ -599,12 +613,30 @@ var SchemaValidationSpanProcessor = class {
599
613
  } catch {
600
614
  return;
601
615
  }
616
+ if (this.opts.stampViolations) this.stamp(span, violations);
602
617
  for (const violation of violations) {
603
618
  this.violationCount++;
604
619
  this.opts.onViolation?.(violation, span);
605
620
  this.handle(violation);
606
621
  }
607
622
  }
623
+ /**
624
+ * Record the violations on the span itself.
625
+ *
626
+ * A conforming span is left alone rather than marked with a zero: the
627
+ * presence of the attribute is what a reader filters on, and stamping every
628
+ * span would make `autotel.schema.violations` mean nothing while costing
629
+ * payload on the spans that are fine.
630
+ */
631
+ stamp(span, violations) {
632
+ if (violations.length === 0) return;
633
+ try {
634
+ const worst = violations.some((v) => v.severity === "error") ? "error" : "warning";
635
+ span.attributes[SCHEMA_VIOLATION_ATTRS.count] = violations.length;
636
+ span.attributes[SCHEMA_VIOLATION_ATTRS.severity] = worst;
637
+ span.attributes[SCHEMA_VIOLATION_ATTRS.codes] = violations.slice(0, MAX_STAMPED_CODES).map((v) => v.attribute ? `${v.code}:${v.attribute}` : v.code);
638
+ } catch {}
639
+ }
608
640
  handle(violation) {
609
641
  const mode = this.opts.mode ?? "warn";
610
642
  if (mode === "silent") return;
@@ -631,4 +663,4 @@ function createSchemaValidationProcessor(opts) {
631
663
  }
632
664
 
633
665
  //#endregion
634
- export { validateScenarioSpec as _, validateSpan as a, allowsAdditionalAttributes as c, checkScenario as d, evaluateScenario as f, proposeScenario as g, parseCardinality as h, hasErrors as i, defineContract as l, isScenarioClosed as m, createSchemaValidationProcessor as n, ATTRIBUTE_TYPES as o, formatScenarioResult as p, formatViolation as r, STABILITIES as s, SchemaValidationSpanProcessor as t, resolveAttributeSpec as u };
666
+ export { proposeScenario as _, hasErrors as a, STABILITIES as c, resolveAttributeSpec as d, checkScenario as f, parseCardinality as g, isScenarioClosed as h, formatViolation as i, allowsAdditionalAttributes as l, formatScenarioResult as m, SchemaValidationSpanProcessor as n, validateSpan as o, evaluateScenario as p, createSchemaValidationProcessor as r, ATTRIBUTE_TYPES as s, SCHEMA_VIOLATION_ATTRS as t, defineContract as u, validateScenarioSpec as v };
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
- const require_processor = require('./processor-C9NmN0wQ.cjs');
2
+ const require_processor = require('./processor-DQvVwsvP.cjs');
3
3
 
4
+ exports.SCHEMA_VIOLATION_ATTRS = require_processor.SCHEMA_VIOLATION_ATTRS;
4
5
  exports.SchemaValidationSpanProcessor = require_processor.SchemaValidationSpanProcessor;
5
6
  exports.createSchemaValidationProcessor = require_processor.createSchemaValidationProcessor;
@@ -45,7 +45,30 @@ interface SchemaValidationProcessorOptions extends ValidateOptions {
45
45
  enabledInProduction?: boolean;
46
46
  /** Throttle window for repeated identical warnings (ms). Default 60s. */
47
47
  warnIntervalMs?: number;
48
+ /**
49
+ * Write the violations onto the span before it is exported. Default `false`.
50
+ *
51
+ * **This is the handoff to anything that reads the span later.** The app
52
+ * owns the contract, so the app is the only thing that can validate; a
53
+ * viewer or a backend reading exported spans has no contract and never
54
+ * can. Marking the span is what lets a violation travel to where someone
55
+ * will see it.
56
+ *
57
+ * Opt-in because it changes what gets exported, and because the attributes
58
+ * cost payload on every non-conforming span. Turn it on in development, and
59
+ * in CI if something downstream reads the result.
60
+ *
61
+ * Ordering matters: this processor has to run *before* the one that exports,
62
+ * or the stamp lands after the span has already gone.
63
+ */
64
+ stampViolations?: boolean;
48
65
  }
66
+ /** Attributes written onto a span carrying contract violations. */
67
+ declare const SCHEMA_VIOLATION_ATTRS: {
68
+ readonly count: "autotel.schema.violations";
69
+ readonly severity: "autotel.schema.violation.severity";
70
+ readonly codes: "autotel.schema.violation.codes";
71
+ };
49
72
  /**
50
73
  * Validates each ending span against a {@link TelemetryContract}. Bounded,
51
74
  * deduplicated warnings; fail-open on any internal error.
@@ -61,6 +84,15 @@ declare class SchemaValidationSpanProcessor implements SpanProcessorLike {
61
84
  get totalViolations(): number;
62
85
  onStart(_span: SpanLike, _parentContext: OtelContext): void;
63
86
  onEnd(span: ReadableSpanLike): void;
87
+ /**
88
+ * Record the violations on the span itself.
89
+ *
90
+ * A conforming span is left alone rather than marked with a zero: the
91
+ * presence of the attribute is what a reader filters on, and stamping every
92
+ * span would make `autotel.schema.violations` mean nothing while costing
93
+ * payload on the spans that are fine.
94
+ */
95
+ private stamp;
64
96
  private handle;
65
97
  private maybeWarn;
66
98
  forceFlush(): Promise<void>;
@@ -68,4 +100,4 @@ declare class SchemaValidationSpanProcessor implements SpanProcessorLike {
68
100
  }
69
101
  declare function createSchemaValidationProcessor(opts: SchemaValidationProcessorOptions): SchemaValidationSpanProcessor;
70
102
  //#endregion
71
- export { ContextValue, OtelContext, ReadableSpanLike, SchemaProcessorMode, SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, SpanLike, SpanProcessorLike, createSchemaValidationProcessor };
103
+ export { ContextValue, OtelContext, ReadableSpanLike, SCHEMA_VIOLATION_ATTRS, SchemaProcessorMode, SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, SpanLike, SpanProcessorLike, createSchemaValidationProcessor };
@@ -45,7 +45,30 @@ interface SchemaValidationProcessorOptions extends ValidateOptions {
45
45
  enabledInProduction?: boolean;
46
46
  /** Throttle window for repeated identical warnings (ms). Default 60s. */
47
47
  warnIntervalMs?: number;
48
+ /**
49
+ * Write the violations onto the span before it is exported. Default `false`.
50
+ *
51
+ * **This is the handoff to anything that reads the span later.** The app
52
+ * owns the contract, so the app is the only thing that can validate; a
53
+ * viewer or a backend reading exported spans has no contract and never
54
+ * can. Marking the span is what lets a violation travel to where someone
55
+ * will see it.
56
+ *
57
+ * Opt-in because it changes what gets exported, and because the attributes
58
+ * cost payload on every non-conforming span. Turn it on in development, and
59
+ * in CI if something downstream reads the result.
60
+ *
61
+ * Ordering matters: this processor has to run *before* the one that exports,
62
+ * or the stamp lands after the span has already gone.
63
+ */
64
+ stampViolations?: boolean;
48
65
  }
66
+ /** Attributes written onto a span carrying contract violations. */
67
+ declare const SCHEMA_VIOLATION_ATTRS: {
68
+ readonly count: "autotel.schema.violations";
69
+ readonly severity: "autotel.schema.violation.severity";
70
+ readonly codes: "autotel.schema.violation.codes";
71
+ };
49
72
  /**
50
73
  * Validates each ending span against a {@link TelemetryContract}. Bounded,
51
74
  * deduplicated warnings; fail-open on any internal error.
@@ -61,6 +84,15 @@ declare class SchemaValidationSpanProcessor implements SpanProcessorLike {
61
84
  get totalViolations(): number;
62
85
  onStart(_span: SpanLike, _parentContext: OtelContext): void;
63
86
  onEnd(span: ReadableSpanLike): void;
87
+ /**
88
+ * Record the violations on the span itself.
89
+ *
90
+ * A conforming span is left alone rather than marked with a zero: the
91
+ * presence of the attribute is what a reader filters on, and stamping every
92
+ * span would make `autotel.schema.violations` mean nothing while costing
93
+ * payload on the spans that are fine.
94
+ */
95
+ private stamp;
64
96
  private handle;
65
97
  private maybeWarn;
66
98
  forceFlush(): Promise<void>;
@@ -68,4 +100,4 @@ declare class SchemaValidationSpanProcessor implements SpanProcessorLike {
68
100
  }
69
101
  declare function createSchemaValidationProcessor(opts: SchemaValidationProcessorOptions): SchemaValidationSpanProcessor;
70
102
  //#endregion
71
- export { ContextValue, OtelContext, ReadableSpanLike, SchemaProcessorMode, SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, SpanLike, SpanProcessorLike, createSchemaValidationProcessor };
103
+ export { ContextValue, OtelContext, ReadableSpanLike, SCHEMA_VIOLATION_ATTRS, SchemaProcessorMode, SchemaValidationProcessorOptions, SchemaValidationSpanProcessor, SpanLike, SpanProcessorLike, createSchemaValidationProcessor };
package/dist/processor.js CHANGED
@@ -1,3 +1,3 @@
1
- import { n as createSchemaValidationProcessor, t as SchemaValidationSpanProcessor } from "./processor-Cn0HNUvw.js";
1
+ import { n as SchemaValidationSpanProcessor, r as createSchemaValidationProcessor, t as SCHEMA_VIOLATION_ATTRS } from "./processor-PQss56h3.js";
2
2
 
3
- export { SchemaValidationSpanProcessor, createSchemaValidationProcessor };
3
+ export { SCHEMA_VIOLATION_ATTRS, SchemaValidationSpanProcessor, createSchemaValidationProcessor };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autotel-schema",
3
- "version": "11.0.1",
3
+ "version": "13.0.0",
4
4
  "description": "Your telemetry surface as a typed, versioned contract — declare the spans and attributes your service emits, validate live spans against them, and diff the surface across commits to catch breaking trace changes before they ship.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -44,7 +44,7 @@
44
44
  "author": "Jag Reehal <jag@jagreehal.com> (https://jagreehal.com)",
45
45
  "license": "Apache-2.0",
46
46
  "peerDependencies": {
47
- "autotel": "7.0.1"
47
+ "autotel": "7.2.0"
48
48
  },
49
49
  "peerDependenciesMeta": {
50
50
  "autotel": {
@@ -16,6 +16,17 @@
16
16
  "exfiltration_capable"
17
17
  ]
18
18
  },
19
+ "agent.consent.evidence": {
20
+ "type": "string",
21
+ "stability": "stable",
22
+ "required": false,
23
+ "highCardinality": false,
24
+ "enum": [
25
+ "observed",
26
+ "inferred"
27
+ ],
28
+ "description": "Whether the consent outcome was witnessed or reconstructed. Defaults to inferred: no runtime reports the human click, so an approval deduced from the tool having run must never be cited as a human decision."
29
+ },
19
30
  "agent.consent.outcome": {
20
31
  "type": "string",
21
32
  "stability": "stable",
@@ -122,6 +133,91 @@
122
133
  "highCardinality": false,
123
134
  "description": "Agent audit marker"
124
135
  },
136
+ "detection.correlation_id": {
137
+ "type": "string",
138
+ "stability": "stable",
139
+ "required": false,
140
+ "highCardinality": true,
141
+ "description": "Session the detection belongs to"
142
+ },
143
+ "detection.disposition.note": {
144
+ "type": "string",
145
+ "stability": "stable",
146
+ "required": false,
147
+ "highCardinality": false,
148
+ "description": "Why the finding was closed. Required for false_positive and risk_accepted."
149
+ },
150
+ "detection.disposition.status": {
151
+ "type": "string",
152
+ "stability": "stable",
153
+ "required": false,
154
+ "highCardinality": false,
155
+ "enum": [
156
+ "new",
157
+ "acknowledged",
158
+ "in_progress",
159
+ "resolved",
160
+ "false_positive",
161
+ "risk_accepted"
162
+ ],
163
+ "description": "Triage decision recorded against a detection"
164
+ },
165
+ "detection.disposition.supersedes": {
166
+ "type": "string",
167
+ "stability": "stable",
168
+ "required": false,
169
+ "highCardinality": false,
170
+ "enum": [
171
+ "new",
172
+ "acknowledged",
173
+ "in_progress",
174
+ "resolved",
175
+ "false_positive",
176
+ "risk_accepted"
177
+ ],
178
+ "description": "Status this decision replaces — dispositions are appended, never edited, so a reversal survives."
179
+ },
180
+ "detection.first_at": {
181
+ "type": "number",
182
+ "stability": "stable",
183
+ "required": false,
184
+ "highCardinality": false,
185
+ "description": "Epoch ms of the first step matched by the rule"
186
+ },
187
+ "detection.last_at": {
188
+ "type": "number",
189
+ "stability": "stable",
190
+ "required": false,
191
+ "highCardinality": false,
192
+ "description": "Epoch ms of the last step matched by the rule"
193
+ },
194
+ "detection.rule_id": {
195
+ "type": "string",
196
+ "stability": "stable",
197
+ "required": false,
198
+ "highCardinality": false,
199
+ "description": "Sequence rule that fired"
200
+ },
201
+ "detection.severity": {
202
+ "type": "string",
203
+ "stability": "stable",
204
+ "required": false,
205
+ "highCardinality": false,
206
+ "enum": [
207
+ "low",
208
+ "medium",
209
+ "high",
210
+ "critical"
211
+ ],
212
+ "description": "Severity of the rule that fired"
213
+ },
214
+ "detection.steps": {
215
+ "type": "number",
216
+ "stability": "stable",
217
+ "required": false,
218
+ "highCardinality": false,
219
+ "description": "How many ordered steps the rule matched"
220
+ },
125
221
  "mcp.security.injection.verdict": {
126
222
  "type": "string",
127
223
  "stability": "stable",