@vorim/sdk 3.1.0 → 3.2.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 (37) hide show
  1. package/dist/index.cjs +174 -6
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.d.cts +226 -2
  4. package/dist/index.d.ts +226 -2
  5. package/dist/index.js +163 -5
  6. package/dist/index.js.map +1 -1
  7. package/dist/integrations/anthropic.cjs +108 -4
  8. package/dist/integrations/anthropic.cjs.map +1 -1
  9. package/dist/integrations/anthropic.d.cts +13 -2
  10. package/dist/integrations/anthropic.d.ts +13 -2
  11. package/dist/integrations/anthropic.js +96 -4
  12. package/dist/integrations/anthropic.js.map +1 -1
  13. package/dist/integrations/crewai.cjs +8 -2
  14. package/dist/integrations/crewai.cjs.map +1 -1
  15. package/dist/integrations/crewai.d.cts +18 -0
  16. package/dist/integrations/crewai.d.ts +18 -0
  17. package/dist/integrations/crewai.js +8 -2
  18. package/dist/integrations/crewai.js.map +1 -1
  19. package/dist/integrations/langchain.cjs +140 -10
  20. package/dist/integrations/langchain.cjs.map +1 -1
  21. package/dist/integrations/langchain.d.cts +23 -2
  22. package/dist/integrations/langchain.d.ts +23 -2
  23. package/dist/integrations/langchain.js +128 -10
  24. package/dist/integrations/langchain.js.map +1 -1
  25. package/dist/integrations/llamaindex.cjs +96 -4
  26. package/dist/integrations/llamaindex.cjs.map +1 -1
  27. package/dist/integrations/llamaindex.d.cts +7 -1
  28. package/dist/integrations/llamaindex.d.ts +7 -1
  29. package/dist/integrations/llamaindex.js +84 -4
  30. package/dist/integrations/llamaindex.js.map +1 -1
  31. package/dist/integrations/openai.cjs +108 -4
  32. package/dist/integrations/openai.cjs.map +1 -1
  33. package/dist/integrations/openai.d.cts +15 -2
  34. package/dist/integrations/openai.d.ts +15 -2
  35. package/dist/integrations/openai.js +96 -4
  36. package/dist/integrations/openai.js.map +1 -1
  37. package/package.json +1 -1
package/dist/index.d.cts CHANGED
@@ -52,6 +52,29 @@ interface AuditEventInput {
52
52
  error_code?: string;
53
53
  signature?: string;
54
54
  metadata?: Record<string, unknown>;
55
+ /**
56
+ * Replayable agent decision evidence (VAIP -02 schema fields).
57
+ *
58
+ * Stored and exported but NOT covered by the v0 canonical signature
59
+ * form. They will enter canonical bytes in v1 (RFC 8785 JCS) in a
60
+ * follow-up release. Until then, advisory.
61
+ *
62
+ * Use the helpers from this package to compute the hashes:
63
+ * - {@link hashToolCatalogue}
64
+ * - {@link hashSystemPrompt}
65
+ */
66
+ model_version?: string;
67
+ tool_catalogue_hash?: string;
68
+ system_prompt_hash?: string;
69
+ prev_event_hash?: string;
70
+ /**
71
+ * Canonical-form recipe the `signature` was computed over.
72
+ * Absent/null ↔ 'v0' (pipe-joined six-field form). Set to 'v1' for
73
+ * RFC 8785 JCS over the full event minus signature and canonical_form.
74
+ * The SDK sets this automatically when {@link VorimConfig.canonicalForm}
75
+ * is `"v1"`; you can also pass it on a per-event basis.
76
+ */
77
+ canonical_form?: 'v0' | 'v1';
55
78
  }
