@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.
@@ -0,0 +1,1758 @@
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
+ * Visibility level for trace events and spans.
14
+ * - "public": Safe to disclose without revealing sensitive information
15
+ * - "private": Contains potentially sensitive data, disclosed only with consent
16
+ * - "secret": Never disclosed, hashes only for verification
17
+ */
18
+ type Visibility = "public" | "private" | "secret";
19
+ /**
20
+ * Status of a trace run or span.
21
+ */
22
+ type TraceStatus = "running" | "completed" | "failed" | "cancelled";
23
+ /**
24
+ * Schema version for trace format.
25
+ */
26
+ type SchemaVersion = "1.0";
27
+ /**
28
+ * Base interface shared by all trace events.
29
+ * @property kind - Discriminator for event type
30
+ * @property id - UUID v4 unique identifier
31
+ * @property seq - Monotonic sequence number (THE ordering authority)
32
+ * @property timestamp - ISO 8601 timestamp (informational, not for ordering)
33
+ * @property visibility - Controls disclosure level
34
+ * @property hash - SHA-256 of canonical(event without hash field)
35
+ */
36
+ interface BaseTraceEvent {
37
+ kind: string;
38
+ id: string;
39
+ seq: number;
40
+ timestamp: string;
41
+ visibility: Visibility;
42
+ hash?: string;
43
+ }
44
+ /**
45
+ * Command execution event.
46
+ * Default visibility: "public" (args may be redacted by policy)
47
+ */
48
+ interface CommandEvent extends BaseTraceEvent {
49
+ kind: "command";
50
+ command: string;
51
+ args?: string[];
52
+ cwd?: string;
53
+ env?: Record<string, string>;
54
+ exitCode?: number;
55
+ }
56
+ /**
57
+ * Output/result event from command or operation.
58
+ * Default visibility: "private" (may contain secrets, PII, API responses)
59
+ */
60
+ interface OutputEvent extends BaseTraceEvent {
61
+ kind: "output";
62
+ stream: "stdout" | "stderr" | "combined";
63
+ content: string;
64
+ truncated?: boolean;
65
+ originalSize?: number;
66
+ }
67
+ /**
68
+ * Decision point event where agent made a choice.
69
+ * Default visibility: "private" (leaks reasoning/strategy)
70
+ */
71
+ interface DecisionEvent extends BaseTraceEvent {
72
+ kind: "decision";
73
+ decision: string;
74
+ reasoning?: string;
75
+ alternatives?: string[];
76
+ confidence?: number;
77
+ }
78
+ /**
79
+ * Observation/state assertion event.
80
+ * Default visibility: "public" (generally safe state assertions)
81
+ */
82
+ interface ObservationEvent extends BaseTraceEvent {
83
+ kind: "observation";
84
+ observation: string;
85
+ category?: string;
86
+ data?: Record<string, unknown>;
87
+ }
88
+ /**
89
+ * Error event capturing failures.
90
+ * Default visibility: "private" (stack traces, internal details)
91
+ */
92
+ interface ErrorTraceEvent extends BaseTraceEvent {
93
+ kind: "error";
94
+ error: string;
95
+ code?: string;
96
+ stack?: string;
97
+ recoverable?: boolean;
98
+ }
99
+ /**
100
+ * Custom event for extension.
101
+ * Default visibility: "private" (unknown content)
102
+ */
103
+ interface CustomEvent extends BaseTraceEvent {
104
+ kind: "custom";
105
+ eventType: string;
106
+ data: Record<string, unknown>;
107
+ }
108
+ /**
109
+ * Discriminated union of all trace event types.
110
+ */
111
+ type TraceEvent = CommandEvent | OutputEvent | DecisionEvent | ObservationEvent | ErrorTraceEvent | CustomEvent;
112
+ /**
113
+ * Event kind string literals for type guards.
114
+ */
115
+ type TraceEventKind = TraceEvent["kind"];
116
+ /**
117
+ * Default visibility for each event kind.
118
+ */
119
+ declare const DEFAULT_EVENT_VISIBILITY: Record<TraceEventKind, Visibility>;
120
+ /**
121
+ * A span represents a logical unit of work containing related events.
122
+ * Spans can be nested via parentSpanId to form a tree structure.
123
+ *
124
+ * @property id - UUID v4 unique identifier
125
+ * @property spanSeq - Monotonic sequence (THE ordering authority for spans)
126
+ * @property parentSpanId - Optional parent span for nesting
127
+ * @property name - Human-readable span name
128
+ * @property status - Current span status
129
+ * @property visibility - Span-level visibility (can override events)
130
+ * @property eventIds - References to events (NOT embedded events)
131
+ * @property childSpanIds - References to child spans
132
+ * @property hash - H("poi-trace:span:v1|" + canon(spanHeader) + "|" + eventHashes)
133
+ */
134
+ interface TraceSpan {
135
+ id: string;
136
+ spanSeq: number;
137
+ parentSpanId?: string;
138
+ name: string;
139
+ status: TraceStatus;
140
+ visibility: Visibility;
141
+ startedAt: string;
142
+ endedAt?: string;
143
+ durationMs?: number;
144
+ eventIds: string[];
145
+ childSpanIds: string[];
146
+ metadata?: Record<string, unknown>;
147
+ hash?: string;
148
+ }
149
+ /**
150
+ * Complete trace run containing all events and spans.
151
+ *
152
+ * @property id - UUID v4 unique identifier for this run
153
+ * @property schemaVersion - Always "1.0" for this version
154
+ * @property agentId - Identifier of the agent that produced this trace
155
+ * @property status - Current run status
156
+ * @property events - All events (flat array, ordered by seq)
157
+ * @property spans - All spans (flat array, parent-child via IDs)
158
+ * @property rollingHash - Updated after each event
159
+ * @property rootHash - Final: H(rollingHash + spanHashes)
160
+ * @property nextSeq - Internal: next seq to assign
161
+ */
162
+ interface TraceRun {
163
+ id: string;
164
+ schemaVersion: SchemaVersion;
165
+ agentId: string;
166
+ status: TraceStatus;
167
+ startedAt: string;
168
+ endedAt?: string;
169
+ durationMs?: number;
170
+ events: TraceEvent[];
171
+ spans: TraceSpan[];
172
+ metadata?: Record<string, unknown>;
173
+ rollingHash: string;
174
+ rootHash?: string;
175
+ nextSeq: number;
176
+ nextSpanSeq: number;
177
+ }
178
+ /**
179
+ * State for incremental rolling hash computation.
180
+ */
181
+ interface RollingHashState {
182
+ currentHash: string;
183
+ itemCount: number;
184
+ }
185
+ /**
186
+ * Span-level Merkle tree for selective disclosure.
187
+ * Leaves are span hashes, ordered by spanSeq.
188
+ *
189
+ * @property rootHash - Merkle root (THE disclosure commitment)
190
+ * @property leafCount - Number of leaf nodes (spans)
191
+ * @property depth - Tree depth
192
+ * @property leafHashes - For local proof generation (optional storage)
193
+ */
194
+ interface TraceMerkleTree {
195
+ rootHash: string;
196
+ leafCount: number;
197
+ depth: number;
198
+ leafHashes: string[];
199
+ }
200
+ /**
201
+ * Merkle proof for a single leaf (span).
202
+ *
203
+ * @property leafHash - Hash of the leaf being proven
204
+ * @property leafIndex - 0-indexed position in leaf array
205
+ * @property siblings - Path from leaf to root with position hints
206
+ * @property rootHash - Expected Merkle root
207
+ */
208
+ interface MerkleProof {
209
+ leafHash: string;
210
+ leafIndex: number;
211
+ siblings: Array<{
212
+ hash: string;
213
+ position: "left" | "right";
214
+ }>;
215
+ rootHash: string;
216
+ }
217
+ /**
218
+ * Annotated span with full data for public disclosure.
219
+ */
220
+ interface AnnotatedSpan extends TraceSpan {
221
+ events: TraceEvent[];
222
+ }
223
+ /**
224
+ * Public view of a trace bundle - safe to share externally.
225
+ * Contains only public spans with their events, plus hashes of redacted spans.
226
+ *
227
+ * @property redactionPolicyId - Identifies which redaction rules were applied
228
+ * @property redactionRulesHash - H(canonical(redactionRules)) for reproducibility
229
+ */
230
+ interface TraceBundlePublicView {
231
+ runId: string;
232
+ agentId: string;
233
+ schemaVersion: SchemaVersion;
234
+ startedAt: string;
235
+ endedAt: string;
236
+ durationMs: number;
237
+ status: string;
238
+ totalEvents: number;
239
+ totalSpans: number;
240
+ rootHash: string;
241
+ merkleRoot: string;
242
+ publicSpans: AnnotatedSpan[];
243
+ redactedSpanHashes: Array<{
244
+ spanId: string;
245
+ hash: string;
246
+ }>;
247
+ redactionPolicyId?: string;
248
+ redactionRulesHash?: string;
249
+ }
250
+ /**
251
+ * Complete trace bundle with cryptographic commitments.
252
+ * Contains both public view and private data.
253
+ *
254
+ * @property formatVersion - Bundle format version
255
+ * @property publicView - Safe to share externally
256
+ * @property privateRun - Full trace data
257
+ * @property merkleRoot - Span-level Merkle root
258
+ * @property rootHash - Rolling hash final (execution sequence)
259
+ * @property manifestHash - Set after manifest creation
260
+ * @property signerId - Optional signer identifier
261
+ * @property signature - Optional signature over bundle
262
+ */
263
+ interface TraceBundle {
264
+ formatVersion: SchemaVersion;
265
+ publicView: TraceBundlePublicView;
266
+ privateRun: TraceRun;
267
+ merkleRoot: string;
268
+ rootHash: string;
269
+ manifestHash?: string;
270
+ signerId?: string;
271
+ signature?: string;
272
+ }
273
+ /**
274
+ * Interface for signing providers.
275
+ * Consumers provide implementation (e.g., HSM, KMS, local key).
276
+ */
277
+ interface SignatureProvider {
278
+ signerId: string;
279
+ sign(data: Uint8Array): Promise<Uint8Array>;
280
+ verify(data: Uint8Array, signature: Uint8Array, signerId: string): Promise<boolean>;
281
+ }
282
+ /**
283
+ * Information about a stored chunk.
284
+ *
285
+ * @property index - Chunk sequence number
286
+ * @property hash - SHA-256 of chunk content (BEFORE compression)
287
+ * @property size - Bytes (uncompressed)
288
+ * @property compressedSize - Bytes (if compressed)
289
+ * @property compression - Hint for consumers (process-trace doesn't compress)
290
+ * @property spanIds - Which spans are in this chunk
291
+ */
292
+ interface ChunkInfo {
293
+ index: number;
294
+ hash: string;
295
+ size: number;
296
+ compressedSize?: number;
297
+ compression?: "gzip" | "none";
298
+ spanIds: string[];
299
+ }
300
+ /**
301
+ * Chunk data ready for storage.
302
+ */
303
+ interface Chunk {
304
+ info: ChunkInfo;
305
+ content: string;
306
+ }
307
+ /**
308
+ * Manifest describing stored trace data.
309
+ * This file is public-safe and serves as the entry point for retrieval.
310
+ *
311
+ * Storage layout:
312
+ * ```
313
+ * <storageUri>/
314
+ * manifest.json # TraceManifest (public-safe)
315
+ * chunks/
316
+ * <hash1>.json.gz # Compressed chunk
317
+ * <hash2>.json.gz
318
+ * ```
319
+ */
320
+ interface TraceManifest {
321
+ formatVersion: SchemaVersion;
322
+ runId: string;
323
+ agentId: string;
324
+ rootHash: string;
325
+ merkleRoot: string;
326
+ manifestHash?: string;
327
+ totalEvents: number;
328
+ totalSpans: number;
329
+ startedAt: string;
330
+ endedAt: string;
331
+ durationMs: number;
332
+ chunks: ChunkInfo[];
333
+ publicView: TraceBundlePublicView;
334
+ }
335
+ /**
336
+ * Disclosure mode determines what data is revealed.
337
+ * - "membership": Merkle proof only (proves span exists, hash matches)
338
+ * - "full": Merkle proof + span data + event data
339
+ */
340
+ type DisclosureMode = "membership" | "full";
341
+ /**
342
+ * Result of selective disclosure operation.
343
+ */
344
+ interface DisclosureResult {
345
+ mode: DisclosureMode;
346
+ rootHash: string;
347
+ merkleRoot: string;
348
+ disclosedSpans: Array<{
349
+ spanId: string;
350
+ proof: MerkleProof;
351
+ span?: TraceSpan;
352
+ events?: TraceEvent[];
353
+ }>;
354
+ }
355
+ /**
356
+ * Result of bundle verification.
357
+ */
358
+ interface TraceVerificationResult {
359
+ valid: boolean;
360
+ errors: string[];
361
+ warnings: string[];
362
+ checks: {
363
+ rollingHashValid: boolean;
364
+ rootHashValid: boolean;
365
+ merkleRootValid: boolean;
366
+ spanHashesValid: boolean;
367
+ eventHashesValid: boolean;
368
+ sequenceValid: boolean;
369
+ };
370
+ }
371
+ /**
372
+ * Result of manifest verification.
373
+ */
374
+ interface ManifestVerificationResult {
375
+ valid: boolean;
376
+ errors: string[];
377
+ warnings: string[];
378
+ checks: {
379
+ manifestHashValid: boolean;
380
+ chunkHashesValid: boolean;
381
+ rootHashMatches: boolean;
382
+ merkleRootMatches: boolean;
383
+ };
384
+ }
385
+ /**
386
+ * Options for creating a new trace.
387
+ */
388
+ interface CreateTraceOptions {
389
+ agentId: string;
390
+ description?: string;
391
+ metadata?: Record<string, unknown>;
392
+ }
393
+ /**
394
+ * Options for creating a new span.
395
+ */
396
+ interface CreateSpanOptions {
397
+ name: string;
398
+ parentSpanId?: string;
399
+ visibility?: Visibility;
400
+ metadata?: Record<string, unknown>;
401
+ }
402
+ /**
403
+ * Options for creating a manifest with chunks.
404
+ */
405
+ interface CreateManifestOptions {
406
+ chunkSize?: number;
407
+ compression?: "gzip" | "none";
408
+ }
409
+ /**
410
+ * Domain separation prefixes for hashing.
411
+ * These prevent cross-context hash collisions.
412
+ */
413
+ declare const HASH_DOMAIN_PREFIXES: {
414
+ readonly event: "poi-trace:event:v1|";
415
+ readonly roll: "poi-trace:roll:v1|";
416
+ readonly span: "poi-trace:span:v1|";
417
+ readonly leaf: "poi-trace:leaf:v1|";
418
+ readonly node: "poi-trace:node:v1|";
419
+ readonly manifest: "poi-trace:manifest:v1|";
420
+ readonly root: "poi-trace:root:v1|";
421
+ };
422
+ /**
423
+ * Type for domain prefix keys.
424
+ */
425
+ type HashDomain = keyof typeof HASH_DOMAIN_PREFIXES;
426
+
427
+ /**
428
+ * @fileoverview Selective disclosure of trace spans with Merkle proofs.
429
+ *
430
+ * Location: packages/process-trace/src/disclosure.ts
431
+ *
432
+ * This module implements selective disclosure functionality for trace bundles,
433
+ * enabling privacy-preserving audits and compliance workflows. It allows verifiers
434
+ * to prove the existence of specific spans without revealing the entire trace.
435
+ *
436
+ * Key Concepts:
437
+ * - Selective Disclosure: Reveal only specific spans from a trace bundle
438
+ * - Membership Proofs: Prove a span exists without revealing its contents
439
+ * - Full Disclosure: Prove existence AND reveal span data with events
440
+ *
441
+ * Disclosure Modes:
442
+ * - "membership": Merkle proof only - proves span exists with specific hash
443
+ * without exposing the actual span data. Useful for compliance checks.
444
+ * - "full": Merkle proof + span data + event data - allows verifier to
445
+ * recompute hashes and fully verify the span contents.
446
+ *
447
+ * Use Cases:
448
+ * - Audit: "Show me span 3" (full mode) - auditor sees exactly what happened
449
+ * - Compliance: "Prove span exists" (membership) - no data exposure
450
+ * - Selective sharing: Disclose only public spans to external parties
451
+ *
452
+ * Used by:
453
+ * - Audit workflows: Selective disclosure of trace spans
454
+ * - Compliance verification: Prove span existence without data exposure
455
+ * - API endpoints: Create and verify disclosure requests
456
+ *
457
+ * @example
458
+ * ```typescript
459
+ * // Full disclosure of specific spans
460
+ * const result = await selectiveDisclose(bundle, ["span-1", "span-3"], "full");
461
+ * for (const disclosed of result.disclosedSpans) {
462
+ * console.log("Span:", disclosed.span?.name);
463
+ * console.log("Events:", disclosed.events?.length);
464
+ * }
465
+ *
466
+ * // Membership proof only (no data exposure)
467
+ * const membershipResult = await selectiveDisclose(bundle, ["span-2"], "membership");
468
+ *
469
+ * // Verify disclosure against anchor
470
+ * const verification = await verifyDisclosure(result, anchor.rootHash, anchor.merkleRoot);
471
+ * if (!verification.valid) {
472
+ * console.error("Verification failed:", verification.errors);
473
+ * }
474
+ * ```
475
+ */
476
+
477
+ /**
478
+ * Disclosure request structure for API use.
479
+ *
480
+ * This interface defines the shape of a disclosure request that can be
481
+ * transmitted over network APIs. It contains all the information needed
482
+ * to identify the bundle and specify which spans to disclose.
483
+ *
484
+ * @property bundleRootHash - The root hash of the bundle for identification
485
+ * @property bundleMerkleRoot - The Merkle root for verification
486
+ * @property spanIds - Array of span IDs to disclose
487
+ * @property mode - Disclosure mode (membership or full)
488
+ */
489
+ interface DisclosureRequest {
490
+ bundleRootHash: string;
491
+ bundleMerkleRoot: string;
492
+ spanIds: string[];
493
+ mode: DisclosureMode;
494
+ }
495
+ /**
496
+ * Check if a span can be disclosed (exists in bundle).
497
+ *
498
+ * This function performs a simple existence check to determine if a span
499
+ * with the given ID exists in the bundle. It searches the privateRun.spans
500
+ * array for a matching span ID.
501
+ *
502
+ * @param bundle - The trace bundle to check
503
+ * @param spanId - The ID of the span to look for
504
+ * @returns true if the span exists in the bundle, false otherwise
505
+ *
506
+ * @example
507
+ * ```typescript
508
+ * if (canDisclose(bundle, "span-123")) {
509
+ * const result = await selectiveDisclose(bundle, ["span-123"], "full");
510
+ * } else {
511
+ * console.error("Span not found in bundle");
512
+ * }
513
+ * ```
514
+ */
515
+ declare function canDisclose(bundle: TraceBundle, spanId: string): boolean;
516
+ /**
517
+ * Get span index by ID (needed for proof generation).
518
+ *
519
+ * Returns the index of a span in the sorted spans array (sorted by spanSeq).
520
+ * This index is used for Merkle proof generation, as the proof depends on
521
+ * the position of the span's leaf in the Merkle tree.
522
+ *
523
+ * @param bundle - The trace bundle containing the span
524
+ * @param spanId - The ID of the span to find
525
+ * @returns The 0-indexed position of the span in the sorted array
526
+ * @throws Error if the span is not found in the bundle
527
+ *
528
+ * @example
529
+ * ```typescript
530
+ * const index = getSpanIndex(bundle, "span-456");
531
+ * console.log(`Span is at index ${index} in the Merkle tree`);
532
+ * ```
533
+ */
534
+ declare function getSpanIndex(bundle: TraceBundle, spanId: string): number;
535
+ /**
536
+ * Create a disclosure request (for API use).
537
+ *
538
+ * This function creates a structured disclosure request object that can be
539
+ * serialized and transmitted over network APIs. The request contains all
540
+ * information needed to identify the bundle and specify which spans to disclose.
541
+ *
542
+ * @param bundle - The trace bundle to create a request for
543
+ * @param spanIds - Array of span IDs to request disclosure for
544
+ * @param mode - The disclosure mode (membership or full)
545
+ * @returns A DisclosureRequest object ready for transmission
546
+ *
547
+ * @example
548
+ * ```typescript
549
+ * const request = createDisclosureRequest(
550
+ * bundle,
551
+ * ["span-1", "span-3"],
552
+ * "full"
553
+ * );
554
+ *
555
+ * // Send request to disclosure service
556
+ * const response = await fetch("/api/disclose", {
557
+ * method: "POST",
558
+ * body: JSON.stringify(request),
559
+ * });
560
+ * ```
561
+ */
562
+ declare function createDisclosureRequest(bundle: TraceBundle, spanIds: string[], mode: DisclosureMode): DisclosureRequest;
563
+ /**
564
+ * Selectively disclose specific spans from a bundle.
565
+ *
566
+ * This function generates disclosure results for the specified spans. Depending
567
+ * on the disclosure mode, it includes either just Merkle proofs (membership mode)
568
+ * or Merkle proofs plus full span and event data (full mode).
569
+ *
570
+ * The function validates that all requested spans exist in the bundle before
571
+ * proceeding with disclosure generation.
572
+ *
573
+ * @param bundle - The trace bundle containing all data
574
+ * @param spanIds - IDs of spans to disclose
575
+ * @param mode - Disclosure mode:
576
+ * - "membership": Merkle proof only (proves span exists with hash)
577
+ * - "full": Merkle proof + span data + event data
578
+ * @returns Promise resolving to DisclosureResult with proofs and optionally data
579
+ * @throws Error if any requested spanId does not exist in the bundle
580
+ *
581
+ * @example
582
+ * ```typescript
583
+ * // Full disclosure - includes span data and events
584
+ * const fullResult = await selectiveDisclose(bundle, ["span-1"], "full");
585
+ * console.log(fullResult.disclosedSpans[0].span?.name);
586
+ * console.log(fullResult.disclosedSpans[0].events?.length);
587
+ *
588
+ * // Membership disclosure - proof only, no data
589
+ * const membershipResult = await selectiveDisclose(bundle, ["span-1"], "membership");
590
+ * // membershipResult.disclosedSpans[0].span is undefined
591
+ * // membershipResult.disclosedSpans[0].events is undefined
592
+ * ```
593
+ */
594
+ declare function selectiveDisclose(bundle: TraceBundle, spanIds: string[], mode: DisclosureMode): Promise<DisclosureResult>;
595
+ /**
596
+ * Verify a disclosure result against expected hashes.
597
+ *
598
+ * This function performs comprehensive verification of a disclosure result:
599
+ * 1. Checks that rootHash matches the expected value from the anchor
600
+ * 2. Checks that merkleRoot matches the expected value from the anchor
601
+ * 3. For each disclosed span, verifies the Merkle proof
602
+ * 4. For full mode disclosures, verifies span hash recomputation
603
+ *
604
+ * @param disclosure - The disclosure result to verify
605
+ * @param expectedRootHash - Expected root hash from anchor/on-chain commitment
606
+ * @param expectedMerkleRoot - Expected Merkle root from anchor/on-chain commitment
607
+ * @returns Promise resolving to verification result with validity status and errors
608
+ *
609
+ * @example
610
+ * ```typescript
611
+ * const disclosure = await selectiveDisclose(bundle, ["span-1"], "full");
612
+ * const verification = await verifyDisclosure(
613
+ * disclosure,
614
+ * anchor.rootHash,
615
+ * anchor.merkleRoot
616
+ * );
617
+ *
618
+ * if (verification.valid) {
619
+ * console.log("Disclosure verified successfully");
620
+ * } else {
621
+ * console.error("Verification failed:", verification.errors);
622
+ * }
623
+ * ```
624
+ */
625
+ declare function verifyDisclosure(disclosure: DisclosureResult, expectedRootHash: string, expectedMerkleRoot: string): Promise<{
626
+ valid: boolean;
627
+ errors: string[];
628
+ }>;
629
+ /**
630
+ * Verify a single span's disclosure (with data).
631
+ *
632
+ * This function performs detailed verification of a disclosed span:
633
+ * 1. Recomputes the span hash from the provided span and events
634
+ * 2. Computes the expected leaf hash from the span hash
635
+ * 3. Verifies the leaf hash matches the proof's leafHash
636
+ * 4. Verifies the Merkle proof is valid
637
+ *
638
+ * This is used for "full" mode disclosures where span data is provided.
639
+ *
640
+ * @param disclosed - Object containing spanId, proof, span data, and events
641
+ * @param expectedMerkleRoot - Expected Merkle root from anchor/on-chain commitment
642
+ * @returns Promise resolving to verification result with validity status and errors
643
+ *
644
+ * @example
645
+ * ```typescript
646
+ * const result = await verifySpanDisclosure(
647
+ * {
648
+ * spanId: "span-123",
649
+ * proof: merkleProof,
650
+ * span: spanData,
651
+ * events: spanEvents,
652
+ * },
653
+ * expectedMerkleRoot
654
+ * );
655
+ *
656
+ * if (result.valid) {
657
+ * console.log("Span data is authentic and included in the trace");
658
+ * }
659
+ * ```
660
+ */
661
+ declare function verifySpanDisclosure(disclosed: {
662
+ spanId: string;
663
+ proof: MerkleProof;
664
+ span: TraceSpan;
665
+ events: TraceEvent[];
666
+ }, expectedMerkleRoot: string): Promise<{
667
+ valid: boolean;
668
+ errors: string[];
669
+ }>;
670
+
671
+ /**
672
+ * @fileoverview Main API for building traces - creating runs, adding spans, events, and finalizing.
673
+ *
674
+ * Location: packages/process-trace/src/trace-builder.ts
675
+ *
676
+ * This module provides the primary entry points for constructing trace runs. It handles:
677
+ * - Creating new trace runs with proper initialization
678
+ * - Adding spans (logical groupings of related events)
679
+ * - Adding events with automatic sequencing, timestamping, and hashing
680
+ * - Closing spans and computing span hashes
681
+ * - Finalizing traces with Merkle tree construction and root hash computation
682
+ * - Generating public views for external sharing
683
+ *
684
+ * The trace builder maintains internal state (rolling hash, sequence counters) and
685
+ * ensures cryptographic integrity at each step. Events are ordered by monotonic
686
+ * sequence numbers (seq), not timestamps, to guarantee deterministic ordering.
687
+ *
688
+ * Used by:
689
+ * - Agent implementations to record execution traces
690
+ * - Integration tests for trace verification
691
+ * - Audit workflows for compliance reporting
692
+ *
693
+ * @example
694
+ * ```typescript
695
+ * // Create a new trace
696
+ * const run = await createTrace({ agentId: "agent-1" });
697
+ *
698
+ * // Add a span for a logical unit of work
699
+ * const span = addSpan(run, { name: "build-project" });
700
+ *
701
+ * // Add events to the span
702
+ * await addEvent(run, span.id, { kind: "command", command: "npm install" });
703
+ * await addEvent(run, span.id, { kind: "output", stream: "stdout", content: "done" });
704
+ *
705
+ * // Close the span and finalize
706
+ * await closeSpan(run, span.id);
707
+ * const bundle = await finalizeTrace(run);
708
+ * ```
709
+ */
710
+
711
+ /**
712
+ * Create a new trace run.
713
+ *
714
+ * Initializes a fresh trace with:
715
+ * - Unique UUID for the run ID
716
+ * - Schema version "1.0"
717
+ * - Status "running"
718
+ * - Genesis rolling hash state
719
+ * - Empty events and spans arrays
720
+ * - Sequence counters at 0
721
+ *
722
+ * @param opts - Options for creating the trace
723
+ * @param opts.agentId - Identifier of the agent producing this trace
724
+ * @param opts.description - Optional human-readable description
725
+ * @param opts.metadata - Optional key-value metadata
726
+ * @returns Promise resolving to the initialized TraceRun
727
+ *
728
+ * @example
729
+ * ```typescript
730
+ * const run = await createTrace({
731
+ * agentId: "claude-agent-v1",
732
+ * description: "Build and test the project",
733
+ * metadata: { environment: "production" },
734
+ * });
735
+ * ```
736
+ */
737
+ declare function createTrace(opts: CreateTraceOptions): Promise<TraceRun>;
738
+ /**
739
+ * Add a new span to a trace run.
740
+ *
741
+ * Creates a span with:
742
+ * - Unique UUID for span ID
743
+ * - Assigned spanSeq from run.nextSpanSeq
744
+ * - Status "running"
745
+ * - Empty eventIds and childSpanIds arrays
746
+ *
747
+ * If a parentSpanId is provided, the span is added to the parent's childSpanIds.
748
+ *
749
+ * @param run - The trace run to add the span to (mutated in place)
750
+ * @param opts - Options for creating the span
751
+ * @param opts.name - Human-readable name for the span
752
+ * @param opts.parentSpanId - Optional parent span ID for nesting
753
+ * @param opts.visibility - Span visibility level (defaults to "private")
754
+ * @param opts.metadata - Optional key-value metadata
755
+ * @returns The created TraceSpan
756
+ * @throws Error if the run is finalized or parent span is not found
757
+ *
758
+ * @example
759
+ * ```typescript
760
+ * // Create a top-level span
761
+ * const buildSpan = addSpan(run, { name: "build" });
762
+ *
763
+ * // Create a nested span
764
+ * const installSpan = addSpan(run, {
765
+ * name: "npm-install",
766
+ * parentSpanId: buildSpan.id,
767
+ * visibility: "public",
768
+ * });
769
+ * ```
770
+ */
771
+ declare function addSpan(run: TraceRun, opts: CreateSpanOptions): TraceSpan;
772
+ /**
773
+ * Get a span by ID from a run.
774
+ *
775
+ * @param run - The trace run to search
776
+ * @param spanId - The span ID to find
777
+ * @returns The span if found, undefined otherwise
778
+ *
779
+ * @example
780
+ * ```typescript
781
+ * const span = getSpan(run, "some-span-id");
782
+ * if (span) {
783
+ * console.log(`Found span: ${span.name}`);
784
+ * }
785
+ * ```
786
+ */
787
+ declare function getSpan(run: TraceRun, spanId: string): TraceSpan | undefined;
788
+ /**
789
+ * Get events for a span.
790
+ *
791
+ * Returns all events belonging to the specified span, sorted by sequence number.
792
+ *
793
+ * @param run - The trace run containing the events
794
+ * @param spanId - The span ID to get events for
795
+ * @returns Array of TraceEvents for the span, sorted by seq
796
+ *
797
+ * @example
798
+ * ```typescript
799
+ * const events = getSpanEvents(run, span.id);
800
+ * for (const event of events) {
801
+ * console.log(`Event ${event.seq}: ${event.kind}`);
802
+ * }
803
+ * ```
804
+ */
805
+ declare function getSpanEvents$1(run: TraceRun, spanId: string): TraceEvent[];
806
+ /**
807
+ * Type helper to extract the event type by kind.
808
+ * Used for type-safe event creation without runtime fields.
809
+ */
810
+ type EventWithoutRuntimeFields<K extends TraceEventKind> = Omit<Extract<TraceEvent, {
811
+ kind: K;
812
+ }>, "id" | "seq" | "timestamp" | "hash">;
813
+ /**
814
+ * Add an event to a span within a trace run.
815
+ *
816
+ * Automatically assigns:
817
+ * - Unique UUID for event ID
818
+ * - Monotonic sequence number from run.nextSeq
819
+ * - ISO 8601 timestamp
820
+ * - Default visibility based on event kind (if not specified)
821
+ * - Computed event hash
822
+ *
823
+ * Also updates the run's rolling hash to maintain cryptographic chain.
824
+ *
825
+ * @param run - The trace run (mutated in place)
826
+ * @param spanId - ID of the span to add event to
827
+ * @param event - Event data without runtime fields (id, seq, timestamp, hash)
828
+ * @returns Promise resolving to the complete TraceEvent
829
+ * @throws Error if run is finalized, span not found, or span is closed
830
+ *
831
+ * @example
832
+ * ```typescript
833
+ * // Add a command event
834
+ * const cmdEvent = await addEvent(run, span.id, {
835
+ * kind: "command",
836
+ * command: "npm install",
837
+ * args: ["--save-dev", "typescript"],
838
+ * visibility: "public",
839
+ * });
840
+ *
841
+ * // Add an output event (will use default "private" visibility)
842
+ * const outEvent = await addEvent(run, span.id, {
843
+ * kind: "output",
844
+ * stream: "stdout",
845
+ * content: "added 120 packages",
846
+ * });
847
+ * ```
848
+ */
849
+ declare function addEvent<K extends TraceEventKind>(run: TraceRun, spanId: string, event: EventWithoutRuntimeFields<K>): Promise<TraceEvent>;
850
+ /**
851
+ * Close a span, marking it as completed/failed/cancelled.
852
+ *
853
+ * Sets the span's:
854
+ * - status (default "completed")
855
+ * - endedAt timestamp
856
+ * - durationMs (calculated from startedAt to endedAt)
857
+ * - hash (computed from span header + event hashes)
858
+ *
859
+ * @param run - The trace run containing the span (mutated in place)
860
+ * @param spanId - ID of the span to close
861
+ * @param status - Final status (default "completed")
862
+ * @throws Error if span not found or already closed
863
+ *
864
+ * @example
865
+ * ```typescript
866
+ * // Close with default "completed" status
867
+ * await closeSpan(run, span.id);
868
+ *
869
+ * // Close with explicit status
870
+ * await closeSpan(run, span.id, "failed");
871
+ * ```
872
+ */
873
+ declare function closeSpan(run: TraceRun, spanId: string, status?: TraceStatus): Promise<void>;
874
+ /**
875
+ * Check if a run is finalized.
876
+ *
877
+ * A run is considered finalized when it has a rootHash set.
878
+ *
879
+ * @param run - The trace run to check
880
+ * @returns true if the run is finalized
881
+ *
882
+ * @example
883
+ * ```typescript
884
+ * if (!isFinalized(run)) {
885
+ * // Can still add spans and events
886
+ * await addEvent(run, span.id, { kind: "command", command: "ls" });
887
+ * }
888
+ * ```
889
+ */
890
+ declare function isFinalized(run: TraceRun): boolean;
891
+ /**
892
+ * Finalize a trace run, computing all final hashes and creating a bundle.
893
+ *
894
+ * Finalization performs:
895
+ * 1. Closes any open spans (with status "completed")
896
+ * 2. Sets run status to "completed"
897
+ * 3. Sets run endedAt and durationMs
898
+ * 4. Builds Merkle tree from spans
899
+ * 5. Computes root hash from rolling hash + span hashes
900
+ * 6. Creates public view (only public spans with their events)
901
+ * 7. Returns complete TraceBundle
902
+ *
903
+ * After finalization, no more spans or events can be added.
904
+ *
905
+ * @param run - The trace run to finalize (mutated in place)
906
+ * @returns Promise resolving to the complete TraceBundle
907
+ * @throws Error if the run is already finalized
908
+ *
909
+ * @example
910
+ * ```typescript
911
+ * // Finalize and get the bundle
912
+ * const bundle = await finalizeTrace(run);
913
+ *
914
+ * // Access the cryptographic commitments
915
+ * console.log(`Root hash: ${bundle.rootHash}`);
916
+ * console.log(`Merkle root: ${bundle.merkleRoot}`);
917
+ *
918
+ * // Access the public view for sharing
919
+ * console.log(`Public spans: ${bundle.publicView.publicSpans.length}`);
920
+ * ```
921
+ */
922
+ declare function finalizeTrace(run: TraceRun): Promise<TraceBundle>;
923
+ /**
924
+ * Get total event count for a trace run.
925
+ *
926
+ * @param run - The trace run
927
+ * @returns Number of events in the run
928
+ */
929
+ declare function getEventCount(run: TraceRun): number;
930
+ /**
931
+ * Get total span count for a trace run.
932
+ *
933
+ * @param run - The trace run
934
+ * @returns Number of spans in the run
935
+ */
936
+ declare function getSpanCount(run: TraceRun): number;
937
+ /**
938
+ * Get all root spans (spans without a parent).
939
+ *
940
+ * @param run - The trace run
941
+ * @returns Array of root-level spans
942
+ */
943
+ declare function getRootSpans(run: TraceRun): TraceSpan[];
944
+ /**
945
+ * Get child spans for a given parent span.
946
+ *
947
+ * @param run - The trace run
948
+ * @param parentSpanId - The parent span ID
949
+ * @returns Array of child spans
950
+ */
951
+ declare function getChildSpans(run: TraceRun, parentSpanId: string): TraceSpan[];
952
+ /**
953
+ * Get an event by ID from a run.
954
+ *
955
+ * @param run - The trace run
956
+ * @param eventId - The event ID to find
957
+ * @returns The event if found, undefined otherwise
958
+ */
959
+ declare function getEvent(run: TraceRun, eventId: string): TraceEvent | undefined;
960
+ /**
961
+ * Get all events of a specific kind from a run.
962
+ *
963
+ * @param run - The trace run
964
+ * @param kind - The event kind to filter by
965
+ * @returns Array of events matching the kind
966
+ */
967
+ declare function getEventsByKind<K extends TraceEventKind>(run: TraceRun, kind: K): Extract<TraceEvent, {
968
+ kind: K;
969
+ }>[];
970
+
971
+ /**
972
+ * @fileoverview Rolling hash computation for trace events using domain-separated SHA-256.
973
+ *
974
+ * Location: packages/process-trace/src/rolling-hash.ts
975
+ *
976
+ * This module implements cryptographic rolling hash computation for the process-trace
977
+ * package. Rolling hashes provide tamper-evident sequencing of trace events, ensuring
978
+ * that any modification to the event sequence is detectable.
979
+ *
980
+ * Domain Separation:
981
+ * - Event hashes use prefix "poi-trace:event:v1|" to prevent cross-context collisions
982
+ * - Rolling hashes use prefix "poi-trace:roll:v1|" for chain linking
983
+ * - Root hashes use prefix "poi-trace:root:v1|" for final commitment
984
+ *
985
+ * The rolling hash forms a hash chain: each hash incorporates the previous hash,
986
+ * creating an ordered, tamper-evident sequence. This is similar to blockchain
987
+ * block linking but at the event level.
988
+ *
989
+ * Used by:
990
+ * - TraceBuilder: Incrementally updates rolling hash as events are added
991
+ * - TraceBundle: Computes final root hash for the complete trace
992
+ * - TraceVerifier: Validates that event sequences have not been tampered with
993
+ *
994
+ * @example
995
+ * ```typescript
996
+ * // Initialize rolling hash state
997
+ * const state = await initRollingHash();
998
+ *
999
+ * // Add events incrementally
1000
+ * for (const event of events) {
1001
+ * const eventHash = await computeEventHash(event);
1002
+ * state = await updateRollingHash(state, eventHash);
1003
+ * }
1004
+ *
1005
+ * // Or compute in batch
1006
+ * const finalHash = await computeRollingHash(events);
1007
+ *
1008
+ * // Compute root hash including span hashes
1009
+ * const rootHash = await computeRootHash(finalHash, spans);
1010
+ * ```
1011
+ */
1012
+
1013
+ /**
1014
+ * Compute hash for a single event using domain separation.
1015
+ *
1016
+ * The event hash is computed as:
1017
+ * `H("poi-trace:event:v1|" + canonicalize(eventWithoutHash))`
1018
+ *
1019
+ * The 'hash' field is removed before hashing to avoid circularity - otherwise
1020
+ * computing the hash would require knowing the hash.
1021
+ *
1022
+ * @param event - The trace event to hash
1023
+ * @returns Promise resolving to the event hash as a lowercase hex string
1024
+ *
1025
+ * @example
1026
+ * ```typescript
1027
+ * const event: TraceEvent = {
1028
+ * kind: "command",
1029
+ * id: "550e8400-e29b-41d4-a716-446655440000",
1030
+ * seq: 1,
1031
+ * timestamp: "2024-01-15T10:30:00.000Z",
1032
+ * visibility: "public",
1033
+ * command: "npm install",
1034
+ * };
1035
+ * const hash = await computeEventHash(event);
1036
+ * // Returns 64-character hex string
1037
+ * ```
1038
+ */
1039
+ declare function computeEventHash(event: TraceEvent): Promise<string>;
1040
+ /**
1041
+ * Initialize rolling hash state with the genesis hash.
1042
+ *
1043
+ * The genesis hash is computed as:
1044
+ * `H("poi-trace:roll:v1|genesis")`
1045
+ *
1046
+ * This provides a well-known starting point for all rolling hash chains,
1047
+ * ensuring that empty traces have a deterministic hash value.
1048
+ *
1049
+ * @returns Promise resolving to the initial rolling hash state
1050
+ *
1051
+ * @example
1052
+ * ```typescript
1053
+ * const state = await initRollingHash();
1054
+ * console.log(state.currentHash); // Genesis hash
1055
+ * console.log(state.itemCount); // 0
1056
+ * ```
1057
+ */
1058
+ declare function initRollingHash(): Promise<RollingHashState>;
1059
+ /**
1060
+ * Update rolling hash state with a new event hash.
1061
+ *
1062
+ * The new rolling hash is computed as:
1063
+ * `H("poi-trace:roll:v1|" + prevHash + "|" + eventHash)`
1064
+ *
1065
+ * This creates a hash chain where each hash depends on all previous hashes,
1066
+ * making it impossible to modify earlier events without invalidating all
1067
+ * subsequent hashes.
1068
+ *
1069
+ * @param state - Current rolling hash state
1070
+ * @param eventHash - Hash of the event to add (from computeEventHash)
1071
+ * @returns Promise resolving to the updated rolling hash state
1072
+ *
1073
+ * @example
1074
+ * ```typescript
1075
+ * let state = await initRollingHash();
1076
+ *
1077
+ * const eventHash = await computeEventHash(event);
1078
+ * state = await updateRollingHash(state, eventHash);
1079
+ *
1080
+ * console.log(state.currentHash); // New rolling hash
1081
+ * console.log(state.itemCount); // 1
1082
+ * ```
1083
+ */
1084
+ declare function updateRollingHash(state: RollingHashState, eventHash: string): Promise<RollingHashState>;
1085
+ /**
1086
+ * Compute rolling hash for a sequence of events (batch mode).
1087
+ *
1088
+ * This function processes all events and returns the final rolling hash.
1089
+ * Events are sorted by their `seq` field before processing to ensure
1090
+ * deterministic ordering.
1091
+ *
1092
+ * The result is identical to calling `updateRollingHash` sequentially
1093
+ * for each event, making it suitable for verification.
1094
+ *
1095
+ * @param events - Array of trace events to hash
1096
+ * @returns Promise resolving to the final rolling hash as a hex string
1097
+ *
1098
+ * @example
1099
+ * ```typescript
1100
+ * const events: TraceEvent[] = [
1101
+ * { kind: "command", seq: 1, ... },
1102
+ * { kind: "output", seq: 2, ... },
1103
+ * { kind: "decision", seq: 3, ... },
1104
+ * ];
1105
+ *
1106
+ * const finalHash = await computeRollingHash(events);
1107
+ * ```
1108
+ */
1109
+ declare function computeRollingHash(events: TraceEvent[]): Promise<string>;
1110
+ /**
1111
+ * Verify that a rolling hash matches the expected value for given events.
1112
+ *
1113
+ * This function recomputes the rolling hash from the events and compares
1114
+ * it to the expected value. Used to verify trace integrity.
1115
+ *
1116
+ * @param events - Array of trace events to verify
1117
+ * @param expectedHash - The expected rolling hash value
1118
+ * @returns Promise resolving to true if the hash matches, false otherwise
1119
+ *
1120
+ * @example
1121
+ * ```typescript
1122
+ * const isValid = await verifyRollingHash(events, storedRollingHash);
1123
+ * if (!isValid) {
1124
+ * console.error("Trace has been tampered with!");
1125
+ * }
1126
+ * ```
1127
+ */
1128
+ declare function verifyRollingHash(events: TraceEvent[], expectedHash: string): Promise<boolean>;
1129
+ /**
1130
+ * Compute the final root hash from rolling hash and span hashes.
1131
+ *
1132
+ * The root hash is computed as:
1133
+ * `H("poi-trace:root:v1|" + rollingHash + "|" + spanHash1 + "|" + spanHash2 + ...)`
1134
+ *
1135
+ * Spans are sorted by their `spanSeq` field before joining to ensure
1136
+ * deterministic ordering. This creates a single commitment that covers
1137
+ * both the event sequence (via rolling hash) and the span structure.
1138
+ *
1139
+ * @param rollingHash - The final rolling hash from all events
1140
+ * @param spans - Array of trace spans (must have hash field populated)
1141
+ * @returns Promise resolving to the root hash as a hex string
1142
+ *
1143
+ * @example
1144
+ * ```typescript
1145
+ * const rollingHash = await computeRollingHash(events);
1146
+ * const rootHash = await computeRootHash(rollingHash, spans);
1147
+ *
1148
+ * // rootHash can now be published as the trace commitment
1149
+ * ```
1150
+ */
1151
+ declare function computeRootHash(rollingHash: string, spans: TraceSpan[]): Promise<string>;
1152
+ /**
1153
+ * Compute event hashes for multiple events in batch.
1154
+ * Useful for pre-computing hashes before building a Merkle tree.
1155
+ *
1156
+ * @param events - Array of trace events
1157
+ * @returns Promise resolving to array of event hashes in seq order
1158
+ */
1159
+ declare function computeEventHashes(events: TraceEvent[]): Promise<string[]>;
1160
+ /**
1161
+ * Get the genesis hash for testing and verification.
1162
+ * This is the initial hash value before any events are added.
1163
+ *
1164
+ * @returns Promise resolving to the genesis hash
1165
+ */
1166
+ declare function getGenesisHash(): Promise<string>;
1167
+
1168
+ /**
1169
+ * @fileoverview Merkle tree implementation for span-level selective disclosure.
1170
+ *
1171
+ * Location: packages/process-trace/src/merkle.ts
1172
+ *
1173
+ * This module implements a span-level Merkle tree that enables selective disclosure
1174
+ * of trace spans. Verifiers can prove inclusion of specific spans without revealing
1175
+ * the entire trace, supporting privacy-preserving audit and compliance workflows.
1176
+ *
1177
+ * Domain Separation Rules:
1178
+ * - spanHash = H("poi-trace:span:v1|" + canon(spanHeader) + "|" + eventHash1 + "|" + eventHash2 + ...)
1179
+ * - merkleLeaf = H("poi-trace:leaf:v1|" + spanHash)
1180
+ * - merkleNode = H("poi-trace:node:v1|" + left + "|" + right)
1181
+ *
1182
+ * Used by:
1183
+ * - TraceBuilder: builds Merkle tree when finalizing traces
1184
+ * - Verification: verifies span inclusion proofs
1185
+ * - Selective disclosure: generates proofs for specific spans
1186
+ */
1187
+
1188
+ /**
1189
+ * Compute the hash for a span including its event hashes.
1190
+ *
1191
+ * The span hash is computed as:
1192
+ * H("poi-trace:span:v1|" + canon(spanHeaderWithoutHash) + "|" + eventHash1 + "|" + eventHash2 + ...)
1193
+ *
1194
+ * The span header includes all fields except the `hash` field itself.
1195
+ * Event hashes are concatenated in sequence order, joined by "|".
1196
+ *
1197
+ * @param span - The span to compute hash for
1198
+ * @param eventHashes - Array of event hashes in sequence order
1199
+ * @returns Promise resolving to the span hash as a hex string
1200
+ *
1201
+ * @example
1202
+ * const spanHash = await computeSpanHash(span, ["abc123...", "def456..."]);
1203
+ */
1204
+ declare function computeSpanHash(span: TraceSpan, eventHashes: string[]): Promise<string>;
1205
+ /**
1206
+ * Build a Merkle tree from spans.
1207
+ *
1208
+ * Leaves are computed as H("poi-trace:leaf:v1|" + spanHash) in spanSeq order.
1209
+ * Internal nodes are computed as H("poi-trace:node:v1|" + left + "|" + right).
1210
+ *
1211
+ * ODD-LEAF RULE: If there is an odd number of nodes at any level, the last
1212
+ * hash is duplicated to create a balanced tree.
1213
+ *
1214
+ * @param spans - Array of spans (will be sorted by spanSeq)
1215
+ * @param events - Array of all events (used to get hashes for spans)
1216
+ * @returns Promise resolving to the complete Merkle tree
1217
+ *
1218
+ * @example
1219
+ * const tree = await buildSpanMerkleTree(spans, events);
1220
+ * console.log(tree.rootHash); // Merkle root for disclosure commitment
1221
+ */
1222
+ declare function buildSpanMerkleTree(spans: TraceSpan[], events: TraceEvent[]): Promise<TraceMerkleTree>;
1223
+ /**
1224
+ * Generate a Merkle proof for a specific span by index.
1225
+ *
1226
+ * The proof contains the sibling hashes along the path from the leaf to the root,
1227
+ * with position hints ("left" or "right") indicating which side each sibling is on.
1228
+ *
1229
+ * @param tree - The complete Merkle tree
1230
+ * @param spanIndex - 0-indexed position of the span in the tree
1231
+ * @returns MerkleProof for the specified span
1232
+ * @throws Error if spanIndex is out of bounds
1233
+ *
1234
+ * @example
1235
+ * const proof = generateMerkleProof(tree, 2);
1236
+ * console.log(proof.siblings); // [{hash: "...", position: "right"}, ...]
1237
+ */
1238
+ declare function generateMerkleProof(tree: TraceMerkleTree, spanIndex: number): MerkleProof;
1239
+ /**
1240
+ * Verify a Merkle proof against the expected root.
1241
+ *
1242
+ * Starting from the leaf hash, the proof is recomputed by combining with
1243
+ * sibling hashes according to their positions. The final computed root
1244
+ * must match the expected rootHash in the proof.
1245
+ *
1246
+ * @param proof - The Merkle proof to verify
1247
+ * @returns Promise resolving to true if the proof is valid
1248
+ *
1249
+ * @example
1250
+ * const valid = await verifyMerkleProof(proof);
1251
+ * if (!valid) {
1252
+ * throw new Error("Merkle proof verification failed");
1253
+ * }
1254
+ */
1255
+ declare function verifyMerkleProof(proof: MerkleProof): Promise<boolean>;
1256
+ /**
1257
+ * Verify a span's inclusion using its proof and data.
1258
+ *
1259
+ * This function recomputes the span hash from the provided span and events,
1260
+ * then verifies that the resulting leaf hash matches the proof and that
1261
+ * the proof is valid against the expected root.
1262
+ *
1263
+ * @param proof - The Merkle proof for the span
1264
+ * @param span - The span data to verify
1265
+ * @param events - The events belonging to this span
1266
+ * @returns Promise resolving to true if span is validly included
1267
+ *
1268
+ * @example
1269
+ * const valid = await verifySpanInclusion(proof, span, spanEvents);
1270
+ * if (valid) {
1271
+ * console.log("Span is cryptographically included in the trace");
1272
+ * }
1273
+ */
1274
+ declare function verifySpanInclusion(proof: MerkleProof, span: TraceSpan, events: TraceEvent[]): Promise<boolean>;
1275
+
1276
+ /**
1277
+ * @fileoverview Bundle creation, extraction, verification, and signing for trace bundles.
1278
+ *
1279
+ * Location: packages/process-trace/src/bundle.ts
1280
+ *
1281
+ * This module provides the core functionality for working with trace bundles:
1282
+ * - Creating bundles from finalized trace runs
1283
+ * - Extracting public views for safe external sharing
1284
+ * - Verifying bundle integrity (hashes, sequences, merkle proofs)
1285
+ * - Signing and verifying bundle signatures
1286
+ *
1287
+ * A TraceBundle is the finalized, immutable form of a trace run that includes:
1288
+ * - The complete private trace run data
1289
+ * - A public view with redacted sensitive information
1290
+ * - Cryptographic commitments (rootHash, merkleRoot)
1291
+ * - Optional signature for authenticity verification
1292
+ *
1293
+ * Visibility Rules:
1294
+ * - "public": Events/spans are included in the publicView
1295
+ * - "private": Hash included in redactedSpanHashes, data not disclosed
1296
+ * - "secret": Hash included in redactedSpanHashes, data never disclosed
1297
+ *
1298
+ * Used by:
1299
+ * - TraceBuilder: Creates bundles when finalizing traces
1300
+ * - TraceVerifier: Validates bundle integrity
1301
+ * - TraceStorage: Prepares bundles for storage/transmission
1302
+ * - Disclosure workflows: Extracts public views for sharing
1303
+ *
1304
+ * @example
1305
+ * ```typescript
1306
+ * // Create a bundle from a finalized run
1307
+ * const bundle = await createBundle(finalizedRun);
1308
+ *
1309
+ * // Extract public view for sharing
1310
+ * const publicView = extractPublicView(bundle);
1311
+ *
1312
+ * // Verify bundle integrity
1313
+ * const result = await verifyBundle(bundle);
1314
+ * if (!result.valid) {
1315
+ * console.error("Bundle verification failed:", result.errors);
1316
+ * }
1317
+ *
1318
+ * // Sign a bundle
1319
+ * const signedBundle = await signBundle(bundle, signatureProvider);
1320
+ * ```
1321
+ */
1322
+
1323
+ /**
1324
+ * Check if a span should be included in public view.
1325
+ *
1326
+ * Only spans with visibility "public" are included in the public view.
1327
+ * Private and secret spans are redacted (only their hashes are included).
1328
+ *
1329
+ * @param span - The span to check
1330
+ * @returns true if the span is public and should be included in publicView
1331
+ *
1332
+ * @example
1333
+ * ```typescript
1334
+ * if (isPublicSpan(span)) {
1335
+ * publicSpans.push(span);
1336
+ * } else {
1337
+ * redactedSpanHashes.push({ spanId: span.id, hash: span.hash });
1338
+ * }
1339
+ * ```
1340
+ */
1341
+ declare function isPublicSpan(span: TraceSpan): boolean;
1342
+ /**
1343
+ * Check if an event should be included in public view.
1344
+ *
1345
+ * Only events with visibility "public" are included in the public view.
1346
+ * Private and secret events are not disclosed.
1347
+ *
1348
+ * @param event - The event to check
1349
+ * @returns true if the event is public and should be included in publicView
1350
+ *
1351
+ * @example
1352
+ * ```typescript
1353
+ * const publicEvents = events.filter(isPublicEvent);
1354
+ * ```
1355
+ */
1356
+ declare function isPublicEvent(event: TraceEvent): boolean;
1357
+ /**
1358
+ * Filter events by visibility, returning only public events.
1359
+ *
1360
+ * This function creates a new array containing only events with
1361
+ * visibility === "public". The original array is not modified.
1362
+ *
1363
+ * @param events - Array of trace events to filter
1364
+ * @returns Array containing only public events
1365
+ *
1366
+ * @example
1367
+ * ```typescript
1368
+ * const allEvents = getSpanEvents(span, run.events);
1369
+ * const publicEvents = filterPublicEvents(allEvents);
1370
+ * ```
1371
+ */
1372
+ declare function filterPublicEvents(events: TraceEvent[]): TraceEvent[];
1373
+ /**
1374
+ * Create a bundle from a finalized trace run.
1375
+ *
1376
+ * The run should already have rootHash computed (i.e., be finalized).
1377
+ * This function:
1378
+ * 1. Validates the run is finalized
1379
+ * 2. Builds the Merkle tree if not already computed
1380
+ * 3. Creates the public view with redacted sensitive data
1381
+ * 4. Returns the complete bundle
1382
+ *
1383
+ * @param run - The finalized trace run (must have rootHash)
1384
+ * @returns Promise resolving to the complete TraceBundle
1385
+ * @throws Error if the run is not finalized (missing rootHash)
1386
+ *
1387
+ * @example
1388
+ * ```typescript
1389
+ * // Finalize the run first
1390
+ * const finalizedRun = await finalizeTraceRun(run);
1391
+ *
1392
+ * // Create the bundle
1393
+ * const bundle = await createBundle(finalizedRun);
1394
+ * console.log(bundle.rootHash); // Cryptographic commitment
1395
+ * console.log(bundle.merkleRoot); // Merkle root for selective disclosure
1396
+ * ```
1397
+ */
1398
+ declare function createBundle(run: TraceRun): Promise<TraceBundle>;
1399
+ /**
1400
+ * Extract the public view from a bundle.
1401
+ *
1402
+ * Returns only public spans with their public events.
1403
+ * This is a convenience function that returns the pre-computed public view
1404
+ * from the bundle. Use this for sharing trace information externally.
1405
+ *
1406
+ * Note: The public view is computed when the bundle is created, so this
1407
+ * function simply returns the existing public view. If you need to
1408
+ * re-compute the public view (e.g., with different redaction rules),
1409
+ * you should create a new bundle.
1410
+ *
1411
+ * @param bundle - The trace bundle
1412
+ * @returns The TraceBundlePublicView (safe to share externally)
1413
+ *
1414
+ * @example
1415
+ * ```typescript
1416
+ * const bundle = await createBundle(run);
1417
+ * const publicView = extractPublicView(bundle);
1418
+ *
1419
+ * // Safe to share externally
1420
+ * await sendToAuditSystem(publicView);
1421
+ * ```
1422
+ */
1423
+ declare function extractPublicView(bundle: TraceBundle): TraceBundlePublicView;
1424
+ /**
1425
+ * Verify a bundle's integrity.
1426
+ *
1427
+ * Performs comprehensive validation including:
1428
+ * - Event hashes are correct (recomputed and compared)
1429
+ * - Span hashes are correct (recomputed and compared)
1430
+ * - Rolling hash matches (recomputed from events)
1431
+ * - Root hash matches (recomputed from rolling hash + span hashes)
1432
+ * - Merkle root matches (recomputed from span tree)
1433
+ * - Event sequence is monotonic (0, 1, 2, ...)
1434
+ * - Span sequence is monotonic (0, 1, 2, ...)
1435
+ *
1436
+ * @param bundle - The trace bundle to verify
1437
+ * @returns Promise resolving to comprehensive verification result
1438
+ *
1439
+ * @example
1440
+ * ```typescript
1441
+ * const result = await verifyBundle(bundle);
1442
+ *
1443
+ * if (!result.valid) {
1444
+ * console.error("Bundle verification failed!");
1445
+ * console.error("Errors:", result.errors);
1446
+ * console.error("Warnings:", result.warnings);
1447
+ * console.error("Checks:", result.checks);
1448
+ * }
1449
+ * ```
1450
+ */
1451
+ declare function verifyBundle(bundle: TraceBundle): Promise<TraceVerificationResult>;
1452
+ /**
1453
+ * Sign a bundle using the provided signature provider.
1454
+ *
1455
+ * Signs the canonical JSON of { rootHash, merkleRoot, manifestHash? }.
1456
+ * The signature and signer ID are added to the bundle.
1457
+ *
1458
+ * @param bundle - The bundle to sign
1459
+ * @param provider - The signature provider implementation
1460
+ * @returns Promise resolving to the signed bundle (new object, original unchanged)
1461
+ *
1462
+ * @example
1463
+ * ```typescript
1464
+ * const provider: SignatureProvider = {
1465
+ * signerId: "agent-123",
1466
+ * sign: async (data) => await myHSM.sign(data),
1467
+ * verify: async (data, sig, signerId) => await myHSM.verify(data, sig),
1468
+ * };
1469
+ *
1470
+ * const signedBundle = await signBundle(bundle, provider);
1471
+ * console.log(signedBundle.signature); // Hex-encoded signature
1472
+ * console.log(signedBundle.signerId); // "agent-123"
1473
+ * ```
1474
+ */
1475
+ declare function signBundle(bundle: TraceBundle, provider: SignatureProvider): Promise<TraceBundle>;
1476
+ /**
1477
+ * Verify a bundle's signature.
1478
+ *
1479
+ * Recomputes the signing payload and verifies the signature using
1480
+ * the provider. The bundle must have both signature and signerId set.
1481
+ *
1482
+ * @param bundle - The signed bundle to verify
1483
+ * @param provider - The signature provider implementation
1484
+ * @returns Promise resolving to true if signature is valid, false otherwise
1485
+ *
1486
+ * @example
1487
+ * ```typescript
1488
+ * const isValid = await verifyBundleSignature(signedBundle, provider);
1489
+ * if (!isValid) {
1490
+ * throw new Error("Bundle signature verification failed!");
1491
+ * }
1492
+ * ```
1493
+ */
1494
+ declare function verifyBundleSignature(bundle: TraceBundle, provider: SignatureProvider): Promise<boolean>;
1495
+ /**
1496
+ * Get all events belonging to a specific span.
1497
+ *
1498
+ * @param span - The span to get events for
1499
+ * @param events - Array of all events
1500
+ * @returns Array of events belonging to the span, sorted by seq
1501
+ */
1502
+ declare function getSpanEvents(span: TraceSpan, events: TraceEvent[]): TraceEvent[];
1503
+ /**
1504
+ * Count events by visibility level in a run.
1505
+ *
1506
+ * @param run - The trace run to analyze
1507
+ * @returns Object with counts for each visibility level
1508
+ */
1509
+ declare function countEventsByVisibility(run: TraceRun): Record<Visibility, number>;
1510
+ /**
1511
+ * Count spans by visibility level in a run.
1512
+ *
1513
+ * @param run - The trace run to analyze
1514
+ * @returns Object with counts for each visibility level
1515
+ */
1516
+ declare function countSpansByVisibility(run: TraceRun): Record<Visibility, number>;
1517
+
1518
+ /**
1519
+ * @fileoverview Manifest creation and verification for off-chain trace storage.
1520
+ *
1521
+ * Location: packages/process-trace/src/manifest.ts
1522
+ *
1523
+ * This module provides functionality for creating manifests and chunks from trace bundles,
1524
+ * enabling efficient off-chain storage of trace data. The manifest serves as a public-safe
1525
+ * entry point for trace retrieval, while chunks contain the actual span and event data.
1526
+ *
1527
+ * Key features:
1528
+ * - Creates manifests with cryptographic commitments for integrity verification
1529
+ * - Chunks trace data by size for efficient storage and retrieval
1530
+ * - Provides verification functions to ensure manifest and chunk integrity
1531
+ * - Supports reconstruction of trace bundles from manifests and chunks
1532
+ *
1533
+ * Storage Layout (for consumers):
1534
+ * ```
1535
+ * <storageUri>/
1536
+ * manifest.json # TraceManifest (public-safe)
1537
+ * chunks/
1538
+ * <hash1>.json # Or .json.gz if compressed by consumer
1539
+ * <hash2>.json
1540
+ * ```
1541
+ *
1542
+ * Used by:
1543
+ * - Storage adapters for persisting trace data
1544
+ * - Retrieval workflows for reconstructing traces
1545
+ * - Verification workflows for validating stored traces
1546
+ *
1547
+ * @example
1548
+ * ```typescript
1549
+ * // Create manifest for storage
1550
+ * const { manifest, chunks } = await createManifest(bundle, { chunkSize: 500_000 });
1551
+ *
1552
+ * // Store chunks (consumer handles actual storage)
1553
+ * for (const chunk of chunks) {
1554
+ * const path = getChunkPath(chunk.info);
1555
+ * await storage.write(path, chunk.content);
1556
+ * }
1557
+ *
1558
+ * // Store manifest
1559
+ * await storage.write("manifest.json", JSON.stringify(manifest));
1560
+ *
1561
+ * // Later: verify
1562
+ * const result = await verifyManifest(manifest, loadedChunks);
1563
+ * if (!result.valid) {
1564
+ * console.error("Manifest verification failed:", result.errors);
1565
+ * }
1566
+ * ```
1567
+ */
1568
+
1569
+ /**
1570
+ * Create a manifest and chunks from a trace bundle.
1571
+ *
1572
+ * Chunks contain private span/event data for off-chain storage. Each chunk
1573
+ * includes a subset of spans and their associated events, grouped to fit
1574
+ * within the target chunk size.
1575
+ *
1576
+ * The manifest contains:
1577
+ * - Metadata from the bundle (runId, agentId, timestamps, etc.)
1578
+ * - Cryptographic commitments (rootHash, merkleRoot)
1579
+ * - Chunk information (index, hash, size, spanIds)
1580
+ * - The complete publicView for quick access
1581
+ *
1582
+ * @param bundle - Finalized trace bundle to create manifest from
1583
+ * @param options - Optional chunking options
1584
+ * @param options.chunkSize - Target chunk size in bytes (default: 1MB)
1585
+ * @param options.compression - Compression hint for consumers (default: "none")
1586
+ * @returns Promise resolving to manifest and array of chunks
1587
+ *
1588
+ * @example
1589
+ * ```typescript
1590
+ * const { manifest, chunks } = await createManifest(bundle, {
1591
+ * chunkSize: 500_000, // 500KB chunks
1592
+ * });
1593
+ *
1594
+ * console.log(`Created ${chunks.length} chunks`);
1595
+ * console.log(`Manifest hash: ${manifest.manifestHash}`);
1596
+ * ```
1597
+ */
1598
+ declare function createManifest(bundle: TraceBundle, options?: CreateManifestOptions): Promise<{
1599
+ manifest: TraceManifest;
1600
+ chunks: Chunk[];
1601
+ }>;
1602
+ /**
1603
+ * Compute the manifest hash.
1604
+ *
1605
+ * The manifest hash is computed as:
1606
+ * `H("poi-trace:manifest:v1|" + canonical(manifestWithoutHash))`
1607
+ *
1608
+ * This hash serves as a cryptographic commitment to the manifest contents,
1609
+ * enabling integrity verification of stored manifests.
1610
+ *
1611
+ * @param manifest - Manifest object without the manifestHash field
1612
+ * @returns Promise resolving to the manifest hash as a hex string
1613
+ *
1614
+ * @example
1615
+ * ```typescript
1616
+ * const manifestHash = await computeManifestHash(manifestWithoutHash);
1617
+ * const completeManifest = { ...manifestWithoutHash, manifestHash };
1618
+ * ```
1619
+ */
1620
+ declare function computeManifestHash(manifest: Omit<TraceManifest, "manifestHash">): Promise<string>;
1621
+ /**
1622
+ * Verify a manifest against its chunks.
1623
+ *
1624
+ * Performs comprehensive validation including:
1625
+ * - Manifest hash matches recomputed hash
1626
+ * - Each chunk hash matches its content
1627
+ * - All chunk indices are present
1628
+ * - Root hash in manifest is present
1629
+ * - Merkle root in manifest is present
1630
+ *
1631
+ * @param manifest - The manifest to verify
1632
+ * @param chunks - The chunks referenced by the manifest
1633
+ * @returns Promise resolving to verification result with errors and check statuses
1634
+ *
1635
+ * @example
1636
+ * ```typescript
1637
+ * const result = await verifyManifest(manifest, chunks);
1638
+ * if (!result.valid) {
1639
+ * console.error("Verification failed:", result.errors);
1640
+ * } else {
1641
+ * console.log("Manifest and chunks are valid");
1642
+ * }
1643
+ * ```
1644
+ */
1645
+ declare function verifyManifest(manifest: TraceManifest, chunks: Chunk[]): Promise<ManifestVerificationResult>;
1646
+ /**
1647
+ * Reconstruct a trace bundle from manifest and chunks.
1648
+ *
1649
+ * This is the inverse operation of createManifest. It parses all chunk
1650
+ * contents, merges spans and events, and reconstructs the complete
1651
+ * TraceBundle.
1652
+ *
1653
+ * Note: The reconstructed bundle will use the publicView from the manifest
1654
+ * and construct a privateRun from the chunk data.
1655
+ *
1656
+ * @param manifest - The manifest describing the trace
1657
+ * @param chunks - All chunks referenced by the manifest
1658
+ * @returns Promise resolving to the reconstructed TraceBundle
1659
+ * @throws Error if required chunks are missing or corrupted
1660
+ *
1661
+ * @example
1662
+ * ```typescript
1663
+ * // Load manifest and chunks from storage
1664
+ * const manifest = JSON.parse(await storage.read("manifest.json"));
1665
+ * const chunks = await loadChunks(manifest.chunks);
1666
+ *
1667
+ * // Reconstruct the bundle
1668
+ * const bundle = await reconstructBundleFromManifest(manifest, chunks);
1669
+ *
1670
+ * // Now you can access the full trace data
1671
+ * console.log(`Reconstructed ${bundle.privateRun.events.length} events`);
1672
+ * ```
1673
+ */
1674
+ declare function reconstructBundleFromManifest(manifest: TraceManifest, chunks: Chunk[]): Promise<TraceBundle>;
1675
+ /**
1676
+ * Get the storage path for a chunk.
1677
+ *
1678
+ * Returns the relative path where the chunk should be stored.
1679
+ * The consumer is responsible for adding any compression suffix
1680
+ * (e.g., ".gz" if compressed) and handling the actual storage.
1681
+ *
1682
+ * @param chunkInfo - Information about the chunk
1683
+ * @returns The relative storage path for the chunk
1684
+ *
1685
+ * @example
1686
+ * ```typescript
1687
+ * const path = getChunkPath(chunk.info);
1688
+ * // Returns: "chunks/abc123...def.json"
1689
+ *
1690
+ * // Consumer adds compression suffix if needed
1691
+ * const storagePath = chunk.info.compression === "gzip"
1692
+ * ? path + ".gz"
1693
+ * : path;
1694
+ * ```
1695
+ */
1696
+ declare function getChunkPath(chunkInfo: ChunkInfo): string;
1697
+ /**
1698
+ * Parse chunk content from JSON string.
1699
+ *
1700
+ * Parses the serialized chunk content and returns the spans and events
1701
+ * contained within. This function handles the internal chunk format.
1702
+ *
1703
+ * @param content - JSON string of chunk content
1704
+ * @returns Object containing spans and events arrays
1705
+ * @throws Error if content cannot be parsed or is malformed
1706
+ *
1707
+ * @example
1708
+ * ```typescript
1709
+ * const { spans, events } = parseChunkContent(chunk.content);
1710
+ * console.log(`Chunk contains ${spans.length} spans and ${events.length} events`);
1711
+ * ```
1712
+ */
1713
+ declare function parseChunkContent(content: string): {
1714
+ spans: TraceSpan[];
1715
+ events: TraceEvent[];
1716
+ };
1717
+
1718
+ /**
1719
+ * @summary Main entry point for @fluxpointstudios/orynq-sdk-process-trace package.
1720
+ *
1721
+ * This package provides cryptographic process tracing for Proof-of-Intent SDK.
1722
+ * It enables agents to create tamper-evident execution traces with:
1723
+ * - Rolling hash chains for event ordering verification
1724
+ * - Span-level Merkle trees for selective disclosure
1725
+ * - Public/private visibility controls for privacy-preserving audits
1726
+ *
1727
+ * Key features:
1728
+ * - TraceBuilder API for creating and managing trace runs
1729
+ * - Event and span hash computation with domain separation
1730
+ * - Bundle creation with cryptographic commitments
1731
+ * - Merkle proof generation for selective disclosure
1732
+ * - Signature support via pluggable providers
1733
+ *
1734
+ * Usage:
1735
+ * ```typescript
1736
+ * import {
1737
+ * createTrace,
1738
+ * addSpan,
1739
+ * addEvent,
1740
+ * closeSpan,
1741
+ * finalizeTrace,
1742
+ * } from "@fluxpointstudios/orynq-sdk-process-trace";
1743
+ *
1744
+ * const run = await createTrace({ agentId: "agent-1" });
1745
+ * const span = addSpan(run, { name: "build-project" });
1746
+ * await addEvent(run, span.id, { kind: "command", command: "npm install" });
1747
+ * await closeSpan(run, span.id);
1748
+ * const bundle = await finalizeTrace(run);
1749
+ * ```
1750
+ */
1751
+
1752
+ /**
1753
+ * Package version.
1754
+ * Updated automatically during build.
1755
+ */
1756
+ declare const VERSION = "0.1.0";
1757
+
1758
+ export { type AnnotatedSpan, type BaseTraceEvent, type Chunk, type ChunkInfo, type CommandEvent, type CreateManifestOptions, type CreateSpanOptions, type CreateTraceOptions, type CustomEvent, DEFAULT_EVENT_VISIBILITY, type DecisionEvent, type DisclosureMode, type DisclosureRequest, type DisclosureResult, type ErrorTraceEvent, HASH_DOMAIN_PREFIXES, type HashDomain, type ManifestVerificationResult, type MerkleProof, type ObservationEvent, type OutputEvent, type RollingHashState, type SchemaVersion, type SignatureProvider, type TraceBundle, type TraceBundlePublicView, type TraceEvent, type TraceEventKind, type TraceManifest, type TraceMerkleTree, type TraceRun, type TraceSpan, type TraceStatus, type TraceVerificationResult, VERSION, type Visibility, addEvent, addSpan, buildSpanMerkleTree, canDisclose, closeSpan, computeEventHash, computeEventHashes, computeManifestHash, computeRollingHash, computeRootHash, computeSpanHash, countEventsByVisibility, countSpansByVisibility, createBundle, createDisclosureRequest, createManifest, createTrace, extractPublicView, filterPublicEvents, finalizeTrace, generateMerkleProof, getSpanEvents as getBundleSpanEvents, getChildSpans, getChunkPath, getEvent, getEventCount, getEventsByKind, getGenesisHash, getRootSpans, getSpan, getSpanCount, getSpanEvents$1 as getSpanEvents, getSpanIndex, initRollingHash, isFinalized, isPublicEvent, isPublicSpan, parseChunkContent, reconstructBundleFromManifest, selectiveDisclose, signBundle, updateRollingHash, verifyBundle, verifyBundleSignature, verifyDisclosure, verifyManifest, verifyMerkleProof, verifyRollingHash, verifySpanDisclosure, verifySpanInclusion };