@fluxpointstudios/orynq-sdk-process-trace 0.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.
package/src/types.ts ADDED
@@ -0,0 +1,522 @@
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;