56
79
  interface TrustRecord {
57
80
  agent_id: string;
@@ -68,6 +91,138 @@ interface TrustRecord {
68
91
  last_active?: string;
69
92
  }
70
93
 
94
+ /**
95
+ * Replayable agent decision evidence helpers.
96
+ *
97
+ * Canonical-form hashing for the VAIP -02 schema fields that the SDK
98
+ * attaches to audit events. The hashes recorded in audit_events.tool_catalogue_hash
99
+ * and audit_events.system_prompt_hash use these functions, so the bytes
100
+ * an auditor or counterparty reconstructs must match what the SDK produced.
101
+ *
102
+ * These helpers are intentionally separate from the signing path. The
103
+ * v0 canonical signature form (event_type|action|resource|input_hash|
104
+ * output_hash|result) does NOT cover model_version, tool_catalogue_hash,
105
+ * or system_prompt_hash. They will enter the canonical bytes in v1
106
+ * (RFC 8785 JCS) in a follow-up release.
107
+ *
108
+ * Stable across SDK versions: the canonical-form version is documented
109
+ * in CANONICAL_TOOL_CATALOGUE_VERSION. Future changes get a v2 etc;
110
+ * never edit the existing v1 logic, or already-recorded hashes lose
111
+ * their meaning.
112
+ */
113
+ /**
114
+ * Canonical-form version for tool catalogue hashes produced by this SDK.
115
+ * Recorded in tool_catalogue_canon_version on the event metadata (when
116
+ * the metadata field is used) so verifiers know which hash recipe to
117
+ * reproduce. Increment ONLY if the algorithm changes in a way that
118
+ * would change the hash for the same logical catalogue.
119
+ */
120
+ declare const CANONICAL_TOOL_CATALOGUE_VERSION: "v1";
121
+ /**
122
+ * Minimum shape a tool needs for catalogue hashing. The framework
123
+ * integrations adapt their native tool objects to this shape before
124
+ * calling hashToolCatalogue.
125
+ */
126
+ interface CatalogueTool {
127
+ /** The name the model sees and calls. Required. */
128
+ name: string;
129
+ /** Human-readable description shown to the model. Optional; absent ↔ empty string. */
130
+ description?: string;
131
+ /**
132
+ * JSON Schema describing the tool's input parameters. Optional;
133
+ * absent ↔ empty object `{}`. The schema gets RFC 8785 JCS-canonicalised
134
+ * before hashing so semantically-equivalent variations (key order,
135
+ * whitespace) produce the same hash.
136
+ */
137
+ schema?: Record<string, unknown> | null;
138
+ }
139
+ /**
140
+ * RFC 8785 JSON Canonicalization Scheme, sufficient subset for tool
141
+ * catalogue values.
142
+ *
143
+ * Rules:
144
+ * - Object keys sorted lexicographically by UTF-16 code units (which
145
+ * is what JS string comparison does naturally).
146
+ * - No whitespace between tokens.
147
+ * - Numbers: integers as integers, finite floats per ECMAScript
148
+ * Number.prototype.toString. JCS forbids NaN and Infinity.
149
+ * - Strings: JSON-escape using minimal set per RFC 8259 § 7.
150
+ * - null, true, false, arrays: as JSON.stringify produces them, since
151
+ * JSON.stringify already produces the canonical form for these.
152
+ *
153
+ * Not vendoring a full library because tool schemas don't carry
154
+ * non-integer numbers in practice and the JS spec for Number.toString
155
+ * happens to coincide with JCS § 3.2.2.2 for the integer case.
156
+ */
157
+ declare function jcsCanonicalise(value: unknown): string;
158
+ /**
159
+ * Hash a single tool definition. Returns `sha256:<hex>`.
160
+ *
161
+ * Canonical form (v1):
162
+ * JCS-canonicalised JSON of `{name, description, schema}` where
163
+ * absent fields substitute `description: ""` and `schema: {}`.
164
+ */
165
+ declare function hashTool(tool: CatalogueTool): Promise<string>;
166
+ /**
167
+ * Hash an entire tool catalogue. Returns `sha256:<hex>`.
168
+ *
169
+ * Reordering tools does NOT change the hash (tool hashes sorted
170
+ * lexicographically before concatenation). Adding, removing, or
171
+ * modifying a tool DOES change the hash.
172
+ *
173
+ * Per-tool hashing first means a verifier comparing two catalogue
174
+ * hashes that differ can also be given the per-tool hashes to
175
+ * identify which specific tool changed.
176
+ */
177
+ declare function hashToolCatalogue(tools: CatalogueTool[]): Promise<string>;
178
+ /**
179
+ * Hash a system prompt. Returns `sha256:<hex>`.
180
+ *
181
+ * The prompt is UTF-8 encoded and hashed verbatim — no normalisation.
182
+ * If a caller wants to ignore whitespace or comment differences, they
183
+ * should normalise before calling. The intent here is deterministic
184
+ * reproducibility, not semantic equivalence.
185
+ */
186
+ declare function hashSystemPrompt(prompt: string): Promise<string>;
187
+ /**
188
+ * Convenience: hash the previous event's canonical bytes for use in
189
+ * the prev_event_hash field of hash-chained ingest. Caller provides
190
+ * the canonical bytes (use canonicalPayloadV0 from the main module).
191
+ */
192
+ declare function hashPreviousEvent(canonicalBytes: string): Promise<string>;
193
+ /**
194
+ * Raw inputs the integration captures from the framework. Set by the
195
+ * integration's config; turned into hashes by {@link prepareReplayContext}.
196
+ */
197
+ interface ReplayInputs {
198
+ /** Stable identifier for the model. E.g. `"anthropic:claude-opus-4-8"`. */
199
+ modelVersion?: string;
200
+ /** Tools available to the agent at call time. Hashed via {@link hashToolCatalogue}. */
201
+ tools?: CatalogueTool[];
202
+ /** System prompt active at call time. Hashed via {@link hashSystemPrompt}. */
203
+ systemPrompt?: string;
204
+ }
205
+ /**
206
+ * Pre-computed hashes ready to attach to audit events. The three keys
207
+ * match the audit_events column names.
208
+ */
209
+ interface ReplayContext {
210
+ model_version?: string;
211
+ tool_catalogue_hash?: string;
212
+ system_prompt_hash?: string;
213
+ }
214
+ /**
215
+ * Compute replay context once from raw inputs. Use at integration
216
+ * setup time so each emit can attach the hashes without re-hashing.
217
+ *
218
+ * Returns an object suitable for spreading into an AuditEventInput:
219
+ * `await vorim.emit({ ...event, ...replayContext })`
220
+ *
221
+ * If a field is absent in the inputs, it is absent in the result
222
+ * (not the empty string). That keeps the event lean.
223
+ */
224
+ declare function prepareReplayContext(inputs: ReplayInputs): Promise<ReplayContext>;
225
+
71
226
  interface VorimConfig {
72
227
  apiKey: string;
73
228
  baseUrl?: string;
@@ -80,6 +235,25 @@ interface VorimConfig {
80
235
  * {@link VorimSDK.register}. Events for unknown agents pass through unsigned.
81
236
  */
82
237
  autoSign?: boolean;
238
+ /**
239
+ * Canonical form to use when signing. Default `"v0"` for backward-compat
240
+ * with `@vorim/sdk` 3.1.x. Set to `"v1"` to sign the full event object
241
+ * via RFC 8785 JCS, covering replayable-evidence fields (model_version,
242
+ * tool_catalogue_hash, system_prompt_hash, prev_event_hash). v1 events
243
+ * carry `canonical_form: "v1"` on the wire so the server can dispatch
244
+ * verification correctly.
245
+ */
246
+ canonicalForm?: 'v0' | 'v1';
247
+ /**
248
+ * Hash-chain events per agent so deletion of a single audit row
249
+ * becomes detectable. Default `false` (no chaining). When enabled,
250
+ * the SDK sets `prev_event_hash` on each event to SHA-256 of the
251
+ * previous event's canonical bytes for the same agent. The first
252
+ * event after enable / process restart has `prev_event_hash = null`,
253
+ * which the verifier reports as `chain_restart` (informational, not
254
+ * a failure). Chain integrity is checked by `@vorim/verify`.
255
+ */
256
+ chainEvents?: boolean;
83
257
  }
84
258
  /**
85
259
  * VAIP v0 canonical bytes used by Vorim's per-event signing.
@@ -94,11 +268,25 @@ interface VorimConfig {
94
268
  * edit this one. Old signatures must remain verifiable.
95
269
  */
96
270
  declare function canonicalPayloadV0(event: AuditEventInput): string;
271
+ /**
272
+ * VAIP v1 canonical bytes for audit-event signing (RFC 8785 JCS).
273
+ *
274
+ * Signs the full event object excluding `signature` (the field being
275
+ * computed) and `canonical_form` (metadata about the recipe). Unlike v0,
276
+ * v1 covers the replayable-evidence fields and the metadata field.
277
+ *
278
+ * Re-exports `jcsCanonicalise` from `./replay.js` which is the byte-exact
279
+ * twin of `@vorim/shared-types`' implementation. The cross-language parity
280
+ * script enforces equivalence with the Python SDK.
281
+ */
282
+ declare function canonicalPayloadV1(event: AuditEventInput): string;
97
283
  declare class VorimSDK {
98
284
  private apiKey;
99
285
  private baseUrl;
100
286
  private timeout;
101
287
  private autoSign;
288
+ private canonicalForm;
289
+ private chainEvents;
102
290
  /**
103
291
  * In-memory keyring mapping agent_id -> PEM-encoded Ed25519 private key.
104
292
  * Populated automatically by register() and registerEphemeral(), or
@@ -106,6 +294,21 @@ declare class VorimSDK {
106
294
  * caller is responsible for durable key storage.
107
295
  */
108
296
  private agentKeys;
297
+ /**
298
+ * Per-agent hash of the last emitted event's canonical bytes. Used to
299
+ * populate prev_event_hash on the next emit when chainEvents is on.
300
+ * Empty string ↔ no previous event (chain restart). Reset by
301
+ * forgetAgentKey() so reusing an agent_id after revocation doesn't
302
+ * link to the old chain.
303
+ */
304
+ private lastEventHash;
305
+ /**
306
+ * Per-agent emit promise. Each new emit awaits the previous one so
307
+ * the chain is constructed in order. Concurrent emits to the same
308
+ * agent are serialised (correct); concurrent emits to different
309
+ * agents remain parallel (fast).
310
+ */
311
+ private chainLocks;
109
312
  constructor(config: VorimConfig);
110
313
  /**
111
314
  * Register a previously-issued agent keypair so this SDK instance can
@@ -117,7 +320,8 @@ declare class VorimSDK {
117
320
  /**
118
321
  * Forget an agent's signing key (e.g. after revocation). Subsequent emit()
119
322
  * calls for that agent will pass through unsigned unless a key is provided
120
- * inline.
323
+ * inline. Also clears the per-agent chain state — re-using the same
324
+ * agent_id after revocation does NOT link to the old chain.
121
325
  */
122
326
  forgetAgentKey(agentId: string): void;
123
327
  /**
@@ -220,8 +424,28 @@ declare class VorimSDK {
220
424
  * signatures on the event are respected (caller-signed events are not
221
425
  * re-signed). Per-agent failure is non-fatal: if signing throws, the event
222
426
  * still sends unsigned so a single bad key doesn't break a batch.
427
+ *
428
+ * Canonical-form dispatch:
429
+ * - If the event already carries `canonical_form`, that wins (caller
430
+ * opted in/out for this specific event).
431
+ * - Otherwise the SDK-level `canonicalForm` (config) applies.
432
+ * - v0 signs the pipe-joined 6 fields. v1 signs the RFC 8785 JCS
433
+ * bytes over the full event minus signature and canonical_form,
434
+ * and the event goes on the wire with `canonical_form: "v1"`.
435
+ *
436
+ * Chain construction:
437
+ * - When chainEvents is on, the event gets `prev_event_hash` set to
438
+ * the SHA-256 of the previous event's canonical bytes for the
439
+ * same agent, set BEFORE the signature is computed (so v1
440
+ * signatures cover the chain link).
441
+ * - Chain ops are serialised per-agent via `chainLocks` so
442
+ * concurrent emits to the same agent build a deterministic chain.
223
443
  */
224
444
  private prepareEvent;
445
+ /** Serialise per-agent and apply chain hash + sign. */
446
+ private prepareEventChained;
447
+ /** Sign an event right now, no chain handling. */
448
+ private signEventNow;
225
449
  /**
226
450
  * Export a signed audit bundle for a date range.
227
451
  */
@@ -344,4 +568,4 @@ declare class VorimError extends Error {
344
568
  }
345
569
  declare function createVorim(config: VorimConfig): VorimSDK;
346
570
 
347
- export { type Agent, type AgentRegistrationInput, type AgentRegistrationResult, type AgentStatus, type AuditEventInput, type AuditEventType, type AuditResult, type PermissionCheckResult, type PermissionScope, type TrustRecord, type VorimConfig, VorimError, VorimSDK, canonicalPayloadV0, createVorim as default };
571
+ export { type Agent, type AgentRegistrationInput, type AgentRegistrationResult, type AgentStatus, type AuditEventInput, type AuditEventType, type AuditResult, CANONICAL_TOOL_CATALOGUE_VERSION, type CatalogueTool, type PermissionCheckResult, type PermissionScope, type ReplayContext, type ReplayInputs, type TrustRecord, type VorimConfig, VorimError, VorimSDK, canonicalPayloadV0, canonicalPayloadV1, createVorim as default, hashPreviousEvent, hashSystemPrompt, hashTool, hashToolCatalogue, jcsCanonicalise, prepareReplayContext };
package/dist/index.d.ts CHANGED
@@ -52,6 +52,29 @@ interface AuditEventInput {
52
52
  error_code?: string;
53
53
  signature?: string;
54
54
  metadata?: Record<string, unknown>;
55
+ /**
56
+ * Replayable agent decision evidence (VAIP -02 schema fields).
57
+ *
58
+ * Stored and exported but NOT covered by the v0 canonical signature
59
+ * form. They will enter canonical bytes in v1 (RFC 8785 JCS) in a
60
+ * follow-up release. Until then, advisory.
61
+ *
62
+ * Use the helpers from this package to compute the hashes:
63
+ * - {@link hashToolCatalogue}
64
+ * - {@link hashSystemPrompt}
65
+ */
66
+ model_version?: string;
67
+ tool_catalogue_hash?: string;
68
+ system_prompt_hash?: string;
69
+ prev_event_hash?: string;
70
+ /**
71
+ * Canonical-form recipe the `signature` was computed over.
72
+ * Absent/null ↔ 'v0' (pipe-joined six-field form). Set to 'v1' for
73
+ * RFC 8785 JCS over the full event minus signature and canonical_form.
74
+ * The SDK sets this automatically when {@link VorimConfig.canonicalForm}
75
+ * is `"v1"`; you can also pass it on a per-event basis.
76
+ */
77
+ canonical_form?: 'v0' | 'v1';
55
78
  }
56
79
  interface TrustRecord {
57
80
  agent_id: string;
@@ -68,6 +91,138 @@ interface TrustRecord {
68
91
  last_active?: string;
69
92
  }
70
93
 
94
+ /**
95
+ * Replayable agent decision evidence helpers.
96
+ *
97
+ * Canonical-form hashing for the VAIP -02 schema fields that the SDK
98
+ * attaches to audit events. The hashes recorded in audit_events.tool_catalogue_hash
99
+ * and audit_events.system_prompt_hash use these functions, so the bytes
100
+ * an auditor or counterparty reconstructs must match what the SDK produced.
101
+ *
102
+ * These helpers are intentionally separate from the signing path. The
103
+ * v0 canonical signature form (event_type|action|resource|input_hash|
104
+ * output_hash|result) does NOT cover model_version, tool_catalogue_hash,
105
+ * or system_prompt_hash. They will enter the canonical bytes in v1
106
+ * (RFC 8785 JCS) in a follow-up release.
107
+ *
108
+ * Stable across SDK versions: the canonical-form version is documented
109
+ * in CANONICAL_TOOL_CATALOGUE_VERSION. Future changes get a v2 etc;
110
+ * never edit the existing v1 logic, or already-recorded hashes lose
111
+ * their meaning.
112
+ */
113
+ /**
114
+ * Canonical-form version for tool catalogue hashes produced by this SDK.
115
+ * Recorded in tool_catalogue_canon_version on the event metadata (when
116
+ * the metadata field is used) so verifiers know which hash recipe to
117
+ * reproduce. Increment ONLY if the algorithm changes in a way that
118
+ * would change the hash for the same logical catalogue.
119
+ */
120
+ declare const CANONICAL_TOOL_CATALOGUE_VERSION: "v1";
121
+ /**
122
+ * Minimum shape a tool needs for catalogue hashing. The framework
123
+ * integrations adapt their native tool objects to this shape before
124
+ * calling hashToolCatalogue.
125
+ */
126
+ interface CatalogueTool {
127
+ /** The name the model sees and calls. Required. */
128
+ name: string;
129
+ /** Human-readable description shown to the model. Optional; absent ↔ empty string. */
130
+ description?: string;
131
+ /**
132
+ * JSON Schema describing the tool's input parameters. Optional;
133
+ * absent ↔ empty object `{}`. The schema gets RFC 8785 JCS-canonicalised
134
+ * before hashing so semantically-equivalent variations (key order,
135
+ * whitespace) produce the same hash.
136
+ */
137
+ schema?: Record<string, unknown> | null;
138
+ }
139
+ /**
140
+ * RFC 8785 JSON Canonicalization Scheme, sufficient subset for tool
141
+ * catalogue values.
142
+ *
143
+ * Rules:
144
+ * - Object keys sorted lexicographically by UTF-16 code units (which
145
+ * is what JS string comparison does naturally).
146
+ * - No whitespace between tokens.
147
+ * - Numbers: integers as integers, finite floats per ECMAScript
148
+ * Number.prototype.toString. JCS forbids NaN and Infinity.
149
+ * - Strings: JSON-escape using minimal set per RFC 8259 § 7.
150
+ * - null, true, false, arrays: as JSON.stringify produces them, since
151
+ * JSON.stringify already produces the canonical form for these.
152
+ *
153
+ * Not vendoring a full library because tool schemas don't carry
154
+ * non-integer numbers in practice and the JS spec for Number.toString
155
+ * happens to coincide with JCS § 3.2.2.2 for the integer case.
156
+ */
157
+ declare function jcsCanonicalise(value: unknown): string;
158
+ /**
159
+ * Hash a single tool definition. Returns `sha256:<hex>`.
160
+ *
161
+ * Canonical form (v1):
162
+ * JCS-canonicalised JSON of `{name, description, schema}` where
163
+ * absent fields substitute `description: ""` and `schema: {}`.
164
+ */
165
+ declare function hashTool(tool: CatalogueTool): Promise<string>;
166
+ /**
167
+ * Hash an entire tool catalogue. Returns `sha256:<hex>`.
168
+ *
169
+ * Reordering tools does NOT change the hash (tool hashes sorted
170
+ * lexicographically before concatenation). Adding, removing, or
171
+ * modifying a tool DOES change the hash.
172
+ *
173
+ * Per-tool hashing first means a verifier comparing two catalogue
174
+ * hashes that differ can also be given the per-tool hashes to
175
+ * identify which specific tool changed.
176
+ */
177
+ declare function hashToolCatalogue(tools: CatalogueTool[]): Promise<string>;
178
+ /**
179
+ * Hash a system prompt. Returns `sha256:<hex>`.
180
+ *
181
+ * The prompt is UTF-8 encoded and hashed verbatim — no normalisation.
182
+ * If a caller wants to ignore whitespace or comment differences, they
183
+ * should normalise before calling. The intent here is deterministic
184
+ * reproducibility, not semantic equivalence.
185
+ */
186
+ declare function hashSystemPrompt(prompt: string): Promise<string>;
187
+ /**
188
+ * Convenience: hash the previous event's canonical bytes for use in
189
+ * the prev_event_hash field of hash-chained ingest. Caller provides
190
+ * the canonical bytes (use canonicalPayloadV0 from the main module).
191
+ */
192
+ declare function hashPreviousEvent(canonicalBytes: string): Promise<string>;
193
+ /**
194
+ * Raw inputs the integration captures from the framework. Set by the
195
+ * integration's config; turned into hashes by {@link prepareReplayContext}.
196
+ */
197
+ interface ReplayInputs {
198
+ /** Stable identifier for the model. E.g. `"anthropic:claude-opus-4-8"`. */
199
+ modelVersion?: string;
200
+ /** Tools available to the agent at call time. Hashed via {@link hashToolCatalogue}. */
201
+ tools?: CatalogueTool[];
202
+ /** System prompt active at call time. Hashed via {@link hashSystemPrompt}. */
203
+ systemPrompt?: string;
204
+ }
205
+ /**
206
+ * Pre-computed hashes ready to attach to audit events. The three keys
207
+ * match the audit_events column names.
208
+ */
209
+ interface ReplayContext {
210
+ model_version?: string;
211
+ tool_catalogue_hash?: string;
212
+ system_prompt_hash?: string;
213
+ }
214
+ /**
215
+ * Compute replay context once from raw inputs. Use at integration
216
+ * setup time so each emit can attach the hashes without re-hashing.
217
+ *
218
+ * Returns an object suitable for spreading into an AuditEventInput:
219
+ * `await vorim.emit({ ...event, ...replayContext })`
220
+ *
221
+ * If a field is absent in the inputs, it is absent in the result
222
+ * (not the empty string). That keeps the event lean.
223
+ */
224
+ declare function prepareReplayContext(inputs: ReplayInputs): Promise<ReplayContext>;
225
+
71
226
  interface VorimConfig {
72
227
  apiKey: string;
73
228
  baseUrl?: string;
@@ -80,6 +235,25 @@ interface VorimConfig {
80
235
  * {@link VorimSDK.register}. Events for unknown agents pass through unsigned.
81
236
  */
82
237
  autoSign?: boolean;
238
+ /**
239
+ * Canonical form to use when signing. Default `"v0"` for backward-compat
240
+ * with `@vorim/sdk` 3.1.x. Set to `"v1"` to sign the full event object
241
+ * via RFC 8785 JCS, covering replayable-evidence fields (model_version,
242
+ * tool_catalogue_hash, system_prompt_hash, prev_event_hash). v1 events
243
+ * carry `canonical_form: "v1"` on the wire so the server can dispatch
244
+ * verification correctly.
245
+ */
246
+ canonicalForm?: 'v0' | 'v1';
247
+ /**
248
+ * Hash-chain events per agent so deletion of a single audit row
249
+ * becomes detectable. Default `false` (no chaining). When enabled,
250
+ * the SDK sets `prev_event_hash` on each event to SHA-256 of the
251
+ * previous event's canonical bytes for the same agent. The first
252
+ * event after enable / process restart has `prev_event_hash = null`,
253
+ * which the verifier reports as `chain_restart` (informational, not
254
+ * a failure). Chain integrity is checked by `@vorim/verify`.
255
+ */
256
+ chainEvents?: boolean;
83
257
  }
84
258
  /**
85
259
  * VAIP v0 canonical bytes used by Vorim's per-event signing.
@@ -94,11 +268,25 @@ interface VorimConfig {
94
268
  * edit this one. Old signatures must remain verifiable.
95
269
  */
96
270
  declare function canonicalPayloadV0(event: AuditEventInput): string;
271
+ /**
272
+ * VAIP v1 canonical bytes for audit-event signing (RFC 8785 JCS).
273
+ *
274
+ * Signs the full event object excluding `signature` (the field being
275
+ * computed) and `canonical_form` (metadata about the recipe). Unlike v0,
276
+ * v1 covers the replayable-evidence fields and the metadata field.
277
+ *
278
+ * Re-exports `jcsCanonicalise` from `./replay.js` which is the byte-exact
279
+ * twin of `@vorim/shared-types`' implementation. The cross-language parity
280
+ * script enforces equivalence with the Python SDK.
281
+ */
282
+ declare function canonicalPayloadV1(event: AuditEventInput): string;
97
283
  declare class VorimSDK {
98
284
  private apiKey;
99
285
  private baseUrl;
100
286
  private timeout;
101
287
  private autoSign;
288
+ private canonicalForm;
289
+ private chainEvents;
102
290
  /**
103
291
  * In-memory keyring mapping agent_id -> PEM-encoded Ed25519 private key.
104
292
  * Populated automatically by register() and registerEphemeral(), or
@@ -106,6 +294,21 @@ declare class VorimSDK {
106
294
  * caller is responsible for durable key storage.
107
295
  */
108
296
  private agentKeys;
297
+ /**
298
+ * Per-agent hash of the last emitted event's canonical bytes. Used to
299
+ * populate prev_event_hash on the next emit when chainEvents is on.
300
+ * Empty string ↔ no previous event (chain restart). Reset by
301
+ * forgetAgentKey() so reusing an agent_id after revocation doesn't
302
+ * link to the old chain.
303
+ */
304
+ private lastEventHash;
305
+ /**
306
+ * Per-agent emit promise. Each new emit awaits the previous one so
307
+ * the chain is constructed in order. Concurrent emits to the same
308
+ * agent are serialised (correct); concurrent emits to different
309
+ * agents remain parallel (fast).
310
+ */
311
+ private chainLocks;
109
312
  constructor(config: VorimConfig);
110
313
  /**
111
314
  * Register a previously-issued agent keypair so this SDK instance can
@@ -117,7 +320,8 @@ declare class VorimSDK {
117
320
  /**
118
321
  * Forget an agent's signing key (e.g. after revocation). Subsequent emit()
119
322
  * calls for that agent will pass through unsigned unless a key is provided
120
- * inline.
323
+ * inline. Also clears the per-agent chain state — re-using the same
324
+ * agent_id after revocation does NOT link to the old chain.
121
325
  */
122
326
  forgetAgentKey(agentId: string): void;
123
327
  /**
@@ -220,8 +424,28 @@ declare class VorimSDK {
220
424
  * signatures on the event are respected (caller-signed events are not
221
425
  * re-signed). Per-agent failure is non-fatal: if signing throws, the event
222
426
  * still sends unsigned so a single bad key doesn't break a batch.
427
+ *
428
+ * Canonical-form dispatch:
429
+ * - If the event already carries `canonical_form`, that wins (caller
430
+ * opted in/out for this specific event).
431
+ * - Otherwise the SDK-level `canonicalForm` (config) applies.
432
+ * - v0 signs the pipe-joined 6 fields. v1 signs the RFC 8785 JCS
433
+ * bytes over the full event minus signature and canonical_form,
434
+ * and the event goes on the wire with `canonical_form: "v1"`.
435
+ *
436
+ * Chain construction:
437
+ * - When chainEvents is on, the event gets `prev_event_hash` set to
438
+ * the SHA-256 of the previous event's canonical bytes for the
439
+ * same agent, set BEFORE the signature is computed (so v1
440
+ * signatures cover the chain link).
441
+ * - Chain ops are serialised per-agent via `chainLocks` so
442
+ * concurrent emits to the same agent build a deterministic chain.
223
443
  */
224
444
  private prepareEvent;
445
+ /** Serialise per-agent and apply chain hash + sign. */
446
+ private prepareEventChained;
447
+ /** Sign an event right now, no chain handling. */
448
+ private signEventNow;
225
449
  /**
226
450
  * Export a signed audit bundle for a date range.
227
451
  */
@@ -344,4 +568,4 @@ declare class VorimError extends Error {
344
568
  }
345
569
  declare function createVorim(config: VorimConfig): VorimSDK;
346
570
 
347
- export { type Agent, type AgentRegistrationInput, type AgentRegistrationResult, type AgentStatus, type AuditEventInput, type AuditEventType, type AuditResult, type PermissionCheckResult, type PermissionScope, type TrustRecord, type VorimConfig, VorimError, VorimSDK, canonicalPayloadV0, createVorim as default };
571
+ export { type Agent, type AgentRegistrationInput, type AgentRegistrationResult, type AgentStatus, type AuditEventInput, type AuditEventType, type AuditResult, CANONICAL_TOOL_CATALOGUE_VERSION, type CatalogueTool, type PermissionCheckResult, type PermissionScope, type ReplayContext, type ReplayInputs, type TrustRecord, type VorimConfig, VorimError, VorimSDK, canonicalPayloadV0, canonicalPayloadV1, createVorim as default, hashPreviousEvent, hashSystemPrompt, hashTool, hashToolCatalogue, jcsCanonicalise, prepareReplayContext };