@attest-ai/core 0.5.0 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (123) hide show
  1. package/dist/cjs/index.cjs +741 -25
  2. package/dist/cjs/index.cjs.map +1 -1
  3. package/dist/cjs/index.d.cts +145 -8
  4. package/dist/cjs/proto/index.cjs +81 -0
  5. package/dist/cjs/proto/index.cjs.map +1 -1
  6. package/dist/cjs/proto/index.d.cts +145 -3
  7. package/dist/esm/cli.js +321 -2
  8. package/dist/esm/cli.js.map +1 -1
  9. package/dist/esm/index.d.ts +145 -8
  10. package/dist/esm/index.js +724 -25
  11. package/dist/esm/index.js.map +1 -1
  12. package/dist/esm/proto/index.d.ts +145 -3
  13. package/dist/esm/proto/index.js +77 -0
  14. package/dist/esm/proto/index.js.map +1 -1
  15. package/package.json +4 -4
  16. package/dist/adapters/anthropic.d.ts +0 -31
  17. package/dist/adapters/anthropic.d.ts.map +0 -1
  18. package/dist/adapters/anthropic.js +0 -42
  19. package/dist/adapters/anthropic.js.map +0 -1
  20. package/dist/adapters/gemini.d.ts +0 -30
  21. package/dist/adapters/gemini.d.ts.map +0 -1
  22. package/dist/adapters/gemini.js +0 -41
  23. package/dist/adapters/gemini.js.map +0 -1
  24. package/dist/adapters/index.d.ts +0 -11
  25. package/dist/adapters/index.d.ts.map +0 -1
  26. package/dist/adapters/index.js +0 -7
  27. package/dist/adapters/index.js.map +0 -1
  28. package/dist/adapters/manual.d.ts +0 -9
  29. package/dist/adapters/manual.d.ts.map +0 -1
  30. package/dist/adapters/manual.js +0 -16
  31. package/dist/adapters/manual.js.map +0 -1
  32. package/dist/adapters/ollama.d.ts +0 -19
  33. package/dist/adapters/ollama.d.ts.map +0 -1
  34. package/dist/adapters/ollama.js +0 -30
  35. package/dist/adapters/ollama.js.map +0 -1
  36. package/dist/adapters/openai.d.ts +0 -34
  37. package/dist/adapters/openai.d.ts.map +0 -1
  38. package/dist/adapters/openai.js +0 -42
  39. package/dist/adapters/openai.js.map +0 -1
  40. package/dist/adapters/otel.d.ts +0 -25
  41. package/dist/adapters/otel.d.ts.map +0 -1
  42. package/dist/adapters/otel.js +0 -133
  43. package/dist/adapters/otel.js.map +0 -1
  44. package/dist/agent.d.ts +0 -14
  45. package/dist/agent.d.ts.map +0 -1
  46. package/dist/agent.js +0 -54
  47. package/dist/agent.js.map +0 -1
  48. package/dist/client.d.ts +0 -23
  49. package/dist/client.d.ts.map +0 -1
  50. package/dist/client.js +0 -171
  51. package/dist/client.js.map +0 -1
  52. package/dist/config.d.ts +0 -21
  53. package/dist/config.d.ts.map +0 -1
  54. package/dist/config.js +0 -31
  55. package/dist/config.js.map +0 -1
  56. package/dist/context.d.ts +0 -4
  57. package/dist/context.d.ts.map +0 -1
  58. package/dist/context.js +0 -3
  59. package/dist/context.js.map +0 -1
  60. package/dist/delegate.d.ts +0 -3
  61. package/dist/delegate.d.ts.map +0 -1
  62. package/dist/delegate.js +0 -24
  63. package/dist/delegate.js.map +0 -1
  64. package/dist/engine-downloader.d.ts +0 -7
  65. package/dist/engine-downloader.d.ts.map +0 -1
  66. package/dist/engine-downloader.js +0 -136
  67. package/dist/engine-downloader.js.map +0 -1
  68. package/dist/engine-manager.d.ts +0 -26
  69. package/dist/engine-manager.d.ts.map +0 -1
  70. package/dist/engine-manager.js +0 -172
  71. package/dist/engine-manager.js.map +0 -1
  72. package/dist/expect.d.ts +0 -133
  73. package/dist/expect.d.ts.map +0 -1
  74. package/dist/expect.js +0 -330
  75. package/dist/expect.js.map +0 -1
  76. package/dist/index.d.ts +0 -16
  77. package/dist/index.d.ts.map +0 -1
  78. package/dist/index.js +0 -15
  79. package/dist/index.js.map +0 -1
  80. package/dist/proto/codec.d.ts +0 -20
  81. package/dist/proto/codec.d.ts.map +0 -1
  82. package/dist/proto/codec.js +0 -71
  83. package/dist/proto/codec.js.map +0 -1
  84. package/dist/proto/constants.d.ts +0 -21
  85. package/dist/proto/constants.d.ts.map +0 -1
  86. package/dist/proto/constants.js +0 -25
  87. package/dist/proto/constants.js.map +0 -1
  88. package/dist/proto/errors.d.ts +0 -13
  89. package/dist/proto/errors.d.ts.map +0 -1
  90. package/dist/proto/errors.js +0 -24
  91. package/dist/proto/errors.js.map +0 -1
  92. package/dist/proto/index.d.ts +0 -5
  93. package/dist/proto/index.d.ts.map +0 -1
  94. package/dist/proto/index.js +0 -5
  95. package/dist/proto/index.js.map +0 -1
  96. package/dist/proto/types.d.ts +0 -104
  97. package/dist/proto/types.d.ts.map +0 -1
  98. package/dist/proto/types.js +0 -2
  99. package/dist/proto/types.js.map +0 -1
  100. package/dist/result.d.ts +0 -15
  101. package/dist/result.d.ts.map +0 -1
  102. package/dist/result.js +0 -32
  103. package/dist/result.js.map +0 -1
  104. package/dist/simulation.d.ts +0 -8
  105. package/dist/simulation.d.ts.map +0 -1
  106. package/dist/simulation.js +0 -21
  107. package/dist/simulation.js.map +0 -1
  108. package/dist/tier.d.ts +0 -5
  109. package/dist/tier.d.ts.map +0 -1
  110. package/dist/tier.js +0 -10
  111. package/dist/tier.js.map +0 -1
  112. package/dist/trace-tree.d.ts +0 -20
  113. package/dist/trace-tree.d.ts.map +0 -1
  114. package/dist/trace-tree.js +0 -92
  115. package/dist/trace-tree.js.map +0 -1
  116. package/dist/trace.d.ts +0 -41
  117. package/dist/trace.d.ts.map +0 -1
  118. package/dist/trace.js +0 -88
  119. package/dist/trace.js.map +0 -1
  120. package/dist/version.d.ts +0 -3
  121. package/dist/version.d.ts.map +0 -1
  122. package/dist/version.js +0 -3
  123. package/dist/version.js.map +0 -1
@@ -1,12 +1,12 @@
1
- import { InitializeResult, Trace, Assertion, EvaluateBatchResult, Step, AssertionResult } from './proto/index.cjs';
2
- export { AgentId, AssertionId, AssertionSpec, ConstraintSpec, ContentSpec, ERR_ASSERTION_ERROR, ERR_ENGINE_ERROR, ERR_INVALID_TRACE, ERR_PROVIDER_ERROR, ERR_SESSION_ERROR, ERR_TIMEOUT, EmbeddingSpec, EngineTimeoutError, ErrorData, EvaluateBatchParams, InitializeParams, LlmJudgeSpec, PluginSpec, ProtocolError, RPCError, RPCRequest, RPCResponse, STATUS_HARD_FAIL, STATUS_PASS, STATUS_SOFT_FAIL, STEP_AGENT_CALL, STEP_LLM_CALL, STEP_RETRIEVAL, STEP_TOOL_CALL, SchemaSpec, ShutdownResult, SubmitPluginResultParams, TYPE_CONSTRAINT, TYPE_CONTENT, TYPE_EMBEDDING, TYPE_LLM_JUDGE, TYPE_PLUGIN, TYPE_SCHEMA, TYPE_TRACE, TYPE_TRACE_TREE, TraceId, TraceMetadata, TraceSpec, TraceTreeSpec, agentId, assertionId, decodeResponse, encodeRequest, extractId, extractResult, traceId } from './proto/index.cjs';
1
+ import { InitializeResult, ProtocolLogger, ProtocolDiagnostic, Trace, Assertion, EvaluateBatchResult, DriftReport, SimulatePersona, ConversationMessage, SimulateFaultConfig, Step, AssertionResult } from './proto/index.cjs';
2
+ export { AgentId, AssertionId, AssertionSpec, BiasProbe, ConstraintSpec, ContentSpec, ERR_ASSERTION_ERROR, ERR_ENGINE_ERROR, ERR_INVALID_TRACE, ERR_PROVIDER_ERROR, ERR_SESSION_ERROR, ERR_TIMEOUT, EmbeddingSpec, EngineTimeoutError, ErrorData, EvaluateBatchParams, GenerateUserMessageParams, GenerateUserMessageResult, InitializeParams, JudgeAgreement, JudgeMetadata, LlmJudgeSpec, PluginSpec, ProtocolDesyncError, ProtocolDiagnosticBuffer, ProtocolDiagnosticKind, ProtocolError, QueryDriftParams, QueryDriftResult, RPCError, RPCRequest, RPCResponse, STATUS_HARD_FAIL, STATUS_PASS, STATUS_SOFT_FAIL, STEP_AGENT_CALL, STEP_LLM_CALL, STEP_RETRIEVAL, STEP_TOOL_CALL, SchemaSpec, ShutdownResult, SubmitPluginResultParams, TYPE_CONSTRAINT, TYPE_CONTENT, TYPE_EMBEDDING, TYPE_LLM_JUDGE, TYPE_PLUGIN, TYPE_SCHEMA, TYPE_TRACE, TYPE_TRACE_TREE, TraceId, TraceMetadata, TraceSpec, TraceTreeSpec, agentId, assertionId, decodeResponse, encodeRequest, extractId, extractResult, layerForType, previewLine, traceId } from './proto/index.cjs';
3
3
  import { ChildProcess } from 'node:child_process';
