@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/LICENSE +21 -0
- package/dist/index.cjs +1339 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +1758 -0
- package/dist/index.d.ts +1758 -0
- package/dist/index.js +1285 -0
- package/dist/index.js.map +1 -0
- package/package.json +69 -0
- package/src/.gitkeep +0 -0
- package/src/__tests__/bundle.test.ts +860 -0
- package/src/__tests__/integration.test.ts +611 -0
- package/src/__tests__/merkle.test.ts +756 -0
- package/src/__tests__/rolling-hash.test.ts +622 -0
- package/src/__tests__/trace-builder.test.ts +1012 -0
- package/src/__tests__/types.test.ts +414 -0
- package/src/bundle.ts +810 -0
- package/src/disclosure.ts +527 -0
- package/src/index.ts +265 -0
- package/src/manifest.ts +687 -0
- package/src/merkle.ts +428 -0
- package/src/rolling-hash.ts +366 -0
- package/src/trace-builder.ts +725 -0
- package/src/types.ts +522 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/types.ts","../src/rolling-hash.ts","../src/merkle.ts","../src/trace-builder.ts","../src/bundle.ts","../src/disclosure.ts","../src/manifest.ts","../src/index.ts"],"names":["canonicalize","sha256StringHex","leafHash","createPublicView","bytesToHex","hexToBytes","getSpanEvents"],"mappings":"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","file":"index.cjs","sourcesContent":["/**\r\n * @fileoverview Type definitions for the process-trace package.\r\n * All types are consolidated in this single file to avoid confusion.\r\n *\r\n * Key concepts:\r\n * - TraceEvent: Individual events within a trace (commands, outputs, decisions, etc.)\r\n * - TraceSpan: Logical groupings of events with parent-child relationships\r\n * - TraceRun: Complete execution trace containing all events and spans\r\n * - TraceBundle: Finalized trace with cryptographic commitments\r\n * - Visibility: Controls what data is exposed in public views\r\n */\r\n\r\n// =============================================================================\r\n// VISIBILITY & COMMON TYPES\r\n// =============================================================================\r\n\r\n/**\r\n * Visibility level for trace events and spans.\r\n * - \"public\": Safe to disclose without revealing sensitive information\r\n * - \"private\": Contains potentially sensitive data, disclosed only with consent\r\n * - \"secret\": Never disclosed, hashes only for verification\r\n */\r\nexport type Visibility = \"public\" | \"private\" | \"secret\";\r\n\r\n/**\r\n * Status of a trace run or span.\r\n */\r\nexport type TraceStatus = \"running\" | \"completed\" | \"failed\" | \"cancelled\";\r\n\r\n/**\r\n * Schema version for trace format.\r\n */\r\nexport type SchemaVersion = \"1.0\";\r\n\r\n// =============================================================================\r\n// TRACE EVENTS\r\n// =============================================================================\r\n\r\n/**\r\n * Base interface shared by all trace events.\r\n * @property kind - Discriminator for event type\r\n * @property id - UUID v4 unique identifier\r\n * @property seq - Monotonic sequence number (THE ordering authority)\r\n * @property timestamp - ISO 8601 timestamp (informational, not for ordering)\r\n * @property visibility - Controls disclosure level\r\n * @property hash - SHA-256 of canonical(event without hash field)\r\n */\r\nexport interface BaseTraceEvent {\r\n kind: string;\r\n id: string;\r\n seq: number;\r\n timestamp: string;\r\n visibility: Visibility;\r\n hash?: string;\r\n}\r\n\r\n/**\r\n * Command execution event.\r\n * Default visibility: \"public\" (args may be redacted by policy)\r\n */\r\nexport interface CommandEvent extends BaseTraceEvent {\r\n kind: \"command\";\r\n command: string;\r\n args?: string[];\r\n cwd?: string;\r\n env?: Record<string, string>;\r\n exitCode?: number;\r\n}\r\n\r\n/**\r\n * Output/result event from command or operation.\r\n * Default visibility: \"private\" (may contain secrets, PII, API responses)\r\n */\r\nexport interface OutputEvent extends BaseTraceEvent {\r\n kind: \"output\";\r\n stream: \"stdout\" | \"stderr\" | \"combined\";\r\n content: string;\r\n truncated?: boolean;\r\n originalSize?: number;\r\n}\r\n\r\n/**\r\n * Decision point event where agent made a choice.\r\n * Default visibility: \"private\" (leaks reasoning/strategy)\r\n */\r\nexport interface DecisionEvent extends BaseTraceEvent {\r\n kind: \"decision\";\r\n decision: string;\r\n reasoning?: string;\r\n alternatives?: string[];\r\n confidence?: number;\r\n}\r\n\r\n/**\r\n * Observation/state assertion event.\r\n * Default visibility: \"public\" (generally safe state assertions)\r\n */\r\nexport interface ObservationEvent extends BaseTraceEvent {\r\n kind: \"observation\";\r\n observation: string;\r\n category?: string;\r\n data?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Error event capturing failures.\r\n * Default visibility: \"private\" (stack traces, internal details)\r\n */\r\nexport interface ErrorTraceEvent extends BaseTraceEvent {\r\n kind: \"error\";\r\n error: string;\r\n code?: string;\r\n stack?: string;\r\n recoverable?: boolean;\r\n}\r\n\r\n/**\r\n * Custom event for extension.\r\n * Default visibility: \"private\" (unknown content)\r\n */\r\nexport interface CustomEvent extends BaseTraceEvent {\r\n kind: \"custom\";\r\n eventType: string;\r\n data: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Discriminated union of all trace event types.\r\n */\r\nexport type TraceEvent =\r\n | CommandEvent\r\n | OutputEvent\r\n | DecisionEvent\r\n | ObservationEvent\r\n | ErrorTraceEvent\r\n | CustomEvent;\r\n\r\n/**\r\n * Event kind string literals for type guards.\r\n */\r\nexport type TraceEventKind = TraceEvent[\"kind\"];\r\n\r\n/**\r\n * Default visibility for each event kind.\r\n */\r\nexport const DEFAULT_EVENT_VISIBILITY: Record<TraceEventKind, Visibility> = {\r\n command: \"public\",\r\n output: \"private\",\r\n decision: \"private\",\r\n observation: \"public\",\r\n error: \"private\",\r\n custom: \"private\",\r\n};\r\n\r\n// =============================================================================\r\n// TRACE SPANS\r\n// =============================================================================\r\n\r\n/**\r\n * A span represents a logical unit of work containing related events.\r\n * Spans can be nested via parentSpanId to form a tree structure.\r\n *\r\n * @property id - UUID v4 unique identifier\r\n * @property spanSeq - Monotonic sequence (THE ordering authority for spans)\r\n * @property parentSpanId - Optional parent span for nesting\r\n * @property name - Human-readable span name\r\n * @property status - Current span status\r\n * @property visibility - Span-level visibility (can override events)\r\n * @property eventIds - References to events (NOT embedded events)\r\n * @property childSpanIds - References to child spans\r\n * @property hash - H(\"poi-trace:span:v1|\" + canon(spanHeader) + \"|\" + eventHashes)\r\n */\r\nexport interface TraceSpan {\r\n id: string;\r\n spanSeq: number;\r\n parentSpanId?: string;\r\n name: string;\r\n status: TraceStatus;\r\n visibility: Visibility;\r\n startedAt: string;\r\n endedAt?: string;\r\n durationMs?: number;\r\n eventIds: string[];\r\n childSpanIds: string[];\r\n metadata?: Record<string, unknown>;\r\n hash?: string;\r\n}\r\n\r\n// =============================================================================\r\n// TRACE RUN\r\n// =============================================================================\r\n\r\n/**\r\n * Complete trace run containing all events and spans.\r\n *\r\n * @property id - UUID v4 unique identifier for this run\r\n * @property schemaVersion - Always \"1.0\" for this version\r\n * @property agentId - Identifier of the agent that produced this trace\r\n * @property status - Current run status\r\n * @property events - All events (flat array, ordered by seq)\r\n * @property spans - All spans (flat array, parent-child via IDs)\r\n * @property rollingHash - Updated after each event\r\n * @property rootHash - Final: H(rollingHash + spanHashes)\r\n * @property nextSeq - Internal: next seq to assign\r\n */\r\nexport interface TraceRun {\r\n id: string;\r\n schemaVersion: SchemaVersion;\r\n agentId: string;\r\n status: TraceStatus;\r\n startedAt: string;\r\n endedAt?: string;\r\n durationMs?: number;\r\n events: TraceEvent[];\r\n spans: TraceSpan[];\r\n metadata?: Record<string, unknown>;\r\n rollingHash: string;\r\n rootHash?: string;\r\n nextSeq: number;\r\n nextSpanSeq: number;\r\n}\r\n\r\n// =============================================================================\r\n// ROLLING HASH\r\n// =============================================================================\r\n\r\n/**\r\n * State for incremental rolling hash computation.\r\n */\r\nexport interface RollingHashState {\r\n currentHash: string;\r\n itemCount: number;\r\n}\r\n\r\n// =============================================================================\r\n// MERKLE TREE\r\n// =============================================================================\r\n\r\n/**\r\n * Span-level Merkle tree for selective disclosure.\r\n * Leaves are span hashes, ordered by spanSeq.\r\n *\r\n * @property rootHash - Merkle root (THE disclosure commitment)\r\n * @property leafCount - Number of leaf nodes (spans)\r\n * @property depth - Tree depth\r\n * @property leafHashes - For local proof generation (optional storage)\r\n */\r\nexport interface TraceMerkleTree {\r\n rootHash: string;\r\n leafCount: number;\r\n depth: number;\r\n leafHashes: string[];\r\n}\r\n\r\n/**\r\n * Merkle proof for a single leaf (span).\r\n *\r\n * @property leafHash - Hash of the leaf being proven\r\n * @property leafIndex - 0-indexed position in leaf array\r\n * @property siblings - Path from leaf to root with position hints\r\n * @property rootHash - Expected Merkle root\r\n */\r\nexport interface MerkleProof {\r\n leafHash: string;\r\n leafIndex: number;\r\n siblings: Array<{ hash: string; position: \"left\" | \"right\" }>;\r\n rootHash: string;\r\n}\r\n\r\n// =============================================================================\r\n// BUNDLE & PUBLIC VIEW\r\n// =============================================================================\r\n\r\n/**\r\n * Annotated span with full data for public disclosure.\r\n */\r\nexport interface AnnotatedSpan extends TraceSpan {\r\n events: TraceEvent[];\r\n}\r\n\r\n/**\r\n * Public view of a trace bundle - safe to share externally.\r\n * Contains only public spans with their events, plus hashes of redacted spans.\r\n *\r\n * @property redactionPolicyId - Identifies which redaction rules were applied\r\n * @property redactionRulesHash - H(canonical(redactionRules)) for reproducibility\r\n */\r\nexport interface TraceBundlePublicView {\r\n runId: string;\r\n agentId: string;\r\n schemaVersion: SchemaVersion;\r\n startedAt: string;\r\n endedAt: string;\r\n durationMs: number;\r\n status: string;\r\n totalEvents: number;\r\n totalSpans: number;\r\n rootHash: string;\r\n merkleRoot: string;\r\n publicSpans: AnnotatedSpan[];\r\n redactedSpanHashes: Array<{ spanId: string; hash: string }>;\r\n redactionPolicyId?: string;\r\n redactionRulesHash?: string;\r\n}\r\n\r\n/**\r\n * Complete trace bundle with cryptographic commitments.\r\n * Contains both public view and private data.\r\n *\r\n * @property formatVersion - Bundle format version\r\n * @property publicView - Safe to share externally\r\n * @property privateRun - Full trace data\r\n * @property merkleRoot - Span-level Merkle root\r\n * @property rootHash - Rolling hash final (execution sequence)\r\n * @property manifestHash - Set after manifest creation\r\n * @property signerId - Optional signer identifier\r\n * @property signature - Optional signature over bundle\r\n */\r\nexport interface TraceBundle {\r\n formatVersion: SchemaVersion;\r\n publicView: TraceBundlePublicView;\r\n privateRun: TraceRun;\r\n merkleRoot: string;\r\n rootHash: string;\r\n manifestHash?: string;\r\n signerId?: string;\r\n signature?: string;\r\n}\r\n\r\n// =============================================================================\r\n// SIGNATURE PROVIDER (OPTIONAL)\r\n// =============================================================================\r\n\r\n/**\r\n * Interface for signing providers.\r\n * Consumers provide implementation (e.g., HSM, KMS, local key).\r\n */\r\nexport interface SignatureProvider {\r\n signerId: string;\r\n sign(data: Uint8Array): Promise<Uint8Array>;\r\n verify(\r\n data: Uint8Array,\r\n signature: Uint8Array,\r\n signerId: string\r\n ): Promise<boolean>;\r\n}\r\n\r\n// =============================================================================\r\n// MANIFEST & CHUNKS (OFF-CHAIN STORAGE)\r\n// =============================================================================\r\n\r\n/**\r\n * Information about a stored chunk.\r\n *\r\n * @property index - Chunk sequence number\r\n * @property hash - SHA-256 of chunk content (BEFORE compression)\r\n * @property size - Bytes (uncompressed)\r\n * @property compressedSize - Bytes (if compressed)\r\n * @property compression - Hint for consumers (process-trace doesn't compress)\r\n * @property spanIds - Which spans are in this chunk\r\n */\r\nexport interface ChunkInfo {\r\n index: number;\r\n hash: string;\r\n size: number;\r\n compressedSize?: number;\r\n compression?: \"gzip\" | \"none\";\r\n spanIds: string[];\r\n}\r\n\r\n/**\r\n * Chunk data ready for storage.\r\n */\r\nexport interface Chunk {\r\n info: ChunkInfo;\r\n content: string;\r\n}\r\n\r\n/**\r\n * Manifest describing stored trace data.\r\n * This file is public-safe and serves as the entry point for retrieval.\r\n *\r\n * Storage layout:\r\n * ```\r\n * <storageUri>/\r\n * manifest.json # TraceManifest (public-safe)\r\n * chunks/\r\n * <hash1>.json.gz # Compressed chunk\r\n * <hash2>.json.gz\r\n * ```\r\n */\r\nexport interface TraceManifest {\r\n formatVersion: SchemaVersion;\r\n runId: string;\r\n agentId: string;\r\n rootHash: string;\r\n merkleRoot: string;\r\n manifestHash?: string;\r\n totalEvents: number;\r\n totalSpans: number;\r\n startedAt: string;\r\n endedAt: string;\r\n durationMs: number;\r\n chunks: ChunkInfo[];\r\n publicView: TraceBundlePublicView;\r\n}\r\n\r\n// =============================================================================\r\n// SELECTIVE DISCLOSURE\r\n// =============================================================================\r\n\r\n/**\r\n * Disclosure mode determines what data is revealed.\r\n * - \"membership\": Merkle proof only (proves span exists, hash matches)\r\n * - \"full\": Merkle proof + span data + event data\r\n */\r\nexport type DisclosureMode = \"membership\" | \"full\";\r\n\r\n/**\r\n * Result of selective disclosure operation.\r\n */\r\nexport interface DisclosureResult {\r\n mode: DisclosureMode;\r\n rootHash: string;\r\n merkleRoot: string;\r\n disclosedSpans: Array<{\r\n spanId: string;\r\n proof: MerkleProof;\r\n span?: TraceSpan;\r\n events?: TraceEvent[];\r\n }>;\r\n}\r\n\r\n// =============================================================================\r\n// VERIFICATION RESULTS\r\n// =============================================================================\r\n\r\n/**\r\n * Result of bundle verification.\r\n */\r\nexport interface TraceVerificationResult {\r\n valid: boolean;\r\n errors: string[];\r\n warnings: string[];\r\n checks: {\r\n rollingHashValid: boolean;\r\n rootHashValid: boolean;\r\n merkleRootValid: boolean;\r\n spanHashesValid: boolean;\r\n eventHashesValid: boolean;\r\n sequenceValid: boolean;\r\n };\r\n}\r\n\r\n/**\r\n * Result of manifest verification.\r\n */\r\nexport interface ManifestVerificationResult {\r\n valid: boolean;\r\n errors: string[];\r\n warnings: string[];\r\n checks: {\r\n manifestHashValid: boolean;\r\n chunkHashesValid: boolean;\r\n rootHashMatches: boolean;\r\n merkleRootMatches: boolean;\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// BUILDER OPTIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Options for creating a new trace.\r\n */\r\nexport interface CreateTraceOptions {\r\n agentId: string;\r\n description?: string;\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Options for creating a new span.\r\n */\r\nexport interface CreateSpanOptions {\r\n name: string;\r\n parentSpanId?: string;\r\n visibility?: Visibility;\r\n metadata?: Record<string, unknown>;\r\n}\r\n\r\n/**\r\n * Options for creating a manifest with chunks.\r\n */\r\nexport interface CreateManifestOptions {\r\n chunkSize?: number;\r\n compression?: \"gzip\" | \"none\";\r\n}\r\n\r\n// =============================================================================\r\n// DOMAIN SEPARATION PREFIXES\r\n// =============================================================================\r\n\r\n/**\r\n * Domain separation prefixes for hashing.\r\n * These prevent cross-context hash collisions.\r\n */\r\nexport const HASH_DOMAIN_PREFIXES = {\r\n event: \"poi-trace:event:v1|\",\r\n roll: \"poi-trace:roll:v1|\",\r\n span: \"poi-trace:span:v1|\",\r\n leaf: \"poi-trace:leaf:v1|\",\r\n node: \"poi-trace:node:v1|\",\r\n manifest: \"poi-trace:manifest:v1|\",\r\n root: \"poi-trace:root:v1|\",\r\n} as const;\r\n\r\n/**\r\n * Type for domain prefix keys.\r\n */\r\nexport type HashDomain = keyof typeof HASH_DOMAIN_PREFIXES;\r\n","/**\r\n * @fileoverview Rolling hash computation for trace events using domain-separated SHA-256.\r\n *\r\n * Location: packages/process-trace/src/rolling-hash.ts\r\n *\r\n * This module implements cryptographic rolling hash computation for the process-trace\r\n * package. Rolling hashes provide tamper-evident sequencing of trace events, ensuring\r\n * that any modification to the event sequence is detectable.\r\n *\r\n * Domain Separation:\r\n * - Event hashes use prefix \"poi-trace:event:v1|\" to prevent cross-context collisions\r\n * - Rolling hashes use prefix \"poi-trace:roll:v1|\" for chain linking\r\n * - Root hashes use prefix \"poi-trace:root:v1|\" for final commitment\r\n *\r\n * The rolling hash forms a hash chain: each hash incorporates the previous hash,\r\n * creating an ordered, tamper-evident sequence. This is similar to blockchain\r\n * block linking but at the event level.\r\n *\r\n * Used by:\r\n * - TraceBuilder: Incrementally updates rolling hash as events are added\r\n * - TraceBundle: Computes final root hash for the complete trace\r\n * - TraceVerifier: Validates that event sequences have not been tampered with\r\n *\r\n * @example\r\n * ```typescript\r\n * // Initialize rolling hash state\r\n * const state = await initRollingHash();\r\n *\r\n * // Add events incrementally\r\n * for (const event of events) {\r\n * const eventHash = await computeEventHash(event);\r\n * state = await updateRollingHash(state, eventHash);\r\n * }\r\n *\r\n * // Or compute in batch\r\n * const finalHash = await computeRollingHash(events);\r\n *\r\n * // Compute root hash including span hashes\r\n * const rootHash = await computeRootHash(finalHash, spans);\r\n * ```\r\n */\r\n\r\nimport {\r\n sha256StringHex,\r\n canonicalize,\r\n} from \"@fluxpointstudios/orynq-sdk-core/utils\";\r\n\r\nimport type { RollingHashState, TraceEvent, TraceSpan } from \"./types.js\";\r\nimport { HASH_DOMAIN_PREFIXES } from \"./types.js\";\r\n\r\n// -----------------------------------------------------------------------------\r\n// Constants\r\n// -----------------------------------------------------------------------------\r\n\r\n/**\r\n * Genesis seed for the initial rolling hash state.\r\n * The first rolling hash is H(\"poi-trace:roll:v1|genesis\").\r\n */\r\nconst GENESIS_SEED = \"genesis\";\r\n\r\n// -----------------------------------------------------------------------------\r\n// Event Hash Functions\r\n// -----------------------------------------------------------------------------\r\n\r\n/**\r\n * Compute hash for a single event using domain separation.\r\n *\r\n * The event hash is computed as:\r\n * `H(\"poi-trace:event:v1|\" + canonicalize(eventWithoutHash))`\r\n *\r\n * The 'hash' field is removed before hashing to avoid circularity - otherwise\r\n * computing the hash would require knowing the hash.\r\n *\r\n * @param event - The trace event to hash\r\n * @returns Promise resolving to the event hash as a lowercase hex string\r\n *\r\n * @example\r\n * ```typescript\r\n * const event: TraceEvent = {\r\n * kind: \"command\",\r\n * id: \"550e8400-e29b-41d4-a716-446655440000\",\r\n * seq: 1,\r\n * timestamp: \"2024-01-15T10:30:00.000Z\",\r\n * visibility: \"public\",\r\n * command: \"npm install\",\r\n * };\r\n * const hash = await computeEventHash(event);\r\n * // Returns 64-character hex string\r\n * ```\r\n */\r\nexport async function computeEventHash(event: TraceEvent): Promise<string> {\r\n // Create a copy without the hash field to avoid circularity\r\n const eventWithoutHash = removeHashField(event);\r\n\r\n // Canonicalize for deterministic serialization\r\n const canonical = canonicalize(eventWithoutHash);\r\n\r\n // Apply domain separation and hash\r\n const prefixedData = HASH_DOMAIN_PREFIXES.event + canonical;\r\n\r\n return sha256StringHex(prefixedData);\r\n}\r\n\r\n/**\r\n * Remove the 'hash' field from an event object.\r\n * Returns a shallow copy with all fields except 'hash'.\r\n *\r\n * @param event - Event to process\r\n * @returns Event copy without the hash field\r\n */\r\nfunction removeHashField<T extends { hash?: string }>(event: T): Omit<T, \"hash\"> {\r\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\r\n const { hash: _, ...rest } = event;\r\n return rest;\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// Rolling Hash State Management\r\n// -----------------------------------------------------------------------------\r\n\r\n/**\r\n * Initialize rolling hash state with the genesis hash.\r\n *\r\n * The genesis hash is computed as:\r\n * `H(\"poi-trace:roll:v1|genesis\")`\r\n *\r\n * This provides a well-known starting point for all rolling hash chains,\r\n * ensuring that empty traces have a deterministic hash value.\r\n *\r\n * @returns Promise resolving to the initial rolling hash state\r\n *\r\n * @example\r\n * ```typescript\r\n * const state = await initRollingHash();\r\n * console.log(state.currentHash); // Genesis hash\r\n * console.log(state.itemCount); // 0\r\n * ```\r\n */\r\nexport async function initRollingHash(): Promise<RollingHashState> {\r\n const genesisInput = HASH_DOMAIN_PREFIXES.roll + GENESIS_SEED;\r\n const genesisHash = await sha256StringHex(genesisInput);\r\n\r\n return {\r\n currentHash: genesisHash,\r\n itemCount: 0,\r\n };\r\n}\r\n\r\n/**\r\n * Update rolling hash state with a new event hash.\r\n *\r\n * The new rolling hash is computed as:\r\n * `H(\"poi-trace:roll:v1|\" + prevHash + \"|\" + eventHash)`\r\n *\r\n * This creates a hash chain where each hash depends on all previous hashes,\r\n * making it impossible to modify earlier events without invalidating all\r\n * subsequent hashes.\r\n *\r\n * @param state - Current rolling hash state\r\n * @param eventHash - Hash of the event to add (from computeEventHash)\r\n * @returns Promise resolving to the updated rolling hash state\r\n *\r\n * @example\r\n * ```typescript\r\n * let state = await initRollingHash();\r\n *\r\n * const eventHash = await computeEventHash(event);\r\n * state = await updateRollingHash(state, eventHash);\r\n *\r\n * console.log(state.currentHash); // New rolling hash\r\n * console.log(state.itemCount); // 1\r\n * ```\r\n */\r\nexport async function updateRollingHash(\r\n state: RollingHashState,\r\n eventHash: string\r\n): Promise<RollingHashState> {\r\n // Construct the input: prefix + prevHash + \"|\" + eventHash\r\n const input = HASH_DOMAIN_PREFIXES.roll + state.currentHash + \"|\" + eventHash;\r\n const newHash = await sha256StringHex(input);\r\n\r\n return {\r\n currentHash: newHash,\r\n itemCount: state.itemCount + 1,\r\n };\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// Batch Rolling Hash Computation\r\n// -----------------------------------------------------------------------------\r\n\r\n/**\r\n * Compute rolling hash for a sequence of events (batch mode).\r\n *\r\n * This function processes all events and returns the final rolling hash.\r\n * Events are sorted by their `seq` field before processing to ensure\r\n * deterministic ordering.\r\n *\r\n * The result is identical to calling `updateRollingHash` sequentially\r\n * for each event, making it suitable for verification.\r\n *\r\n * @param events - Array of trace events to hash\r\n * @returns Promise resolving to the final rolling hash as a hex string\r\n *\r\n * @example\r\n * ```typescript\r\n * const events: TraceEvent[] = [\r\n * { kind: \"command\", seq: 1, ... },\r\n * { kind: \"output\", seq: 2, ... },\r\n * { kind: \"decision\", seq: 3, ... },\r\n * ];\r\n *\r\n * const finalHash = await computeRollingHash(events);\r\n * ```\r\n */\r\nexport async function computeRollingHash(events: TraceEvent[]): Promise<string> {\r\n // Sort events by seq to ensure deterministic ordering\r\n const sortedEvents = [...events].sort((a, b) => a.seq - b.seq);\r\n\r\n // Initialize with genesis hash\r\n let state = await initRollingHash();\r\n\r\n // Process each event in sequence\r\n for (const event of sortedEvents) {\r\n const eventHash = await computeEventHash(event);\r\n state = await updateRollingHash(state, eventHash);\r\n }\r\n\r\n return state.currentHash;\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// Verification Functions\r\n// -----------------------------------------------------------------------------\r\n\r\n/**\r\n * Verify that a rolling hash matches the expected value for given events.\r\n *\r\n * This function recomputes the rolling hash from the events and compares\r\n * it to the expected value. Used to verify trace integrity.\r\n *\r\n * @param events - Array of trace events to verify\r\n * @param expectedHash - The expected rolling hash value\r\n * @returns Promise resolving to true if the hash matches, false otherwise\r\n *\r\n * @example\r\n * ```typescript\r\n * const isValid = await verifyRollingHash(events, storedRollingHash);\r\n * if (!isValid) {\r\n * console.error(\"Trace has been tampered with!\");\r\n * }\r\n * ```\r\n */\r\nexport async function verifyRollingHash(\r\n events: TraceEvent[],\r\n expectedHash: string\r\n): Promise<boolean> {\r\n const computedHash = await computeRollingHash(events);\r\n return constantTimeCompare(computedHash, expectedHash.toLowerCase());\r\n}\r\n\r\n/**\r\n * Constant-time string comparison to prevent timing attacks.\r\n *\r\n * @param a - First string\r\n * @param b - Second string\r\n * @returns true if strings are equal\r\n */\r\nfunction constantTimeCompare(a: string, b: string): boolean {\r\n if (a.length !== b.length) {\r\n return false;\r\n }\r\n\r\n let result = 0;\r\n for (let i = 0; i < a.length; i++) {\r\n result |= a.charCodeAt(i) ^ b.charCodeAt(i);\r\n }\r\n\r\n return result === 0;\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// Root Hash Computation\r\n// -----------------------------------------------------------------------------\r\n\r\n/**\r\n * Compute the final root hash from rolling hash and span hashes.\r\n *\r\n * The root hash is computed as:\r\n * `H(\"poi-trace:root:v1|\" + rollingHash + \"|\" + spanHash1 + \"|\" + spanHash2 + ...)`\r\n *\r\n * Spans are sorted by their `spanSeq` field before joining to ensure\r\n * deterministic ordering. This creates a single commitment that covers\r\n * both the event sequence (via rolling hash) and the span structure.\r\n *\r\n * @param rollingHash - The final rolling hash from all events\r\n * @param spans - Array of trace spans (must have hash field populated)\r\n * @returns Promise resolving to the root hash as a hex string\r\n *\r\n * @example\r\n * ```typescript\r\n * const rollingHash = await computeRollingHash(events);\r\n * const rootHash = await computeRootHash(rollingHash, spans);\r\n *\r\n * // rootHash can now be published as the trace commitment\r\n * ```\r\n */\r\nexport async function computeRootHash(\r\n rollingHash: string,\r\n spans: TraceSpan[]\r\n): Promise<string> {\r\n // Sort spans by spanSeq for deterministic ordering\r\n const sortedSpans = [...spans].sort((a, b) => a.spanSeq - b.spanSeq);\r\n\r\n // Extract span hashes in order\r\n const spanHashes = sortedSpans.map((span) => {\r\n if (!span.hash) {\r\n throw new Error(`Span ${span.id} is missing hash field`);\r\n }\r\n return span.hash;\r\n });\r\n\r\n // Build the input string\r\n // Format: prefix + rollingHash + \"|\" + spanHash1 + \"|\" + spanHash2 + ...\r\n let input = HASH_DOMAIN_PREFIXES.root + rollingHash;\r\n\r\n if (spanHashes.length > 0) {\r\n input += \"|\" + spanHashes.join(\"|\");\r\n }\r\n\r\n return sha256StringHex(input);\r\n}\r\n\r\n// -----------------------------------------------------------------------------\r\n// Utility Exports for Testing\r\n// -----------------------------------------------------------------------------\r\n\r\n/**\r\n * Compute event hashes for multiple events in batch.\r\n * Useful for pre-computing hashes before building a Merkle tree.\r\n *\r\n * @param events - Array of trace events\r\n * @returns Promise resolving to array of event hashes in seq order\r\n */\r\nexport async function computeEventHashes(\r\n events: TraceEvent[]\r\n): Promise<string[]> {\r\n // Sort by seq for deterministic ordering\r\n const sortedEvents = [...events].sort((a, b) => a.seq - b.seq);\r\n\r\n // Compute hashes in parallel for performance\r\n const hashPromises = sortedEvents.map((event) => computeEventHash(event));\r\n\r\n return Promise.all(hashPromises);\r\n}\r\n\r\n/**\r\n * Get the genesis hash for testing and verification.\r\n * This is the initial hash value before any events are added.\r\n *\r\n * @returns Promise resolving to the genesis hash\r\n */\r\nexport async function getGenesisHash(): Promise<string> {\r\n const state = await initRollingHash();\r\n return state.currentHash;\r\n}\r\n","/**\r\n * @fileoverview Merkle tree implementation for span-level selective disclosure.\r\n *\r\n * Location: packages/process-trace/src/merkle.ts\r\n *\r\n * This module implements a span-level Merkle tree that enables selective disclosure\r\n * of trace spans. Verifiers can prove inclusion of specific spans without revealing\r\n * the entire trace, supporting privacy-preserving audit and compliance workflows.\r\n *\r\n * Domain Separation Rules:\r\n * - spanHash = H(\"poi-trace:span:v1|\" + canon(spanHeader) + \"|\" + eventHash1 + \"|\" + eventHash2 + ...)\r\n * - merkleLeaf = H(\"poi-trace:leaf:v1|\" + spanHash)\r\n * - merkleNode = H(\"poi-trace:node:v1|\" + left + \"|\" + right)\r\n *\r\n * Used by:\r\n * - TraceBuilder: builds Merkle tree when finalizing traces\r\n * - Verification: verifies span inclusion proofs\r\n * - Selective disclosure: generates proofs for specific spans\r\n */\r\n\r\nimport {\r\n sha256StringHex,\r\n canonicalize,\r\n} from \"@fluxpointstudios/orynq-sdk-core/utils\";\r\n\r\nimport type {\r\n TraceMerkleTree,\r\n MerkleProof,\r\n TraceSpan,\r\n TraceEvent,\r\n} from \"./types.js\";\r\nimport { HASH_DOMAIN_PREFIXES } from \"./types.js\";\r\n\r\n// =============================================================================\r\n// SPAN HASH COMPUTATION\r\n// =============================================================================\r\n\r\n/**\r\n * Compute the hash for a span including its event hashes.\r\n *\r\n * The span hash is computed as:\r\n * H(\"poi-trace:span:v1|\" + canon(spanHeaderWithoutHash) + \"|\" + eventHash1 + \"|\" + eventHash2 + ...)\r\n *\r\n * The span header includes all fields except the `hash` field itself.\r\n * Event hashes are concatenated in sequence order, joined by \"|\".\r\n *\r\n * @param span - The span to compute hash for\r\n * @param eventHashes - Array of event hashes in sequence order\r\n * @returns Promise resolving to the span hash as a hex string\r\n *\r\n * @example\r\n * const spanHash = await computeSpanHash(span, [\"abc123...\", \"def456...\"]);\r\n */\r\nexport async function computeSpanHash(\r\n span: TraceSpan,\r\n eventHashes: string[]\r\n): Promise<string> {\r\n // Extract span header (all fields except hash)\r\n const spanHeader: Omit<TraceSpan, \"hash\"> = {\r\n id: span.id,\r\n spanSeq: span.spanSeq,\r\n name: span.name,\r\n status: span.status,\r\n visibility: span.visibility,\r\n startedAt: span.startedAt,\r\n eventIds: span.eventIds,\r\n childSpanIds: span.childSpanIds,\r\n };\r\n\r\n // Include optional fields only if they exist\r\n if (span.parentSpanId !== undefined) {\r\n (spanHeader as Record<string, unknown>).parentSpanId = span.parentSpanId;\r\n }\r\n if (span.endedAt !== undefined) {\r\n (spanHeader as Record<string, unknown>).endedAt = span.endedAt;\r\n }\r\n if (span.durationMs !== undefined) {\r\n (spanHeader as Record<string, unknown>).durationMs = span.durationMs;\r\n }\r\n if (span.metadata !== undefined) {\r\n (spanHeader as Record<string, unknown>).metadata = span.metadata;\r\n }\r\n\r\n // Canonicalize the span header\r\n const canonicalHeader = canonicalize(spanHeader, { removeNulls: true });\r\n\r\n // Build the hash input: prefix + canon(header) + \"|\" + eventHashes joined by \"|\"\r\n let hashInput = HASH_DOMAIN_PREFIXES.span + canonicalHeader;\r\n\r\n // Append event hashes if any exist\r\n if (eventHashes.length > 0) {\r\n hashInput += \"|\" + eventHashes.join(\"|\");\r\n }\r\n\r\n return sha256StringHex(hashInput);\r\n}\r\n\r\n// =============================================================================\r\n// MERKLE TREE BUILDING\r\n// =============================================================================\r\n\r\n/**\r\n * Build a Merkle tree from spans.\r\n *\r\n * Leaves are computed as H(\"poi-trace:leaf:v1|\" + spanHash) in spanSeq order.\r\n * Internal nodes are computed as H(\"poi-trace:node:v1|\" + left + \"|\" + right).\r\n *\r\n * ODD-LEAF RULE: If there is an odd number of nodes at any level, the last\r\n * hash is duplicated to create a balanced tree.\r\n *\r\n * @param spans - Array of spans (will be sorted by spanSeq)\r\n * @param events - Array of all events (used to get hashes for spans)\r\n * @returns Promise resolving to the complete Merkle tree\r\n *\r\n * @example\r\n * const tree = await buildSpanMerkleTree(spans, events);\r\n * console.log(tree.rootHash); // Merkle root for disclosure commitment\r\n */\r\nexport async function buildSpanMerkleTree(\r\n spans: TraceSpan[],\r\n events: TraceEvent[]\r\n): Promise<TraceMerkleTree> {\r\n // Handle empty spans case\r\n if (spans.length === 0) {\r\n return {\r\n rootHash: \"\",\r\n leafCount: 0,\r\n depth: 0,\r\n leafHashes: [],\r\n };\r\n }\r\n\r\n // Sort spans by spanSeq for deterministic ordering\r\n const sortedSpans = [...spans].sort((a, b) => a.spanSeq - b.spanSeq);\r\n\r\n // Create a map of event ID to event for quick lookup\r\n const eventMap = new Map<string, TraceEvent>();\r\n for (const event of events) {\r\n eventMap.set(event.id, event);\r\n }\r\n\r\n // Compute leaf hashes for each span\r\n const leafHashes: string[] = [];\r\n for (const span of sortedSpans) {\r\n // Get event hashes for this span in seq order\r\n const spanEvents = span.eventIds\r\n .map((id) => eventMap.get(id))\r\n .filter((e): e is TraceEvent => e !== undefined)\r\n .sort((a, b) => a.seq - b.seq);\r\n\r\n const eventHashes = spanEvents.map((e) => e.hash ?? \"\");\r\n\r\n // Compute span hash\r\n const spanHash = await computeSpanHash(span, eventHashes);\r\n\r\n // Compute leaf hash: H(\"poi-trace:leaf:v1|\" + spanHash)\r\n const leafHash = await sha256StringHex(HASH_DOMAIN_PREFIXES.leaf + spanHash);\r\n leafHashes.push(leafHash);\r\n }\r\n\r\n // Build tree bottom-up\r\n const tree = await buildTreeFromLeaves(leafHashes);\r\n\r\n return {\r\n rootHash: tree.rootHash,\r\n leafCount: leafHashes.length,\r\n depth: tree.depth,\r\n leafHashes,\r\n };\r\n}\r\n\r\n/**\r\n * Internal helper to build the Merkle tree from leaf hashes.\r\n * Returns the root hash and tree depth.\r\n */\r\nasync function buildTreeFromLeaves(\r\n leafHashes: string[]\r\n): Promise<{ rootHash: string; depth: number }> {\r\n // Handle single leaf case\r\n if (leafHashes.length === 1) {\r\n const rootHash = leafHashes[0];\r\n if (rootHash === undefined) {\r\n throw new Error(\"Unexpected empty leaf hash array\");\r\n }\r\n return {\r\n rootHash,\r\n depth: 0,\r\n };\r\n }\r\n\r\n let currentLevel = [...leafHashes];\r\n let depth = 0;\r\n\r\n // Build tree bottom-up until we reach the root\r\n while (currentLevel.length > 1) {\r\n const nextLevel: string[] = [];\r\n\r\n // Process pairs of nodes\r\n for (let i = 0; i < currentLevel.length; i += 2) {\r\n const left = currentLevel[i];\r\n if (left === undefined) {\r\n throw new Error(\"Unexpected undefined hash in tree level\");\r\n }\r\n // If odd number of nodes, duplicate the last one\r\n const right = i + 1 < currentLevel.length ? (currentLevel[i + 1] ?? left) : left;\r\n\r\n // Compute parent: H(\"poi-trace:node:v1|\" + left + \"|\" + right)\r\n const parentHash = await sha256StringHex(\r\n HASH_DOMAIN_PREFIXES.node + left + \"|\" + right\r\n );\r\n nextLevel.push(parentHash);\r\n }\r\n\r\n currentLevel = nextLevel;\r\n depth++;\r\n }\r\n\r\n const finalRoot = currentLevel[0];\r\n if (finalRoot === undefined) {\r\n throw new Error(\"Unexpected empty tree level\");\r\n }\r\n return {\r\n rootHash: finalRoot,\r\n depth,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// MERKLE PROOF GENERATION\r\n// =============================================================================\r\n\r\n/**\r\n * Generate a Merkle proof for a specific span by index.\r\n *\r\n * The proof contains the sibling hashes along the path from the leaf to the root,\r\n * with position hints (\"left\" or \"right\") indicating which side each sibling is on.\r\n *\r\n * @param tree - The complete Merkle tree\r\n * @param spanIndex - 0-indexed position of the span in the tree\r\n * @returns MerkleProof for the specified span\r\n * @throws Error if spanIndex is out of bounds\r\n *\r\n * @example\r\n * const proof = generateMerkleProof(tree, 2);\r\n * console.log(proof.siblings); // [{hash: \"...\", position: \"right\"}, ...]\r\n */\r\nexport function generateMerkleProof(\r\n tree: TraceMerkleTree,\r\n spanIndex: number\r\n): MerkleProof {\r\n // Validate index bounds\r\n if (spanIndex < 0 || spanIndex >= tree.leafCount) {\r\n throw new Error(\r\n `Span index ${spanIndex} is out of bounds (0-${tree.leafCount - 1})`\r\n );\r\n }\r\n\r\n // Handle single leaf case - no siblings needed\r\n if (tree.leafCount === 1) {\r\n const leafHash = tree.leafHashes[0];\r\n if (leafHash === undefined) {\r\n throw new Error(\"Unexpected empty leaf hash array in tree\");\r\n }\r\n return {\r\n leafHash,\r\n leafIndex: 0,\r\n siblings: [],\r\n rootHash: tree.rootHash,\r\n };\r\n }\r\n\r\n const siblings: Array<{ hash: string; position: \"left\" | \"right\" }> = [];\r\n\r\n // We need to rebuild the tree structure to get sibling hashes\r\n // Start with leaf level and work up\r\n let currentLevel = [...tree.leafHashes];\r\n let currentIndex = spanIndex;\r\n\r\n while (currentLevel.length > 1) {\r\n // Get sibling index and position\r\n const isLeftChild = currentIndex % 2 === 0;\r\n const siblingIndex = isLeftChild ? currentIndex + 1 : currentIndex - 1;\r\n\r\n // Handle odd-leaf case: if no sibling exists, it's a duplicate of current\r\n let siblingHash: string;\r\n if (siblingIndex >= currentLevel.length) {\r\n // This is the duplicate case - sibling is the same as current\r\n const currentHash = currentLevel[currentIndex];\r\n if (currentHash === undefined) {\r\n throw new Error(\"Unexpected undefined hash at current index\");\r\n }\r\n siblingHash = currentHash;\r\n } else {\r\n const hash = currentLevel[siblingIndex];\r\n if (hash === undefined) {\r\n throw new Error(\"Unexpected undefined hash at sibling index\");\r\n }\r\n siblingHash = hash;\r\n }\r\n\r\n // Position is where the sibling sits relative to current node\r\n siblings.push({\r\n hash: siblingHash,\r\n position: isLeftChild ? \"right\" : \"left\",\r\n });\r\n\r\n // Build next level (synchronously since we already have hashes)\r\n // We need to compute the next level to continue traversal\r\n const nextLevel: string[] = [];\r\n for (let i = 0; i < currentLevel.length; i += 2) {\r\n const left = currentLevel[i] ?? \"\";\r\n const right = i + 1 < currentLevel.length ? (currentLevel[i + 1] ?? left) : left;\r\n // We don't actually need to compute the hash here, just track structure\r\n nextLevel.push(`${left}|${right}`); // Placeholder for structure tracking\r\n }\r\n\r\n // Move up the tree\r\n currentLevel = nextLevel;\r\n currentIndex = Math.floor(currentIndex / 2);\r\n }\r\n\r\n const leafHash = tree.leafHashes[spanIndex];\r\n if (leafHash === undefined) {\r\n throw new Error(`Unexpected undefined leaf hash at index ${spanIndex}`);\r\n }\r\n return {\r\n leafHash,\r\n leafIndex: spanIndex,\r\n siblings,\r\n rootHash: tree.rootHash,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// MERKLE PROOF VERIFICATION\r\n// =============================================================================\r\n\r\n/**\r\n * Verify a Merkle proof against the expected root.\r\n *\r\n * Starting from the leaf hash, the proof is recomputed by combining with\r\n * sibling hashes according to their positions. The final computed root\r\n * must match the expected rootHash in the proof.\r\n *\r\n * @param proof - The Merkle proof to verify\r\n * @returns Promise resolving to true if the proof is valid\r\n *\r\n * @example\r\n * const valid = await verifyMerkleProof(proof);\r\n * if (!valid) {\r\n * throw new Error(\"Merkle proof verification failed\");\r\n * }\r\n */\r\nexport async function verifyMerkleProof(proof: MerkleProof): Promise<boolean> {\r\n // Start with the leaf hash\r\n let currentHash = proof.leafHash;\r\n\r\n // Traverse up the tree using the sibling hashes\r\n for (const sibling of proof.siblings) {\r\n // Combine hashes based on sibling position\r\n let left: string;\r\n let right: string;\r\n\r\n if (sibling.position === \"left\") {\r\n // Sibling is on the left, current is on the right\r\n left = sibling.hash;\r\n right = currentHash;\r\n } else {\r\n // Sibling is on the right, current is on the left\r\n left = currentHash;\r\n right = sibling.hash;\r\n }\r\n\r\n // Compute parent hash: H(\"poi-trace:node:v1|\" + left + \"|\" + right)\r\n currentHash = await sha256StringHex(\r\n HASH_DOMAIN_PREFIXES.node + left + \"|\" + right\r\n );\r\n }\r\n\r\n // Verify computed root matches expected root\r\n return currentHash === proof.rootHash;\r\n}\r\n\r\n/**\r\n * Verify a span's inclusion using its proof and data.\r\n *\r\n * This function recomputes the span hash from the provided span and events,\r\n * then verifies that the resulting leaf hash matches the proof and that\r\n * the proof is valid against the expected root.\r\n *\r\n * @param proof - The Merkle proof for the span\r\n * @param span - The span data to verify\r\n * @param events - The events belonging to this span\r\n * @returns Promise resolving to true if span is validly included\r\n *\r\n * @example\r\n * const valid = await verifySpanInclusion(proof, span, spanEvents);\r\n * if (valid) {\r\n * console.log(\"Span is cryptographically included in the trace\");\r\n * }\r\n */\r\nexport async function verifySpanInclusion(\r\n proof: MerkleProof,\r\n span: TraceSpan,\r\n events: TraceEvent[]\r\n): Promise<boolean> {\r\n // Sort events by seq to get deterministic order\r\n const sortedEvents = [...events].sort((a, b) => a.seq - b.seq);\r\n\r\n // Get event hashes in seq order\r\n const eventHashes = sortedEvents.map((e) => e.hash ?? \"\");\r\n\r\n // Recompute the span hash\r\n const spanHash = await computeSpanHash(span, eventHashes);\r\n\r\n // Compute the expected leaf hash\r\n const computedLeafHash = await sha256StringHex(\r\n HASH_DOMAIN_PREFIXES.leaf + spanHash\r\n );\r\n\r\n // Verify the leaf hash matches what's in the proof\r\n if (computedLeafHash !== proof.leafHash) {\r\n return false;\r\n }\r\n\r\n // Verify the Merkle proof itself\r\n return verifyMerkleProof(proof);\r\n}\r\n","/**\r\n * @fileoverview Main API for building traces - creating runs, adding spans, events, and finalizing.\r\n *\r\n * Location: packages/process-trace/src/trace-builder.ts\r\n *\r\n * This module provides the primary entry points for constructing trace runs. It handles:\r\n * - Creating new trace runs with proper initialization\r\n * - Adding spans (logical groupings of related events)\r\n * - Adding events with automatic sequencing, timestamping, and hashing\r\n * - Closing spans and computing span hashes\r\n * - Finalizing traces with Merkle tree construction and root hash computation\r\n * - Generating public views for external sharing\r\n *\r\n * The trace builder maintains internal state (rolling hash, sequence counters) and\r\n * ensures cryptographic integrity at each step. Events are ordered by monotonic\r\n * sequence numbers (seq), not timestamps, to guarantee deterministic ordering.\r\n *\r\n * Used by:\r\n * - Agent implementations to record execution traces\r\n * - Integration tests for trace verification\r\n * - Audit workflows for compliance reporting\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create a new trace\r\n * const run = await createTrace({ agentId: \"agent-1\" });\r\n *\r\n * // Add a span for a logical unit of work\r\n * const span = addSpan(run, { name: \"build-project\" });\r\n *\r\n * // Add events to the span\r\n * await addEvent(run, span.id, { kind: \"command\", command: \"npm install\" });\r\n * await addEvent(run, span.id, { kind: \"output\", stream: \"stdout\", content: \"done\" });\r\n *\r\n * // Close the span and finalize\r\n * await closeSpan(run, span.id);\r\n * const bundle = await finalizeTrace(run);\r\n * ```\r\n */\r\n\r\nimport type {\r\n TraceRun,\r\n TraceSpan,\r\n TraceEvent,\r\n TraceBundle,\r\n TraceBundlePublicView,\r\n CreateTraceOptions,\r\n CreateSpanOptions,\r\n Visibility,\r\n TraceStatus,\r\n TraceEventKind,\r\n AnnotatedSpan,\r\n} from \"./types.js\";\r\nimport { DEFAULT_EVENT_VISIBILITY } from \"./types.js\";\r\nimport {\r\n computeEventHash,\r\n initRollingHash,\r\n updateRollingHash,\r\n computeRootHash,\r\n} from \"./rolling-hash.js\";\r\nimport { buildSpanMerkleTree, computeSpanHash } from \"./merkle.js\";\r\n\r\n// =============================================================================\r\n// TRACE CREATION\r\n// =============================================================================\r\n\r\n/**\r\n * Create a new trace run.\r\n *\r\n * Initializes a fresh trace with:\r\n * - Unique UUID for the run ID\r\n * - Schema version \"1.0\"\r\n * - Status \"running\"\r\n * - Genesis rolling hash state\r\n * - Empty events and spans arrays\r\n * - Sequence counters at 0\r\n *\r\n * @param opts - Options for creating the trace\r\n * @param opts.agentId - Identifier of the agent producing this trace\r\n * @param opts.description - Optional human-readable description\r\n * @param opts.metadata - Optional key-value metadata\r\n * @returns Promise resolving to the initialized TraceRun\r\n *\r\n * @example\r\n * ```typescript\r\n * const run = await createTrace({\r\n * agentId: \"claude-agent-v1\",\r\n * description: \"Build and test the project\",\r\n * metadata: { environment: \"production\" },\r\n * });\r\n * ```\r\n */\r\nexport async function createTrace(opts: CreateTraceOptions): Promise<TraceRun> {\r\n // Validate required fields\r\n if (!opts.agentId || typeof opts.agentId !== \"string\") {\r\n throw new Error(\"agentId is required and must be a non-empty string\");\r\n }\r\n\r\n // Generate unique run ID using crypto.randomUUID (Node 18+)\r\n const runId = crypto.randomUUID();\r\n\r\n // Initialize rolling hash state\r\n const hashState = await initRollingHash();\r\n\r\n // Build the trace run object\r\n const run: TraceRun = {\r\n id: runId,\r\n schemaVersion: \"1.0\",\r\n agentId: opts.agentId,\r\n status: \"running\",\r\n startedAt: new Date().toISOString(),\r\n events: [],\r\n spans: [],\r\n rollingHash: hashState.currentHash,\r\n nextSeq: 0,\r\n nextSpanSeq: 0,\r\n };\r\n\r\n // Add optional metadata\r\n if (opts.metadata !== undefined) {\r\n run.metadata = { ...opts.metadata };\r\n }\r\n\r\n // Add description to metadata if provided\r\n if (opts.description !== undefined) {\r\n run.metadata = {\r\n ...run.metadata,\r\n description: opts.description,\r\n };\r\n }\r\n\r\n return run;\r\n}\r\n\r\n// =============================================================================\r\n// SPAN MANAGEMENT\r\n// =============================================================================\r\n\r\n/**\r\n * Add a new span to a trace run.\r\n *\r\n * Creates a span with:\r\n * - Unique UUID for span ID\r\n * - Assigned spanSeq from run.nextSpanSeq\r\n * - Status \"running\"\r\n * - Empty eventIds and childSpanIds arrays\r\n *\r\n * If a parentSpanId is provided, the span is added to the parent's childSpanIds.\r\n *\r\n * @param run - The trace run to add the span to (mutated in place)\r\n * @param opts - Options for creating the span\r\n * @param opts.name - Human-readable name for the span\r\n * @param opts.parentSpanId - Optional parent span ID for nesting\r\n * @param opts.visibility - Span visibility level (defaults to \"private\")\r\n * @param opts.metadata - Optional key-value metadata\r\n * @returns The created TraceSpan\r\n * @throws Error if the run is finalized or parent span is not found\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create a top-level span\r\n * const buildSpan = addSpan(run, { name: \"build\" });\r\n *\r\n * // Create a nested span\r\n * const installSpan = addSpan(run, {\r\n * name: \"npm-install\",\r\n * parentSpanId: buildSpan.id,\r\n * visibility: \"public\",\r\n * });\r\n * ```\r\n */\r\nexport function addSpan(run: TraceRun, opts: CreateSpanOptions): TraceSpan {\r\n // Validate run is not finalized\r\n if (isFinalized(run)) {\r\n throw new Error(\"Cannot add span to a finalized trace run\");\r\n }\r\n\r\n // Validate required fields\r\n if (!opts.name || typeof opts.name !== \"string\") {\r\n throw new Error(\"name is required and must be a non-empty string\");\r\n }\r\n\r\n // Validate parent span exists if specified\r\n if (opts.parentSpanId !== undefined) {\r\n const parentSpan = getSpan(run, opts.parentSpanId);\r\n if (!parentSpan) {\r\n throw new Error(`Parent span not found: ${opts.parentSpanId}`);\r\n }\r\n if (parentSpan.status !== \"running\") {\r\n throw new Error(`Parent span is not running: ${opts.parentSpanId}`);\r\n }\r\n }\r\n\r\n // Generate unique span ID\r\n const spanId = crypto.randomUUID();\r\n\r\n // Assign spanSeq and increment counter\r\n const spanSeq = run.nextSpanSeq++;\r\n\r\n // Determine visibility (default to \"private\" if not specified)\r\n const visibility: Visibility = opts.visibility ?? \"private\";\r\n\r\n // Create the span\r\n const span: TraceSpan = {\r\n id: spanId,\r\n spanSeq,\r\n name: opts.name,\r\n status: \"running\",\r\n visibility,\r\n startedAt: new Date().toISOString(),\r\n eventIds: [],\r\n childSpanIds: [],\r\n };\r\n\r\n // Add optional fields\r\n if (opts.parentSpanId !== undefined) {\r\n span.parentSpanId = opts.parentSpanId;\r\n }\r\n\r\n if (opts.metadata !== undefined) {\r\n span.metadata = { ...opts.metadata };\r\n }\r\n\r\n // Add to run's spans array\r\n run.spans.push(span);\r\n\r\n // If there's a parent span, add this span to its childSpanIds\r\n if (opts.parentSpanId !== undefined) {\r\n const parentSpan = getSpan(run, opts.parentSpanId);\r\n if (parentSpan) {\r\n parentSpan.childSpanIds.push(spanId);\r\n }\r\n }\r\n\r\n return span;\r\n}\r\n\r\n/**\r\n * Get a span by ID from a run.\r\n *\r\n * @param run - The trace run to search\r\n * @param spanId - The span ID to find\r\n * @returns The span if found, undefined otherwise\r\n *\r\n * @example\r\n * ```typescript\r\n * const span = getSpan(run, \"some-span-id\");\r\n * if (span) {\r\n * console.log(`Found span: ${span.name}`);\r\n * }\r\n * ```\r\n */\r\nexport function getSpan(run: TraceRun, spanId: string): TraceSpan | undefined {\r\n return run.spans.find((s) => s.id === spanId);\r\n}\r\n\r\n/**\r\n * Get events for a span.\r\n *\r\n * Returns all events belonging to the specified span, sorted by sequence number.\r\n *\r\n * @param run - The trace run containing the events\r\n * @param spanId - The span ID to get events for\r\n * @returns Array of TraceEvents for the span, sorted by seq\r\n *\r\n * @example\r\n * ```typescript\r\n * const events = getSpanEvents(run, span.id);\r\n * for (const event of events) {\r\n * console.log(`Event ${event.seq}: ${event.kind}`);\r\n * }\r\n * ```\r\n */\r\nexport function getSpanEvents(run: TraceRun, spanId: string): TraceEvent[] {\r\n const span = getSpan(run, spanId);\r\n if (!span) {\r\n return [];\r\n }\r\n\r\n // Get events by their IDs and sort by seq\r\n const eventMap = new Map(run.events.map((e) => [e.id, e]));\r\n const spanEvents = span.eventIds\r\n .map((id) => eventMap.get(id))\r\n .filter((e): e is TraceEvent => e !== undefined);\r\n\r\n return spanEvents.sort((a, b) => a.seq - b.seq);\r\n}\r\n\r\n// =============================================================================\r\n// EVENT MANAGEMENT\r\n// =============================================================================\r\n\r\n/**\r\n * Type helper to extract the event type by kind.\r\n * Used for type-safe event creation without runtime fields.\r\n */\r\ntype EventWithoutRuntimeFields<K extends TraceEventKind> = Omit<\r\n Extract<TraceEvent, { kind: K }>,\r\n \"id\" | \"seq\" | \"timestamp\" | \"hash\"\r\n>;\r\n\r\n/**\r\n * Add an event to a span within a trace run.\r\n *\r\n * Automatically assigns:\r\n * - Unique UUID for event ID\r\n * - Monotonic sequence number from run.nextSeq\r\n * - ISO 8601 timestamp\r\n * - Default visibility based on event kind (if not specified)\r\n * - Computed event hash\r\n *\r\n * Also updates the run's rolling hash to maintain cryptographic chain.\r\n *\r\n * @param run - The trace run (mutated in place)\r\n * @param spanId - ID of the span to add event to\r\n * @param event - Event data without runtime fields (id, seq, timestamp, hash)\r\n * @returns Promise resolving to the complete TraceEvent\r\n * @throws Error if run is finalized, span not found, or span is closed\r\n *\r\n * @example\r\n * ```typescript\r\n * // Add a command event\r\n * const cmdEvent = await addEvent(run, span.id, {\r\n * kind: \"command\",\r\n * command: \"npm install\",\r\n * args: [\"--save-dev\", \"typescript\"],\r\n * visibility: \"public\",\r\n * });\r\n *\r\n * // Add an output event (will use default \"private\" visibility)\r\n * const outEvent = await addEvent(run, span.id, {\r\n * kind: \"output\",\r\n * stream: \"stdout\",\r\n * content: \"added 120 packages\",\r\n * });\r\n * ```\r\n */\r\nexport async function addEvent<K extends TraceEventKind>(\r\n run: TraceRun,\r\n spanId: string,\r\n event: EventWithoutRuntimeFields<K>\r\n): Promise<TraceEvent> {\r\n // Validate run is not finalized\r\n if (isFinalized(run)) {\r\n throw new Error(\"Cannot add event to a finalized trace run\");\r\n }\r\n\r\n // Find the span\r\n const span = getSpan(run, spanId);\r\n if (!span) {\r\n throw new Error(`Span not found: ${spanId}`);\r\n }\r\n\r\n // Validate span is still running\r\n if (span.status !== \"running\") {\r\n throw new Error(`Cannot add event to closed span: ${spanId} (status: ${span.status})`);\r\n }\r\n\r\n // Validate event has a kind\r\n if (!event.kind || typeof event.kind !== \"string\") {\r\n throw new Error(\"Event kind is required and must be a non-empty string\");\r\n }\r\n\r\n // Generate event ID\r\n const eventId = crypto.randomUUID();\r\n\r\n // Assign sequence number and increment counter\r\n const seq = run.nextSeq++;\r\n\r\n // Get current timestamp\r\n const timestamp = new Date().toISOString();\r\n\r\n // Determine visibility: use provided value or default for the event kind\r\n const visibility: Visibility =\r\n event.visibility ?? DEFAULT_EVENT_VISIBILITY[event.kind as TraceEventKind] ?? \"private\";\r\n\r\n // Build the complete event (without hash initially)\r\n // We use 'as unknown as TraceEvent' because TypeScript cannot infer\r\n // that adding runtime fields to EventWithoutRuntimeFields<K> produces a valid TraceEvent.\r\n // The caller ensures the correct event shape via the generic constraint.\r\n const completeEvent = {\r\n ...event,\r\n id: eventId,\r\n seq,\r\n timestamp,\r\n visibility,\r\n } as unknown as TraceEvent;\r\n\r\n // Compute event hash\r\n const eventHash = await computeEventHash(completeEvent);\r\n completeEvent.hash = eventHash;\r\n\r\n // Update rolling hash\r\n const currentState = {\r\n currentHash: run.rollingHash,\r\n itemCount: run.events.length,\r\n };\r\n const newState = await updateRollingHash(currentState, eventHash);\r\n run.rollingHash = newState.currentHash;\r\n\r\n // Add event ID to span's eventIds\r\n span.eventIds.push(eventId);\r\n\r\n // Add event to run's events array\r\n run.events.push(completeEvent);\r\n\r\n return completeEvent;\r\n}\r\n\r\n// =============================================================================\r\n// SPAN CLOSING\r\n// =============================================================================\r\n\r\n/**\r\n * Close a span, marking it as completed/failed/cancelled.\r\n *\r\n * Sets the span's:\r\n * - status (default \"completed\")\r\n * - endedAt timestamp\r\n * - durationMs (calculated from startedAt to endedAt)\r\n * - hash (computed from span header + event hashes)\r\n *\r\n * @param run - The trace run containing the span (mutated in place)\r\n * @param spanId - ID of the span to close\r\n * @param status - Final status (default \"completed\")\r\n * @throws Error if span not found or already closed\r\n *\r\n * @example\r\n * ```typescript\r\n * // Close with default \"completed\" status\r\n * await closeSpan(run, span.id);\r\n *\r\n * // Close with explicit status\r\n * await closeSpan(run, span.id, \"failed\");\r\n * ```\r\n */\r\nexport async function closeSpan(\r\n run: TraceRun,\r\n spanId: string,\r\n status: TraceStatus = \"completed\"\r\n): Promise<void> {\r\n // Find the span\r\n const span = getSpan(run, spanId);\r\n if (!span) {\r\n throw new Error(`Span not found: ${spanId}`);\r\n }\r\n\r\n // Validate span is still running\r\n if (span.status !== \"running\") {\r\n throw new Error(`Span already closed: ${spanId} (status: ${span.status})`);\r\n }\r\n\r\n // Set final status\r\n span.status = status;\r\n\r\n // Set end timestamp\r\n const endedAt = new Date().toISOString();\r\n span.endedAt = endedAt;\r\n\r\n // Calculate duration\r\n const startTime = new Date(span.startedAt).getTime();\r\n const endTime = new Date(endedAt).getTime();\r\n span.durationMs = endTime - startTime;\r\n\r\n // Get event hashes for this span in seq order\r\n const spanEvents = getSpanEvents(run, spanId);\r\n const eventHashes = spanEvents.map((e) => e.hash ?? \"\");\r\n\r\n // Compute span hash\r\n span.hash = await computeSpanHash(span, eventHashes);\r\n}\r\n\r\n// =============================================================================\r\n// TRACE FINALIZATION\r\n// =============================================================================\r\n\r\n/**\r\n * Check if a run is finalized.\r\n *\r\n * A run is considered finalized when it has a rootHash set.\r\n *\r\n * @param run - The trace run to check\r\n * @returns true if the run is finalized\r\n *\r\n * @example\r\n * ```typescript\r\n * if (!isFinalized(run)) {\r\n * // Can still add spans and events\r\n * await addEvent(run, span.id, { kind: \"command\", command: \"ls\" });\r\n * }\r\n * ```\r\n */\r\nexport function isFinalized(run: TraceRun): boolean {\r\n return run.rootHash !== undefined;\r\n}\r\n\r\n/**\r\n * Finalize a trace run, computing all final hashes and creating a bundle.\r\n *\r\n * Finalization performs:\r\n * 1. Closes any open spans (with status \"completed\")\r\n * 2. Sets run status to \"completed\"\r\n * 3. Sets run endedAt and durationMs\r\n * 4. Builds Merkle tree from spans\r\n * 5. Computes root hash from rolling hash + span hashes\r\n * 6. Creates public view (only public spans with their events)\r\n * 7. Returns complete TraceBundle\r\n *\r\n * After finalization, no more spans or events can be added.\r\n *\r\n * @param run - The trace run to finalize (mutated in place)\r\n * @returns Promise resolving to the complete TraceBundle\r\n * @throws Error if the run is already finalized\r\n *\r\n * @example\r\n * ```typescript\r\n * // Finalize and get the bundle\r\n * const bundle = await finalizeTrace(run);\r\n *\r\n * // Access the cryptographic commitments\r\n * console.log(`Root hash: ${bundle.rootHash}`);\r\n * console.log(`Merkle root: ${bundle.merkleRoot}`);\r\n *\r\n * // Access the public view for sharing\r\n * console.log(`Public spans: ${bundle.publicView.publicSpans.length}`);\r\n * ```\r\n */\r\nexport async function finalizeTrace(run: TraceRun): Promise<TraceBundle> {\r\n // Validate run is not already finalized\r\n if (isFinalized(run)) {\r\n throw new Error(\"Trace run is already finalized\");\r\n }\r\n\r\n // Close any open spans\r\n for (const span of run.spans) {\r\n if (span.status === \"running\") {\r\n await closeSpan(run, span.id, \"completed\");\r\n }\r\n }\r\n\r\n // Set run status to completed\r\n run.status = \"completed\";\r\n\r\n // Set end timestamp and duration\r\n const endedAt = new Date().toISOString();\r\n run.endedAt = endedAt;\r\n const startTime = new Date(run.startedAt).getTime();\r\n const endTime = new Date(endedAt).getTime();\r\n run.durationMs = endTime - startTime;\r\n\r\n // Build Merkle tree from spans\r\n const merkleTree = await buildSpanMerkleTree(run.spans, run.events);\r\n\r\n // Compute root hash from rolling hash + span hashes\r\n const rootHash = await computeRootHash(run.rollingHash, run.spans);\r\n run.rootHash = rootHash;\r\n\r\n // Create public view\r\n const publicView = createPublicView(run, merkleTree.rootHash);\r\n\r\n // Build and return the complete bundle\r\n const bundle: TraceBundle = {\r\n formatVersion: \"1.0\",\r\n publicView,\r\n privateRun: run,\r\n merkleRoot: merkleTree.rootHash,\r\n rootHash,\r\n };\r\n\r\n return bundle;\r\n}\r\n\r\n// =============================================================================\r\n// PUBLIC VIEW GENERATION\r\n// =============================================================================\r\n\r\n/**\r\n * Create a public view of the trace suitable for external sharing.\r\n *\r\n * The public view includes:\r\n * - Run metadata (id, agentId, timestamps, etc.)\r\n * - Cryptographic commitments (rootHash, merkleRoot)\r\n * - Public spans with their events\r\n * - Hashes of redacted (non-public) spans\r\n *\r\n * Private and secret data is excluded, but their hashes are included\r\n * for verification purposes.\r\n *\r\n * @param run - The finalized trace run\r\n * @param merkleRoot - The Merkle root from the span tree\r\n * @returns The public view of the trace bundle\r\n */\r\nfunction createPublicView(\r\n run: TraceRun,\r\n merkleRoot: string\r\n): TraceBundlePublicView {\r\n // Build event lookup map\r\n const eventMap = new Map(run.events.map((e) => [e.id, e]));\r\n\r\n // Separate public spans from non-public\r\n const publicSpans: AnnotatedSpan[] = [];\r\n const redactedSpanHashes: Array<{ spanId: string; hash: string }> = [];\r\n\r\n for (const span of run.spans) {\r\n if (span.visibility === \"public\") {\r\n // Include public spans with their events\r\n const spanEvents = span.eventIds\r\n .map((id) => eventMap.get(id))\r\n .filter((e): e is TraceEvent => e !== undefined)\r\n // Only include public events within public spans\r\n .filter((e) => e.visibility === \"public\")\r\n .sort((a, b) => a.seq - b.seq);\r\n\r\n const annotatedSpan: AnnotatedSpan = {\r\n ...span,\r\n events: spanEvents,\r\n };\r\n publicSpans.push(annotatedSpan);\r\n } else {\r\n // Include only the hash for non-public spans\r\n if (span.hash) {\r\n redactedSpanHashes.push({\r\n spanId: span.id,\r\n hash: span.hash,\r\n });\r\n }\r\n }\r\n }\r\n\r\n // Sort public spans by spanSeq\r\n publicSpans.sort((a, b) => a.spanSeq - b.spanSeq);\r\n\r\n // Sort redacted span hashes by spanId for consistency\r\n redactedSpanHashes.sort((a, b) => a.spanId.localeCompare(b.spanId));\r\n\r\n const publicView: TraceBundlePublicView = {\r\n runId: run.id,\r\n agentId: run.agentId,\r\n schemaVersion: run.schemaVersion,\r\n startedAt: run.startedAt,\r\n endedAt: run.endedAt ?? run.startedAt, // Fallback for safety\r\n durationMs: run.durationMs ?? 0,\r\n status: run.status,\r\n totalEvents: run.events.length,\r\n totalSpans: run.spans.length,\r\n rootHash: run.rootHash ?? \"\",\r\n merkleRoot,\r\n publicSpans,\r\n redactedSpanHashes,\r\n };\r\n\r\n return publicView;\r\n}\r\n\r\n// =============================================================================\r\n// UTILITY FUNCTIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Get total event count for a trace run.\r\n *\r\n * @param run - The trace run\r\n * @returns Number of events in the run\r\n */\r\nexport function getEventCount(run: TraceRun): number {\r\n return run.events.length;\r\n}\r\n\r\n/**\r\n * Get total span count for a trace run.\r\n *\r\n * @param run - The trace run\r\n * @returns Number of spans in the run\r\n */\r\nexport function getSpanCount(run: TraceRun): number {\r\n return run.spans.length;\r\n}\r\n\r\n/**\r\n * Get all root spans (spans without a parent).\r\n *\r\n * @param run - The trace run\r\n * @returns Array of root-level spans\r\n */\r\nexport function getRootSpans(run: TraceRun): TraceSpan[] {\r\n return run.spans.filter((s) => s.parentSpanId === undefined);\r\n}\r\n\r\n/**\r\n * Get child spans for a given parent span.\r\n *\r\n * @param run - The trace run\r\n * @param parentSpanId - The parent span ID\r\n * @returns Array of child spans\r\n */\r\nexport function getChildSpans(run: TraceRun, parentSpanId: string): TraceSpan[] {\r\n return run.spans.filter((s) => s.parentSpanId === parentSpanId);\r\n}\r\n\r\n/**\r\n * Get an event by ID from a run.\r\n *\r\n * @param run - The trace run\r\n * @param eventId - The event ID to find\r\n * @returns The event if found, undefined otherwise\r\n */\r\nexport function getEvent(run: TraceRun, eventId: string): TraceEvent | undefined {\r\n return run.events.find((e) => e.id === eventId);\r\n}\r\n\r\n/**\r\n * Get all events of a specific kind from a run.\r\n *\r\n * @param run - The trace run\r\n * @param kind - The event kind to filter by\r\n * @returns Array of events matching the kind\r\n */\r\nexport function getEventsByKind<K extends TraceEventKind>(\r\n run: TraceRun,\r\n kind: K\r\n): Extract<TraceEvent, { kind: K }>[] {\r\n return run.events.filter(\r\n (e): e is Extract<TraceEvent, { kind: K }> => e.kind === kind\r\n );\r\n}\r\n","/**\r\n * @fileoverview Bundle creation, extraction, verification, and signing for trace bundles.\r\n *\r\n * Location: packages/process-trace/src/bundle.ts\r\n *\r\n * This module provides the core functionality for working with trace bundles:\r\n * - Creating bundles from finalized trace runs\r\n * - Extracting public views for safe external sharing\r\n * - Verifying bundle integrity (hashes, sequences, merkle proofs)\r\n * - Signing and verifying bundle signatures\r\n *\r\n * A TraceBundle is the finalized, immutable form of a trace run that includes:\r\n * - The complete private trace run data\r\n * - A public view with redacted sensitive information\r\n * - Cryptographic commitments (rootHash, merkleRoot)\r\n * - Optional signature for authenticity verification\r\n *\r\n * Visibility Rules:\r\n * - \"public\": Events/spans are included in the publicView\r\n * - \"private\": Hash included in redactedSpanHashes, data not disclosed\r\n * - \"secret\": Hash included in redactedSpanHashes, data never disclosed\r\n *\r\n * Used by:\r\n * - TraceBuilder: Creates bundles when finalizing traces\r\n * - TraceVerifier: Validates bundle integrity\r\n * - TraceStorage: Prepares bundles for storage/transmission\r\n * - Disclosure workflows: Extracts public views for sharing\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create a bundle from a finalized run\r\n * const bundle = await createBundle(finalizedRun);\r\n *\r\n * // Extract public view for sharing\r\n * const publicView = extractPublicView(bundle);\r\n *\r\n * // Verify bundle integrity\r\n * const result = await verifyBundle(bundle);\r\n * if (!result.valid) {\r\n * console.error(\"Bundle verification failed:\", result.errors);\r\n * }\r\n *\r\n * // Sign a bundle\r\n * const signedBundle = await signBundle(bundle, signatureProvider);\r\n * ```\r\n */\r\n\r\nimport {\r\n canonicalize,\r\n bytesToHex,\r\n hexToBytes,\r\n} from \"@fluxpointstudios/orynq-sdk-core/utils\";\r\n\r\nimport type {\r\n TraceBundle,\r\n TraceBundlePublicView,\r\n TraceRun,\r\n TraceSpan,\r\n TraceEvent,\r\n AnnotatedSpan,\r\n TraceVerificationResult,\r\n SignatureProvider,\r\n Visibility,\r\n} from \"./types.js\";\r\n\r\nimport {\r\n computeEventHash,\r\n computeRollingHash,\r\n computeRootHash,\r\n} from \"./rolling-hash.js\";\r\n\r\nimport { buildSpanMerkleTree, computeSpanHash } from \"./merkle.js\";\r\n\r\n// =============================================================================\r\n// VISIBILITY HELPERS\r\n// =============================================================================\r\n\r\n/**\r\n * Check if a span should be included in public view.\r\n *\r\n * Only spans with visibility \"public\" are included in the public view.\r\n * Private and secret spans are redacted (only their hashes are included).\r\n *\r\n * @param span - The span to check\r\n * @returns true if the span is public and should be included in publicView\r\n *\r\n * @example\r\n * ```typescript\r\n * if (isPublicSpan(span)) {\r\n * publicSpans.push(span);\r\n * } else {\r\n * redactedSpanHashes.push({ spanId: span.id, hash: span.hash });\r\n * }\r\n * ```\r\n */\r\nexport function isPublicSpan(span: TraceSpan): boolean {\r\n return span.visibility === \"public\";\r\n}\r\n\r\n/**\r\n * Check if an event should be included in public view.\r\n *\r\n * Only events with visibility \"public\" are included in the public view.\r\n * Private and secret events are not disclosed.\r\n *\r\n * @param event - The event to check\r\n * @returns true if the event is public and should be included in publicView\r\n *\r\n * @example\r\n * ```typescript\r\n * const publicEvents = events.filter(isPublicEvent);\r\n * ```\r\n */\r\nexport function isPublicEvent(event: TraceEvent): boolean {\r\n return event.visibility === \"public\";\r\n}\r\n\r\n/**\r\n * Filter events by visibility, returning only public events.\r\n *\r\n * This function creates a new array containing only events with\r\n * visibility === \"public\". The original array is not modified.\r\n *\r\n * @param events - Array of trace events to filter\r\n * @returns Array containing only public events\r\n *\r\n * @example\r\n * ```typescript\r\n * const allEvents = getSpanEvents(span, run.events);\r\n * const publicEvents = filterPublicEvents(allEvents);\r\n * ```\r\n */\r\nexport function filterPublicEvents(events: TraceEvent[]): TraceEvent[] {\r\n return events.filter(isPublicEvent);\r\n}\r\n\r\n// =============================================================================\r\n// BUNDLE CREATION\r\n// =============================================================================\r\n\r\n/**\r\n * Create a bundle from a finalized trace run.\r\n *\r\n * The run should already have rootHash computed (i.e., be finalized).\r\n * This function:\r\n * 1. Validates the run is finalized\r\n * 2. Builds the Merkle tree if not already computed\r\n * 3. Creates the public view with redacted sensitive data\r\n * 4. Returns the complete bundle\r\n *\r\n * @param run - The finalized trace run (must have rootHash)\r\n * @returns Promise resolving to the complete TraceBundle\r\n * @throws Error if the run is not finalized (missing rootHash)\r\n *\r\n * @example\r\n * ```typescript\r\n * // Finalize the run first\r\n * const finalizedRun = await finalizeTraceRun(run);\r\n *\r\n * // Create the bundle\r\n * const bundle = await createBundle(finalizedRun);\r\n * console.log(bundle.rootHash); // Cryptographic commitment\r\n * console.log(bundle.merkleRoot); // Merkle root for selective disclosure\r\n * ```\r\n */\r\nexport async function createBundle(run: TraceRun): Promise<TraceBundle> {\r\n // Validate run is finalized\r\n if (!run.rootHash) {\r\n throw new Error(\r\n \"Cannot create bundle from non-finalized run: rootHash is missing. \" +\r\n \"Call finalizeTraceRun() before creating a bundle.\"\r\n );\r\n }\r\n\r\n if (run.status === \"running\") {\r\n throw new Error(\r\n \"Cannot create bundle from running trace. \" +\r\n \"The trace must be completed, failed, or cancelled.\"\r\n );\r\n }\r\n\r\n // Ensure all events have hashes computed\r\n for (const event of run.events) {\r\n if (!event.hash) {\r\n throw new Error(\r\n `Event ${event.id} (seq ${event.seq}) is missing hash. ` +\r\n \"All events must have hashes computed before creating a bundle.\"\r\n );\r\n }\r\n }\r\n\r\n // Ensure all spans have hashes computed\r\n for (const span of run.spans) {\r\n if (!span.hash) {\r\n throw new Error(\r\n `Span ${span.id} (spanSeq ${span.spanSeq}) is missing hash. ` +\r\n \"All spans must have hashes computed before creating a bundle.\"\r\n );\r\n }\r\n }\r\n\r\n // Build Merkle tree from spans\r\n const merkleTree = await buildSpanMerkleTree(run.spans, run.events);\r\n\r\n // Create the public view\r\n const publicView = createPublicView(run, merkleTree.rootHash);\r\n\r\n // Construct the bundle\r\n const bundle: TraceBundle = {\r\n formatVersion: run.schemaVersion,\r\n publicView,\r\n privateRun: run,\r\n merkleRoot: merkleTree.rootHash,\r\n rootHash: run.rootHash,\r\n };\r\n\r\n return bundle;\r\n}\r\n\r\n/**\r\n * Internal helper to create the public view from a run.\r\n *\r\n * @param run - The finalized trace run\r\n * @param merkleRoot - The computed Merkle root\r\n * @returns The TraceBundlePublicView\r\n */\r\nfunction createPublicView(\r\n run: TraceRun,\r\n merkleRoot: string\r\n): TraceBundlePublicView {\r\n // Create event lookup map\r\n const eventMap = new Map<string, TraceEvent>();\r\n for (const event of run.events) {\r\n eventMap.set(event.id, event);\r\n }\r\n\r\n // Separate public and non-public spans\r\n const publicSpans: AnnotatedSpan[] = [];\r\n const redactedSpanHashes: Array<{ spanId: string; hash: string }> = [];\r\n\r\n for (const span of run.spans) {\r\n if (isPublicSpan(span)) {\r\n // Get events for this span and filter to public only\r\n const spanEvents = span.eventIds\r\n .map((id) => eventMap.get(id))\r\n .filter((e): e is TraceEvent => e !== undefined)\r\n .filter(isPublicEvent)\r\n .sort((a, b) => a.seq - b.seq);\r\n\r\n // Create annotated span with embedded events\r\n const annotatedSpan: AnnotatedSpan = {\r\n ...span,\r\n events: spanEvents,\r\n };\r\n\r\n publicSpans.push(annotatedSpan);\r\n } else {\r\n // Non-public span: include only hash reference\r\n redactedSpanHashes.push({\r\n spanId: span.id,\r\n hash: span.hash ?? \"\",\r\n });\r\n }\r\n }\r\n\r\n // Sort public spans by spanSeq for deterministic ordering\r\n publicSpans.sort((a, b) => a.spanSeq - b.spanSeq);\r\n\r\n // Sort redacted hashes by spanId for deterministic ordering\r\n redactedSpanHashes.sort((a, b) => a.spanId.localeCompare(b.spanId));\r\n\r\n return {\r\n runId: run.id,\r\n agentId: run.agentId,\r\n schemaVersion: run.schemaVersion,\r\n startedAt: run.startedAt,\r\n endedAt: run.endedAt ?? new Date().toISOString(),\r\n durationMs: run.durationMs ?? 0,\r\n status: run.status,\r\n totalEvents: run.events.length,\r\n totalSpans: run.spans.length,\r\n rootHash: run.rootHash ?? \"\",\r\n merkleRoot,\r\n publicSpans,\r\n redactedSpanHashes,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// PUBLIC VIEW EXTRACTION\r\n// =============================================================================\r\n\r\n/**\r\n * Extract the public view from a bundle.\r\n *\r\n * Returns only public spans with their public events.\r\n * This is a convenience function that returns the pre-computed public view\r\n * from the bundle. Use this for sharing trace information externally.\r\n *\r\n * Note: The public view is computed when the bundle is created, so this\r\n * function simply returns the existing public view. If you need to\r\n * re-compute the public view (e.g., with different redaction rules),\r\n * you should create a new bundle.\r\n *\r\n * @param bundle - The trace bundle\r\n * @returns The TraceBundlePublicView (safe to share externally)\r\n *\r\n * @example\r\n * ```typescript\r\n * const bundle = await createBundle(run);\r\n * const publicView = extractPublicView(bundle);\r\n *\r\n * // Safe to share externally\r\n * await sendToAuditSystem(publicView);\r\n * ```\r\n */\r\nexport function extractPublicView(bundle: TraceBundle): TraceBundlePublicView {\r\n return bundle.publicView;\r\n}\r\n\r\n// =============================================================================\r\n// BUNDLE VERIFICATION\r\n// =============================================================================\r\n\r\n/**\r\n * Verify a bundle's integrity.\r\n *\r\n * Performs comprehensive validation including:\r\n * - Event hashes are correct (recomputed and compared)\r\n * - Span hashes are correct (recomputed and compared)\r\n * - Rolling hash matches (recomputed from events)\r\n * - Root hash matches (recomputed from rolling hash + span hashes)\r\n * - Merkle root matches (recomputed from span tree)\r\n * - Event sequence is monotonic (0, 1, 2, ...)\r\n * - Span sequence is monotonic (0, 1, 2, ...)\r\n *\r\n * @param bundle - The trace bundle to verify\r\n * @returns Promise resolving to comprehensive verification result\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await verifyBundle(bundle);\r\n *\r\n * if (!result.valid) {\r\n * console.error(\"Bundle verification failed!\");\r\n * console.error(\"Errors:\", result.errors);\r\n * console.error(\"Warnings:\", result.warnings);\r\n * console.error(\"Checks:\", result.checks);\r\n * }\r\n * ```\r\n */\r\nexport async function verifyBundle(\r\n bundle: TraceBundle\r\n): Promise<TraceVerificationResult> {\r\n const errors: string[] = [];\r\n const warnings: string[] = [];\r\n const checks = {\r\n rollingHashValid: false,\r\n rootHashValid: false,\r\n merkleRootValid: false,\r\n spanHashesValid: false,\r\n eventHashesValid: false,\r\n sequenceValid: false,\r\n };\r\n\r\n const run = bundle.privateRun;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Verify Event Sequence\r\n // ---------------------------------------------------------------------------\r\n\r\n const sequenceErrors = verifySequences(run);\r\n if (sequenceErrors.length === 0) {\r\n checks.sequenceValid = true;\r\n } else {\r\n errors.push(...sequenceErrors);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Verify Event Hashes\r\n // ---------------------------------------------------------------------------\r\n\r\n const eventHashErrors = await verifyEventHashes(run.events);\r\n if (eventHashErrors.length === 0) {\r\n checks.eventHashesValid = true;\r\n } else {\r\n errors.push(...eventHashErrors);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Verify Span Hashes\r\n // ---------------------------------------------------------------------------\r\n\r\n const spanHashErrors = await verifySpanHashes(run.spans, run.events);\r\n if (spanHashErrors.length === 0) {\r\n checks.spanHashesValid = true;\r\n } else {\r\n errors.push(...spanHashErrors);\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Verify Rolling Hash\r\n // ---------------------------------------------------------------------------\r\n\r\n try {\r\n const computedRollingHash = await computeRollingHash(run.events);\r\n if (computedRollingHash === run.rollingHash) {\r\n checks.rollingHashValid = true;\r\n } else {\r\n errors.push(\r\n `Rolling hash mismatch: expected ${run.rollingHash}, computed ${computedRollingHash}`\r\n );\r\n }\r\n } catch (error) {\r\n errors.push(\r\n `Failed to compute rolling hash: ${error instanceof Error ? error.message : String(error)}`\r\n );\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Verify Root Hash\r\n // ---------------------------------------------------------------------------\r\n\r\n try {\r\n const computedRootHash = await computeRootHash(run.rollingHash, run.spans);\r\n if (computedRootHash === bundle.rootHash) {\r\n checks.rootHashValid = true;\r\n } else {\r\n errors.push(\r\n `Root hash mismatch: expected ${bundle.rootHash}, computed ${computedRootHash}`\r\n );\r\n }\r\n } catch (error) {\r\n errors.push(\r\n `Failed to compute root hash: ${error instanceof Error ? error.message : String(error)}`\r\n );\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Verify Merkle Root\r\n // ---------------------------------------------------------------------------\r\n\r\n try {\r\n const merkleTree = await buildSpanMerkleTree(run.spans, run.events);\r\n if (merkleTree.rootHash === bundle.merkleRoot) {\r\n checks.merkleRootValid = true;\r\n } else {\r\n errors.push(\r\n `Merkle root mismatch: expected ${bundle.merkleRoot}, computed ${merkleTree.rootHash}`\r\n );\r\n }\r\n } catch (error) {\r\n errors.push(\r\n `Failed to compute Merkle root: ${error instanceof Error ? error.message : String(error)}`\r\n );\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Additional Warnings\r\n // ---------------------------------------------------------------------------\r\n\r\n // Warn if there are no public spans\r\n if (bundle.publicView.publicSpans.length === 0 && run.spans.length > 0) {\r\n warnings.push(\r\n \"No public spans in bundle. The public view will be empty. \" +\r\n \"Consider marking some spans as public for transparency.\"\r\n );\r\n }\r\n\r\n // Warn if run status doesn't match public view status\r\n if (bundle.publicView.status !== run.status) {\r\n warnings.push(\r\n `Status mismatch between publicView (${bundle.publicView.status}) and privateRun (${run.status})`\r\n );\r\n }\r\n\r\n // Determine overall validity\r\n const valid =\r\n checks.rollingHashValid &&\r\n checks.rootHashValid &&\r\n checks.merkleRootValid &&\r\n checks.spanHashesValid &&\r\n checks.eventHashesValid &&\r\n checks.sequenceValid;\r\n\r\n return {\r\n valid,\r\n errors,\r\n warnings,\r\n checks,\r\n };\r\n}\r\n\r\n/**\r\n * Verify event and span sequences are monotonic.\r\n *\r\n * @param run - The trace run to verify\r\n * @returns Array of error messages (empty if valid)\r\n */\r\nfunction verifySequences(run: TraceRun): string[] {\r\n const errors: string[] = [];\r\n\r\n // Sort events by seq to check monotonicity\r\n const sortedEvents = [...run.events].sort((a, b) => a.seq - b.seq);\r\n\r\n // Check event sequence is monotonic starting from 0\r\n for (let i = 0; i < sortedEvents.length; i++) {\r\n const event = sortedEvents[i];\r\n // Handle noUncheckedIndexedAccess - event is guaranteed to exist after loop bounds check\r\n if (event !== undefined && event.seq !== i) {\r\n errors.push(\r\n `Event sequence gap: expected seq ${i}, found ${event.seq} for event ${event.id}`\r\n );\r\n }\r\n }\r\n\r\n // Sort spans by spanSeq to check monotonicity\r\n const sortedSpans = [...run.spans].sort((a, b) => a.spanSeq - b.spanSeq);\r\n\r\n // Check span sequence is monotonic starting from 0\r\n for (let i = 0; i < sortedSpans.length; i++) {\r\n const span = sortedSpans[i];\r\n // Handle noUncheckedIndexedAccess - span is guaranteed to exist after loop bounds check\r\n if (span !== undefined && span.spanSeq !== i) {\r\n errors.push(\r\n `Span sequence gap: expected spanSeq ${i}, found ${span.spanSeq} for span ${span.id}`\r\n );\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Verify all event hashes are correct.\r\n *\r\n * @param events - Array of events to verify\r\n * @returns Promise resolving to array of error messages (empty if valid)\r\n */\r\nasync function verifyEventHashes(events: TraceEvent[]): Promise<string[]> {\r\n const errors: string[] = [];\r\n\r\n for (const event of events) {\r\n if (!event.hash) {\r\n errors.push(`Event ${event.id} (seq ${event.seq}) is missing hash`);\r\n continue;\r\n }\r\n\r\n try {\r\n const computedHash = await computeEventHash(event);\r\n if (computedHash !== event.hash) {\r\n errors.push(\r\n `Event hash mismatch for ${event.id} (seq ${event.seq}): ` +\r\n `expected ${event.hash}, computed ${computedHash}`\r\n );\r\n }\r\n } catch (error) {\r\n errors.push(\r\n `Failed to compute hash for event ${event.id}: ` +\r\n `${error instanceof Error ? error.message : String(error)}`\r\n );\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n/**\r\n * Verify all span hashes are correct.\r\n *\r\n * @param spans - Array of spans to verify\r\n * @param events - Array of all events (for looking up event hashes)\r\n * @returns Promise resolving to array of error messages (empty if valid)\r\n */\r\nasync function verifySpanHashes(\r\n spans: TraceSpan[],\r\n events: TraceEvent[]\r\n): Promise<string[]> {\r\n const errors: string[] = [];\r\n\r\n // Create event lookup map\r\n const eventMap = new Map<string, TraceEvent>();\r\n for (const event of events) {\r\n eventMap.set(event.id, event);\r\n }\r\n\r\n for (const span of spans) {\r\n if (!span.hash) {\r\n errors.push(\r\n `Span ${span.id} (spanSeq ${span.spanSeq}) is missing hash`\r\n );\r\n continue;\r\n }\r\n\r\n try {\r\n // Get event hashes for this span in seq order\r\n const spanEvents = span.eventIds\r\n .map((id) => eventMap.get(id))\r\n .filter((e): e is TraceEvent => e !== undefined)\r\n .sort((a, b) => a.seq - b.seq);\r\n\r\n const eventHashes = spanEvents.map((e) => e.hash ?? \"\");\r\n\r\n const computedHash = await computeSpanHash(span, eventHashes);\r\n if (computedHash !== span.hash) {\r\n errors.push(\r\n `Span hash mismatch for ${span.id} (spanSeq ${span.spanSeq}): ` +\r\n `expected ${span.hash}, computed ${computedHash}`\r\n );\r\n }\r\n } catch (error) {\r\n errors.push(\r\n `Failed to compute hash for span ${span.id}: ` +\r\n `${error instanceof Error ? error.message : String(error)}`\r\n );\r\n }\r\n }\r\n\r\n return errors;\r\n}\r\n\r\n// =============================================================================\r\n// BUNDLE SIGNING\r\n// =============================================================================\r\n\r\n/**\r\n * Sign a bundle using the provided signature provider.\r\n *\r\n * Signs the canonical JSON of { rootHash, merkleRoot, manifestHash? }.\r\n * The signature and signer ID are added to the bundle.\r\n *\r\n * @param bundle - The bundle to sign\r\n * @param provider - The signature provider implementation\r\n * @returns Promise resolving to the signed bundle (new object, original unchanged)\r\n *\r\n * @example\r\n * ```typescript\r\n * const provider: SignatureProvider = {\r\n * signerId: \"agent-123\",\r\n * sign: async (data) => await myHSM.sign(data),\r\n * verify: async (data, sig, signerId) => await myHSM.verify(data, sig),\r\n * };\r\n *\r\n * const signedBundle = await signBundle(bundle, provider);\r\n * console.log(signedBundle.signature); // Hex-encoded signature\r\n * console.log(signedBundle.signerId); // \"agent-123\"\r\n * ```\r\n */\r\nexport async function signBundle(\r\n bundle: TraceBundle,\r\n provider: SignatureProvider\r\n): Promise<TraceBundle> {\r\n // Create the signing payload\r\n const signingPayload: {\r\n rootHash: string;\r\n merkleRoot: string;\r\n manifestHash?: string;\r\n } = {\r\n rootHash: bundle.rootHash,\r\n merkleRoot: bundle.merkleRoot,\r\n };\r\n\r\n // Include manifestHash if present\r\n if (bundle.manifestHash) {\r\n signingPayload.manifestHash = bundle.manifestHash;\r\n }\r\n\r\n // Canonicalize to get deterministic bytes\r\n const canonicalPayload = canonicalize(signingPayload);\r\n const payloadBytes = new TextEncoder().encode(canonicalPayload);\r\n\r\n // Sign using the provider\r\n const signatureBytes = await provider.sign(payloadBytes);\r\n const signatureHex = bytesToHex(signatureBytes);\r\n\r\n // Return new bundle with signature\r\n return {\r\n ...bundle,\r\n signerId: provider.signerId,\r\n signature: signatureHex,\r\n };\r\n}\r\n\r\n/**\r\n * Verify a bundle's signature.\r\n *\r\n * Recomputes the signing payload and verifies the signature using\r\n * the provider. The bundle must have both signature and signerId set.\r\n *\r\n * @param bundle - The signed bundle to verify\r\n * @param provider - The signature provider implementation\r\n * @returns Promise resolving to true if signature is valid, false otherwise\r\n *\r\n * @example\r\n * ```typescript\r\n * const isValid = await verifyBundleSignature(signedBundle, provider);\r\n * if (!isValid) {\r\n * throw new Error(\"Bundle signature verification failed!\");\r\n * }\r\n * ```\r\n */\r\nexport async function verifyBundleSignature(\r\n bundle: TraceBundle,\r\n provider: SignatureProvider\r\n): Promise<boolean> {\r\n // Check required fields\r\n if (!bundle.signature) {\r\n return false;\r\n }\r\n\r\n if (!bundle.signerId) {\r\n return false;\r\n }\r\n\r\n try {\r\n // Recreate the signing payload\r\n const signingPayload: {\r\n rootHash: string;\r\n merkleRoot: string;\r\n manifestHash?: string;\r\n } = {\r\n rootHash: bundle.rootHash,\r\n merkleRoot: bundle.merkleRoot,\r\n };\r\n\r\n // Include manifestHash if it was present when signed\r\n if (bundle.manifestHash) {\r\n signingPayload.manifestHash = bundle.manifestHash;\r\n }\r\n\r\n // Canonicalize to get deterministic bytes\r\n const canonicalPayload = canonicalize(signingPayload);\r\n const payloadBytes = new TextEncoder().encode(canonicalPayload);\r\n\r\n // Convert signature from hex\r\n const signatureBytes = hexToBytes(bundle.signature);\r\n\r\n // Verify using the provider\r\n return await provider.verify(payloadBytes, signatureBytes, bundle.signerId);\r\n } catch (error) {\r\n // Verification failed due to error (invalid format, etc.)\r\n return false;\r\n }\r\n}\r\n\r\n// =============================================================================\r\n// UTILITY FUNCTIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Get all events belonging to a specific span.\r\n *\r\n * @param span - The span to get events for\r\n * @param events - Array of all events\r\n * @returns Array of events belonging to the span, sorted by seq\r\n */\r\nexport function getSpanEvents(\r\n span: TraceSpan,\r\n events: TraceEvent[]\r\n): TraceEvent[] {\r\n const eventMap = new Map<string, TraceEvent>();\r\n for (const event of events) {\r\n eventMap.set(event.id, event);\r\n }\r\n\r\n return span.eventIds\r\n .map((id) => eventMap.get(id))\r\n .filter((e): e is TraceEvent => e !== undefined)\r\n .sort((a, b) => a.seq - b.seq);\r\n}\r\n\r\n/**\r\n * Count events by visibility level in a run.\r\n *\r\n * @param run - The trace run to analyze\r\n * @returns Object with counts for each visibility level\r\n */\r\nexport function countEventsByVisibility(run: TraceRun): Record<Visibility, number> {\r\n const counts: Record<Visibility, number> = {\r\n public: 0,\r\n private: 0,\r\n secret: 0,\r\n };\r\n\r\n for (const event of run.events) {\r\n counts[event.visibility]++;\r\n }\r\n\r\n return counts;\r\n}\r\n\r\n/**\r\n * Count spans by visibility level in a run.\r\n *\r\n * @param run - The trace run to analyze\r\n * @returns Object with counts for each visibility level\r\n */\r\nexport function countSpansByVisibility(run: TraceRun): Record<Visibility, number> {\r\n const counts: Record<Visibility, number> = {\r\n public: 0,\r\n private: 0,\r\n secret: 0,\r\n };\r\n\r\n for (const span of run.spans) {\r\n counts[span.visibility]++;\r\n }\r\n\r\n return counts;\r\n}\r\n","/**\r\n * @fileoverview Selective disclosure of trace spans with Merkle proofs.\r\n *\r\n * Location: packages/process-trace/src/disclosure.ts\r\n *\r\n * This module implements selective disclosure functionality for trace bundles,\r\n * enabling privacy-preserving audits and compliance workflows. It allows verifiers\r\n * to prove the existence of specific spans without revealing the entire trace.\r\n *\r\n * Key Concepts:\r\n * - Selective Disclosure: Reveal only specific spans from a trace bundle\r\n * - Membership Proofs: Prove a span exists without revealing its contents\r\n * - Full Disclosure: Prove existence AND reveal span data with events\r\n *\r\n * Disclosure Modes:\r\n * - \"membership\": Merkle proof only - proves span exists with specific hash\r\n * without exposing the actual span data. Useful for compliance checks.\r\n * - \"full\": Merkle proof + span data + event data - allows verifier to\r\n * recompute hashes and fully verify the span contents.\r\n *\r\n * Use Cases:\r\n * - Audit: \"Show me span 3\" (full mode) - auditor sees exactly what happened\r\n * - Compliance: \"Prove span exists\" (membership) - no data exposure\r\n * - Selective sharing: Disclose only public spans to external parties\r\n *\r\n * Used by:\r\n * - Audit workflows: Selective disclosure of trace spans\r\n * - Compliance verification: Prove span existence without data exposure\r\n * - API endpoints: Create and verify disclosure requests\r\n *\r\n * @example\r\n * ```typescript\r\n * // Full disclosure of specific spans\r\n * const result = await selectiveDisclose(bundle, [\"span-1\", \"span-3\"], \"full\");\r\n * for (const disclosed of result.disclosedSpans) {\r\n * console.log(\"Span:\", disclosed.span?.name);\r\n * console.log(\"Events:\", disclosed.events?.length);\r\n * }\r\n *\r\n * // Membership proof only (no data exposure)\r\n * const membershipResult = await selectiveDisclose(bundle, [\"span-2\"], \"membership\");\r\n *\r\n * // Verify disclosure against anchor\r\n * const verification = await verifyDisclosure(result, anchor.rootHash, anchor.merkleRoot);\r\n * if (!verification.valid) {\r\n * console.error(\"Verification failed:\", verification.errors);\r\n * }\r\n * ```\r\n */\r\n\r\nimport type {\r\n TraceBundle,\r\n TraceSpan,\r\n TraceEvent,\r\n DisclosureMode,\r\n DisclosureResult,\r\n MerkleProof,\r\n} from \"./types.js\";\r\nimport {\r\n generateMerkleProof,\r\n verifyMerkleProof,\r\n buildSpanMerkleTree,\r\n computeSpanHash,\r\n} from \"./merkle.js\";\r\nimport { HASH_DOMAIN_PREFIXES } from \"./types.js\";\r\nimport { sha256StringHex } from \"@fluxpointstudios/orynq-sdk-core/utils\";\r\n\r\n// =============================================================================\r\n// DISCLOSURE REQUEST\r\n// =============================================================================\r\n\r\n/**\r\n * Disclosure request structure for API use.\r\n *\r\n * This interface defines the shape of a disclosure request that can be\r\n * transmitted over network APIs. It contains all the information needed\r\n * to identify the bundle and specify which spans to disclose.\r\n *\r\n * @property bundleRootHash - The root hash of the bundle for identification\r\n * @property bundleMerkleRoot - The Merkle root for verification\r\n * @property spanIds - Array of span IDs to disclose\r\n * @property mode - Disclosure mode (membership or full)\r\n */\r\nexport interface DisclosureRequest {\r\n bundleRootHash: string;\r\n bundleMerkleRoot: string;\r\n spanIds: string[];\r\n mode: DisclosureMode;\r\n}\r\n\r\n// =============================================================================\r\n// HELPER FUNCTIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Check if a span can be disclosed (exists in bundle).\r\n *\r\n * This function performs a simple existence check to determine if a span\r\n * with the given ID exists in the bundle. It searches the privateRun.spans\r\n * array for a matching span ID.\r\n *\r\n * @param bundle - The trace bundle to check\r\n * @param spanId - The ID of the span to look for\r\n * @returns true if the span exists in the bundle, false otherwise\r\n *\r\n * @example\r\n * ```typescript\r\n * if (canDisclose(bundle, \"span-123\")) {\r\n * const result = await selectiveDisclose(bundle, [\"span-123\"], \"full\");\r\n * } else {\r\n * console.error(\"Span not found in bundle\");\r\n * }\r\n * ```\r\n */\r\nexport function canDisclose(bundle: TraceBundle, spanId: string): boolean {\r\n return bundle.privateRun.spans.some((span) => span.id === spanId);\r\n}\r\n\r\n/**\r\n * Get span index by ID (needed for proof generation).\r\n *\r\n * Returns the index of a span in the sorted spans array (sorted by spanSeq).\r\n * This index is used for Merkle proof generation, as the proof depends on\r\n * the position of the span's leaf in the Merkle tree.\r\n *\r\n * @param bundle - The trace bundle containing the span\r\n * @param spanId - The ID of the span to find\r\n * @returns The 0-indexed position of the span in the sorted array\r\n * @throws Error if the span is not found in the bundle\r\n *\r\n * @example\r\n * ```typescript\r\n * const index = getSpanIndex(bundle, \"span-456\");\r\n * console.log(`Span is at index ${index} in the Merkle tree`);\r\n * ```\r\n */\r\nexport function getSpanIndex(bundle: TraceBundle, spanId: string): number {\r\n // Sort spans by spanSeq for consistent ordering (matches Merkle tree order)\r\n const sortedSpans = [...bundle.privateRun.spans].sort(\r\n (a, b) => a.spanSeq - b.spanSeq\r\n );\r\n\r\n const index = sortedSpans.findIndex((span) => span.id === spanId);\r\n\r\n if (index === -1) {\r\n throw new Error(\r\n `Span with ID \"${spanId}\" not found in bundle. ` +\r\n `Available span IDs: ${sortedSpans.map((s) => s.id).join(\", \")}`\r\n );\r\n }\r\n\r\n return index;\r\n}\r\n\r\n/**\r\n * Get events belonging to a specific span from the bundle.\r\n *\r\n * @param bundle - The trace bundle\r\n * @param span - The span to get events for\r\n * @returns Array of events sorted by seq\r\n */\r\nfunction getSpanEventsFromBundle(\r\n bundle: TraceBundle,\r\n span: TraceSpan\r\n): TraceEvent[] {\r\n // Create event lookup map\r\n const eventMap = new Map<string, TraceEvent>();\r\n for (const event of bundle.privateRun.events) {\r\n eventMap.set(event.id, event);\r\n }\r\n\r\n // Get events for this span and sort by seq\r\n return span.eventIds\r\n .map((id) => eventMap.get(id))\r\n .filter((e): e is TraceEvent => e !== undefined)\r\n .sort((a, b) => a.seq - b.seq);\r\n}\r\n\r\n// =============================================================================\r\n// DISCLOSURE REQUEST CREATION\r\n// =============================================================================\r\n\r\n/**\r\n * Create a disclosure request (for API use).\r\n *\r\n * This function creates a structured disclosure request object that can be\r\n * serialized and transmitted over network APIs. The request contains all\r\n * information needed to identify the bundle and specify which spans to disclose.\r\n *\r\n * @param bundle - The trace bundle to create a request for\r\n * @param spanIds - Array of span IDs to request disclosure for\r\n * @param mode - The disclosure mode (membership or full)\r\n * @returns A DisclosureRequest object ready for transmission\r\n *\r\n * @example\r\n * ```typescript\r\n * const request = createDisclosureRequest(\r\n * bundle,\r\n * [\"span-1\", \"span-3\"],\r\n * \"full\"\r\n * );\r\n *\r\n * // Send request to disclosure service\r\n * const response = await fetch(\"/api/disclose\", {\r\n * method: \"POST\",\r\n * body: JSON.stringify(request),\r\n * });\r\n * ```\r\n */\r\nexport function createDisclosureRequest(\r\n bundle: TraceBundle,\r\n spanIds: string[],\r\n mode: DisclosureMode\r\n): DisclosureRequest {\r\n return {\r\n bundleRootHash: bundle.rootHash,\r\n bundleMerkleRoot: bundle.merkleRoot,\r\n spanIds: [...spanIds], // Create a copy to prevent external mutation\r\n mode,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// SELECTIVE DISCLOSURE\r\n// =============================================================================\r\n\r\n/**\r\n * Selectively disclose specific spans from a bundle.\r\n *\r\n * This function generates disclosure results for the specified spans. Depending\r\n * on the disclosure mode, it includes either just Merkle proofs (membership mode)\r\n * or Merkle proofs plus full span and event data (full mode).\r\n *\r\n * The function validates that all requested spans exist in the bundle before\r\n * proceeding with disclosure generation.\r\n *\r\n * @param bundle - The trace bundle containing all data\r\n * @param spanIds - IDs of spans to disclose\r\n * @param mode - Disclosure mode:\r\n * - \"membership\": Merkle proof only (proves span exists with hash)\r\n * - \"full\": Merkle proof + span data + event data\r\n * @returns Promise resolving to DisclosureResult with proofs and optionally data\r\n * @throws Error if any requested spanId does not exist in the bundle\r\n *\r\n * @example\r\n * ```typescript\r\n * // Full disclosure - includes span data and events\r\n * const fullResult = await selectiveDisclose(bundle, [\"span-1\"], \"full\");\r\n * console.log(fullResult.disclosedSpans[0].span?.name);\r\n * console.log(fullResult.disclosedSpans[0].events?.length);\r\n *\r\n * // Membership disclosure - proof only, no data\r\n * const membershipResult = await selectiveDisclose(bundle, [\"span-1\"], \"membership\");\r\n * // membershipResult.disclosedSpans[0].span is undefined\r\n * // membershipResult.disclosedSpans[0].events is undefined\r\n * ```\r\n */\r\nexport async function selectiveDisclose(\r\n bundle: TraceBundle,\r\n spanIds: string[],\r\n mode: DisclosureMode\r\n): Promise<DisclosureResult> {\r\n // Validate all spanIds exist in bundle\r\n const missingSpanIds: string[] = [];\r\n for (const spanId of spanIds) {\r\n if (!canDisclose(bundle, spanId)) {\r\n missingSpanIds.push(spanId);\r\n }\r\n }\r\n\r\n if (missingSpanIds.length > 0) {\r\n throw new Error(\r\n `Cannot disclose spans that do not exist in bundle: ${missingSpanIds.join(\", \")}`\r\n );\r\n }\r\n\r\n // Build the Merkle tree for proof generation\r\n const merkleTree = await buildSpanMerkleTree(\r\n bundle.privateRun.spans,\r\n bundle.privateRun.events\r\n );\r\n\r\n // Sort spans by spanSeq for consistent indexing\r\n const sortedSpans = [...bundle.privateRun.spans].sort(\r\n (a, b) => a.spanSeq - b.spanSeq\r\n );\r\n\r\n // Create a map for quick span lookup\r\n const spanMap = new Map<string, TraceSpan>();\r\n for (const span of sortedSpans) {\r\n spanMap.set(span.id, span);\r\n }\r\n\r\n // Generate disclosures for each requested span\r\n const disclosedSpans: DisclosureResult[\"disclosedSpans\"] = [];\r\n\r\n for (const spanId of spanIds) {\r\n // Get the span and its index\r\n const span = spanMap.get(spanId);\r\n if (!span) {\r\n // This should not happen since we validated above, but handle defensively\r\n throw new Error(`Span \"${spanId}\" not found after validation`);\r\n }\r\n\r\n const spanIndex = getSpanIndex(bundle, spanId);\r\n\r\n // Generate Merkle proof\r\n const proof = generateMerkleProof(merkleTree, spanIndex);\r\n\r\n // Build the disclosed span entry\r\n if (mode === \"full\") {\r\n // Full mode: include span data and events\r\n const events = getSpanEventsFromBundle(bundle, span);\r\n\r\n disclosedSpans.push({\r\n spanId,\r\n proof,\r\n span: { ...span }, // Clone to prevent external mutation\r\n events: events.map((e) => ({ ...e })), // Clone events\r\n });\r\n } else {\r\n // Membership mode: proof only, no data\r\n disclosedSpans.push({\r\n spanId,\r\n proof,\r\n // span and events are undefined in membership mode\r\n });\r\n }\r\n }\r\n\r\n return {\r\n mode,\r\n rootHash: bundle.rootHash,\r\n merkleRoot: bundle.merkleRoot,\r\n disclosedSpans,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// VERIFICATION FUNCTIONS\r\n// =============================================================================\r\n\r\n/**\r\n * Verify a disclosure result against expected hashes.\r\n *\r\n * This function performs comprehensive verification of a disclosure result:\r\n * 1. Checks that rootHash matches the expected value from the anchor\r\n * 2. Checks that merkleRoot matches the expected value from the anchor\r\n * 3. For each disclosed span, verifies the Merkle proof\r\n * 4. For full mode disclosures, verifies span hash recomputation\r\n *\r\n * @param disclosure - The disclosure result to verify\r\n * @param expectedRootHash - Expected root hash from anchor/on-chain commitment\r\n * @param expectedMerkleRoot - Expected Merkle root from anchor/on-chain commitment\r\n * @returns Promise resolving to verification result with validity status and errors\r\n *\r\n * @example\r\n * ```typescript\r\n * const disclosure = await selectiveDisclose(bundle, [\"span-1\"], \"full\");\r\n * const verification = await verifyDisclosure(\r\n * disclosure,\r\n * anchor.rootHash,\r\n * anchor.merkleRoot\r\n * );\r\n *\r\n * if (verification.valid) {\r\n * console.log(\"Disclosure verified successfully\");\r\n * } else {\r\n * console.error(\"Verification failed:\", verification.errors);\r\n * }\r\n * ```\r\n */\r\nexport async function verifyDisclosure(\r\n disclosure: DisclosureResult,\r\n expectedRootHash: string,\r\n expectedMerkleRoot: string\r\n): Promise<{ valid: boolean; errors: string[] }> {\r\n const errors: string[] = [];\r\n\r\n // Check rootHash matches expected\r\n if (disclosure.rootHash !== expectedRootHash) {\r\n errors.push(\r\n `Root hash mismatch: disclosure has \"${disclosure.rootHash}\", ` +\r\n `expected \"${expectedRootHash}\"`\r\n );\r\n }\r\n\r\n // Check merkleRoot matches expected\r\n if (disclosure.merkleRoot !== expectedMerkleRoot) {\r\n errors.push(\r\n `Merkle root mismatch: disclosure has \"${disclosure.merkleRoot}\", ` +\r\n `expected \"${expectedMerkleRoot}\"`\r\n );\r\n }\r\n\r\n // Verify each disclosed span\r\n for (const disclosed of disclosure.disclosedSpans) {\r\n // Verify the Merkle proof for this span\r\n const proofValid = await verifyMerkleProof(disclosed.proof);\r\n\r\n if (!proofValid) {\r\n errors.push(\r\n `Merkle proof verification failed for span \"${disclosed.spanId}\"`\r\n );\r\n continue; // Skip further checks for this span\r\n }\r\n\r\n // Verify proof rootHash matches expected\r\n if (disclosed.proof.rootHash !== expectedMerkleRoot) {\r\n errors.push(\r\n `Proof root hash mismatch for span \"${disclosed.spanId}\": ` +\r\n `proof has \"${disclosed.proof.rootHash}\", expected \"${expectedMerkleRoot}\"`\r\n );\r\n }\r\n\r\n // For full mode with data, verify span hash recomputation\r\n if (disclosure.mode === \"full\" && disclosed.span && disclosed.events) {\r\n const spanVerification = await verifySpanDisclosure(\r\n {\r\n spanId: disclosed.spanId,\r\n proof: disclosed.proof,\r\n span: disclosed.span,\r\n events: disclosed.events,\r\n },\r\n expectedMerkleRoot\r\n );\r\n\r\n if (!spanVerification.valid) {\r\n errors.push(...spanVerification.errors);\r\n }\r\n }\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n\r\n/**\r\n * Verify a single span's disclosure (with data).\r\n *\r\n * This function performs detailed verification of a disclosed span:\r\n * 1. Recomputes the span hash from the provided span and events\r\n * 2. Computes the expected leaf hash from the span hash\r\n * 3. Verifies the leaf hash matches the proof's leafHash\r\n * 4. Verifies the Merkle proof is valid\r\n *\r\n * This is used for \"full\" mode disclosures where span data is provided.\r\n *\r\n * @param disclosed - Object containing spanId, proof, span data, and events\r\n * @param expectedMerkleRoot - Expected Merkle root from anchor/on-chain commitment\r\n * @returns Promise resolving to verification result with validity status and errors\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await verifySpanDisclosure(\r\n * {\r\n * spanId: \"span-123\",\r\n * proof: merkleProof,\r\n * span: spanData,\r\n * events: spanEvents,\r\n * },\r\n * expectedMerkleRoot\r\n * );\r\n *\r\n * if (result.valid) {\r\n * console.log(\"Span data is authentic and included in the trace\");\r\n * }\r\n * ```\r\n */\r\nexport async function verifySpanDisclosure(\r\n disclosed: {\r\n spanId: string;\r\n proof: MerkleProof;\r\n span: TraceSpan;\r\n events: TraceEvent[];\r\n },\r\n expectedMerkleRoot: string\r\n): Promise<{ valid: boolean; errors: string[] }> {\r\n const errors: string[] = [];\r\n\r\n // Sort events by seq for deterministic hash computation\r\n const sortedEvents = [...disclosed.events].sort((a, b) => a.seq - b.seq);\r\n\r\n // Get event hashes in seq order\r\n const eventHashes = sortedEvents.map((e) => e.hash ?? \"\");\r\n\r\n // Recompute span hash from span + events\r\n const computedSpanHash = await computeSpanHash(disclosed.span, eventHashes);\r\n\r\n // Compute expected leaf hash: H(\"poi-trace:leaf:v1|\" + spanHash)\r\n const computedLeafHash = await sha256StringHex(\r\n HASH_DOMAIN_PREFIXES.leaf + computedSpanHash\r\n );\r\n\r\n // Verify leaf hash matches proof.leafHash\r\n if (computedLeafHash !== disclosed.proof.leafHash) {\r\n errors.push(\r\n `Span hash verification failed for \"${disclosed.spanId}\": ` +\r\n `computed leaf hash \"${computedLeafHash}\" does not match ` +\r\n `proof leaf hash \"${disclosed.proof.leafHash}\". ` +\r\n `The span data may have been modified.`\r\n );\r\n }\r\n\r\n // Verify Merkle proof\r\n const proofValid = await verifyMerkleProof(disclosed.proof);\r\n if (!proofValid) {\r\n errors.push(\r\n `Merkle proof verification failed for span \"${disclosed.spanId}\"`\r\n );\r\n }\r\n\r\n // Verify proof rootHash matches expected\r\n if (disclosed.proof.rootHash !== expectedMerkleRoot) {\r\n errors.push(\r\n `Proof root hash mismatch for span \"${disclosed.spanId}\": ` +\r\n `proof has \"${disclosed.proof.rootHash}\", expected \"${expectedMerkleRoot}\"`\r\n );\r\n }\r\n\r\n return {\r\n valid: errors.length === 0,\r\n errors,\r\n };\r\n}\r\n","/**\r\n * @fileoverview Manifest creation and verification for off-chain trace storage.\r\n *\r\n * Location: packages/process-trace/src/manifest.ts\r\n *\r\n * This module provides functionality for creating manifests and chunks from trace bundles,\r\n * enabling efficient off-chain storage of trace data. The manifest serves as a public-safe\r\n * entry point for trace retrieval, while chunks contain the actual span and event data.\r\n *\r\n * Key features:\r\n * - Creates manifests with cryptographic commitments for integrity verification\r\n * - Chunks trace data by size for efficient storage and retrieval\r\n * - Provides verification functions to ensure manifest and chunk integrity\r\n * - Supports reconstruction of trace bundles from manifests and chunks\r\n *\r\n * Storage Layout (for consumers):\r\n * ```\r\n * <storageUri>/\r\n * manifest.json # TraceManifest (public-safe)\r\n * chunks/\r\n * <hash1>.json # Or .json.gz if compressed by consumer\r\n * <hash2>.json\r\n * ```\r\n *\r\n * Used by:\r\n * - Storage adapters for persisting trace data\r\n * - Retrieval workflows for reconstructing traces\r\n * - Verification workflows for validating stored traces\r\n *\r\n * @example\r\n * ```typescript\r\n * // Create manifest for storage\r\n * const { manifest, chunks } = await createManifest(bundle, { chunkSize: 500_000 });\r\n *\r\n * // Store chunks (consumer handles actual storage)\r\n * for (const chunk of chunks) {\r\n * const path = getChunkPath(chunk.info);\r\n * await storage.write(path, chunk.content);\r\n * }\r\n *\r\n * // Store manifest\r\n * await storage.write(\"manifest.json\", JSON.stringify(manifest));\r\n *\r\n * // Later: verify\r\n * const result = await verifyManifest(manifest, loadedChunks);\r\n * if (!result.valid) {\r\n * console.error(\"Manifest verification failed:\", result.errors);\r\n * }\r\n * ```\r\n */\r\n\r\nimport { sha256StringHex, canonicalize } from \"@fluxpointstudios/orynq-sdk-core/utils\";\r\nimport type {\r\n TraceManifest,\r\n TraceBundle,\r\n ChunkInfo,\r\n Chunk,\r\n CreateManifestOptions,\r\n ManifestVerificationResult,\r\n TraceSpan,\r\n TraceEvent,\r\n TraceRun,\r\n} from \"./types.js\";\r\nimport { HASH_DOMAIN_PREFIXES } from \"./types.js\";\r\n\r\n// =============================================================================\r\n// CONSTANTS\r\n// =============================================================================\r\n\r\n/**\r\n * Default chunk size in bytes (1MB of uncompressed JSON).\r\n * This is the target size for chunking; actual chunks may be slightly larger\r\n * to avoid splitting spans across chunks.\r\n */\r\nconst DEFAULT_CHUNK_SIZE = 1_000_000;\r\n\r\n// =============================================================================\r\n// CHUNK CONTENT TYPE\r\n// =============================================================================\r\n\r\n/**\r\n * Content format for a chunk.\r\n * Contains spans and their associated events.\r\n */\r\ninterface ChunkContent {\r\n spans: TraceSpan[];\r\n events: TraceEvent[];\r\n}\r\n\r\n// =============================================================================\r\n// MANIFEST CREATION\r\n// =============================================================================\r\n\r\n/**\r\n * Create a manifest and chunks from a trace bundle.\r\n *\r\n * Chunks contain private span/event data for off-chain storage. Each chunk\r\n * includes a subset of spans and their associated events, grouped to fit\r\n * within the target chunk size.\r\n *\r\n * The manifest contains:\r\n * - Metadata from the bundle (runId, agentId, timestamps, etc.)\r\n * - Cryptographic commitments (rootHash, merkleRoot)\r\n * - Chunk information (index, hash, size, spanIds)\r\n * - The complete publicView for quick access\r\n *\r\n * @param bundle - Finalized trace bundle to create manifest from\r\n * @param options - Optional chunking options\r\n * @param options.chunkSize - Target chunk size in bytes (default: 1MB)\r\n * @param options.compression - Compression hint for consumers (default: \"none\")\r\n * @returns Promise resolving to manifest and array of chunks\r\n *\r\n * @example\r\n * ```typescript\r\n * const { manifest, chunks } = await createManifest(bundle, {\r\n * chunkSize: 500_000, // 500KB chunks\r\n * });\r\n *\r\n * console.log(`Created ${chunks.length} chunks`);\r\n * console.log(`Manifest hash: ${manifest.manifestHash}`);\r\n * ```\r\n */\r\nexport async function createManifest(\r\n bundle: TraceBundle,\r\n options?: CreateManifestOptions\r\n): Promise<{ manifest: TraceManifest; chunks: Chunk[] }> {\r\n const chunkSize = options?.chunkSize ?? DEFAULT_CHUNK_SIZE;\r\n const compression = options?.compression ?? \"none\";\r\n\r\n const run = bundle.privateRun;\r\n\r\n // Build event lookup map for efficient access\r\n const eventMap = new Map<string, TraceEvent>();\r\n for (const event of run.events) {\r\n eventMap.set(event.id, event);\r\n }\r\n\r\n // Group spans into chunks based on size\r\n const chunks: Chunk[] = [];\r\n let currentChunkSpans: TraceSpan[] = [];\r\n let currentChunkEvents: TraceEvent[] = [];\r\n let currentChunkSize = 0;\r\n let chunkIndex = 0;\r\n\r\n // Sort spans by spanSeq for deterministic ordering\r\n const sortedSpans = [...run.spans].sort((a, b) => a.spanSeq - b.spanSeq);\r\n\r\n for (const span of sortedSpans) {\r\n // Get events for this span\r\n const spanEvents = span.eventIds\r\n .map((id) => eventMap.get(id))\r\n .filter((e): e is TraceEvent => e !== undefined)\r\n .sort((a, b) => a.seq - b.seq);\r\n\r\n // Estimate size of this span and its events\r\n const spanJson = JSON.stringify(span);\r\n const eventsJson = spanEvents.map((e) => JSON.stringify(e)).join(\"\");\r\n const spanSize = spanJson.length + eventsJson.length;\r\n\r\n // If adding this span would exceed chunk size and we have content, finalize current chunk\r\n if (currentChunkSize + spanSize > chunkSize && currentChunkSpans.length > 0) {\r\n const chunk = await createChunk(\r\n chunkIndex,\r\n currentChunkSpans,\r\n currentChunkEvents,\r\n compression\r\n );\r\n chunks.push(chunk);\r\n chunkIndex++;\r\n\r\n // Reset for next chunk\r\n currentChunkSpans = [];\r\n currentChunkEvents = [];\r\n currentChunkSize = 0;\r\n }\r\n\r\n // Add span and its events to current chunk\r\n currentChunkSpans.push(span);\r\n currentChunkEvents.push(...spanEvents);\r\n currentChunkSize += spanSize;\r\n }\r\n\r\n // Create final chunk if there's remaining content\r\n if (currentChunkSpans.length > 0) {\r\n const chunk = await createChunk(\r\n chunkIndex,\r\n currentChunkSpans,\r\n currentChunkEvents,\r\n compression\r\n );\r\n chunks.push(chunk);\r\n }\r\n\r\n // Build manifest without hash first\r\n const manifestWithoutHash: Omit<TraceManifest, \"manifestHash\"> = {\r\n formatVersion: bundle.formatVersion,\r\n runId: run.id,\r\n agentId: run.agentId,\r\n rootHash: bundle.rootHash,\r\n merkleRoot: bundle.merkleRoot,\r\n totalEvents: run.events.length,\r\n totalSpans: run.spans.length,\r\n startedAt: run.startedAt,\r\n endedAt: run.endedAt ?? run.startedAt,\r\n durationMs: run.durationMs ?? 0,\r\n chunks: chunks.map((c) => c.info),\r\n publicView: bundle.publicView,\r\n };\r\n\r\n // Compute manifest hash\r\n const manifestHash = await computeManifestHash(manifestWithoutHash);\r\n\r\n // Build complete manifest\r\n const manifest: TraceManifest = {\r\n ...manifestWithoutHash,\r\n manifestHash,\r\n };\r\n\r\n return { manifest, chunks };\r\n}\r\n\r\n/**\r\n * Internal helper to create a chunk from spans and events.\r\n *\r\n * @param index - Chunk sequence number\r\n * @param spans - Spans to include in this chunk\r\n * @param events - Events to include in this chunk\r\n * @param compression - Compression hint\r\n * @returns Promise resolving to the complete Chunk\r\n */\r\nasync function createChunk(\r\n index: number,\r\n spans: TraceSpan[],\r\n events: TraceEvent[],\r\n compression: \"gzip\" | \"none\"\r\n): Promise<Chunk> {\r\n // Build chunk content\r\n const content: ChunkContent = {\r\n spans,\r\n events,\r\n };\r\n\r\n // Serialize to JSON (deterministic ordering via canonicalize)\r\n const contentJson = canonicalize(content);\r\n\r\n // Compute hash of content BEFORE any compression\r\n const hash = await sha256StringHex(contentJson);\r\n\r\n // Get span IDs for this chunk\r\n const spanIds = spans.map((s) => s.id);\r\n\r\n // Build chunk info\r\n const info: ChunkInfo = {\r\n index,\r\n hash,\r\n size: contentJson.length,\r\n compression,\r\n spanIds,\r\n };\r\n\r\n return {\r\n info,\r\n content: contentJson,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// MANIFEST HASH COMPUTATION\r\n// =============================================================================\r\n\r\n/**\r\n * Compute the manifest hash.\r\n *\r\n * The manifest hash is computed as:\r\n * `H(\"poi-trace:manifest:v1|\" + canonical(manifestWithoutHash))`\r\n *\r\n * This hash serves as a cryptographic commitment to the manifest contents,\r\n * enabling integrity verification of stored manifests.\r\n *\r\n * @param manifest - Manifest object without the manifestHash field\r\n * @returns Promise resolving to the manifest hash as a hex string\r\n *\r\n * @example\r\n * ```typescript\r\n * const manifestHash = await computeManifestHash(manifestWithoutHash);\r\n * const completeManifest = { ...manifestWithoutHash, manifestHash };\r\n * ```\r\n */\r\nexport async function computeManifestHash(\r\n manifest: Omit<TraceManifest, \"manifestHash\">\r\n): Promise<string> {\r\n // Canonicalize the manifest for deterministic serialization\r\n const canonical = canonicalize(manifest);\r\n\r\n // Apply domain separation and hash\r\n const prefixedData = HASH_DOMAIN_PREFIXES.manifest + canonical;\r\n\r\n return sha256StringHex(prefixedData);\r\n}\r\n\r\n// =============================================================================\r\n// MANIFEST VERIFICATION\r\n// =============================================================================\r\n\r\n/**\r\n * Verify a manifest against its chunks.\r\n *\r\n * Performs comprehensive validation including:\r\n * - Manifest hash matches recomputed hash\r\n * - Each chunk hash matches its content\r\n * - All chunk indices are present\r\n * - Root hash in manifest is present\r\n * - Merkle root in manifest is present\r\n *\r\n * @param manifest - The manifest to verify\r\n * @param chunks - The chunks referenced by the manifest\r\n * @returns Promise resolving to verification result with errors and check statuses\r\n *\r\n * @example\r\n * ```typescript\r\n * const result = await verifyManifest(manifest, chunks);\r\n * if (!result.valid) {\r\n * console.error(\"Verification failed:\", result.errors);\r\n * } else {\r\n * console.log(\"Manifest and chunks are valid\");\r\n * }\r\n * ```\r\n */\r\nexport async function verifyManifest(\r\n manifest: TraceManifest,\r\n chunks: Chunk[]\r\n): Promise<ManifestVerificationResult> {\r\n const errors: string[] = [];\r\n const warnings: string[] = [];\r\n const checks = {\r\n manifestHashValid: false,\r\n chunkHashesValid: false,\r\n rootHashMatches: false,\r\n merkleRootMatches: false,\r\n };\r\n\r\n // ---------------------------------------------------------------------------\r\n // Verify Manifest Hash\r\n // ---------------------------------------------------------------------------\r\n\r\n try {\r\n // Create manifest without hash for recomputation\r\n const manifestWithoutHash: Omit<TraceManifest, \"manifestHash\"> = {\r\n formatVersion: manifest.formatVersion,\r\n runId: manifest.runId,\r\n agentId: manifest.agentId,\r\n rootHash: manifest.rootHash,\r\n merkleRoot: manifest.merkleRoot,\r\n totalEvents: manifest.totalEvents,\r\n totalSpans: manifest.totalSpans,\r\n startedAt: manifest.startedAt,\r\n endedAt: manifest.endedAt,\r\n durationMs: manifest.durationMs,\r\n chunks: manifest.chunks,\r\n publicView: manifest.publicView,\r\n };\r\n\r\n const computedHash = await computeManifestHash(manifestWithoutHash);\r\n\r\n if (manifest.manifestHash === computedHash) {\r\n checks.manifestHashValid = true;\r\n } else {\r\n errors.push(\r\n `Manifest hash mismatch: expected ${manifest.manifestHash}, computed ${computedHash}`\r\n );\r\n }\r\n } catch (error) {\r\n errors.push(\r\n `Failed to compute manifest hash: ${error instanceof Error ? error.message : String(error)}`\r\n );\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Verify Chunk Hashes\r\n // ---------------------------------------------------------------------------\r\n\r\n // Build chunk lookup by index\r\n const chunkByIndex = new Map<number, Chunk>();\r\n for (const chunk of chunks) {\r\n chunkByIndex.set(chunk.info.index, chunk);\r\n }\r\n\r\n let allChunkHashesValid = true;\r\n\r\n for (const chunkInfo of manifest.chunks) {\r\n const chunk = chunkByIndex.get(chunkInfo.index);\r\n\r\n if (!chunk) {\r\n errors.push(`Missing chunk at index ${chunkInfo.index}`);\r\n allChunkHashesValid = false;\r\n continue;\r\n }\r\n\r\n try {\r\n // Compute hash of chunk content\r\n const computedHash = await sha256StringHex(chunk.content);\r\n\r\n if (computedHash !== chunkInfo.hash) {\r\n errors.push(\r\n `Chunk ${chunkInfo.index} hash mismatch: expected ${chunkInfo.hash}, computed ${computedHash}`\r\n );\r\n allChunkHashesValid = false;\r\n }\r\n\r\n // Verify size matches\r\n if (chunk.content.length !== chunkInfo.size) {\r\n errors.push(\r\n `Chunk ${chunkInfo.index} size mismatch: expected ${chunkInfo.size}, got ${chunk.content.length}`\r\n );\r\n allChunkHashesValid = false;\r\n }\r\n } catch (error) {\r\n errors.push(\r\n `Failed to verify chunk ${chunkInfo.index}: ${error instanceof Error ? error.message : String(error)}`\r\n );\r\n allChunkHashesValid = false;\r\n }\r\n }\r\n\r\n // Check for extra chunks not in manifest\r\n for (const chunk of chunks) {\r\n const inManifest = manifest.chunks.some((c) => c.index === chunk.info.index);\r\n if (!inManifest) {\r\n warnings.push(`Extra chunk at index ${chunk.info.index} not referenced in manifest`);\r\n }\r\n }\r\n\r\n checks.chunkHashesValid = allChunkHashesValid;\r\n\r\n // ---------------------------------------------------------------------------\r\n // Verify Root Hash Presence\r\n // ---------------------------------------------------------------------------\r\n\r\n if (manifest.rootHash && manifest.rootHash.length > 0) {\r\n checks.rootHashMatches = true;\r\n } else {\r\n errors.push(\"Manifest is missing rootHash\");\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Verify Merkle Root Presence\r\n // ---------------------------------------------------------------------------\r\n\r\n if (manifest.merkleRoot && manifest.merkleRoot.length > 0) {\r\n checks.merkleRootMatches = true;\r\n } else {\r\n errors.push(\"Manifest is missing merkleRoot\");\r\n }\r\n\r\n // ---------------------------------------------------------------------------\r\n // Additional Warnings\r\n // ---------------------------------------------------------------------------\r\n\r\n if (manifest.chunks.length === 0) {\r\n warnings.push(\"Manifest has no chunks - trace data may be empty\");\r\n }\r\n\r\n if (manifest.totalSpans === 0 && manifest.chunks.length > 0) {\r\n warnings.push(\"Manifest reports 0 spans but has chunks\");\r\n }\r\n\r\n // Determine overall validity\r\n const valid =\r\n checks.manifestHashValid &&\r\n checks.chunkHashesValid &&\r\n checks.rootHashMatches &&\r\n checks.merkleRootMatches;\r\n\r\n return {\r\n valid,\r\n errors,\r\n warnings,\r\n checks,\r\n };\r\n}\r\n\r\n// =============================================================================\r\n// BUNDLE RECONSTRUCTION\r\n// =============================================================================\r\n\r\n/**\r\n * Reconstruct a trace bundle from manifest and chunks.\r\n *\r\n * This is the inverse operation of createManifest. It parses all chunk\r\n * contents, merges spans and events, and reconstructs the complete\r\n * TraceBundle.\r\n *\r\n * Note: The reconstructed bundle will use the publicView from the manifest\r\n * and construct a privateRun from the chunk data.\r\n *\r\n * @param manifest - The manifest describing the trace\r\n * @param chunks - All chunks referenced by the manifest\r\n * @returns Promise resolving to the reconstructed TraceBundle\r\n * @throws Error if required chunks are missing or corrupted\r\n *\r\n * @example\r\n * ```typescript\r\n * // Load manifest and chunks from storage\r\n * const manifest = JSON.parse(await storage.read(\"manifest.json\"));\r\n * const chunks = await loadChunks(manifest.chunks);\r\n *\r\n * // Reconstruct the bundle\r\n * const bundle = await reconstructBundleFromManifest(manifest, chunks);\r\n *\r\n * // Now you can access the full trace data\r\n * console.log(`Reconstructed ${bundle.privateRun.events.length} events`);\r\n * ```\r\n */\r\nexport async function reconstructBundleFromManifest(\r\n manifest: TraceManifest,\r\n chunks: Chunk[]\r\n): Promise<TraceBundle> {\r\n // Build chunk lookup by index\r\n const chunkByIndex = new Map<number, Chunk>();\r\n for (const chunk of chunks) {\r\n chunkByIndex.set(chunk.info.index, chunk);\r\n }\r\n\r\n // Parse all chunks and merge spans/events\r\n const allSpans: TraceSpan[] = [];\r\n const allEvents: TraceEvent[] = [];\r\n\r\n // Process chunks in order\r\n const sortedChunkInfos = [...manifest.chunks].sort((a, b) => a.index - b.index);\r\n\r\n for (const chunkInfo of sortedChunkInfos) {\r\n const chunk = chunkByIndex.get(chunkInfo.index);\r\n\r\n if (!chunk) {\r\n throw new Error(`Missing chunk at index ${chunkInfo.index}`);\r\n }\r\n\r\n // Parse chunk content\r\n const { spans, events } = parseChunkContent(chunk.content);\r\n\r\n allSpans.push(...spans);\r\n allEvents.push(...events);\r\n }\r\n\r\n // Sort spans by spanSeq and events by seq for proper ordering\r\n allSpans.sort((a, b) => a.spanSeq - b.spanSeq);\r\n allEvents.sort((a, b) => a.seq - b.seq);\r\n\r\n // Compute the next sequence numbers\r\n const nextSeq = allEvents.length > 0\r\n ? Math.max(...allEvents.map(e => e.seq)) + 1\r\n : 0;\r\n const nextSpanSeq = allSpans.length > 0\r\n ? Math.max(...allSpans.map(s => s.spanSeq)) + 1\r\n : 0;\r\n\r\n // Reconstruct the trace run\r\n // Note: We need to derive rollingHash from events if possible, but that would\r\n // require recomputing. For now, we store a placeholder and note that full\r\n // verification would need the original rollingHash.\r\n const privateRun: TraceRun = {\r\n id: manifest.runId,\r\n schemaVersion: manifest.formatVersion,\r\n agentId: manifest.agentId,\r\n status: manifest.publicView.status as \"running\" | \"completed\" | \"failed\" | \"cancelled\",\r\n startedAt: manifest.startedAt,\r\n endedAt: manifest.endedAt,\r\n durationMs: manifest.durationMs,\r\n events: allEvents,\r\n spans: allSpans,\r\n rollingHash: \"\", // Would need to be recomputed for full verification\r\n rootHash: manifest.rootHash,\r\n nextSeq,\r\n nextSpanSeq,\r\n };\r\n\r\n // Build the complete bundle\r\n const bundle: TraceBundle = {\r\n formatVersion: manifest.formatVersion,\r\n publicView: manifest.publicView,\r\n privateRun,\r\n merkleRoot: manifest.merkleRoot,\r\n rootHash: manifest.rootHash,\r\n };\r\n\r\n // Add manifestHash if present\r\n if (manifest.manifestHash !== undefined) {\r\n bundle.manifestHash = manifest.manifestHash;\r\n }\r\n\r\n return bundle;\r\n}\r\n\r\n// =============================================================================\r\n// CHUNK PATH UTILITIES\r\n// =============================================================================\r\n\r\n/**\r\n * Get the storage path for a chunk.\r\n *\r\n * Returns the relative path where the chunk should be stored.\r\n * The consumer is responsible for adding any compression suffix\r\n * (e.g., \".gz\" if compressed) and handling the actual storage.\r\n *\r\n * @param chunkInfo - Information about the chunk\r\n * @returns The relative storage path for the chunk\r\n *\r\n * @example\r\n * ```typescript\r\n * const path = getChunkPath(chunk.info);\r\n * // Returns: \"chunks/abc123...def.json\"\r\n *\r\n * // Consumer adds compression suffix if needed\r\n * const storagePath = chunk.info.compression === \"gzip\"\r\n * ? path + \".gz\"\r\n * : path;\r\n * ```\r\n */\r\nexport function getChunkPath(chunkInfo: ChunkInfo): string {\r\n return `chunks/${chunkInfo.hash}.json`;\r\n}\r\n\r\n// =============================================================================\r\n// CHUNK CONTENT PARSING\r\n// =============================================================================\r\n\r\n/**\r\n * Parse chunk content from JSON string.\r\n *\r\n * Parses the serialized chunk content and returns the spans and events\r\n * contained within. This function handles the internal chunk format.\r\n *\r\n * @param content - JSON string of chunk content\r\n * @returns Object containing spans and events arrays\r\n * @throws Error if content cannot be parsed or is malformed\r\n *\r\n * @example\r\n * ```typescript\r\n * const { spans, events } = parseChunkContent(chunk.content);\r\n * console.log(`Chunk contains ${spans.length} spans and ${events.length} events`);\r\n * ```\r\n */\r\nexport function parseChunkContent(content: string): { spans: TraceSpan[]; events: TraceEvent[] } {\r\n try {\r\n const parsed = JSON.parse(content) as unknown;\r\n\r\n // Validate parsed content has expected structure\r\n if (typeof parsed !== \"object\" || parsed === null) {\r\n throw new Error(\"Chunk content must be an object\");\r\n }\r\n\r\n const obj = parsed as Record<string, unknown>;\r\n\r\n if (!Array.isArray(obj.spans)) {\r\n throw new Error(\"Chunk content must have a 'spans' array\");\r\n }\r\n\r\n if (!Array.isArray(obj.events)) {\r\n throw new Error(\"Chunk content must have an 'events' array\");\r\n }\r\n\r\n // Type cast with validation\r\n const spans = obj.spans as TraceSpan[];\r\n const events = obj.events as TraceEvent[];\r\n\r\n // Basic validation of spans\r\n for (const span of spans) {\r\n if (typeof span.id !== \"string\" || typeof span.spanSeq !== \"number\") {\r\n throw new Error(\"Invalid span structure in chunk content\");\r\n }\r\n }\r\n\r\n // Basic validation of events\r\n for (const event of events) {\r\n if (typeof event.id !== \"string\" || typeof event.seq !== \"number\") {\r\n throw new Error(\"Invalid event structure in chunk content\");\r\n }\r\n }\r\n\r\n return { spans, events };\r\n } catch (error) {\r\n if (error instanceof SyntaxError) {\r\n throw new Error(`Invalid JSON in chunk content: ${error.message}`);\r\n }\r\n throw error;\r\n }\r\n}\r\n","/**\r\n * @summary Main entry point for @fluxpointstudios/orynq-sdk-process-trace package.\r\n *\r\n * This package provides cryptographic process tracing for Proof-of-Intent SDK.\r\n * It enables agents to create tamper-evident execution traces with:\r\n * - Rolling hash chains for event ordering verification\r\n * - Span-level Merkle trees for selective disclosure\r\n * - Public/private visibility controls for privacy-preserving audits\r\n *\r\n * Key features:\r\n * - TraceBuilder API for creating and managing trace runs\r\n * - Event and span hash computation with domain separation\r\n * - Bundle creation with cryptographic commitments\r\n * - Merkle proof generation for selective disclosure\r\n * - Signature support via pluggable providers\r\n *\r\n * Usage:\r\n * ```typescript\r\n * import {\r\n * createTrace,\r\n * addSpan,\r\n * addEvent,\r\n * closeSpan,\r\n * finalizeTrace,\r\n * } from \"@fluxpointstudios/orynq-sdk-process-trace\";\r\n *\r\n * const run = await createTrace({ agentId: \"agent-1\" });\r\n * const span = addSpan(run, { name: \"build-project\" });\r\n * await addEvent(run, span.id, { kind: \"command\", command: \"npm install\" });\r\n * await closeSpan(run, span.id);\r\n * const bundle = await finalizeTrace(run);\r\n * ```\r\n */\r\n\r\n// ---------------------------------------------------------------------------\r\n// Type Exports\r\n// ---------------------------------------------------------------------------\r\n\r\n// Visibility and common types\r\nexport type {\r\n Visibility,\r\n TraceStatus,\r\n SchemaVersion,\r\n} from \"./types.js\";\r\n\r\n// Event types\r\nexport type {\r\n BaseTraceEvent,\r\n CommandEvent,\r\n OutputEvent,\r\n DecisionEvent,\r\n ObservationEvent,\r\n ErrorTraceEvent,\r\n CustomEvent,\r\n TraceEvent,\r\n TraceEventKind,\r\n} from \"./types.js\";\r\n\r\nexport { DEFAULT_EVENT_VISIBILITY } from \"./types.js\";\r\n\r\n// Span types\r\nexport type { TraceSpan } from \"./types.js\";\r\n\r\n// Run types\r\nexport type {\r\n TraceRun,\r\n RollingHashState,\r\n} from \"./types.js\";\r\n\r\n// Merkle tree types\r\nexport type {\r\n TraceMerkleTree,\r\n MerkleProof,\r\n} from \"./types.js\";\r\n\r\n// Bundle types\r\nexport type {\r\n AnnotatedSpan,\r\n TraceBundlePublicView,\r\n TraceBundle,\r\n} from \"./types.js\";\r\n\r\n// Signature types\r\nexport type { SignatureProvider } from \"./types.js\";\r\n\r\n// Manifest and chunk types\r\nexport type {\r\n ChunkInfo,\r\n Chunk,\r\n TraceManifest,\r\n} from \"./types.js\";\r\n\r\n// Disclosure types\r\nexport type {\r\n DisclosureMode,\r\n DisclosureResult,\r\n} from \"./types.js\";\r\n\r\n// Disclosure request type (from disclosure module)\r\nexport type { DisclosureRequest } from \"./disclosure.js\";\r\n\r\n// Verification types\r\nexport type {\r\n TraceVerificationResult,\r\n ManifestVerificationResult,\r\n} from \"./types.js\";\r\n\r\n// Builder option types\r\nexport type {\r\n CreateTraceOptions,\r\n CreateSpanOptions,\r\n CreateManifestOptions,\r\n} from \"./types.js\";\r\n\r\n// Domain separation constants\r\nexport { HASH_DOMAIN_PREFIXES } from \"./types.js\";\r\nexport type { HashDomain } from \"./types.js\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Trace Builder Exports\r\n// ---------------------------------------------------------------------------\r\n\r\nexport {\r\n // Core builder functions\r\n createTrace,\r\n addSpan,\r\n addEvent,\r\n closeSpan,\r\n finalizeTrace,\r\n\r\n // Query functions\r\n getSpan,\r\n getSpanEvents,\r\n isFinalized,\r\n\r\n // Utility functions\r\n getEventCount,\r\n getSpanCount,\r\n getRootSpans,\r\n getChildSpans,\r\n getEvent,\r\n getEventsByKind,\r\n} from \"./trace-builder.js\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Rolling Hash Exports\r\n// ---------------------------------------------------------------------------\r\n\r\nexport {\r\n // Event hash computation\r\n computeEventHash,\r\n computeEventHashes,\r\n\r\n // Rolling hash state management\r\n initRollingHash,\r\n updateRollingHash,\r\n\r\n // Batch computation\r\n computeRollingHash,\r\n\r\n // Verification\r\n verifyRollingHash,\r\n\r\n // Root hash\r\n computeRootHash,\r\n\r\n // Testing utilities\r\n getGenesisHash,\r\n} from \"./rolling-hash.js\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Merkle Tree Exports\r\n// ---------------------------------------------------------------------------\r\n\r\nexport {\r\n // Span hash computation\r\n computeSpanHash,\r\n\r\n // Tree building\r\n buildSpanMerkleTree,\r\n\r\n // Proof generation and verification\r\n generateMerkleProof,\r\n verifyMerkleProof,\r\n verifySpanInclusion,\r\n} from \"./merkle.js\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Bundle Exports\r\n// ---------------------------------------------------------------------------\r\n\r\nexport {\r\n // Visibility helpers\r\n isPublicSpan,\r\n isPublicEvent,\r\n filterPublicEvents,\r\n\r\n // Bundle creation\r\n createBundle,\r\n\r\n // Public view extraction\r\n extractPublicView,\r\n\r\n // Bundle verification\r\n verifyBundle,\r\n\r\n // Bundle signing\r\n signBundle,\r\n verifyBundleSignature,\r\n\r\n // Utility functions\r\n getSpanEvents as getBundleSpanEvents,\r\n countEventsByVisibility,\r\n countSpansByVisibility,\r\n} from \"./bundle.js\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Disclosure Exports\r\n// ---------------------------------------------------------------------------\r\n\r\nexport {\r\n // Selective disclosure\r\n selectiveDisclose,\r\n\r\n // Verification\r\n verifyDisclosure,\r\n verifySpanDisclosure,\r\n\r\n // Utility functions\r\n canDisclose,\r\n getSpanIndex,\r\n createDisclosureRequest,\r\n} from \"./disclosure.js\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Manifest Exports\r\n// ---------------------------------------------------------------------------\r\n\r\nexport {\r\n // Manifest creation\r\n createManifest,\r\n\r\n // Manifest verification\r\n verifyManifest,\r\n\r\n // Manifest hash computation\r\n computeManifestHash,\r\n\r\n // Bundle reconstruction\r\n reconstructBundleFromManifest,\r\n\r\n // Chunk utilities\r\n getChunkPath,\r\n parseChunkContent,\r\n} from \"./manifest.js\";\r\n\r\n// ---------------------------------------------------------------------------\r\n// Version\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Package version.\r\n * Updated automatically during build.\r\n */\r\nexport const VERSION = \"0.1.0\";\r\n"]}
|