autotel-schema 11.0.0 → 12.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
@@ -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 },
package/dist/index.d.cts CHANGED
@@ -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, 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
@@ -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, 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
@@ -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 },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "autotel-schema",
3
- "version": "11.0.0",
3
+ "version": "12.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.0"
47
+ "autotel": "7.1.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",