@fluxpointstudios/orynq-sdk-process-trace 0.2.0 → 0.3.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/src/types.ts CHANGED
@@ -1,522 +1,713 @@
1
- /**
2
- * @fileoverview Type definitions for the process-trace package.
3
- * All types are consolidated in this single file to avoid confusion.
4
- *
5
- * Key concepts:
6
- * - TraceEvent: Individual events within a trace (commands, outputs, decisions, etc.)
7
- * - TraceSpan: Logical groupings of events with parent-child relationships
8
- * - TraceRun: Complete execution trace containing all events and spans
9
- * - TraceBundle: Finalized trace with cryptographic commitments
10
- * - Visibility: Controls what data is exposed in public views
11
- */
12
-
13
- // =============================================================================
14
- // VISIBILITY & COMMON TYPES
15
- // =============================================================================
16
-
17
- /**
18
- * Visibility level for trace events and spans.
19
- * - "public": Safe to disclose without revealing sensitive information
20
- * - "private": Contains potentially sensitive data, disclosed only with consent
21
- * - "secret": Never disclosed, hashes only for verification
22
- */
23
- export type Visibility = "public" | "private" | "secret";
24
-
25
- /**
26
- * Status of a trace run or span.
27
- */
28
- export type TraceStatus = "running" | "completed" | "failed" | "cancelled";
29
-
30
- /**
31
- * Schema version for trace format.
32
- */
33
- export type SchemaVersion = "1.0";
34
-
35
- // =============================================================================
36
- // TRACE EVENTS
37
- // =============================================================================
38
-
39
- /**
40
- * Base interface shared by all trace events.
41
- * @property kind - Discriminator for event type
42
- * @property id - UUID v4 unique identifier
43
- * @property seq - Monotonic sequence number (THE ordering authority)
44
- * @property timestamp - ISO 8601 timestamp (informational, not for ordering)
45
- * @property visibility - Controls disclosure level
46
- * @property hash - SHA-256 of canonical(event without hash field)
47
- */
48
- export interface BaseTraceEvent {
49
- kind: string;
50
- id: string;
51
- seq: number;
52
- timestamp: string;
53
- visibility: Visibility;
54
- hash?: string;
55
- }
56
-
57
- /**
58
- * Command execution event.
59
- * Default visibility: "public" (args may be redacted by policy)
60
- */
61
- export interface CommandEvent extends BaseTraceEvent {
62
- kind: "command";
63
- command: string;
64
- args?: string[];
65
- cwd?: string;
66
- env?: Record<string, string>;
67
- exitCode?: number;
68
- }
69
-
70
- /**
71
- * Output/result event from command or operation.
72
- * Default visibility: "private" (may contain secrets, PII, API responses)
73
- */
74
- export interface OutputEvent extends BaseTraceEvent {
75
- kind: "output";
76
- stream: "stdout" | "stderr" | "combined";
77
- content: string;
78
- truncated?: boolean;
79
- originalSize?: number;
80
- }
81
-
82
- /**
83
- * Decision point event where agent made a choice.
84
- * Default visibility: "private" (leaks reasoning/strategy)
85
- */
86
- export interface DecisionEvent extends BaseTraceEvent {
87
- kind: "decision";
88
- decision: string;
89
- reasoning?: string;
90
- alternatives?: string[];
91
- confidence?: number;
92
- }
93
-
94
- /**
95
- * Observation/state assertion event.
96
- * Default visibility: "public" (generally safe state assertions)
97
- */
98
- export interface ObservationEvent extends BaseTraceEvent {
99
- kind: "observation";
100
- observation: string;
101
- category?: string;
102
- data?: Record<string, unknown>;
103
- }
104
-
105
- /**
106
- * Error event capturing failures.
107
- * Default visibility: "private" (stack traces, internal details)
108
- */
109
- export interface ErrorTraceEvent extends BaseTraceEvent {
110
- kind: "error";
111
- error: string;
112
- code?: string;
113
- stack?: string;
114
- recoverable?: boolean;
115
- }
116
-
117
- /**
118
- * Custom event for extension.
119
- * Default visibility: "private" (unknown content)
120
- */
121
- export interface CustomEvent extends BaseTraceEvent {
122
- kind: "custom";
123
- eventType: string;
124
- data: Record<string, unknown>;
125
- }
126
-
127
- /**
128
- * Discriminated union of all trace event types.
129
- */
130
- export type TraceEvent =
131
- | CommandEvent
132
- | OutputEvent
133
- | DecisionEvent
134
- | ObservationEvent
135
- | ErrorTraceEvent
136
- | CustomEvent;
137
-
138
- /**
139
- * Event kind string literals for type guards.
140
- */
141
- export type TraceEventKind = TraceEvent["kind"];
142
-
143
- /**
144
- * Default visibility for each event kind.
145
- */
146
- export const DEFAULT_EVENT_VISIBILITY: Record<TraceEventKind, Visibility> = {
147
- command: "public",
148
- output: "private",
149
- decision: "private",
150
- observation: "public",
151
- error: "private",
152
- custom: "private",
153
- };
154
-
155
- // =============================================================================
156
- // TRACE SPANS
157
- // =============================================================================
158
-
159
- /**
160
- * A span represents a logical unit of work containing related events.
161
- * Spans can be nested via parentSpanId to form a tree structure.
162
- *
163
- * @property id - UUID v4 unique identifier
164
- * @property spanSeq - Monotonic sequence (THE ordering authority for spans)
165
- * @property parentSpanId - Optional parent span for nesting
166
- * @property name - Human-readable span name
167
- * @property status - Current span status
168
- * @property visibility - Span-level visibility (can override events)
169
- * @property eventIds - References to events (NOT embedded events)
170
- * @property childSpanIds - References to child spans
171
- * @property hash - H("poi-trace:span:v1|" + canon(spanHeader) + "|" + eventHashes)
172
- */
173
- export interface TraceSpan {
174
- id: string;
175
- spanSeq: number;
176
- parentSpanId?: string;
177
- name: string;
178
- status: TraceStatus;
179
- visibility: Visibility;
180
- startedAt: string;
181
- endedAt?: string;
182
- durationMs?: number;
183
- eventIds: string[];
184
- childSpanIds: string[];
185
- metadata?: Record<string, unknown>;
186
- hash?: string;
187
- }
188
-
189
- // =============================================================================
190
- // TRACE RUN
191
- // =============================================================================
192
-
193
- /**
194
- * Complete trace run containing all events and spans.
195
- *
196
- * @property id - UUID v4 unique identifier for this run
197
- * @property schemaVersion - Always "1.0" for this version
198
- * @property agentId - Identifier of the agent that produced this trace
199
- * @property status - Current run status
200
- * @property events - All events (flat array, ordered by seq)
201
- * @property spans - All spans (flat array, parent-child via IDs)
202
- * @property rollingHash - Updated after each event
203
- * @property rootHash - Final: H(rollingHash + spanHashes)
204
- * @property nextSeq - Internal: next seq to assign
205
- */
206
- export interface TraceRun {
207
- id: string;
208
- schemaVersion: SchemaVersion;
209
- agentId: string;
210
- status: TraceStatus;
211
- startedAt: string;
212
- endedAt?: string;
213
- durationMs?: number;
214
- events: TraceEvent[];
215
- spans: TraceSpan[];
216
- metadata?: Record<string, unknown>;
217
- rollingHash: string;
218
- rootHash?: string;
219
- nextSeq: number;
220
- nextSpanSeq: number;
221
- }
222
-
223
- // =============================================================================
224
- // ROLLING HASH
225
- // =============================================================================
226
-
227
- /**
228
- * State for incremental rolling hash computation.
229
- */
230
- export interface RollingHashState {
231
- currentHash: string;
232
- itemCount: number;
233
- }
234
-
235
- // =============================================================================
236
- // MERKLE TREE
237
- // =============================================================================
238
-
239
- /**
240
- * Span-level Merkle tree for selective disclosure.
241
- * Leaves are span hashes, ordered by spanSeq.
242
- *
243
- * @property rootHash - Merkle root (THE disclosure commitment)
244
- * @property leafCount - Number of leaf nodes (spans)
245
- * @property depth - Tree depth
246
- * @property leafHashes - For local proof generation (optional storage)
247
- */
248
- export interface TraceMerkleTree {
249
- rootHash: string;
250
- leafCount: number;
251
- depth: number;
252
- leafHashes: string[];
253
- }
254
-
255
- /**
256
- * Merkle proof for a single leaf (span).
257
- *
258
- * @property leafHash - Hash of the leaf being proven
259
- * @property leafIndex - 0-indexed position in leaf array
260
- * @property siblings - Path from leaf to root with position hints
261
- * @property rootHash - Expected Merkle root
262
- */
263
- export interface MerkleProof {
264
- leafHash: string;
265
- leafIndex: number;
266
- siblings: Array<{ hash: string; position: "left" | "right" }>;
267
- rootHash: string;
268
- }
269
-
270
- // =============================================================================
271
- // BUNDLE & PUBLIC VIEW
272
- // =============================================================================
273
-
274
- /**
275
- * Annotated span with full data for public disclosure.
276
- */
277
- export interface AnnotatedSpan extends TraceSpan {
278
- events: TraceEvent[];
279
- }
280
-
281
- /**
282
- * Public view of a trace bundle - safe to share externally.
283
- * Contains only public spans with their events, plus hashes of redacted spans.
284
- *
285
- * @property redactionPolicyId - Identifies which redaction rules were applied
286
- * @property redactionRulesHash - H(canonical(redactionRules)) for reproducibility
287
- */
288
- export interface TraceBundlePublicView {
289
- runId: string;
290
- agentId: string;
291
- schemaVersion: SchemaVersion;
292
- startedAt: string;
293
- endedAt: string;
294
- durationMs: number;
295
- status: string;
296
- totalEvents: number;
297
- totalSpans: number;
298
- rootHash: string;
299
- merkleRoot: string;
300
- publicSpans: AnnotatedSpan[];
301
- redactedSpanHashes: Array<{ spanId: string; hash: string }>;
302
- redactionPolicyId?: string;
303
- redactionRulesHash?: string;
304
- }
305
-
306
- /**
307
- * Complete trace bundle with cryptographic commitments.
308
- * Contains both public view and private data.
309
- *
310
- * @property formatVersion - Bundle format version
311
- * @property publicView - Safe to share externally
312
- * @property privateRun - Full trace data
313
- * @property merkleRoot - Span-level Merkle root
314
- * @property rootHash - Rolling hash final (execution sequence)
315
- * @property manifestHash - Set after manifest creation
316
- * @property signerId - Optional signer identifier
317
- * @property signature - Optional signature over bundle
318
- */
319
- export interface TraceBundle {
320
- formatVersion: SchemaVersion;
321
- publicView: TraceBundlePublicView;
322
- privateRun: TraceRun;
323
- merkleRoot: string;
324
- rootHash: string;
325
- manifestHash?: string;
326
- signerId?: string;
327
- signature?: string;
328
- }
329
-
330
- // =============================================================================
331
- // SIGNATURE PROVIDER (OPTIONAL)
332
- // =============================================================================
333
-
334
- /**
335
- * Interface for signing providers.
336
- * Consumers provide implementation (e.g., HSM, KMS, local key).
337
- */
338
- export interface SignatureProvider {
339
- signerId: string;
340
- sign(data: Uint8Array): Promise<Uint8Array>;
341
- verify(
342
- data: Uint8Array,
343
- signature: Uint8Array,
344
- signerId: string
345
- ): Promise<boolean>;
346
- }
347
-
348
- // =============================================================================
349
- // MANIFEST & CHUNKS (OFF-CHAIN STORAGE)
350
- // =============================================================================
351
-
352
- /**
353
- * Information about a stored chunk.
354
- *
355
- * @property index - Chunk sequence number
356
- * @property hash - SHA-256 of chunk content (BEFORE compression)
357
- * @property size - Bytes (uncompressed)
358
- * @property compressedSize - Bytes (if compressed)
359
- * @property compression - Hint for consumers (process-trace doesn't compress)
360
- * @property spanIds - Which spans are in this chunk
361
- */
362
- export interface ChunkInfo {
363
- index: number;
364
- hash: string;
365
- size: number;
366
- compressedSize?: number;
367
- compression?: "gzip" | "none";
368
- spanIds: string[];
369
- }
370
-
371
- /**
372
- * Chunk data ready for storage.
373
- */
374
- export interface Chunk {
375
- info: ChunkInfo;
376
- content: string;
377
- }
378
-
379
- /**
380
- * Manifest describing stored trace data.
381
- * This file is public-safe and serves as the entry point for retrieval.
382
- *
383
- * Storage layout:
384
- * ```
385
- * <storageUri>/
386
- * manifest.json # TraceManifest (public-safe)
387
- * chunks/
388
- * <hash1>.json.gz # Compressed chunk
389
- * <hash2>.json.gz
390
- * ```
391
- */
392
- export interface TraceManifest {
393
- formatVersion: SchemaVersion;
394
- runId: string;
395
- agentId: string;
396
- rootHash: string;
397
- merkleRoot: string;
398
- manifestHash?: string;
399
- totalEvents: number;
400
- totalSpans: number;
401
- startedAt: string;
402
- endedAt: string;
403
- durationMs: number;
404
- chunks: ChunkInfo[];
405
- publicView: TraceBundlePublicView;
406
- }
407
-
408
- // =============================================================================
409
- // SELECTIVE DISCLOSURE
410
- // =============================================================================
411
-
412
- /**
413
- * Disclosure mode determines what data is revealed.
414
- * - "membership": Merkle proof only (proves span exists, hash matches)
415
- * - "full": Merkle proof + span data + event data
416
- */
417
- export type DisclosureMode = "membership" | "full";
418
-
419
- /**
420
- * Result of selective disclosure operation.
421
- */
422
- export interface DisclosureResult {
423
- mode: DisclosureMode;
424
- rootHash: string;
425
- merkleRoot: string;
426
- disclosedSpans: Array<{
427
- spanId: string;
428
- proof: MerkleProof;
429
- span?: TraceSpan;
430
- events?: TraceEvent[];
431
- }>;
432
- }
433
-
434
- // =============================================================================
435
- // VERIFICATION RESULTS
436
- // =============================================================================
437
-
438
- /**
439
- * Result of bundle verification.
440
- */
441
- export interface TraceVerificationResult {
442
- valid: boolean;
443
- errors: string[];
444
- warnings: string[];
445
- checks: {
446
- rollingHashValid: boolean;
447
- rootHashValid: boolean;
448
- merkleRootValid: boolean;
449
- spanHashesValid: boolean;
450
- eventHashesValid: boolean;
451
- sequenceValid: boolean;
452
- };
453
- }
454
-
455
- /**
456
- * Result of manifest verification.
457
- */
458
- export interface ManifestVerificationResult {
459
- valid: boolean;
460
- errors: string[];
461
- warnings: string[];
462
- checks: {
463
- manifestHashValid: boolean;
464
- chunkHashesValid: boolean;
465
- rootHashMatches: boolean;
466
- merkleRootMatches: boolean;
467
- };
468
- }
469
-
470
- // =============================================================================
471
- // BUILDER OPTIONS
472
- // =============================================================================
473
-
474
- /**
475
- * Options for creating a new trace.
476
- */
477
- export interface CreateTraceOptions {
478
- agentId: string;
479
- description?: string;
480
- metadata?: Record<string, unknown>;
481
- }
482
-
483
- /**
484
- * Options for creating a new span.
485
- */
486
- export interface CreateSpanOptions {
487
- name: string;
488
- parentSpanId?: string;
489
- visibility?: Visibility;
490
- metadata?: Record<string, unknown>;
491
- }
492
-
493
- /**
494
- * Options for creating a manifest with chunks.
495
- */
496
- export interface CreateManifestOptions {
497
- chunkSize?: number;
498
- compression?: "gzip" | "none";
499
- }
500
-
501
- // =============================================================================
502
- // DOMAIN SEPARATION PREFIXES
503
- // =============================================================================
504
-
505
- /**
506
- * Domain separation prefixes for hashing.
507
- * These prevent cross-context hash collisions.
508
- */
509
- export const HASH_DOMAIN_PREFIXES = {
510
- event: "poi-trace:event:v1|",
511
- roll: "poi-trace:roll:v1|",
512
- span: "poi-trace:span:v1|",
513
- leaf: "poi-trace:leaf:v1|",
514
- node: "poi-trace:node:v1|",
515
- manifest: "poi-trace:manifest:v1|",
516
- root: "poi-trace:root:v1|",
517
- } as const;
518
-
519
- /**
520
- * Type for domain prefix keys.
521
- */
522
- export type HashDomain = keyof typeof HASH_DOMAIN_PREFIXES;
1
+ /**
2
+ * @fileoverview Type definitions for the process-trace package.
3
+ * All types are consolidated in this single file to avoid confusion.
4
+ *
5
+ * Key concepts:
6
+ * - TraceEvent: Individual events within a trace (commands, outputs, decisions, etc.)
7
+ * - TraceSpan: Logical groupings of events with parent-child relationships
8
+ * - TraceRun: Complete execution trace containing all events and spans
9
+ * - TraceBundle: Finalized trace with cryptographic commitments
10
+ * - Visibility: Controls what data is exposed in public views
11
+ */
12
+
13
+ // =============================================================================
14
+ // VISIBILITY & COMMON TYPES
15
+ // =============================================================================
16
+
17
+ /**
18
+ * Visibility level for trace events and spans.
19
+ * - "public": Safe to disclose without revealing sensitive information
20
+ * - "private": Contains potentially sensitive data, disclosed only with consent
21
+ * - "secret": Never disclosed, hashes only for verification
22
+ */
23
+ export type Visibility = "public" | "private" | "secret";
24
+
25
+ /**
26
+ * Status of a trace run or span.
27
+ */
28
+ export type TraceStatus = "running" | "completed" | "failed" | "cancelled";
29
+
30
+ /**
31
+ * Schema version for trace format.
32
+ */
33
+ export type SchemaVersion = "1.0";
34
+
35
+ // =============================================================================
36
+ // TRACE EVENTS
37
+ // =============================================================================
38
+
39
+ /**
40
+ * Base interface shared by all trace events.
41
+ * @property kind - Discriminator for event type
42
+ * @property id - UUID v4 unique identifier
43
+ * @property seq - Monotonic sequence number (THE ordering authority)
44
+ * @property timestamp - ISO 8601 timestamp (informational, not for ordering)
45
+ * @property visibility - Controls disclosure level
46
+ * @property hash - SHA-256 of canonical(event without hash field)
47
+ */
48
+ export interface BaseTraceEvent {
49
+ kind: string;
50
+ id: string;
51
+ seq: number;
52
+ timestamp: string;
53
+ visibility: Visibility;
54
+ hash?: string;
55
+ }
56
+
57
+ /**
58
+ * Command execution event.
59
+ * Default visibility: "public" (args may be redacted by policy)
60
+ */
61
+ export interface CommandEvent extends BaseTraceEvent {
62
+ kind: "command";
63
+ command: string;
64
+ args?: string[];
65
+ cwd?: string;
66
+ env?: Record<string, string>;
67
+ exitCode?: number;
68
+ }
69
+
70
+ /**
71
+ * Output/result event from command or operation.
72
+ * Default visibility: "private" (may contain secrets, PII, API responses)
73
+ */
74
+ export interface OutputEvent extends BaseTraceEvent {
75
+ kind: "output";
76
+ stream: "stdout" | "stderr" | "combined";
77
+ content: string;
78
+ truncated?: boolean;
79
+ originalSize?: number;
80
+ }
81
+
82
+ /**
83
+ * Decision point event where agent made a choice.
84
+ * Default visibility: "private" (leaks reasoning/strategy)
85
+ */
86
+ export interface DecisionEvent extends BaseTraceEvent {
87
+ kind: "decision";
88
+ decision: string;
89
+ reasoning?: string;
90
+ alternatives?: string[];
91
+ confidence?: number;
92
+ }
93
+
94
+ /**
95
+ * Observation/state assertion event.
96
+ * Default visibility: "public" (generally safe state assertions)
97
+ */
98
+ export interface ObservationEvent extends BaseTraceEvent {
99
+ kind: "observation";
100
+ observation: string;
101
+ category?: string;
102
+ data?: Record<string, unknown>;
103
+ }
104
+
105
+ /**
106
+ * Error event capturing failures.
107
+ * Default visibility: "private" (stack traces, internal details)
108
+ */
109
+ export interface ErrorTraceEvent extends BaseTraceEvent {
110
+ kind: "error";
111
+ error: string;
112
+ code?: string;
113
+ stack?: string;
114
+ recoverable?: boolean;
115
+ }
116
+
117
+ /**
118
+ * Custom event for extension.
119
+ * Default visibility: "private" (unknown content)
120
+ */
121
+ export interface CustomEvent extends BaseTraceEvent {
122
+ kind: "custom";
123
+ eventType: string;
124
+ data: Record<string, unknown>;
125
+ }
126
+
127
+ /**
128
+ * Signature scheme used by a governance attestor.
129
+ * - "sr25519" / "ed25519": Substrate/Materios wallets (verified in-package)
130
+ * - "eip712": EVM typed-data signatures (verified via a pluggable verifier)
131
+ */
132
+ export type GovernanceSignatureScheme = "sr25519" | "ed25519" | "eip712";
133
+
134
+ /**
135
+ * EIP-712 typed-data binding, required to verify an `eip712` governance
136
+ * signature. Mirrors the shape consumed by viem's `verifyTypedData`.
137
+ */
138
+ export interface GovernanceEip712Binding {
139
+ domain: Record<string, unknown>;
140
+ types: Record<string, Array<{ name: string; type: string }>>;
141
+ primaryType: string;
142
+ message?: Record<string, unknown>;
143
+ }
144
+
145
+ /**
146
+ * Governance attestation event — a verifiable, role-scoped sign-off recorded
147
+ * inside a trace (compliance review, release approval, data-steward sign-off).
148
+ *
149
+ * The signature is computed over a canonical, domain-separated preimage of
150
+ * `(runId || role || policyRef || decisionRef || signedAt)` (see
151
+ * `governanceAttestationPreimage`), so an auditor can verify *who* governed a
152
+ * decision without trusting the wrapper that recorded it, and a genuine
153
+ * attestation cannot be replayed into a different trace.
154
+ *
155
+ * Default visibility: "public" (governance provenance is meant to be auditable).
156
+ */
157
+ export interface GovernanceAttestationEvent extends BaseTraceEvent {
158
+ kind: "governance-attestation";
159
+ /** Governance role; common values plus free-form extension. */
160
+ role: "compliance" | "release-authority" | "data-steward" | (string & {});
161
+ /** Hash or URI of the policy being attested to. */
162
+ policyRef: string;
163
+ /** Hash or id of the decision/event being governed. */
164
+ decisionRef: string;
165
+ /** The signing identity and scheme. */
166
+ attestor: { address: string; signatureScheme: GovernanceSignatureScheme };
167
+ /** Signature over the canonical preimage (hex, optionally `0x`-prefixed). */
168
+ signature: string;
169
+ /** ISO 8601 timestamp; part of the signed preimage. */
170
+ signedAt: string;
171
+ /** EIP-712 binding required only when `attestor.signatureScheme === "eip712"`. */
172
+ eip712?: GovernanceEip712Binding;
173
+ }
174
+
175
+ /**
176
+ * Signature scheme for a tool-call receipt.
177
+ * - "http-message-signatures": RFC 9421 signed HTTP responses
178
+ * - "stripe-webhook" / "github-webhook": SaaS webhook HMAC signatures
179
+ * - "jws": generic JWS/JWT-signed responses
180
+ * - (string): forward-compatible custom schemes
181
+ */
182
+ export type ToolReceiptScheme =
183
+ | "http-message-signatures"
184
+ | "stripe-webhook"
185
+ | "github-webhook"
186
+ | "jws"
187
+ | (string & {});
188
+
189
+ /**
190
+ * Verifiable tool-call receipt event — proves "the tool actually returned this
191
+ * response", not merely "the agent says the tool returned this response".
192
+ *
193
+ * The wrapper records a signed receipt produced by (or about) the external
194
+ * system; a verifier independently re-checks `receipt.signature` over
195
+ * `receipt.signedPayload` against `receipt.signer`.
196
+ *
197
+ * Default visibility: "private" (responses may contain PII / secrets — only the
198
+ * hashes and signature are needed for verification).
199
+ */
200
+ export interface ToolReceiptEvent extends BaseTraceEvent {
201
+ kind: "tool-receipt";
202
+ /** Identifier of the tool/endpoint that was called. */
203
+ toolId: string;
204
+ /** Commitment to the request (SHA-256 hex). */
205
+ request: { hash: string };
206
+ /** Commitment to the response, with an optional retained payload. */
207
+ response: { hash: string; payload?: unknown };
208
+ /** The independently-verifiable signed receipt. */
209
+ receipt: {
210
+ scheme: ToolReceiptScheme;
211
+ /** Verifier-resolvable identity: URL, DID, on-chain address, or keyId. */
212
+ signer: string;
213
+ /** Signature bytes (encoding depends on scheme: base64/hex/0x-hex). */
214
+ signature: string;
215
+ /** Canonicalized signed bytes the signature is computed over. */
216
+ signedPayload: string;
217
+ /** Scheme-specific verification material (headers, keyId, components, ...). */
218
+ params?: Record<string, unknown>;
219
+ };
220
+ }
221
+
222
+ /**
223
+ * Discriminated union of all trace event types.
224
+ */
225
+ export type TraceEvent =
226
+ | CommandEvent
227
+ | OutputEvent
228
+ | DecisionEvent
229
+ | ObservationEvent
230
+ | ErrorTraceEvent
231
+ | CustomEvent
232
+ | GovernanceAttestationEvent
233
+ | ToolReceiptEvent;
234
+
235
+ /**
236
+ * Event kind string literals for type guards.
237
+ */
238
+ export type TraceEventKind = TraceEvent["kind"];
239
+
240
+ /**
241
+ * Default visibility for each event kind.
242
+ */
243
+ export const DEFAULT_EVENT_VISIBILITY: Record<TraceEventKind, Visibility> = {
244
+ command: "public",
245
+ output: "private",
246
+ decision: "private",
247
+ observation: "public",
248
+ error: "private",
249
+ custom: "private",
250
+ // Governance provenance is meant to be auditable by third parties.
251
+ "governance-attestation": "public",
252
+ // Tool responses may carry PII/secrets; only hashes + signature are required.
253
+ "tool-receipt": "private",
254
+ };
255
+
256
+ // =============================================================================
257
+ // TRACE SPANS
258
+ // =============================================================================
259
+
260
+ /**
261
+ * A span represents a logical unit of work containing related events.
262
+ * Spans can be nested via parentSpanId to form a tree structure.
263
+ *
264
+ * @property id - UUID v4 unique identifier
265
+ * @property spanSeq - Monotonic sequence (THE ordering authority for spans)
266
+ * @property parentSpanId - Optional parent span for nesting
267
+ * @property name - Human-readable span name
268
+ * @property status - Current span status
269
+ * @property visibility - Span-level visibility (can override events)
270
+ * @property eventIds - References to events (NOT embedded events)
271
+ * @property childSpanIds - References to child spans
272
+ * @property hash - H("poi-trace:span:v1|" + canon(spanHeader) + "|" + eventHashes)
273
+ */
274
+ export interface TraceSpan {
275
+ id: string;
276
+ spanSeq: number;
277
+ parentSpanId?: string;
278
+ name: string;
279
+ status: TraceStatus;
280
+ visibility: Visibility;
281
+ startedAt: string;
282
+ endedAt?: string;
283
+ durationMs?: number;
284
+ eventIds: string[];
285
+ childSpanIds: string[];
286
+ metadata?: Record<string, unknown>;
287
+ hash?: string;
288
+ }
289
+
290
+ // =============================================================================
291
+ // MODEL MANIFEST (PRE-EXECUTION PINNING)
292
+ // =============================================================================
293
+
294
+ /**
295
+ * Fingerprint of the model/data state used during a trace run.
296
+ *
297
+ * Distinct from {@link TraceManifest} (which describes off-chain *storage*
298
+ * chunks). A `ModelManifest` is pinned at {@link CreateTraceOptions} time —
299
+ * *before* execution — and frozen, so the resulting trace can prove that
300
+ * "neither the data nor the model was altered" for a given inference.
301
+ *
302
+ * Two traces of "the same model" should produce the same `modelManifestHash`,
303
+ * so the field values must be deterministic fingerprints (see the
304
+ * `manifestFrom*` builders).
305
+ */
306
+ export interface ModelManifest {
307
+ /** Model checkpoint fingerprint, e.g. "sha256:..." */
308
+ modelHash: string;
309
+ /** Tokenizer fingerprint. */
310
+ tokenizerHash?: string;
311
+ /** System-prompt fingerprint. */
312
+ systemPromptHash?: string;
313
+ /** Training-dataset manifest fingerprint. */
314
+ trainingDataManifest?: string;
315
+ /** Producing framework, e.g. "huggingface" | "openai" | "anthropic" | "checkpoint". */
316
+ framework?: string;
317
+ /** Model identifier (e.g. HF repo id, OpenAI/Anthropic model name). */
318
+ modelId?: string;
319
+ /** Revision / snapshot id, when applicable. */
320
+ revision?: string;
321
+ /** Free-form additional fingerprint inputs (hashed into manifestHash). */
322
+ metadata?: Record<string, unknown>;
323
+ }
324
+
325
+ // =============================================================================
326
+ // TRACE RUN
327
+ // =============================================================================
328
+
329
+ /**
330
+ * Complete trace run containing all events and spans.
331
+ *
332
+ * @property id - UUID v4 unique identifier for this run
333
+ * @property schemaVersion - Always "1.0" for this version
334
+ * @property agentId - Identifier of the agent that produced this trace
335
+ * @property status - Current run status
336
+ * @property events - All events (flat array, ordered by seq)
337
+ * @property spans - All spans (flat array, parent-child via IDs)
338
+ * @property rollingHash - Updated after each event
339
+ * @property rootHash - Final: H(rollingHash + spanHashes)
340
+ * @property nextSeq - Internal: next seq to assign
341
+ */
342
+ export interface TraceRun {
343
+ id: string;
344
+ schemaVersion: SchemaVersion;
345
+ agentId: string;
346
+ status: TraceStatus;
347
+ startedAt: string;
348
+ endedAt?: string;
349
+ durationMs?: number;
350
+ events: TraceEvent[];
351
+ spans: TraceSpan[];
352
+ metadata?: Record<string, unknown>;
353
+ rollingHash: string;
354
+ rootHash?: string;
355
+ nextSeq: number;
356
+ nextSpanSeq: number;
357
+ /**
358
+ * Model/data manifest pinned at createTrace() time (frozen). When present,
359
+ * `modelManifestHash` is the cryptographic commitment to it.
360
+ */
361
+ modelManifest?: ModelManifest;
362
+ /** H("poi-trace:model-manifest:v1|" + canonical(modelManifest)), pinned at creation. */
363
+ modelManifestHash?: string;
364
+ /**
365
+ * Strict-mode flag (pinned at creation). When true, finalizeTrace() throws
366
+ * if no manifest was pinned. Default false (warn-only) for v0.x.
367
+ */
368
+ strict?: boolean;
369
+ }
370
+
371
+ // =============================================================================
372
+ // ROLLING HASH
373
+ // =============================================================================
374
+
375
+ /**
376
+ * State for incremental rolling hash computation.
377
+ */
378
+ export interface RollingHashState {
379
+ currentHash: string;
380
+ itemCount: number;
381
+ }
382
+
383
+ // =============================================================================
384
+ // MERKLE TREE
385
+ // =============================================================================
386
+
387
+ /**
388
+ * Span-level Merkle tree for selective disclosure.
389
+ * Leaves are span hashes, ordered by spanSeq.
390
+ *
391
+ * @property rootHash - Merkle root (THE disclosure commitment)
392
+ * @property leafCount - Number of leaf nodes (spans)
393
+ * @property depth - Tree depth
394
+ * @property leafHashes - For local proof generation (optional storage)
395
+ */
396
+ export interface TraceMerkleTree {
397
+ rootHash: string;
398
+ leafCount: number;
399
+ depth: number;
400
+ leafHashes: string[];
401
+ }
402
+
403
+ /**
404
+ * Merkle proof for a single leaf (span).
405
+ *
406
+ * @property leafHash - Hash of the leaf being proven
407
+ * @property leafIndex - 0-indexed position in leaf array
408
+ * @property siblings - Path from leaf to root with position hints
409
+ * @property rootHash - Expected Merkle root
410
+ */
411
+ export interface MerkleProof {
412
+ leafHash: string;
413
+ leafIndex: number;
414
+ siblings: Array<{ hash: string; position: "left" | "right" }>;
415
+ rootHash: string;
416
+ }
417
+
418
+ // =============================================================================
419
+ // BUNDLE & PUBLIC VIEW
420
+ // =============================================================================
421
+
422
+ /**
423
+ * Annotated span with full data for public disclosure.
424
+ */
425
+ export interface AnnotatedSpan extends TraceSpan {
426
+ events: TraceEvent[];
427
+ }
428
+
429
+ /**
430
+ * Public view of a trace bundle - safe to share externally.
431
+ * Contains only public spans with their events, plus hashes of redacted spans.
432
+ *
433
+ * @property redactionPolicyId - Identifies which redaction rules were applied
434
+ * @property redactionRulesHash - H(canonical(redactionRules)) for reproducibility
435
+ */
436
+ export interface TraceBundlePublicView {
437
+ runId: string;
438
+ agentId: string;
439
+ schemaVersion: SchemaVersion;
440
+ startedAt: string;
441
+ endedAt: string;
442
+ durationMs: number;
443
+ status: string;
444
+ totalEvents: number;
445
+ totalSpans: number;
446
+ rootHash: string;
447
+ merkleRoot: string;
448
+ publicSpans: AnnotatedSpan[];
449
+ redactedSpanHashes: Array<{ spanId: string; hash: string }>;
450
+ redactionPolicyId?: string;
451
+ redactionRulesHash?: string;
452
+ /** Model-state commitment (public-safe: it is only a hash). */
453
+ modelManifestHash?: string;
454
+ /** Pinned model manifest (hashes only — public-safe). */
455
+ modelManifest?: ModelManifest;
456
+ }
457
+
458
+ /**
459
+ * Complete trace bundle with cryptographic commitments.
460
+ * Contains both public view and private data.
461
+ *
462
+ * @property formatVersion - Bundle format version
463
+ * @property publicView - Safe to share externally
464
+ * @property privateRun - Full trace data
465
+ * @property merkleRoot - Span-level Merkle root
466
+ * @property rootHash - Rolling hash final (execution sequence)
467
+ * @property manifestHash - Set after manifest creation
468
+ * @property signerId - Optional signer identifier
469
+ * @property signature - Optional signature over bundle
470
+ */
471
+ export interface TraceBundle {
472
+ formatVersion: SchemaVersion;
473
+ publicView: TraceBundlePublicView;
474
+ privateRun: TraceRun;
475
+ merkleRoot: string;
476
+ rootHash: string;
477
+ manifestHash?: string;
478
+ /**
479
+ * Model/data manifest commitment pinned at createTrace() time. Distinct from
480
+ * `manifestHash` (the off-chain storage-manifest hash). Place this in on-chain
481
+ * anchor metadata to make model drift cryptographically detectable.
482
+ */
483
+ modelManifestHash?: string;
484
+ /** The pinned model manifest (hashes only — public-safe). */
485
+ modelManifest?: ModelManifest;
486
+ signerId?: string;
487
+ signature?: string;
488
+ }
489
+
490
+ // =============================================================================
491
+ // SIGNATURE PROVIDER (OPTIONAL)
492
+ // =============================================================================
493
+
494
+ /**
495
+ * Interface for signing providers.
496
+ * Consumers provide implementation (e.g., HSM, KMS, local key).
497
+ */
498
+ export interface SignatureProvider {
499
+ signerId: string;
500
+ sign(data: Uint8Array): Promise<Uint8Array>;
501
+ verify(
502
+ data: Uint8Array,
503
+ signature: Uint8Array,
504
+ signerId: string
505
+ ): Promise<boolean>;
506
+ }
507
+
508
+ // =============================================================================
509
+ // MANIFEST & CHUNKS (OFF-CHAIN STORAGE)
510
+ // =============================================================================
511
+
512
+ /**
513
+ * Information about a stored chunk.
514
+ *
515
+ * @property index - Chunk sequence number
516
+ * @property hash - SHA-256 of chunk content (BEFORE compression)
517
+ * @property size - Bytes (uncompressed)
518
+ * @property compressedSize - Bytes (if compressed)
519
+ * @property compression - Hint for consumers (process-trace doesn't compress)
520
+ * @property spanIds - Which spans are in this chunk
521
+ */
522
+ export interface ChunkInfo {
523
+ index: number;
524
+ hash: string;
525
+ size: number;
526
+ compressedSize?: number;
527
+ compression?: "gzip" | "none";
528
+ spanIds: string[];
529
+ }
530
+
531
+ /**
532
+ * Chunk data ready for storage.
533
+ */
534
+ export interface Chunk {
535
+ info: ChunkInfo;
536
+ content: string;
537
+ }
538
+
539
+ /**
540
+ * Manifest describing stored trace data.
541
+ * This file is public-safe and serves as the entry point for retrieval.
542
+ *
543
+ * Storage layout:
544
+ * ```
545
+ * <storageUri>/
546
+ * manifest.json # TraceManifest (public-safe)
547
+ * chunks/
548
+ * <hash1>.json.gz # Compressed chunk
549
+ * <hash2>.json.gz
550
+ * ```
551
+ */
552
+ export interface TraceManifest {
553
+ formatVersion: SchemaVersion;
554
+ runId: string;
555
+ agentId: string;
556
+ rootHash: string;
557
+ merkleRoot: string;
558
+ manifestHash?: string;
559
+ totalEvents: number;
560
+ totalSpans: number;
561
+ startedAt: string;
562
+ endedAt: string;
563
+ durationMs: number;
564
+ chunks: ChunkInfo[];
565
+ publicView: TraceBundlePublicView;
566
+ }
567
+
568
+ // =============================================================================
569
+ // SELECTIVE DISCLOSURE
570
+ // =============================================================================
571
+
572
+ /**
573
+ * Disclosure mode determines what data is revealed.
574
+ * - "membership": Merkle proof only (proves span exists, hash matches)
575
+ * - "full": Merkle proof + span data + event data
576
+ */
577
+ export type DisclosureMode = "membership" | "full";
578
+
579
+ /**
580
+ * Result of selective disclosure operation.
581
+ */
582
+ export interface DisclosureResult {
583
+ mode: DisclosureMode;
584
+ rootHash: string;
585
+ merkleRoot: string;
586
+ disclosedSpans: Array<{
587
+ spanId: string;
588
+ proof: MerkleProof;
589
+ span?: TraceSpan;
590
+ events?: TraceEvent[];
591
+ }>;
592
+ }
593
+
594
+ // =============================================================================
595
+ // VERIFICATION RESULTS
596
+ // =============================================================================
597
+
598
+ /**
599
+ * Result of bundle verification.
600
+ */
601
+ export interface TraceVerificationResult {
602
+ valid: boolean;
603
+ errors: string[];
604
+ warnings: string[];
605
+ checks: {
606
+ rollingHashValid: boolean;
607
+ rootHashValid: boolean;
608
+ merkleRootValid: boolean;
609
+ spanHashesValid: boolean;
610
+ eventHashesValid: boolean;
611
+ sequenceValid: boolean;
612
+ /**
613
+ * Model-manifest pin binding (#59): the pinned manifest hashes to its
614
+ * recorded commitment AND that commitment is folded into the committed
615
+ * root. True when no manifest is pinned (nothing to bind).
616
+ */
617
+ modelManifestValid?: boolean;
618
+ /**
619
+ * Set only when governance verification is requested via
620
+ * verifyBundle(bundle, { governance }). Undefined means "not checked".
621
+ */
622
+ governanceValid?: boolean;
623
+ /**
624
+ * Set only when tool-receipt verification is requested via
625
+ * verifyBundle(bundle, { toolReceipts }). Undefined means "not checked".
626
+ */
627
+ toolReceiptsValid?: boolean;
628
+ };
629
+ }
630
+
631
+ /**
632
+ * Result of manifest verification.
633
+ */
634
+ export interface ManifestVerificationResult {
635
+ valid: boolean;
636
+ errors: string[];
637
+ warnings: string[];
638
+ checks: {
639
+ manifestHashValid: boolean;
640
+ chunkHashesValid: boolean;
641
+ rootHashMatches: boolean;
642
+ merkleRootMatches: boolean;
643
+ };
644
+ }
645
+
646
+ // =============================================================================
647
+ // BUILDER OPTIONS
648
+ // =============================================================================
649
+
650
+ /**
651
+ * Options for creating a new trace.
652
+ */
653
+ export interface CreateTraceOptions {
654
+ agentId: string;
655
+ description?: string;
656
+ metadata?: Record<string, unknown>;
657
+ /**
658
+ * Model/data manifest to pin *before* execution. Its hash is computed and
659
+ * frozen at createTrace() time; mutating the manifest afterwards throws.
660
+ */
661
+ manifest?: ModelManifest;
662
+ /**
663
+ * Strict mode. When true, createTrace() requires a `manifest` and
664
+ * finalizeTrace() refuses to finalize an unpinned trace. Default false
665
+ * (warn-only) for v0.x; planned strict-by-default in v1.0.
666
+ */
667
+ strict?: boolean;
668
+ }
669
+
670
+ /**
671
+ * Options for creating a new span.
672
+ */
673
+ export interface CreateSpanOptions {
674
+ name: string;
675
+ parentSpanId?: string;
676
+ visibility?: Visibility;
677
+ metadata?: Record<string, unknown>;
678
+ }
679
+
680
+ /**
681
+ * Options for creating a manifest with chunks.
682
+ */
683
+ export interface CreateManifestOptions {
684
+ chunkSize?: number;
685
+ compression?: "gzip" | "none";
686
+ }
687
+
688
+ // =============================================================================
689
+ // DOMAIN SEPARATION PREFIXES
690
+ // =============================================================================
691
+
692
+ /**
693
+ * Domain separation prefixes for hashing.
694
+ * These prevent cross-context hash collisions.
695
+ */
696
+ export const HASH_DOMAIN_PREFIXES = {
697
+ event: "poi-trace:event:v1|",
698
+ roll: "poi-trace:roll:v1|",
699
+ span: "poi-trace:span:v1|",
700
+ leaf: "poi-trace:leaf:v1|",
701
+ node: "poi-trace:node:v1|",
702
+ manifest: "poi-trace:manifest:v1|",
703
+ root: "poi-trace:root:v1|",
704
+ /** Model/data manifest commitment (pre-execution pinning). */
705
+ modelManifest: "poi-trace:model-manifest:v1|",
706
+ /** Governance-attestation signing preimage. */
707
+ governance: "poi-trace:governance:v1|",
708
+ } as const;
709
+
710
+ /**
711
+ * Type for domain prefix keys.
712
+ */
713
+ export type HashDomain = keyof typeof HASH_DOMAIN_PREFIXES;