4
4
  import { Interface } from 'node:readline';
5
5
  import { AsyncLocalStorage } from 'node:async_hooks';
6
6
  import { EventEmitter } from 'node:events';
7
7
 
8
- declare const VERSION = "0.5.0";
9
- declare const ENGINE_VERSION = "0.5.0";
8
+ declare const VERSION = "0.9.0";
9
+ declare const ENGINE_VERSION = "0.9.0";
10
10
 
11
11
  declare class EngineManager {
12
12
  private enginePath;
@@ -31,6 +31,28 @@ declare class EngineManager {
31
31
  get readlineInterface(): Interface | null;
32
32
  }
33
33
 
34
+ interface AttestClientOptions {
35
+ /** Logger override. When omitted, warnings only emit if ATTEST_DEBUG_PROTOCOL=1. */
36
+ logger?: ProtocolLogger;
37
+ /** Listener invoked for every protocol diagnostic. */
38
+ onDiagnostic?: (diagnostic: ProtocolDiagnostic) => void;
39
+ /** Diagnostic ring-buffer capacity. Default 32. */
40
+ diagnosticBufferSize?: number;
41
+ /** Number of diagnostics in `desyncWindowMs` that triggers desync rejection. Default 3. */
42
+ desyncThreshold?: number;
43
+ /** Window length for desync detection in milliseconds. Default 1000. */
44
+ desyncWindowMs?: number;
45
+ }
46
+ /**
47
+ * AttestClient owns request/response correlation over the engine's
48
+ * NDJSON protocol.
49
+ *
50
+ * Desync detection is a one-way latch: once the diagnostic rate breaches
51
+ * `desyncThreshold` within `desyncWindowMs` the client refuses further
52
+ * sends for the lifetime of the instance. There is no reset hook by
53
+ * design — recovery requires constructing a new client over a fresh
54
+ * engine subprocess.
55
+ */
34
56
  declare class AttestClient {
35
57
  private readonly engine;
36
58
  private requestId;
@@ -38,10 +60,23 @@ declare class AttestClient {
38
60
  private writeChain;
39
61
  private readerActive;
40
62
  private lineHandler;
41
- constructor(engine: EngineManager);
63
+ private readonly logger;
64
+ private readonly diagnosticBuffer;
65
+ private readonly diagnosticListeners;
66
+ private readonly desyncThreshold;
67
+ private readonly desyncWindowMs;
68
+ private desynced;
69
+ constructor(engine: EngineManager, options?: AttestClientOptions);
70
+ /** Subscribe to protocol diagnostics. Returns an unsubscribe function. */
71
+ onProtocolDiagnostic(listener: (diagnostic: ProtocolDiagnostic) => void): () => void;
72
+ /** Snapshot of the diagnostic ring buffer (most recent last). */
73
+ protocolDiagnostics(): readonly ProtocolDiagnostic[];
42
74
  startReader(): void;
43
75
  stopReader(): void;
76
+ private recordDiagnostic;
77
+ private maybeTriggerDesync;
44
78
  private handleLine;
79
+ private handleDecodeFailure;
45
80
  private failAll;
46
81
  sendRequest(method: string, params: Record<string, unknown>, timeoutMs?: number): Promise<unknown>;
47
82
  evaluateBatch(trace: Trace, assertions: readonly Assertion[], options?: {
@@ -50,6 +85,12 @@ declare class AttestClient {
50
85
  submitPluginResult(traceId: string, pluginName: string, assertionId: string, status: string, score: number, explanation: string, options?: {
51
86
  timeout?: number;
52
87
  }): Promise<boolean>;
88
+ queryDrift(assertionId: string, windowSize?: number, options?: {
89
+ timeout?: number;
90
+ }): Promise<DriftReport>;
91
+ generateUserMessage(persona: SimulatePersona, conversationHistory: readonly ConversationMessage[], faultConfig?: SimulateFaultConfig, options?: {
92
+ timeout?: number;
93
+ }): Promise<string>;
53
94
  }
54
95
 
55
96
  declare class TraceBuilder {
@@ -106,6 +147,29 @@ declare class AgentResult {
106
147
  get failCount(): number;
107
148
  }
108
149
 
150
+ /**
151
+ * Terminal-grade rendering of Attest assertion failures.
152
+ *
153
+ * Mirrors the Python attest.cli.diagnostics module so PR comments,
154
+ * pytest output, and vitest output show the same fields. Use as the
155
+ * message argument to a vitest `expect(result.passed, ...)` so
156
+ * reviewers see trace path, expected vs actual, and judge metadata.
157
+ */
158
+
159
+ interface RenderOptions {
160
+ /** Emit ANSI colour escapes. Default false (plain text). */
161
+ color?: boolean;
162
+ /** Source location annotation appended after each block. */
163
+ testFile?: string;
164
+ /** Render passing assertions in addition to failures. Default false. */
165
+ includePassing?: boolean;
166
+ }
167
+ declare function renderAssertionFailure(result: AssertionResult, options?: RenderOptions): string;
168
+ declare function renderSummary(result: AgentResult, options?: {
169
+ color?: boolean;
170
+ }): string;
171
+ declare function renderDiagnostics(result: AgentResult, options?: RenderOptions): string;
172
+
109
173
  declare class TraceTree {
110
174
  readonly root: Trace;
111
175
  constructor(root: Trace);
@@ -517,7 +581,7 @@ declare class ExpectChain {
517
581
  * ```
518
582
  */
519
583
  outputSimilarTo(reference: string, opts?: {
520
- threshold?: number;
584
+ threshold?: number | "dynamic";
521
585
  model?: string;
522
586
  soft?: boolean;
523
587
  }): this;
@@ -538,7 +602,7 @@ declare class ExpectChain {
538
602
  */
539
603
  passesJudge(criteria: string, opts?: {
540
604
  rubric?: string;
541
- threshold?: number;
605
+ threshold?: number | "dynamic";
542
606
  model?: string;
543
607
  soft?: boolean;
544
608
  }): this;
@@ -805,21 +869,36 @@ declare function tier(level: number): <T extends (...args: never[]) => unknown>(
805
869
  * @param options.simulation - Enable simulation mode. All `evaluateBatch` calls
806
870
  * return deterministic pass results without spawning the engine or calling any
807
871
  * LLM. Equivalent to setting `ATTEST_SIMULATION=1` in the environment.
872
+ * @param options.sampleRate - Sampling rate for continuous evaluation (0.0–1.0).
873
+ * Equivalent to setting `ATTEST_SAMPLE_RATE` in the environment.
808
874
  */
809
875
  declare function config(options: {
810
876
  simulation?: boolean;
877
+ sampleRate?: number;
811
878
  }): void;
812
879
  /**
813
880
  * Returns true when simulation mode is active via either the programmatic API
814
881
  * or the `ATTEST_SIMULATION` environment variable.
815
882
  */
816
883
  declare function isSimulationMode(): boolean;
884
+ /**
885
+ * Returns the sampling rate for continuous evaluation. Priority:
886
+ * programmatic `config({ sampleRate })` > `ATTEST_SAMPLE_RATE` env var > 0.
887
+ */
888
+ declare function getSampleRate(): number;
817
889
  /**
818
890
  * Reset all programmatic config to defaults. Primarily for use in tests.
819
891
  * Environment variables are not affected.
820
892
  */
821
893
  declare function resetConfig(): void;
822
894
 
895
+ /**
896
+ * Return a deterministic all-pass result for every assertion without
897
+ * contacting the engine or any LLM provider. Used when simulation mode
898
+ * is active (`ATTEST_SIMULATION=1` or `config({ simulation: true })`).
899
+ */
900
+ declare function simulationEvaluateBatch(assertions: readonly Assertion[]): EvaluateBatchResult;
901
+
823
902
  interface PluginResult {
824
903
  readonly status: string;
825
904
  readonly score: number;
@@ -882,6 +961,64 @@ declare class ContinuousEvalRunner {
882
961
  private scheduleNext;
883
962
  }
884
963
 
964
+ /**
965
+ * Calibration helpers — TS parity with engine/internal/assertion/judge/calibration.go
966
+ * and sdks/python/src/attest/calibration.py.
967
+ *
968
+ * Computes Cohen's κ, agreement %, and ROC-AUC over (human, judge) score
969
+ * pairs and parses CSV/JSONL labels files. Metrics match the engine
970
+ * byte-for-byte on the same input.
971
+ */
972
+ interface LabelPair {
973
+ readonly human: number;
974
+ readonly judge: number;
975
+ }
976
+ interface AgreementResult {
977
+ readonly threshold: number;
978
+ readonly n: number;
979
+ readonly agreement: number;
980
+ readonly cohenKappa: number;
981
+ readonly rocAuc: number;
982
+ }
983
+ interface LabeledRecord {
984
+ input: string;
985
+ humanLabel: number;
986
+ judgeScore: number;
987
+ judgeKnown: boolean;
988
+ }
989
+ /**
990
+ * Compute Cohen's κ, agreement %, and ROC-AUC over labeled pairs.
991
+ *
992
+ * Throws when pairs is empty or threshold is outside (0, 1). Cohen's κ
993
+ * degenerates to 0 when all labels land in a single class for both
994
+ * raters; ROC-AUC is reported as 0 when only one human-class is
995
+ * present.
996
+ */
997
+ declare function computeAgreement(pairs: readonly LabelPair[], threshold: number): AgreementResult;
998
+ /**
999
+ * Parse a 2- or 3-column CSV (input, human_label[, judge_score]).
1000
+ * Header detected when row[0][1] does not parse as a float. Lines
1001
+ * beginning with `#` are skipped.
1002
+ */
1003
+ declare function loadLabelsCSV(text: string): LabeledRecord[];
1004
+ /**
1005
+ * Parse a newline-delimited JSON file. Each line is an object with the
1006
+ * shape {"input": "...", "human_label": 0.9, "judge_score": 0.8}.
1007
+ * `judge_score` is optional.
1008
+ */
1009
+ declare function loadLabelsJSONL(text: string): LabeledRecord[];
1010
+ /**
1011
+ * Return the 16-character SHA-256 prefix used by the engine for prompt
1012
+ * hashes. Mirrors promptHash in engine/internal/assertion/judge_eval.go
1013
+ * so SDK-recorded calibration rows align with JudgeMetadata.prompt_hash.
1014
+ */
1015
+ declare function promptHash(text: string): string;
1016
+
1017
+ declare const FRIENDLY_USER: SimulatePersona;
1018
+ declare const ADVERSARIAL_USER: SimulatePersona;
1019
+ declare const CONFUSED_USER: SimulatePersona;
1020
+ declare const COOPERATIVE_USER: SimulatePersona;
1021
+
885
1022
  declare class ManualAdapter {
886
1023
  private readonly agentId;
887
1024
  constructor(agentId?: string);
@@ -1082,4 +1219,4 @@ interface TraceAdapter {
1082
1219
  traceFromResponse(response: unknown, options?: Record<string, unknown>): Trace;
1083
1220
  }
1084
1221
 
1085
- export { Agent, AgentResult, AlertDispatcher, type AlertPayload, AnthropicAdapter, Assertion, AssertionResult, AttestClient, type AttestPlugin, ContinuousEvalRunner, ENGINE_VERSION, EngineManager, EvaluateBatchResult, ExpectChain, GeminiAdapter, InitializeResult, LangChainAdapter, ManualAdapter, OTelAdapter, OllamaAdapter, OpenAIAdapter, PluginRegistry, type PluginResult, Sampler, Step, TIER_1, TIER_2, TIER_3, Trace, type TraceAdapter, TraceBuilder, TraceTree, VERSION, activeBuilder, agent, attestExpect, config, delegate, executePluginAssertion, isSimulationMode, resetConfig, tier };
1222
+ export { ADVERSARIAL_USER, Agent, AgentResult, type AgreementResult, AlertDispatcher, type AlertPayload, AnthropicAdapter, Assertion, AssertionResult, AttestClient, type AttestClientOptions, type AttestPlugin, CONFUSED_USER, COOPERATIVE_USER, ContinuousEvalRunner, ConversationMessage, DriftReport, ENGINE_VERSION, EngineManager, EvaluateBatchResult, ExpectChain, FRIENDLY_USER, GeminiAdapter, InitializeResult, type LabelPair, type LabeledRecord, LangChainAdapter, ManualAdapter, OTelAdapter, OllamaAdapter, OpenAIAdapter, PluginRegistry, type PluginResult, ProtocolDiagnostic, ProtocolLogger, type RenderOptions, Sampler, SimulateFaultConfig, SimulatePersona, Step, TIER_1, TIER_2, TIER_3, Trace, type TraceAdapter, TraceBuilder, TraceTree, VERSION, activeBuilder, agent, attestExpect, computeAgreement, config, delegate, executePluginAssertion, getSampleRate, isSimulationMode, loadLabelsCSV, loadLabelsJSONL, promptHash, renderAssertionFailure, renderDiagnostics, renderSummary, resetConfig, simulationEvaluateBatch, tier };
@@ -27,6 +27,8 @@ __export(proto_exports, {
27
27
  ERR_SESSION_ERROR: () => ERR_SESSION_ERROR,
28
28
  ERR_TIMEOUT: () => ERR_TIMEOUT,
29
29
  EngineTimeoutError: () => EngineTimeoutError,
30
+ ProtocolDesyncError: () => ProtocolDesyncError,
31
+ ProtocolDiagnosticBuffer: () => ProtocolDiagnosticBuffer,
30
32
  ProtocolError: () => ProtocolError,
31
33
  STATUS_HARD_FAIL: () => STATUS_HARD_FAIL,
32
34
  STATUS_PASS: () => STATUS_PASS,
@@ -49,6 +51,8 @@ __export(proto_exports, {
49
51
  encodeRequest: () => encodeRequest,
50
52
  extractId: () => extractId,
51
53
  extractResult: () => extractResult,
54
+ layerForType: () => layerForType,
55
+ previewLine: () => previewLine,
52
56
  traceId: () => traceId
53
57
  });
54
58
  module.exports = __toCommonJS(proto_exports);
@@ -86,6 +90,27 @@ function assertionId(id) {
86
90
  function agentId(id) {
87
91
  return id;
88
92
  }
93
+ function layerForType(assertionType) {
94
+ switch (assertionType) {
95
+ case "schema":
96
+ return 1;
97
+ case "constraint":
98
+ return 2;
99
+ case "trace":
100
+ case "trace_tree":
101
+ return 3;
102
+ case "content":
103
+ return 4;
104
+ case "embedding":
105
+ return 5;
106
+ case "llm_judge":
107
+ return 6;
108
+ case "plugin":
109
+ return 8;
110
+ default:
111
+ return 0;
112
+ }
113
+ }
89
114
 
90
115
  // src/proto/errors.ts
91
116
  var ProtocolError = class extends Error {
@@ -112,6 +137,58 @@ var EngineTimeoutError = class extends Error {
112
137
  this.timeoutMs = timeoutMs;
113
138
  }
114
139
  };
140
+ var ProtocolDesyncError = class extends Error {
141
+ diagnostics;
142
+ constructor(message, diagnostics) {
143
+ super(message);
144
+ this.name = "ProtocolDesyncError";
145
+ this.diagnostics = diagnostics;
146
+ }
147
+ };
148
+
149
+ // src/proto/diagnostics.ts
150
+ var DEFAULT_BUFFER_SIZE = 32;
151
+ var MAX_LINE_PREVIEW = 512;
152
+ var ProtocolDiagnosticBuffer = class {
153
+ capacity;
154
+ entries = [];
155
+ constructor(capacity = DEFAULT_BUFFER_SIZE) {
156
+ if (capacity <= 0) {
157
+ throw new Error(
158
+ `ProtocolDiagnosticBuffer capacity must be positive, got ${capacity}`
159
+ );
160
+ }
161
+ this.capacity = capacity;
162
+ }
163
+ push(diagnostic) {
164
+ if (this.entries.length >= this.capacity) {
165
+ this.entries.shift();
166
+ }
167
+ this.entries.push(diagnostic);
168
+ }
169
+ snapshot() {
170
+ return this.entries.slice();
171
+ }
172
+ countWithin(windowMs, nowMs) {
173
+ const cutoff = nowMs - windowMs;
174
+ let count = 0;
175
+ for (let i = this.entries.length - 1; i >= 0; i -= 1) {
176
+ if (this.entries[i].timestampMs >= cutoff) {
177
+ count += 1;
178
+ } else {
179
+ break;
180
+ }
181
+ }
182
+ return count;
183
+ }
184
+ clear() {
185
+ this.entries.length = 0;
186
+ }
187
+ };
188
+ function previewLine(line) {
189
+ if (line.length <= MAX_LINE_PREVIEW) return line;
190
+ return line.slice(0, MAX_LINE_PREVIEW) + "\u2026";
191
+ }
115
192
 
116
193
  // src/proto/codec.ts
117
194
  function encodeRequest(id, method, params) {
@@ -181,6 +258,8 @@ function extractId(response) {
181
258
  ERR_SESSION_ERROR,
182
259
  ERR_TIMEOUT,
183
260
  EngineTimeoutError,
261
+ ProtocolDesyncError,
262
+ ProtocolDiagnosticBuffer,
184
263
  ProtocolError,
185
264
  STATUS_HARD_FAIL,
186
265
  STATUS_PASS,
@@ -203,6 +282,8 @@ function extractId(response) {
203
282
  encodeRequest,
204
283
  extractId,
205
284
  extractResult,
285
+ layerForType,
286
+ previewLine,
206
287
  traceId
207
288
  });
208
289
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../../src/proto/index.ts","../../../src/proto/constants.ts","../../../src/proto/types.ts","../../../src/proto/errors.ts","../../../src/proto/codec.ts"],"sourcesContent":["export * from \"./constants.js\";\nexport * from \"./types.js\";\nexport * from \"./errors.js\";\nexport { encodeRequest, decodeResponse, extractResult, extractId } from \"./codec.js\";\n","// Step type constants\nexport const STEP_LLM_CALL = \"llm_call\" as const;\nexport const STEP_TOOL_CALL = \"tool_call\" as const;\nexport const STEP_RETRIEVAL = \"retrieval\" as const;\nexport const STEP_AGENT_CALL = \"agent_call\" as const;\n\n// Status constants\nexport const STATUS_PASS = \"pass\" as const;\nexport const STATUS_SOFT_FAIL = \"soft_fail\" as const;\nexport const STATUS_HARD_FAIL = \"hard_fail\" as const;\n\n// Assertion type constants\nexport const TYPE_SCHEMA = \"schema\" as const;\nexport const TYPE_CONSTRAINT = \"constraint\" as const;\nexport const TYPE_TRACE = \"trace\" as const;\nexport const TYPE_CONTENT = \"content\" as const;\nexport const TYPE_EMBEDDING = \"embedding\" as const;\nexport const TYPE_LLM_JUDGE = \"llm_judge\" as const;\nexport const TYPE_TRACE_TREE = \"trace_tree\" as const;\nexport const TYPE_PLUGIN = \"plugin\" as const;\n\n// Error code constants\nexport const ERR_INVALID_TRACE = 1001 as const;\nexport const ERR_ASSERTION_ERROR = 1002 as const;\nexport const ERR_PROVIDER_ERROR = 2001 as const;\nexport const ERR_ENGINE_ERROR = 3001 as const;\nexport const ERR_TIMEOUT = 3002 as const;\nexport const ERR_SESSION_ERROR = 3003 as const;\n","// ---------------------------------------------------------------------------\n// Branded ID types (T6)\n// ---------------------------------------------------------------------------\n\ndeclare const __brand: unique symbol;\ntype Brand<T, B extends string> = T & { readonly [__brand]: B };\n\nexport type TraceId = Brand<string, \"TraceId\">;\nexport type AssertionId = Brand<string, \"AssertionId\">;\nexport type AgentId = Brand<string, \"AgentId\">;\n\nexport function traceId(id: string): TraceId {\n return id as TraceId;\n}\n\nexport function assertionId(id: string): AssertionId {\n return id as AssertionId;\n}\n\nexport function agentId(id: string): AgentId {\n return id as AgentId;\n}\n\n// ---------------------------------------------------------------------------\n// Assertion spec discriminated unions (T5)\n// ---------------------------------------------------------------------------\n\nexport interface SchemaSpec {\n readonly type: \"schema\";\n readonly target: string;\n readonly schema: Record<string, unknown>;\n}\n\nexport interface ConstraintSpec {\n readonly type: \"constraint\";\n readonly field: string;\n readonly operator: string;\n readonly value?: number;\n readonly min?: number;\n readonly max?: number;\n readonly soft: boolean;\n}\n\nexport interface TraceSpec {\n readonly type: \"trace\";\n readonly check: string;\n readonly tools?: string[];\n readonly tool?: string;\n readonly max_repetitions?: number;\n readonly soft: boolean;\n}\n\nexport interface ContentSpec {\n readonly type: \"content\";\n readonly target: string;\n readonly check: string;\n readonly value?: string;\n readonly values?: string[];\n readonly case_sensitive?: boolean;\n readonly soft?: boolean;\n}\n\nexport interface EmbeddingSpec {\n readonly type: \"embedding\";\n readonly target: string;\n readonly reference: string;\n readonly threshold: number;\n readonly model?: string;\n readonly soft: boolean;\n}\n\nexport interface LlmJudgeSpec {\n readonly type: \"llm_judge\";\n readonly target: string;\n readonly criteria: string;\n readonly rubric: string;\n readonly threshold: number;\n readonly model?: string;\n readonly soft: boolean;\n}\n\nexport interface TraceTreeSpec {\n readonly type: \"trace_tree\";\n readonly check: string;\n readonly [key: string]: unknown;\n}\n\nexport interface PluginSpec {\n readonly type: \"plugin\";\n readonly plugin_id: string;\n readonly config?: Record<string, unknown>;\n readonly soft: boolean;\n}\n\nexport type AssertionSpec =\n | SchemaSpec\n | ConstraintSpec\n | TraceSpec\n | ContentSpec\n | EmbeddingSpec\n | LlmJudgeSpec\n | TraceTreeSpec\n | PluginSpec;\n\n// ---------------------------------------------------------------------------\n// Core protocol types\n// ---------------------------------------------------------------------------\n\nexport interface TraceMetadata {\n readonly total_tokens?: number;\n readonly cost_usd?: number;\n readonly latency_ms?: number;\n readonly model?: string;\n readonly timestamp?: string;\n}\n\nexport interface Step {\n readonly type: string;\n readonly name: string;\n readonly args?: Record<string, unknown>;\n readonly result?: Record<string, unknown>;\n readonly sub_trace?: Trace;\n readonly metadata?: Record<string, unknown>;\n readonly started_at_ms?: number;\n readonly ended_at_ms?: number;\n readonly agent_id?: string;\n readonly agent_role?: string;\n}\n\nexport interface Trace {\n readonly trace_id: string;\n readonly output: Record<string, unknown>;\n readonly schema_version?: number;\n readonly agent_id?: string;\n readonly input?: Record<string, unknown>;\n readonly steps: readonly Step[];\n readonly metadata?: TraceMetadata;\n readonly parent_trace_id?: string;\n}\n\nexport interface Assertion {\n readonly assertion_id: string;\n readonly type: string;\n readonly spec: Record<string, unknown>;\n readonly request_id?: string;\n}\n\nexport interface AssertionResult {\n readonly assertion_id: string;\n readonly status: string;\n readonly score: number;\n readonly explanation: string;\n readonly cost?: number;\n readonly duration_ms?: number;\n readonly request_id?: string;\n}\n\nexport interface ErrorData {\n readonly error_type: string;\n readonly retryable: boolean;\n readonly detail: string;\n}\n\nexport interface RPCError {\n readonly code: number;\n readonly message: string;\n readonly data?: ErrorData;\n}\n\nexport interface RPCRequest {\n readonly jsonrpc: \"2.0\";\n readonly id: number;\n readonly method: string;\n readonly params: Record<string, unknown>;\n}\n\nexport interface RPCResponse {\n readonly jsonrpc: \"2.0\";\n readonly id: number;\n readonly result?: unknown;\n readonly error?: RPCError;\n}\n\nexport interface InitializeParams {\n readonly sdk_name: string;\n readonly sdk_version: string;\n readonly protocol_version: number;\n readonly required_capabilities: readonly string[];\n readonly preferred_encoding?: string;\n}\n\nexport interface InitializeResult {\n readonly engine_version: string;\n readonly protocol_version: number;\n readonly capabilities: readonly string[];\n readonly missing: readonly string[];\n readonly compatible: boolean;\n readonly encoding?: string;\n readonly max_concurrent_requests?: number;\n readonly max_trace_size_bytes?: number;\n readonly max_steps_per_trace?: number;\n}\n\nexport interface EvaluateBatchParams {\n readonly trace: Trace;\n readonly assertions: readonly Assertion[];\n}\n\nexport interface EvaluateBatchResult {\n readonly results: readonly AssertionResult[];\n readonly total_cost?: number;\n readonly total_duration_ms?: number;\n}\n\nexport interface ShutdownResult {\n readonly sessions_completed: number;\n readonly assertions_evaluated: number;\n}\n\nexport interface SubmitPluginResultParams {\n readonly trace_id: string;\n readonly plugin_name: string;\n readonly assertion_id: string;\n readonly result: AssertionResult;\n}\n","import type { ErrorData } from \"./types.js\";\n\nexport class ProtocolError extends Error {\n readonly code: number;\n readonly errorMessage: string;\n readonly data: ErrorData | undefined;\n\n constructor(code: number, message: string, data?: ErrorData) {\n super(message);\n this.name = \"ProtocolError\";\n this.code = code;\n this.errorMessage = message;\n this.data = data;\n }\n}\n\nexport class EngineTimeoutError extends Error {\n readonly method: string;\n readonly timeoutMs: number;\n\n constructor(method: string, timeoutMs: number) {\n super(\n `Engine request '${method}' timed out after ${timeoutMs}ms. ` +\n \"Set ATTEST_ENGINE_TIMEOUT to increase the limit.\",\n );\n this.name = \"EngineTimeoutError\";\n this.method = method;\n this.timeoutMs = timeoutMs;\n }\n}\n","import type { ErrorData, RPCResponse } from \"./types.js\";\nimport { ProtocolError } from \"./errors.js\";\n\n/**\n * Encode a JSON-RPC 2.0 request as an NDJSON line.\n */\nexport function encodeRequest(\n id: number,\n method: string,\n params: Record<string, unknown>,\n): string {\n const msg = {\n jsonrpc: \"2.0\" as const,\n id,\n method,\n params,\n };\n return JSON.stringify(msg) + \"\\n\";\n}\n\n/**\n * Decode a JSON-RPC 2.0 response from an NDJSON line.\n * Throws ProtocolError if the response contains an error.\n * Throws Error for malformed JSON or invalid responses.\n */\nexport function decodeResponse(line: string): RPCResponse {\n const text = line.trim();\n if (!text) {\n throw new Error(\"empty response line\");\n }\n\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch (e) {\n throw new Error(`malformed JSON response: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n if (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n throw new Error(`expected JSON object, got ${Array.isArray(data) ? \"array\" : typeof data}`);\n }\n\n const obj = data as Record<string, unknown>;\n\n if (obj.jsonrpc !== \"2.0\") {\n throw new Error(`invalid jsonrpc version: ${String(obj.jsonrpc)}`);\n }\n\n if (obj.error != null) {\n const err = obj.error as Record<string, unknown>;\n let errorData: ErrorData | undefined;\n\n if (err.data != null) {\n const raw = err.data as Record<string, unknown>;\n errorData = {\n error_type: (raw.error_type as string) ?? \"\",\n retryable: (raw.retryable as boolean) ?? false,\n detail: (raw.detail as string) ?? \"\",\n };\n }\n\n throw new ProtocolError(\n (err.code as number) ?? -1,\n (err.message as string) ?? \"unknown error\",\n errorData,\n );\n }\n\n return obj as unknown as RPCResponse;\n}\n\n/**\n * Extract the result field from a decoded response.\n */\nexport function extractResult(response: RPCResponse): unknown {\n if (response.result === undefined) {\n throw new Error(\"response missing 'result' field\");\n }\n return response.result;\n}\n\n/**\n * Extract the request ID from a decoded response.\n */\nexport function extractId(response: RPCResponse): number {\n if (response.id === undefined) {\n throw new Error(\"response missing 'id' field\");\n }\n return Number(response.id);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../../../src/proto/index.ts","../../../src/proto/constants.ts","../../../src/proto/types.ts","../../../src/proto/errors.ts","../../../src/proto/diagnostics.ts","../../../src/proto/codec.ts"],"sourcesContent":["export * from \"./constants.js\";\nexport * from \"./types.js\";\nexport * from \"./errors.js\";\nexport {\n ProtocolDiagnosticBuffer,\n previewLine,\n} from \"./diagnostics.js\";\nexport type {\n ProtocolDiagnostic,\n ProtocolDiagnosticKind,\n ProtocolLogger,\n} from \"./diagnostics.js\";\nexport { encodeRequest, decodeResponse, extractResult, extractId } from \"./codec.js\";\n","// Step type constants\nexport const STEP_LLM_CALL = \"llm_call\" as const;\nexport const STEP_TOOL_CALL = \"tool_call\" as const;\nexport const STEP_RETRIEVAL = \"retrieval\" as const;\nexport const STEP_AGENT_CALL = \"agent_call\" as const;\n\n// Status constants\nexport const STATUS_PASS = \"pass\" as const;\nexport const STATUS_SOFT_FAIL = \"soft_fail\" as const;\nexport const STATUS_HARD_FAIL = \"hard_fail\" as const;\n\n// Assertion type constants\nexport const TYPE_SCHEMA = \"schema\" as const;\nexport const TYPE_CONSTRAINT = \"constraint\" as const;\nexport const TYPE_TRACE = \"trace\" as const;\nexport const TYPE_CONTENT = \"content\" as const;\nexport const TYPE_EMBEDDING = \"embedding\" as const;\nexport const TYPE_LLM_JUDGE = \"llm_judge\" as const;\nexport const TYPE_TRACE_TREE = \"trace_tree\" as const;\nexport const TYPE_PLUGIN = \"plugin\" as const;\n\n// Error code constants\nexport const ERR_INVALID_TRACE = 1001 as const;\nexport const ERR_ASSERTION_ERROR = 1002 as const;\nexport const ERR_PROVIDER_ERROR = 2001 as const;\nexport const ERR_ENGINE_ERROR = 3001 as const;\nexport const ERR_TIMEOUT = 3002 as const;\nexport const ERR_SESSION_ERROR = 3003 as const;\n","// ---------------------------------------------------------------------------\n// Branded ID types (T6)\n// ---------------------------------------------------------------------------\n\ndeclare const __brand: unique symbol;\ntype Brand<T, B extends string> = T & { readonly [__brand]: B };\n\nexport type TraceId = Brand<string, \"TraceId\">;\nexport type AssertionId = Brand<string, \"AssertionId\">;\nexport type AgentId = Brand<string, \"AgentId\">;\n\nexport function traceId(id: string): TraceId {\n return id as TraceId;\n}\n\nexport function assertionId(id: string): AssertionId {\n return id as AssertionId;\n}\n\nexport function agentId(id: string): AgentId {\n return id as AgentId;\n}\n\n// ---------------------------------------------------------------------------\n// Assertion spec discriminated unions (T5)\n// ---------------------------------------------------------------------------\n\nexport interface SchemaSpec {\n readonly type: \"schema\";\n readonly target: string;\n readonly schema: Record<string, unknown>;\n}\n\nexport interface ConstraintSpec {\n readonly type: \"constraint\";\n readonly field: string;\n readonly operator: string;\n readonly value?: number;\n readonly min?: number;\n readonly max?: number;\n readonly soft: boolean;\n}\n\nexport interface TraceSpec {\n readonly type: \"trace\";\n readonly check: string;\n readonly tools?: string[];\n readonly tool?: string;\n readonly max_repetitions?: number;\n readonly soft: boolean;\n}\n\nexport interface ContentSpec {\n readonly type: \"content\";\n readonly target: string;\n readonly check: string;\n readonly value?: string;\n readonly values?: string[];\n readonly case_sensitive?: boolean;\n readonly soft?: boolean;\n}\n\nexport interface EmbeddingSpec {\n readonly type: \"embedding\";\n readonly target: string;\n readonly reference: string;\n readonly threshold: number | \"dynamic\";\n readonly model?: string;\n readonly soft: boolean;\n}\n\nexport interface LlmJudgeSpec {\n readonly type: \"llm_judge\";\n readonly target: string;\n readonly criteria: string;\n readonly rubric: string;\n readonly threshold: number | \"dynamic\";\n readonly model?: string;\n readonly soft: boolean;\n}\n\nexport interface TraceTreeSpec {\n readonly type: \"trace_tree\";\n readonly check: string;\n readonly [key: string]: unknown;\n}\n\nexport interface PluginSpec {\n readonly type: \"plugin\";\n readonly plugin_id: string;\n readonly config?: Record<string, unknown>;\n readonly soft: boolean;\n}\n\nexport type AssertionSpec =\n | SchemaSpec\n | ConstraintSpec\n | TraceSpec\n | ContentSpec\n | EmbeddingSpec\n | LlmJudgeSpec\n | TraceTreeSpec\n | PluginSpec;\n\n// ---------------------------------------------------------------------------\n// Core protocol types\n// ---------------------------------------------------------------------------\n\nexport interface TraceMetadata {\n readonly total_tokens?: number;\n readonly cost_usd?: number;\n readonly latency_ms?: number;\n readonly model?: string;\n readonly timestamp?: string;\n}\n\nexport interface Step {\n readonly type: string;\n readonly name: string;\n readonly args?: Record<string, unknown>;\n readonly result?: Record<string, unknown>;\n readonly sub_trace?: Trace;\n readonly metadata?: Record<string, unknown>;\n readonly started_at_ms?: number;\n readonly ended_at_ms?: number;\n readonly agent_id?: string;\n readonly agent_role?: string;\n}\n\nexport interface Trace {\n readonly trace_id: string;\n readonly output: Record<string, unknown>;\n readonly schema_version?: number;\n readonly agent_id?: string;\n readonly input?: Record<string, unknown>;\n readonly steps: readonly Step[];\n readonly metadata?: TraceMetadata;\n readonly parent_trace_id?: string;\n}\n\nexport interface Assertion {\n readonly assertion_id: string;\n readonly type: string;\n readonly spec: Record<string, unknown>;\n readonly request_id?: string;\n}\n\n/**\n * Audit trail for an LLM-judge evaluation. Mirrors\n * engine/pkg/types/assertion.go::JudgeMetadata so report v2 payloads\n * round-trip without losing the model / rubric / variance evidence\n * reviewers need to triage a judge failure.\n */\nexport interface JudgeMetadata {\n readonly model?: string;\n readonly rubric_name?: string;\n readonly rubric_version?: string;\n readonly prompt_hash?: string;\n readonly sample_scores?: readonly number[];\n readonly score_mean?: number;\n readonly score_stddev?: number;\n readonly high_variance?: boolean;\n readonly bias_probes?: readonly BiasProbe[];\n readonly calibration?: JudgeAgreement;\n}\n\n/**\n * One judge-bias probe result. Score is the score the judge produced on\n * the mutated input; delta is `score - baseline`. A well-calibrated\n * judge has |delta| close to zero. Mirrors\n * engine/pkg/types/assertion.go::BiasProbe.\n */\nexport interface BiasProbe {\n readonly name: string;\n readonly score: number;\n readonly delta: number;\n}\n\n/**\n * Calibration agreement summary keyed by\n * (rubric_name, rubric_version, prompt_hash). Mirrors\n * engine/pkg/types/assertion.go::JudgeAgreement.\n */\nexport interface JudgeAgreement {\n readonly label_count: number;\n readonly agreement: number;\n readonly cohen_kappa: number;\n readonly roc_auc?: number;\n}\n\nexport interface AssertionResult {\n readonly assertion_id: string;\n readonly status: string;\n readonly score: number;\n readonly explanation: string;\n readonly cost?: number;\n readonly duration_ms?: number;\n readonly request_id?: string;\n readonly threshold_source?: string;\n readonly layer?: number;\n readonly type?: string;\n readonly trace_node_path?: string;\n readonly expected?: string;\n readonly actual?: string;\n readonly suggested_action?: string;\n readonly judge_metadata?: JudgeMetadata;\n}\n\n/**\n * Map an assertion-type string to its pipeline layer (1–8). Returns 0\n * when the type is unknown so callers can route uncategorised results\n * into their own bucket.\n */\nexport function layerForType(assertionType: string | undefined): number {\n switch (assertionType) {\n case \"schema\":\n return 1;\n case \"constraint\":\n return 2;\n case \"trace\":\n case \"trace_tree\":\n return 3;\n case \"content\":\n return 4;\n case \"embedding\":\n return 5;\n case \"llm_judge\":\n return 6;\n case \"plugin\":\n return 8;\n default:\n return 0;\n }\n}\n\nexport interface ErrorData {\n readonly error_type: string;\n readonly retryable: boolean;\n readonly detail: string;\n}\n\nexport interface RPCError {\n readonly code: number;\n readonly message: string;\n readonly data?: ErrorData;\n}\n\nexport interface RPCRequest {\n readonly jsonrpc: \"2.0\";\n readonly id: number;\n readonly method: string;\n readonly params: Record<string, unknown>;\n}\n\nexport interface RPCResponse {\n readonly jsonrpc: \"2.0\";\n readonly id: number;\n readonly result?: unknown;\n readonly error?: RPCError;\n}\n\nexport interface InitializeParams {\n readonly sdk_name: string;\n readonly sdk_version: string;\n readonly protocol_version: number;\n readonly required_capabilities: readonly string[];\n readonly preferred_encoding?: string;\n}\n\nexport interface InitializeResult {\n readonly engine_version: string;\n readonly protocol_version: number;\n readonly capabilities: readonly string[];\n readonly missing: readonly string[];\n readonly compatible: boolean;\n readonly encoding?: string;\n readonly max_concurrent_requests?: number;\n readonly max_trace_size_bytes?: number;\n readonly max_steps_per_trace?: number;\n}\n\nexport interface EvaluateBatchParams {\n readonly trace: Trace;\n readonly assertions: readonly Assertion[];\n}\n\nexport interface EvaluateBatchResult {\n readonly results: readonly AssertionResult[];\n readonly total_cost?: number;\n readonly total_duration_ms?: number;\n /**\n * True when this result was produced by an SDK simulation shim rather\n * than a real engine evaluation. Engine-produced results always carry\n * simulated=false. CI gates can fail builds that accidentally evaluate\n * against the simulator by checking this flag.\n */\n readonly simulated?: boolean;\n}\n\nexport interface ShutdownResult {\n readonly sessions_completed: number;\n readonly assertions_evaluated: number;\n}\n\nexport interface SubmitPluginResultParams {\n readonly trace_id: string;\n readonly plugin_name: string;\n readonly assertion_id: string;\n readonly result: AssertionResult;\n}\n\n// ---------------------------------------------------------------------------\n// Drift detection types\n// ---------------------------------------------------------------------------\n\nexport interface DriftReport {\n readonly assertion_id: string;\n readonly mean: number;\n readonly stddev: number;\n readonly count: number;\n readonly latest_score: number;\n readonly deviation: number;\n readonly status: string;\n}\n\nexport interface QueryDriftParams {\n readonly assertion_id: string;\n readonly window_size: number;\n}\n\nexport interface QueryDriftResult {\n readonly report: DriftReport;\n}\n\n// ---------------------------------------------------------------------------\n// Simulation types\n// ---------------------------------------------------------------------------\n\nexport interface SimulatePersona {\n readonly name: string;\n readonly system_prompt: string;\n readonly style: string;\n readonly temperature: number;\n readonly max_tokens?: number;\n}\n\nexport interface SimulateFaultConfig {\n readonly error_rate: number;\n readonly latency_jitter_ms: number;\n readonly content_corruption: boolean;\n readonly timeout_after_ms: number;\n}\n\nexport interface ConversationMessage {\n readonly role: string;\n readonly content: string;\n}\n\nexport interface GenerateUserMessageParams {\n readonly persona: SimulatePersona;\n readonly conversation_history: readonly ConversationMessage[];\n readonly fault_config?: SimulateFaultConfig;\n}\n\nexport interface GenerateUserMessageResult {\n readonly message: string;\n}\n","import type { ErrorData } from \"./types.js\";\nimport type { ProtocolDiagnostic } from \"./diagnostics.js\";\n\nexport class ProtocolError extends Error {\n readonly code: number;\n readonly errorMessage: string;\n readonly data: ErrorData | undefined;\n\n constructor(code: number, message: string, data?: ErrorData) {\n super(message);\n this.name = \"ProtocolError\";\n this.code = code;\n this.errorMessage = message;\n this.data = data;\n }\n}\n\nexport class EngineTimeoutError extends Error {\n readonly method: string;\n readonly timeoutMs: number;\n\n constructor(method: string, timeoutMs: number) {\n super(\n `Engine request '${method}' timed out after ${timeoutMs}ms. ` +\n \"Set ATTEST_ENGINE_TIMEOUT to increase the limit.\",\n );\n this.name = \"EngineTimeoutError\";\n this.method = method;\n this.timeoutMs = timeoutMs;\n }\n}\n\n/**\n * Raised when the reader loop detects that engine output has lost\n * framing or contains repeated unparseable lines. All in-flight requests\n * are rejected with this error so callers see a visible failure rather\n * than a hung promise.\n */\nexport class ProtocolDesyncError extends Error {\n readonly diagnostics: readonly ProtocolDiagnostic[];\n\n constructor(message: string, diagnostics: readonly ProtocolDiagnostic[]) {\n super(message);\n this.name = \"ProtocolDesyncError\";\n this.diagnostics = diagnostics;\n }\n}\n","/**\n * Protocol diagnostic types for client-side observability.\n *\n * The reader loop emits diagnostics whenever it cannot route a response\n * line: malformed JSON, missing id, unknown id, or non-routable protocol\n * errors. Diagnostics are buffered in a bounded ring (32 entries) and\n * trigger a desync error when the rate exceeds the configured threshold.\n */\n\nexport type ProtocolDiagnosticKind =\n | \"malformed_json\"\n | \"non_object_response\"\n | \"invalid_jsonrpc_version\"\n | \"missing_id\"\n | \"unknown_id\"\n | \"non_routable_error\";\n\nexport interface ProtocolDiagnostic {\n readonly kind: ProtocolDiagnosticKind;\n readonly message: string;\n readonly rawLine: string;\n readonly timestampMs: number;\n}\n\nexport interface ProtocolLogger {\n warn(message: string, ...args: unknown[]): void;\n error(message: string, ...args: unknown[]): void;\n}\n\nconst DEFAULT_BUFFER_SIZE = 32;\nconst MAX_LINE_PREVIEW = 512;\n\nexport class ProtocolDiagnosticBuffer {\n private readonly capacity: number;\n private readonly entries: ProtocolDiagnostic[] = [];\n\n constructor(capacity: number = DEFAULT_BUFFER_SIZE) {\n if (capacity <= 0) {\n throw new Error(\n `ProtocolDiagnosticBuffer capacity must be positive, got ${capacity}`,\n );\n }\n this.capacity = capacity;\n }\n\n push(diagnostic: ProtocolDiagnostic): void {\n if (this.entries.length >= this.capacity) {\n this.entries.shift();\n }\n this.entries.push(diagnostic);\n }\n\n snapshot(): readonly ProtocolDiagnostic[] {\n return this.entries.slice();\n }\n\n countWithin(windowMs: number, nowMs: number): number {\n const cutoff = nowMs - windowMs;\n let count = 0;\n for (let i = this.entries.length - 1; i >= 0; i -= 1) {\n if (this.entries[i]!.timestampMs >= cutoff) {\n count += 1;\n } else {\n break;\n }\n }\n return count;\n }\n\n clear(): void {\n this.entries.length = 0;\n }\n}\n\nexport function previewLine(line: string): string {\n if (line.length <= MAX_LINE_PREVIEW) return line;\n return line.slice(0, MAX_LINE_PREVIEW) + \"…\";\n}\n","import type { ErrorData, RPCResponse } from \"./types.js\";\nimport { ProtocolError } from \"./errors.js\";\n\n/**\n * Encode a JSON-RPC 2.0 request as an NDJSON line.\n */\nexport function encodeRequest(\n id: number,\n method: string,\n params: Record<string, unknown>,\n): string {\n const msg = {\n jsonrpc: \"2.0\" as const,\n id,\n method,\n params,\n };\n return JSON.stringify(msg) + \"\\n\";\n}\n\n/**\n * Decode a JSON-RPC 2.0 response from an NDJSON line.\n * Throws ProtocolError if the response contains an error.\n * Throws Error for malformed JSON or invalid responses.\n */\nexport function decodeResponse(line: string): RPCResponse {\n const text = line.trim();\n if (!text) {\n throw new Error(\"empty response line\");\n }\n\n let data: unknown;\n try {\n data = JSON.parse(text);\n } catch (e) {\n throw new Error(`malformed JSON response: ${e instanceof Error ? e.message : String(e)}`);\n }\n\n if (typeof data !== \"object\" || data === null || Array.isArray(data)) {\n throw new Error(`expected JSON object, got ${Array.isArray(data) ? \"array\" : typeof data}`);\n }\n\n const obj = data as Record<string, unknown>;\n\n if (obj.jsonrpc !== \"2.0\") {\n throw new Error(`invalid jsonrpc version: ${String(obj.jsonrpc)}`);\n }\n\n if (obj.error != null) {\n const err = obj.error as Record<string, unknown>;\n let errorData: ErrorData | undefined;\n\n if (err.data != null) {\n const raw = err.data as Record<string, unknown>;\n errorData = {\n error_type: (raw.error_type as string) ?? \"\",\n retryable: (raw.retryable as boolean) ?? false,\n detail: (raw.detail as string) ?? \"\",\n };\n }\n\n throw new ProtocolError(\n (err.code as number) ?? -1,\n (err.message as string) ?? \"unknown error\",\n errorData,\n );\n }\n\n return obj as unknown as RPCResponse;\n}\n\n/**\n * Extract the result field from a decoded response.\n */\nexport function extractResult(response: RPCResponse): unknown {\n if (response.result === undefined) {\n throw new Error(\"response missing 'result' field\");\n }\n return response.result;\n}\n\n/**\n * Extract the request ID from a decoded response.\n */\nexport function extractId(response: RPCResponse): number {\n if (response.id === undefined) {\n throw new Error(\"response missing 'id' field\");\n }\n return Number(response.id);\n}\n"],"mappings":"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","names":[]}
@@ -65,7 +65,7 @@ interface EmbeddingSpec {
65
65
  readonly type: "embedding";
66
66
  readonly target: string;
67
67
  readonly reference: string;
68
- readonly threshold: number;
68
+ readonly threshold: number | "dynamic";
69
69
  readonly model?: string;
70
70
  readonly soft: boolean;
71
71
  }
@@ -74,7 +74,7 @@ interface LlmJudgeSpec {
74
74
  readonly target: string;
75
75
  readonly criteria: string;
76
76
  readonly rubric: string;
77
- readonly threshold: number;
77
+ readonly threshold: number | "dynamic";
78
78
  readonly model?: string;
79
79
  readonly soft: boolean;
80
80
  }
@@ -125,6 +125,46 @@ interface Assertion {
125
125
  readonly spec: Record<string, unknown>;
126
126
  readonly request_id?: string;
127
127
  }
128
+ /**
129
+ * Audit trail for an LLM-judge evaluation. Mirrors
130
+ * engine/pkg/types/assertion.go::JudgeMetadata so report v2 payloads
131
+ * round-trip without losing the model / rubric / variance evidence
132
+ * reviewers need to triage a judge failure.
133
+ */
134
+ interface JudgeMetadata {
135
+ readonly model?: string;
136
+ readonly rubric_name?: string;
137
+ readonly rubric_version?: string;
138
+ readonly prompt_hash?: string;
139
+ readonly sample_scores?: readonly number[];
140
+ readonly score_mean?: number;
141
+ readonly score_stddev?: number;
142
+ readonly high_variance?: boolean;
143
+ readonly bias_probes?: readonly BiasProbe[];
144
+ readonly calibration?: JudgeAgreement;
145
+ }
146
+ /**
147
+ * One judge-bias probe result. Score is the score the judge produced on
148
+ * the mutated input; delta is `score - baseline`. A well-calibrated
149
+ * judge has |delta| close to zero. Mirrors
150
+ * engine/pkg/types/assertion.go::BiasProbe.
151
+ */
152
+ interface BiasProbe {
153
+ readonly name: string;
154
+ readonly score: number;
155
+ readonly delta: number;
156
+ }
157
+ /**
158
+ * Calibration agreement summary keyed by
159
+ * (rubric_name, rubric_version, prompt_hash). Mirrors
160
+ * engine/pkg/types/assertion.go::JudgeAgreement.
161
+ */
162
+ interface JudgeAgreement {
163
+ readonly label_count: number;
164
+ readonly agreement: number;
165
+ readonly cohen_kappa: number;
166
+ readonly roc_auc?: number;
167
+ }
128
168
  interface AssertionResult {
129
169
  readonly assertion_id: string;
130
170
  readonly status: string;
@@ -133,7 +173,21 @@ interface AssertionResult {
133
173
  readonly cost?: number;
134
174
  readonly duration_ms?: number;
135
175
  readonly request_id?: string;
176
+ readonly threshold_source?: string;
177
+ readonly layer?: number;
178
+ readonly type?: string;
179
+ readonly trace_node_path?: string;
180
+ readonly expected?: string;
181
+ readonly actual?: string;
182
+ readonly suggested_action?: string;
183
+ readonly judge_metadata?: JudgeMetadata;
136
184
  }
185
+ /**
186
+ * Map an assertion-type string to its pipeline layer (1–8). Returns 0
187
+ * when the type is unknown so callers can route uncategorised results
188
+ * into their own bucket.
189
+ */
190
+ declare function layerForType(assertionType: string | undefined): number;
137
191
  interface ErrorData {
138
192
  readonly error_type: string;
139
193
  readonly retryable: boolean;
@@ -182,6 +236,13 @@ interface EvaluateBatchResult {
182
236
  readonly results: readonly AssertionResult[];
183
237
  readonly total_cost?: number;
184
238
  readonly total_duration_ms?: number;
239
+ /**
240
+ * True when this result was produced by an SDK simulation shim rather
241
+ * than a real engine evaluation. Engine-produced results always carry
242
+ * simulated=false. CI gates can fail builds that accidentally evaluate
243
+ * against the simulator by checking this flag.
244
+ */
245
+ readonly simulated?: boolean;
185
246
  }
186
247
  interface ShutdownResult {
187
248
  readonly sessions_completed: number;
@@ -193,6 +254,77 @@ interface SubmitPluginResultParams {
193
254
  readonly assertion_id: string;
194
255
  readonly result: AssertionResult;
195
256
  }
257
+ interface DriftReport {
258
+ readonly assertion_id: string;
259
+ readonly mean: number;
260
+ readonly stddev: number;
261
+ readonly count: number;
262
+ readonly latest_score: number;
263
+ readonly deviation: number;
264
+ readonly status: string;
265
+ }
266
+ interface QueryDriftParams {
267
+ readonly assertion_id: string;
268
+ readonly window_size: number;
269
+ }
270
+ interface QueryDriftResult {
271
+ readonly report: DriftReport;
272
+ }
273
+ interface SimulatePersona {
274
+ readonly name: string;
275
+ readonly system_prompt: string;
276
+ readonly style: string;
277
+ readonly temperature: number;
278
+ readonly max_tokens?: number;
279
+ }
280
+ interface SimulateFaultConfig {
281
+ readonly error_rate: number;
282
+ readonly latency_jitter_ms: number;
283
+ readonly content_corruption: boolean;
284
+ readonly timeout_after_ms: number;
285
+ }
286
+ interface ConversationMessage {
287
+ readonly role: string;
288
+ readonly content: string;
289
+ }
290
+ interface GenerateUserMessageParams {
291
+ readonly persona: SimulatePersona;
292
+ readonly conversation_history: readonly ConversationMessage[];
293
+ readonly fault_config?: SimulateFaultConfig;
294
+ }
295
+ interface GenerateUserMessageResult {
296
+ readonly message: string;
297
+ }
298
+
299
+ /**
300
+ * Protocol diagnostic types for client-side observability.
301
+ *
302
+ * The reader loop emits diagnostics whenever it cannot route a response
303
+ * line: malformed JSON, missing id, unknown id, or non-routable protocol
304
+ * errors. Diagnostics are buffered in a bounded ring (32 entries) and
305
+ * trigger a desync error when the rate exceeds the configured threshold.
306
+ */
307
+ type ProtocolDiagnosticKind = "malformed_json" | "non_object_response" | "invalid_jsonrpc_version" | "missing_id" | "unknown_id" | "non_routable_error";
308
+ interface ProtocolDiagnostic {
309
+ readonly kind: ProtocolDiagnosticKind;
310
+ readonly message: string;
311
+ readonly rawLine: string;
312
+ readonly timestampMs: number;
313
+ }
314
+ interface ProtocolLogger {
315
+ warn(message: string, ...args: unknown[]): void;
316
+ error(message: string, ...args: unknown[]): void;
317
+ }
318
+ declare class ProtocolDiagnosticBuffer {
319
+ private readonly capacity;
320
+ private readonly entries;
321
+ constructor(capacity?: number);
322
+ push(diagnostic: ProtocolDiagnostic): void;
323
+ snapshot(): readonly ProtocolDiagnostic[];
324
+ countWithin(windowMs: number, nowMs: number): number;
325
+ clear(): void;
326
+ }
327
+ declare function previewLine(line: string): string;
196
328
 
197
329
  declare class ProtocolError extends Error {
198
330
  readonly code: number;
@@ -205,6 +337,16 @@ declare class EngineTimeoutError extends Error {
205
337
  readonly timeoutMs: number;
206
338
  constructor(method: string, timeoutMs: number);
207
339
  }
340
+ /**
341
+ * Raised when the reader loop detects that engine output has lost
342
+ * framing or contains repeated unparseable lines. All in-flight requests
343
+ * are rejected with this error so callers see a visible failure rather
344
+ * than a hung promise.
345
+ */
346
+ declare class ProtocolDesyncError extends Error {
347
+ readonly diagnostics: readonly ProtocolDiagnostic[];
348
+ constructor(message: string, diagnostics: readonly ProtocolDiagnostic[]);
349
+ }
208
350
 
209
351
  /**
210
352
  * Encode a JSON-RPC 2.0 request as an NDJSON line.
@@ -225,4 +367,4 @@ declare function extractResult(response: RPCResponse): unknown;
225
367
  */
226
368
  declare function extractId(response: RPCResponse): number;
227
369
 
228
- export { type AgentId, type Assertion, type AssertionId, type AssertionResult, type AssertionSpec, type ConstraintSpec, type ContentSpec, ERR_ASSERTION_ERROR, ERR_ENGINE_ERROR, ERR_INVALID_TRACE, ERR_PROVIDER_ERROR, ERR_SESSION_ERROR, ERR_TIMEOUT, type EmbeddingSpec, EngineTimeoutError, type ErrorData, type EvaluateBatchParams, type EvaluateBatchResult, type InitializeParams, type InitializeResult, type LlmJudgeSpec, type PluginSpec, ProtocolError, type RPCError, type RPCRequest, type RPCResponse, STATUS_HARD_FAIL, STATUS_PASS, STATUS_SOFT_FAIL, STEP_AGENT_CALL, STEP_LLM_CALL, STEP_RETRIEVAL, STEP_TOOL_CALL, type SchemaSpec, type ShutdownResult, type Step, type SubmitPluginResultParams, TYPE_CONSTRAINT, TYPE_CONTENT, TYPE_EMBEDDING, TYPE_LLM_JUDGE, TYPE_PLUGIN, TYPE_SCHEMA, TYPE_TRACE, TYPE_TRACE_TREE, type Trace, type TraceId, type TraceMetadata, type TraceSpec, type TraceTreeSpec, agentId, assertionId, decodeResponse, encodeRequest, extractId, extractResult, traceId };
370
+ export { type AgentId, type Assertion, type AssertionId, type AssertionResult, type AssertionSpec, type BiasProbe, type ConstraintSpec, type ContentSpec, type ConversationMessage, type DriftReport, ERR_ASSERTION_ERROR, ERR_ENGINE_ERROR, ERR_INVALID_TRACE, ERR_PROVIDER_ERROR, ERR_SESSION_ERROR, ERR_TIMEOUT, type EmbeddingSpec, EngineTimeoutError, type ErrorData, type EvaluateBatchParams, type EvaluateBatchResult, type GenerateUserMessageParams, type GenerateUserMessageResult, type InitializeParams, type InitializeResult, type JudgeAgreement, type JudgeMetadata, type LlmJudgeSpec, type PluginSpec, ProtocolDesyncError, type ProtocolDiagnostic, ProtocolDiagnosticBuffer, type ProtocolDiagnosticKind, ProtocolError, type ProtocolLogger, type QueryDriftParams, type QueryDriftResult, type RPCError, type RPCRequest, type RPCResponse, STATUS_HARD_FAIL, STATUS_PASS, STATUS_SOFT_FAIL, STEP_AGENT_CALL, STEP_LLM_CALL, STEP_RETRIEVAL, STEP_TOOL_CALL, type SchemaSpec, type ShutdownResult, type SimulateFaultConfig, type SimulatePersona, type Step, type SubmitPluginResultParams, TYPE_CONSTRAINT, TYPE_CONTENT, TYPE_EMBEDDING, TYPE_LLM_JUDGE, TYPE_PLUGIN, TYPE_SCHEMA, TYPE_TRACE, TYPE_TRACE_TREE, type Trace, type TraceId, type TraceMetadata, type TraceSpec, type TraceTreeSpec, agentId, assertionId, decodeResponse, encodeRequest, extractId, extractResult, layerForType, previewLine, traceId };