@aleutian/verification 0.0.0 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/errors.ts","../src/hash.ts","../src/tombstone.ts","../src/chain.ts","../src/anchorChainHash.ts","../src/fixtures/embedded-keys-dev.json","../src/fixtures/embedded-keys-staging.json","../src/fixtures/embedded-keys-prod.json","../src/keys.ts","../src/canonicalBase64.ts","../src/anchorCanonical.ts","../src/anchor.ts","../src/strictJson.ts","../src/strictText.ts","../src/anchorLoaders.ts","../src/chainV4.ts","../src/internal/constantTime.ts","../src/verify.ts","../src/manifestFreshness.ts","../src/processingMode.ts","../src/consent.ts","../src/consentRenderedHash.ts","../src/webhook.ts","../src/mldsa.ts","../src/keyId.ts","../src/sarEntries.ts","../src/captureEntryV3.ts","../src/canonicalV3.ts","../src/verifyV3.ts","../src/redactedView.ts","../src/tier2/index.ts","../src/tier2/errors.ts","../src/tier2/unseal.ts","../src/proofBundleReader.ts","../src/commitment.ts","../src/proofBundleHashes.ts","../src/sinkShapes.ts","../src/recordEnvelope.ts","../src/proofBundle.ts","../src/proofKeyFile.ts"],"names":["utf8ToBytes","bytesToHex","sha512","HEX_128","MAX_INT64","ml_dsa65","DECIMAL","LONE_SURROGATE","expectedHash","KNOWN_MODES","createHmac","timingSafeEqual","concat","RE_COMPANY_ID","RE_SHA512_HEX","ml_kem768","nacl","sha3_256","shake256","QUOTE","HEX_64","MAX_GLOBAL_SEQ","TIMESTAMP","MLDSA65_PUBLIC_KEY_SIZE","EMPTY_CONTEXT","MLDSA65_SIGNATURE_SIZE"],"mappings":"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","file":"index.cjs","sourcesContent":["// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Error thrown when anchor signature verification fails.\n */\nexport class AnchorVerificationError extends Error {\n override readonly name = \"AnchorVerificationError\";\n\n constructor(message: string) {\n super(message);\n // Maintains proper stack trace for where error was thrown (V8 only)\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, AnchorVerificationError);\n }\n }\n}\n\n/**\n * Error thrown when chain verification encounters an unrecoverable error.\n */\nexport class ChainVerificationError extends Error {\n override readonly name = \"ChainVerificationError\";\n\n constructor(message: string) {\n super(message);\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ChainVerificationError);\n }\n }\n}\n\n/**\n * Thrown when the text of an entries file is not entries (format-spec §11):\n * not JSON, an empty document, an export bundle, an anchor, or an entry with a\n * repeated, misspelled, missing or wrongly typed member.\n *\n * This is an ERROR, never a broken chain: a file that is not entries says\n * nothing about any chain. Messages name a member, never a value.\n */\nexport class EntriesFormatError extends Error {\n override readonly name = \"EntriesFormatError\";\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, EntriesFormatError.prototype);\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, EntriesFormatError);\n }\n }\n}\n\n/**\n * Error codes for webhook verification failures.\n */\nexport type WebhookErrorCode =\n | \"INVALID_FORMAT\"\n | \"INVALID_TIMESTAMP\"\n | \"EXPIRED\"\n | \"FUTURE\"\n | \"INVALID_SIGNATURE\"\n | \"NO_MATCHING_SECRET\"\n | \"SECRET_TOO_SHORT\";\n\n/**\n * Error thrown when webhook signature verification fails.\n */\nexport class WebhookVerificationError extends Error {\n override readonly name = \"WebhookVerificationError\";\n readonly code: WebhookErrorCode;\n\n constructor(code: WebhookErrorCode, message: string) {\n super(`[${code}] ${message}`);\n this.code = code;\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, WebhookVerificationError);\n }\n }\n}\n\n/**\n * Thrown when a ConsentChainEntry fails canonical field validation.\n *\n * Error messages include the field name but NEVER the field value, to prevent\n * log injection from caller-controlled content.\n */\nexport class InvalidConsentEntryError extends Error {\n override readonly name = \"InvalidConsentEntryError\";\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, InvalidConsentEntryError.prototype);\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, InvalidConsentEntryError);\n }\n }\n}\n\n/**\n * Thrown when consent chain entry verification fails for cryptographic reasons:\n * unknown key ID, wrong signature length, content hash mismatch, or failed\n * ML-DSA-65 verification.\n *\n * Error messages do not include signature bytes or key material.\n */\nexport class ConsentVerificationError extends Error {\n override readonly name = \"ConsentVerificationError\";\n\n constructor(message: string) {\n super(message);\n Object.setPrototypeOf(this, ConsentVerificationError.prototype);\n if (Error.captureStackTrace) {\n Error.captureStackTrace(this, ConsentVerificationError);\n }\n }\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * SHA-512 hash abstraction using WebCrypto (requires Node.js >= 19 or any modern browser).\n */\n\n/**\n * Convert a base64 string to Uint8Array.\n *\n * Works in both browser (atob) and Node.js (Buffer).\n *\n * @param base64 - Base64 encoded string\n * @returns Decoded bytes as Uint8Array\n */\nexport function base64ToUint8Array(base64: string): Uint8Array {\n if (typeof Buffer !== \"undefined\") {\n // Node.js\n return new Uint8Array(Buffer.from(base64, \"base64\"));\n } else {\n // Browser\n const binary = atob(base64);\n const bytes = new Uint8Array(binary.length);\n for (let i = 0; i < binary.length; i++) {\n bytes[i] = binary.charCodeAt(i);\n }\n return bytes;\n }\n}\n\n/**\n * Convert Uint8Array to base64 string.\n *\n * @param bytes - Bytes to encode\n * @returns Base64 encoded string\n */\nexport function uint8ArrayToBase64(bytes: Uint8Array): string {\n if (typeof Buffer !== \"undefined\") {\n // Node.js\n return Buffer.from(bytes).toString(\"base64\");\n } else {\n // Browser\n let binary = \"\";\n for (let i = 0; i < bytes.length; i++) {\n binary += String.fromCharCode(bytes[i]!);\n }\n return btoa(binary);\n }\n}\n\n/**\n * Convert Uint8Array to lowercase hex string.\n *\n * @param bytes - Bytes to encode\n * @returns Lowercase hex string\n */\nexport function uint8ArrayToHex(bytes: Uint8Array): string {\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Compute SHA-512 hash, returning lowercase hex string.\n *\n * Uses the WebCrypto API (globalThis.crypto.subtle), which is available\n * natively in all modern browsers and in Node.js >= 19 (without flags).\n * Node.js 20+ (LTS) is recommended. Node.js < 19 is not supported for\n * chain hash computation.\n *\n * This function is async because WebCrypto's `digest` is always async.\n * (Historical note: a sync `sha256Hex` predated the project-wide\n * SHA-256 → SHA-512 upgrade — see `dsar_chain_f_pre_js_webhook_sha512`\n * — and was removed; this is the only SHA hash entry point now.)\n *\n * @param data - String to hash (encoded as UTF-8)\n * @returns Promise resolving to 128-character lowercase hex string\n */\nexport async function sha512Hex(data: string): Promise<string> {\n const encoder = new TextEncoder();\n const bytes = encoder.encode(data);\n const hashBuffer = await crypto.subtle.digest(\"SHA-512\", bytes);\n return Array.from(new Uint8Array(hashBuffer))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Compute SHA-512 hash of raw bytes, returning lowercase hex string.\n *\n * Unlike {@link sha512Hex}, this function accepts a pre-built Uint8Array\n * directly. Use this when the preimage is already assembled as bytes —\n * avoids a string round-trip and correctly handles arbitrary binary data.\n *\n * @param data - Raw bytes to hash\n * @returns Promise resolving to 128-character lowercase hex string\n */\nexport async function sha512HexRaw(data: Uint8Array): Promise<string> {\n const hashBuffer = await crypto.subtle.digest(\"SHA-512\", data);\n return Array.from(new Uint8Array(hashBuffer))\n .map((b) => b.toString(16).padStart(2, \"0\"))\n .join(\"\");\n}\n\n/**\n * Convert hex string to Uint8Array.\n *\n * @param hex - Hex encoded string\n * @returns Decoded bytes as Uint8Array\n */\nexport function hexToUint8Array(hex: string): Uint8Array {\n const bytes = new Uint8Array(hex.length / 2);\n for (let i = 0; i < bytes.length; i++) {\n bytes[i] = parseInt(hex.slice(i * 2, i * 2 + 2), 16);\n }\n return bytes;\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Tombstone detection and validation for the Aleutian verification SDK.\n *\n * Tombstones are GDPR deletion markers that replace original entries while\n * preserving chain integrity. They have specific format requirements that\n * must be validated during chain verification.\n */\n\n/**\n * Prefix for tombstone content hashes.\n */\nexport const TOMBSTONE_CONTENT_HASH_PREFIX = \"TOMBSTONE:\";\n\n/**\n * Prefix for tombstone entry IDs.\n */\nexport const TOMBSTONE_ENTRY_ID_PREFIX = \"tomb_\";\n\n/**\n * Entry type value for tombstones.\n */\nexport const TOMBSTONE_ENTRY_TYPE = \"tombstone\";\n\n/**\n * Regex for validating tombstone content hash hex suffix.\n * Must be exactly 64 lowercase hex characters (32 random bytes, hex-encoded).\n */\nconst HEX_PATTERN = /^[0-9a-f]{64}$/;\n\n/**\n * Check if an entry is a tombstone based on entryType and entryId.\n *\n * Both conditions must be true:\n * - entryType === \"tombstone\"\n * - entryId starts with \"tomb_\"\n *\n * @param entryType - The entry's type field\n * @param entryId - The entry's ID field\n * @returns True if entry is a tombstone\n *\n * @example\n * ```typescript\n * if (isTombstone(entry.entryType, entry.entryId)) {\n * // Handle tombstone entry\n * }\n * ```\n */\nexport function isTombstone(entryType: string, entryId: string): boolean {\n return (\n entryType === TOMBSTONE_ENTRY_TYPE &&\n entryId.startsWith(TOMBSTONE_ENTRY_ID_PREFIX)\n );\n}\n\n/**\n * Check if a contentHash uses tombstone format (prefix check only).\n *\n * This is a lightweight check for hot paths. Use validateTombstoneContentHash\n * for full format validation.\n *\n * @param contentHash - The content hash to check\n * @returns True if content hash starts with \"TOMBSTONE:\"\n *\n * @example\n * ```typescript\n * if (isTombstoneContentHash(entry.contentHash)) {\n * // Content was deleted, original data not available\n * }\n * ```\n */\nexport function isTombstoneContentHash(contentHash: string): boolean {\n return contentHash.startsWith(TOMBSTONE_CONTENT_HASH_PREFIX);\n}\n\n/**\n * Fully validate tombstone content hash format.\n *\n * Valid format: \"TOMBSTONE:\" + 64 lowercase hex characters (32 random bytes)\n * Total length: 74 characters (10 prefix + 64 hex)\n *\n * @param contentHash - The content hash to validate\n * @returns True if format is valid\n *\n * @example\n * ```typescript\n * if (isTombstone(entry.entryType, entry.entryId)) {\n * if (!validateTombstoneContentHash(entry.contentHash)) {\n * // Invalid tombstone format - chain integrity issue\n * }\n * }\n * ```\n */\nexport function validateTombstoneContentHash(contentHash: string): boolean {\n // Total length: \"TOMBSTONE:\" (10) + 64 hex = 74\n if (contentHash.length !== 74) {\n return false;\n }\n if (!contentHash.startsWith(TOMBSTONE_CONTENT_HASH_PREFIX)) {\n return false;\n }\n const hexPart = contentHash.slice(10);\n return HEX_PATTERN.test(hexPart);\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Chain hash computation for the Aleutian verification SDK.\n *\n * Uses Aleutian's chain hash formula:\n * SHA512(\"aleutian.chain.v2:\" + prev + \"|\" + runID + \"|\" + seq + \"|\" + ts + \"|\" + content)\n *\n * Timestamp format: \"2006-01-02T15:04:05.000000Z\" (microsecond precision, 6 digits)\n *\n * NOTE: Unlike what the security review suggested (M-9), the Go SDK does NOT use\n * NFC normalization. This SDK matches Go behavior for cross-SDK compatibility.\n */\n\nimport { sha512Hex } from \"./hash.js\";\nimport { validateTombstoneContentHash } from \"./tombstone.js\";\n\n/**\n * Domain prefix for chain hash computation.\n * This provides domain separation for the hash function.\n */\nexport const CHAIN_HASH_PREFIX = \"aleutian.chain.v2:\";\n\n/**\n * Domain prefix for the v3 chain hash.\n *\n * The \":\" terminator separates the prefix from field data, which is\n * \"|\"-delimited.\n */\nexport const CHAIN_HASH_PREFIX_V3 = \"aleutian.chain.v3:\";\n\n/**\n * Chain hash format versions.\n *\n * An entry records WHICH preimage produced its hash, because the two cannot be\n * told apart by looking at the digest. A verifier that guesses is a verifier\n * that reports false breaks.\n *\n * ZERO MEANS V2, deliberately: every entry written before v3 existed has no\n * version field at all, and an absent field decodes as zero. Treating zero as\n * \"the format that was current when versions were not recorded\" is what keeps\n * those entries verifiable without rewriting them.\n */\nexport const FORMAT_V2 = 2;\nexport const FORMAT_V3 = 3;\n\n// A SHA-512 digest as format-spec §2.1 writes it: exactly 128 lowercase hex.\nconst HASH_HEX = /^[0-9a-f]{128}$/;\n// format-spec §4: UTC, exactly six fractional digits, \"Z\". ASCII digits only\n// (`\\d` would do, but the class says so outright).\nconst TIMESTAMP_FORM =\n /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})\\.[0-9]{6}Z$/;\n// global_seq is a signed 64-bit integer in every implementation (format-spec §2.1).\nconst MAX_GLOBAL_SEQ = 2n ** 63n - 1n;\n\n/**\n * Report whether a value is a SHA-512 digest as the format writes it: exactly\n * 128 lowercase hex characters (format-spec §1). Uppercase is invalid, not\n * equivalent.\n *\n * @param value - The value to check; anything but a string is not a digest\n * @returns True for exactly 128 lowercase hex characters\n */\nexport function isChainDigest(value: unknown): value is string {\n return typeof value === \"string\" && HASH_HEX.test(value);\n}\n\n/**\n * Report whether a stored timestamp is exactly the form the chain hash covers:\n * `YYYY-MM-DDTHH:MM:SS.ffffffZ` (format-spec §4), naming a real calendar\n * instant.\n *\n * Any other spelling of the same instant (an offset such as `+05:30`, no\n * fractional digits, three, or more than six, a lowercase `z`) is refused: the\n * hash covers one spelling, and a second one that hashed the same would be a\n * field an editor could change without detection.\n *\n * @param value - The stored timestamp; anything but a string is refused\n * @returns True only for the exact §4 form\n */\nexport function isChainTimestamp(value: unknown): value is string {\n if (typeof value !== \"string\") return false;\n const m = TIMESTAMP_FORM.exec(value);\n if (!m) return false;\n const year = Number(m[1]);\n const month = Number(m[2]);\n const day = Number(m[3]);\n if (month < 1 || month > 12 || day < 1) return false;\n const leap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n if (day > days[month - 1]!) return false;\n return Number(m[4]) <= 23 && Number(m[5]) <= 59 && Number(m[6]) <= 59;\n}\n\n/**\n * Map a stored format version onto a known format.\n *\n * Zero — an absent field on an entry written before versions were recorded —\n * means v2. Every other value is returned unchanged, INCLUDING unknown ones, so\n * a caller can reject them explicitly rather than have them quietly treated as\n * a format they are not.\n */\nexport function normalizeFormatVersion(version: number | undefined): number {\n return !version ? FORMAT_V2 : version;\n}\n\n/**\n * Compute the SHA-512 v3 chain hash for an entry.\n *\n * v3 exists to make a chain a property of its ENTRIES rather than of the API\n * calls that happened to create it:\n *\n * ```\n * v2 SHA512(\"aleutian.chain.v2:\" + prev + \"|\" + runID + \"|\" + seq + \"|\" + ts + \"|\" + content)\n * v3 SHA512(\"aleutian.chain.v3:\" + prev + \"|\" + globalSeq + \"|\" + ts + \"|\" + content)\n * ```\n *\n * v2 binds runId and a BATCH-LOCAL sequenceNum, so the same entries in the same\n * order hash differently depending on how they were grouped into append calls.\n * That makes a chain impossible to reconstruct from its entries alone, because\n * the batch boundaries are part of the artifact and are recorded nowhere. v3\n * binds globalSeq — the entry's chain-wide position, which v2 never hashed at\n * all — and is batch-independent.\n *\n * ## Why globalSeq accepts a bigint\n *\n * The format's sequence is a 64-bit integer, and JavaScript's `number` holds\n * only 53 bits exactly. `9007199254740993` — one of the reference\n * implementation's own test vectors — becomes `…992` as a literal AND through\n * `JSON.parse`. Passing a `number` above `Number.MAX_SAFE_INTEGER` therefore\n * throws rather than silently hashing a value that is not the one on the wire:\n * a wrong hash reported as a chain break is far worse than a refusal.\n *\n * @param previousHash - Previous entry's chain_hash, or \"\" for the first entry\n * @param globalSeq - The entry's chain-wide position. Pass a bigint beyond 2^53.\n * @param timestamp - RFC 3339 with microsecond precision, exactly as stored\n * @param contentHash - SHA-512 hex of content, or a tombstone content hash\n * @returns 128-character lowercase hex SHA-512 hash\n */\nexport async function computeChainHashV3(\n previousHash: string,\n globalSeq: number | bigint,\n timestamp: string,\n contentHash: string\n): Promise<string> {\n if (typeof globalSeq === \"number\") {\n if (!Number.isSafeInteger(globalSeq)) {\n throw new Error(\n `globalSeq ${globalSeq} is not a safe integer; pass a bigint for values ` +\n `beyond Number.MAX_SAFE_INTEGER — a rounded value would hash to a ` +\n `digest that is not this entry's`\n );\n }\n if (globalSeq < 0) {\n throw new Error(`globalSeq must be non-negative, got ${globalSeq}`);\n }\n } else if (globalSeq < 0n) {\n throw new Error(`globalSeq must be non-negative, got ${globalSeq}`);\n } else if (globalSeq > MAX_GLOBAL_SEQ) {\n throw new Error(`globalSeq must be at most 2^63 - 1, got ${globalSeq}`);\n }\n // format-spec §2.1 and §3: the preimage is \"|\"-delimited and NOT\n // self-delimiting. Every field but previous_hash has a fixed shape, and\n // previous_hash must be empty or one; a malformed field could shift a\n // boundary and make two different entries hash alike.\n if (previousHash !== \"\" && !HASH_HEX.test(previousHash)) {\n throw new Error(\"previousHash must be empty or exactly 128 lowercase hex characters\");\n }\n if (!isChainTimestamp(timestamp)) {\n throw new Error(\"timestamp must be YYYY-MM-DDTHH:MM:SS.ffffffZ (UTC, six digits)\");\n }\n if (!HASH_HEX.test(contentHash) && !validateTombstoneContentHash(contentHash)) {\n throw new Error(\n 'contentHash must be 128 lowercase hex characters, or a tombstone value (\"TOMBSTONE:\" + 64 lowercase hex)'\n );\n }\n\n const preimage =\n CHAIN_HASH_PREFIX_V3 +\n previousHash +\n \"|\" +\n globalSeq.toString() +\n \"|\" +\n timestamp +\n \"|\" +\n contentHash;\n\n return sha512Hex(preimage);\n}\n\n/**\n * Compute the SHA-512 chain hash for an entry.\n *\n * Uses Aleutian's chain hash formula with domain separation:\n * SHA512(\"aleutian.chain.v2:\" + prev + \"|\" + runID + \"|\" + seq + \"|\" + ts + \"|\" + content)\n *\n * @param previousHash - Previous entry's chain_hash (empty string for first in run)\n * @param runId - Batch run identifier\n * @param sequenceNum - 0-indexed position within batch\n * @param timestamp - Entry timestamp in ISO 8601 format with microsecond precision\n * @param contentHash - SHA-512 hex of content, or tombstone content hash\n * @returns Promise resolving to 128-character lowercase hex SHA-512 hash\n *\n * @example\n * ```typescript\n * const hash = await computeChainHash(\n * 'abc123...',\n * 'run_xyz',\n * 42,\n * '2026-01-20T15:30:00.123456Z',\n * 'def456...'\n * );\n * ```\n */\nexport async function computeChainHash(\n previousHash: string,\n runId: string,\n sequenceNum: number,\n timestamp: string,\n contentHash: string\n): Promise<string> {\n if (!Number.isSafeInteger(sequenceNum)) {\n throw new Error(`sequenceNum ${sequenceNum} exceeds Number.MAX_SAFE_INTEGER`);\n }\n // Build preimage with domain separation\n // No NFC normalization - matches Go SDK behavior\n const preimage =\n CHAIN_HASH_PREFIX +\n previousHash +\n \"|\" +\n runId +\n \"|\" +\n sequenceNum.toString() +\n \"|\" +\n timestamp +\n \"|\" +\n contentHash;\n\n return sha512Hex(preimage);\n}\n\n/**\n * Format a Unix millisecond timestamp as ISO 8601 with microsecond precision.\n *\n * Converts Unix milliseconds to the format: \"2006-01-02T15:04:05.000000Z\"\n * Since JavaScript Date only has millisecond precision, the last 3 digits\n * of the microseconds are always \"000\".\n *\n * @param timestampMs - Unix timestamp in milliseconds\n * @returns ISO 8601 string with 6-digit microseconds (last 3 always \"000\")\n */\nexport function formatTimestampMicro(timestampMs: number): string {\n const date = new Date(timestampMs);\n const iso = date.toISOString(); // \"2026-01-20T15:30:00.123Z\"\n // Replace \".123Z\" with \".123000Z\" for microsecond format\n return iso.replace(/\\.(\\d{3})Z$/, \".$1000Z\");\n}\n\n/**\n * Compute chain hash using Unix milliseconds timestamp.\n *\n * This is a convenience function that converts Unix milliseconds to\n * ISO 8601 format before computing the hash. Use this when you have\n * a numeric timestamp instead of a string.\n *\n * @param previousHash - Previous entry's chain_hash (empty string for first in run)\n * @param runId - Batch run identifier\n * @param sequenceNum - 0-indexed position within batch\n * @param timestampMs - Entry timestamp as Unix milliseconds. Sub-millisecond\n * precision is discarded. Always use `Date.now()` or `time.UnixMilli()` values\n * rather than dividing a nanosecond timestamp, which silently truncates and\n * produces a hash that won't match Go/Python.\n * @param contentHash - SHA-512 hex of content, or tombstone content hash\n * @returns Promise resolving to 128-character lowercase hex SHA-512 hash\n *\n * @example\n * ```typescript\n * const hash = await computeChainHashMs(\n * 'abc123...',\n * 'run_xyz',\n * 42,\n * 1706108400123,\n * 'def456...'\n * );\n * ```\n */\nexport async function computeChainHashMs(\n previousHash: string,\n runId: string,\n sequenceNum: number,\n timestampMs: number,\n contentHash: string\n): Promise<string> {\n const timestamp = formatTimestampMicro(timestampMs);\n return computeChainHash(previousHash, runId, sequenceNum, timestamp, contentHash);\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Anchor-of-anchors chain hash (anchor.v2 domain).\n *\n * The audit chain uses TWO distinct SHA-512 domain separators:\n *\n * - `\"aleutian.chain.v2:\"` — per-entry chain links (see `chain.ts`).\n * Stored in `audit_entries.chain_hash`.\n * - `\"aleutian.anchor.v2:\"` — anchor-of-anchors chain (this file).\n * Stored in `anchors.chain_hash`. Binds an\n * anchor to its tip entry AND to the previous\n * anchor.\n *\n * An anchor's `chain_hash` is NOT the tip entry's `chain_hash` — it is a\n * domain-separated SHA-512 over (previousAnchorHash, companyID,\n * startEntryID, endEntryID, tipChainHash). Verifiers MUST recompute this\n * and compare; do not assume byte-equality with the tip entry's hash.\n *\n * Byte-identical to the Go SDK `ComputeAnchorChainHash` at\n * `sdk/verification-go/anchor_chain_hash.go`, the Python SDK\n * `compute_anchor_chain_hash`, and the producer at\n * `internal/chainlinker/anchor_generator.go`.\n *\n * @module\n */\n\nimport { sha512 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex, utf8ToBytes } from \"@noble/hashes/utils.js\";\n\nimport { sha512Hex } from \"./hash.js\";\n\n/**\n * SHA-512 domain separator for the anchor-of-anchors chain.\n * Must be byte-identical across Go/Python/JS SDKs.\n */\nexport const ANCHOR_CHAIN_DOMAIN_V2 = \"aleutian.anchor.v2:\";\n\n/**\n * Genesis previousAnchorHash used for the very first anchor in a\n * company's chain. Computed as `SHA-512(\"aleutian.anchor.seed.v2\")`.\n *\n * Byte-identical to the producer constant at\n * `internal/storage/verification_types.go` and the other SDK constants.\n */\nexport const SEED_ANCHOR_HASH =\n \"03443d96d3b369839f63f98b712463efba04c00551822743108d60c5f291627859\" +\n \"ff0b7dc29f99e3c847b07b0b18bb385426c744847c1b070563f8dd07271f27\";\n\n/**\n * Sentinel `previousAnchorId` value indicating a genesis anchor.\n */\nexport const SEED_ANCHOR_ID = \"anchor_00000000-0000-0000-0000-000000000000\";\n\n/**\n * Bind an anchor to its tip entry and prior anchor.\n *\n * Returns a Promise resolving to the hex-encoded SHA-512 digest over a\n * domain-separated, pipe-delimited concatenation of the inputs.\n * Byte-identical to the Go SDK `ComputeAnchorChainHash` and the producer\n * at `internal/chainlinker/anchor_generator.go`.\n *\n * Async because the JS SDK uses WebCrypto (`crypto.subtle.digest`), which\n * is always async — same pattern as `computeChainHash`.\n *\n * @param previousAnchorHash - The prior anchor's `chain_hash`, or\n * {@link SEED_ANCHOR_HASH} for a genesis anchor\n * (`previousAnchorId === SEED_ANCHOR_ID`).\n * @param companyId - The `company_id` field of the anchor being computed.\n * @param startEntryId - `anchor.range.startEntryId`.\n * @param endEntryId - `anchor.range.endEntryId`.\n * @param tipChainHash - The chain_hash of the entry identified by\n * `endEntryId`, as computed by walking the per-entry chain (NOT the\n * stored value if verifying potentially-tampered data — the verifier\n * walks and recomputes).\n * @returns Promise resolving to hex-encoded 128-char SHA-512 digest.\n */\nexport async function computeAnchorChainHash(\n previousAnchorHash: string,\n companyId: string,\n startEntryId: string,\n endEntryId: string,\n tipChainHash: string,\n): Promise<string> {\n const preimage =\n ANCHOR_CHAIN_DOMAIN_V2 +\n previousAnchorHash +\n \"|\" +\n companyId +\n \"|\" +\n startEntryId +\n \"|\" +\n endEntryId +\n \"|\" +\n tipChainHash;\n return sha512Hex(preimage);\n}\n\n/**\n * SHA-512 domain separator for the v7 anchor chain hash (format-spec §9.4).\n */\nexport const ANCHOR_CHAIN_DOMAIN_V7 = \"aleutian.anchor.v7:\";\n\nconst HEX_128 = /^[0-9a-f]{128}$/;\nconst DECIMAL = /^(0|[1-9][0-9]*)$/;\nconst MAX_INT64 = 2n ** 63n - 1n;\n\n/** A sequence number in format-spec §2.1's decimal grammar, as text. */\nfunction seqText(v: bigint | number | string, field: string): string {\n const s = typeof v === \"number\" && Number.isSafeInteger(v) ? String(v) : typeof v === \"bigint\" ? v.toString() : v;\n if (typeof s !== \"string\" || !DECIMAL.test(s) || s.length > 19 || BigInt(s) > MAX_INT64) {\n throw new Error(`${field} must be an integer from 0 to 2^63 - 1 (a bigint or decimal string beyond 2^53)`);\n }\n return s;\n}\n\n/**\n * The v7 anchor chain hash over fields already checked, synchronously.\n *\n * @internal Validates nothing; see {@link computeAnchorChainHashV7}.\n */\nexport function anchorChainHashV7Sync(\n previousAnchorHash: string,\n subject: string,\n startSeq: string,\n endSeq: string,\n tipChainHash: string\n): string {\n const subjectBytes = utf8ToBytes(subject);\n const head = utf8ToBytes(ANCHOR_CHAIN_DOMAIN_V7 + previousAnchorHash + \"|\");\n const tail = utf8ToBytes(\"|\" + startSeq + \"|\" + endSeq + \"|\" + tipChainHash);\n const n = subjectBytes.length;\n const out = new Uint8Array(head.length + 4 + n + tail.length);\n out.set(head, 0);\n out.set([(n >>> 24) & 0xff, (n >>> 16) & 0xff, (n >>> 8) & 0xff, n & 0xff], head.length);\n out.set(subjectBytes, head.length + 4);\n out.set(tail, head.length + 4 + n);\n return bytesToHex(sha512(out));\n}\n\n/**\n * Compute a v7 anchor's chain hash (format-spec §9.4).\n *\n * # Description\n *\n * `SHA-512(\"aleutian.anchor.v7:\" ‖ previous_anchor_hash ‖ \"|\" ‖ len(subject)\n * ‖ subject ‖ \"|\" ‖ start_seq ‖ \"|\" ‖ end_seq ‖ \"|\" ‖ tip_chain_hash)`, `len`\n * a 4-byte big-endian byte count. The subject is hashed as its UTF-8 bytes,\n * never normalised, and is length-prefixed, so it may contain `|`.\n *\n * Unlike v1-v6, the range is named by sequence: erasing any entry of it (v4,\n * format-spec §5.0) changes nothing this hash covers.\n *\n * # Inputs\n *\n * - previousAnchorHash: the anchor's own `previous_anchor_hash` (the\n * previous anchor's chain hash, or {@link SEED_ANCHOR_HASH}); 128 hex\n * - subject: the anchor's subject, non-empty\n * - startSeq, endSeq: the range, 0 to 2^63 - 1, as bigint, safe number or\n * decimal text\n * - tipChainHash: the chain hash of the entry at `endSeq`; 128 hex\n *\n * # Outputs\n *\n * - Promise<string>: 128 lowercase hex\n * - Error: thrown (as a rejection) when an input is malformed\n *\n * # Example\n *\n * const h = await computeAnchorChainHashV7(SEED_ANCHOR_HASH, \"orders\", 0n, 2n, tip);\n *\n * # Limitations\n *\n * - Not a bind: compare the result with the anchor's `chainHash`.\n *\n * # Assumptions\n *\n * - None.\n */\nexport function computeAnchorChainHashV7(\n previousAnchorHash: string,\n subject: string,\n startSeq: bigint | number | string,\n endSeq: bigint | number | string,\n tipChainHash: string\n): Promise<string> {\n // The executor's throw becomes the rejection.\n return new Promise((resolve) =>\n resolve(anchorChainHashV7Checked(previousAnchorHash, subject, startSeq, endSeq, tipChainHash))\n );\n}\n\nfunction anchorChainHashV7Checked(\n previousAnchorHash: string,\n subject: string,\n startSeq: bigint | number | string,\n endSeq: bigint | number | string,\n tipChainHash: string\n): string {\n if (typeof previousAnchorHash !== \"string\" || !HEX_128.test(previousAnchorHash)) {\n throw new Error(\"previousAnchorHash must be exactly 128 lowercase hex characters\");\n }\n if (typeof subject !== \"string\" || subject === \"\") {\n throw new Error(\"subject must be a non-empty string\");\n }\n if (typeof tipChainHash !== \"string\" || !HEX_128.test(tipChainHash)) {\n throw new Error(\"tipChainHash must be exactly 128 lowercase hex characters\");\n }\n return anchorChainHashV7Sync(\n previousAnchorHash,\n subject,\n seqText(startSeq, \"startSeq\"),\n seqText(endSeq, \"endSeq\"),\n tipChainHash\n );\n}\n","{\n \"aleutian-ml-dsa-65-2026-v1\": \"MIIHsjALBglghkgBZQMEAxIDggehAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\n \"aleutian-ml-dsa-65-2025-v1\": \"MIIHsjALBglghkgBZQMEAxIDggehAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"\n}\n","{\n \"aleutian-ml-dsa-65-2026-v1\": \"MIIHsjALBglghkgBZQMEAxIDggehAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\n \"aleutian-ml-dsa-65-2025-v1\": \"MIIHsjALBglghkgBZQMEAxIDggehAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"\n}\n","{\n \"aleutian-ml-dsa-65-2026-v1\": \"MIIHsjALBglghkgBZQMEAxIDggehAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\",\n \"aleutian-ml-dsa-65-2025-v1\": \"MIIHsjALBglghkgBZQMEAxIDggehAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA\"\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Embedded ML-DSA-65 public keys for offline anchor verification.\n *\n * Keys are stored as SubjectPublicKeyInfo (SPKI) DER base64, matching the\n * format returned by Cloud KMS. On load, the raw 1952-byte key is extracted.\n *\n * Key rotation schedule:\n * - New keys are generated annually\n * - Old keys remain valid for 90 days after rotation\n * - SDK releases bundle current + previous key\n */\n\nimport { base64ToUint8Array } from \"./hash.js\";\n\n/** ML-DSA-65 raw public key size per FIPS 204. */\nexport const MLDSA_PUB_KEY_SIZE = 1952;\n\n/**\n * URL for fetching current public keys from Aleutian's servers.\n *\n * This endpoint can be used to:\n * 1. Check for key revocations\n * 2. Fetch newly rotated keys before SDK updates\n * 3. Verify embedded keys match server-side keys\n *\n * For fully offline verification, use the embedded keys instead.\n */\nexport const PUBLIC_KEYS_ENDPOINT =\n \"https://keys.aleutian.ai/.well-known/anchor-signing-keys.json\";\n\n/**\n * Parse DER length encoding, returning [length, newOffset].\n *\n * RS-1: Bounds-checks all byte accesses to prevent out-of-bounds reads\n * on truncated or malformed DER input.\n */\nfunction readDerLength(data: Uint8Array, offset: number): [number, number] {\n if (offset >= data.length) {\n throw new Error(\"DER: unexpected end of data\");\n }\n const b = data[offset]!;\n offset += 1;\n if (b < 0x80) {\n return [b, offset];\n }\n const numBytes = b & 0x7f;\n if (offset + numBytes > data.length) {\n throw new Error(\"DER: length encoding truncated\");\n }\n let length = 0;\n for (let i = 0; i < numBytes; i++) {\n length = (length << 8) | data[offset]!;\n offset += 1;\n }\n return [length, offset];\n}\n\n/**\n * Decode a SubjectPublicKeyInfo (SPKI) DER base64 ML-DSA-65 public key\n * to raw 1952 bytes.\n *\n * SPKI structure: SEQUENCE { AlgorithmIdentifier SEQUENCE, BIT STRING }\n * The BIT STRING contains: 0x00 (unused bits) + raw 1952-byte key.\n */\nfunction decodeSpkiDer(keyB64: string): Uint8Array {\n const der = base64ToUint8Array(keyB64);\n\n if (der.length < MLDSA_PUB_KEY_SIZE + 20) {\n throw new Error(`Invalid SPKI DER: too short (${der.length} bytes)`);\n }\n\n let pos = 0;\n\n // Skip outer SEQUENCE tag (0x30)\n if (der[pos] !== 0x30) {\n throw new Error(\"Invalid SPKI: expected SEQUENCE tag\");\n }\n pos += 1;\n\n // CR-2: Validate outer SEQUENCE length so truncated DER is caught early.\n const [outerLen, contentStart] = readDerLength(der, pos);\n if (contentStart + outerLen > der.length) {\n throw new Error(\"SPKI DER: outer SEQUENCE truncated\");\n }\n pos = contentStart;\n\n // Skip AlgorithmIdentifier SEQUENCE\n if (der[pos] !== 0x30) {\n throw new Error(\"Invalid SPKI: expected AlgorithmIdentifier SEQUENCE\");\n }\n pos += 1;\n const [algLen, algContentStart] = readDerLength(der, pos);\n pos = algContentStart + algLen;\n\n // Read BIT STRING tag (0x03)\n if (der[pos] !== 0x03) {\n throw new Error(\"Invalid SPKI: expected BIT STRING tag\");\n }\n pos += 1;\n const [bitStringLen, bitStringStart] = readDerLength(der, pos);\n pos = bitStringStart;\n\n // First byte of BIT STRING is unused-bits count (must be 0x00 for keys)\n if (der[pos] !== 0x00) {\n throw new Error(\"Invalid SPKI BIT STRING: non-zero unused bits\");\n }\n pos += 1;\n\n const raw = der.slice(pos, pos + bitStringLen - 1);\n if (raw.length !== MLDSA_PUB_KEY_SIZE) {\n throw new Error(\n `Invalid ML-DSA-65 key size: got ${raw.length} bytes, want ${MLDSA_PUB_KEY_SIZE}`\n );\n }\n return raw;\n}\n\n// Embedded ML-DSA-65 public keys as SPKI DER base64.\n//\n// # Pinning strategy (15n_fix_A4, 2026-05-17)\n//\n// Keys are loaded at module-import time from a per-env JSON fixture file\n// under src/fixtures/. Selection is by the ALEUTIAN_ENV environment\n// variable at process start (defaults to \"dev\").\n//\n// All three env fixtures are statically imported so a bundler that\n// tree-shakes unused branches still keeps the env-selection logic\n// intact. Per-env wheel artifacts (single-fixture bundles) would require\n// build-time customisation — out of scope for v1.\n//\n// # Bootstrap (15n_fix_A4 ceremony)\n//\n// The fixture files ship with all-zero placeholder data. Step 3 of the\n// ceremony overwrites them with real KMS-exported SPKI-DER-base64 entries.\n\nimport devFixture from \"./fixtures/embedded-keys-dev.json\" with { type: \"json\" };\nimport stagingFixture from \"./fixtures/embedded-keys-staging.json\" with { type: \"json\" };\nimport prodFixture from \"./fixtures/embedded-keys-prod.json\" with { type: \"json\" };\n\nfunction loadFixture(): Record<string, string> {\n // process.env is only available in Node-like runtimes; browsers\n // default to dev.\n const env =\n typeof process !== \"undefined\" && process.env && process.env.ALEUTIAN_ENV\n ? process.env.ALEUTIAN_ENV\n : \"dev\";\n switch (env) {\n case \"prod\":\n return prodFixture as Record<string, string>;\n case \"staging\":\n return stagingFixture as Record<string, string>;\n default:\n return devFixture as Record<string, string>;\n }\n}\n\nconst _EMBEDDED_PUBLIC_KEYS_B64: ReadonlyMap<string, string> = new Map(\n Object.entries(loadFixture())\n);\n\n\n/**\n * Embedded ML-DSA-65 public keys for offline anchor verification.\n *\n * Keys are raw 1952-byte Uint8Arrays, decoded from SPKI DER at load time.\n */\nexport const EMBEDDED_PUBLIC_KEYS: ReadonlyMap<string, Uint8Array> = new Map(\n Array.from(_EMBEDDED_PUBLIC_KEYS_B64.entries()).map(([id, b64]) => [\n id,\n decodeSpkiDer(b64),\n ])\n);\n\n/**\n * Get an embedded public key by ID.\n *\n * @param keyId - The key identifier from anchor.signature.publicKeyId\n * @returns The raw 1952-byte ML-DSA-65 public key bytes\n * @throws Error if key ID is not found in embedded keys\n */\nexport function getPublicKey(keyId: string): Uint8Array {\n const key = EMBEDDED_PUBLIC_KEYS.get(keyId);\n if (!key) {\n throw new Error(`Unknown public key ID: ${keyId}`);\n }\n // Defensive copy: callers must not be able to mutate the embedded\n // public key bytes. Mirrors V3 H6 (trust manifest immutability).\n // Ticket: dsar_js_trust_manifest_key_mutability.\n return new Uint8Array(key);\n}\n\n/**\n * Check if a key ID is known (exists in embedded keys).\n *\n * @param keyId - The key identifier to check\n * @returns True if the key ID is known\n */\nexport function isKnownKey(keyId: string): boolean {\n return EMBEDDED_PUBLIC_KEYS.has(keyId);\n}\n\n/**\n * List all known key IDs.\n *\n * @returns Array of key IDs sorted alphabetically\n */\nexport function listKeyIds(): string[] {\n return Array.from(EMBEDDED_PUBLIC_KEYS.keys()).sort();\n}\n\n/**\n * SC-1: Validate that no embedded key is an all-zero development placeholder.\n *\n * Production deployments MUST call this function at startup and handle the\n * thrown error (e.g., fail fast before serving traffic). The embedded keys\n * in this SDK release are development placeholders and MUST be replaced with\n * real keys before production use.\n *\n * @throws Error if any embedded key consists entirely of zero bytes\n */\nexport function validateEmbeddedKeys(): void {\n for (const [id, key] of EMBEDDED_PUBLIC_KEYS.entries()) {\n if (key.every((b) => b === 0)) {\n throw new Error(\n `Embedded key \"${id}\" is a development placeholder (all-zero bytes). ` +\n \"Replace with a real ML-DSA-65 public key before production use.\"\n );\n }\n }\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Strict decoding of CANONICAL base64 (bundle-format §3).\n *\n * Canonical means the standard alphabet with padding (RFC 4648 §4), no\n * whitespace, and the unused bits of the last character zero. Exactly one text\n * decodes to any given bytes, so a value that is not canonical is refused here\n * rather than \"repaired\" by a lenient decoder (`atob`, `Buffer.from`), which\n * would accept several spellings of one value.\n *\n * Browser-safe: no Node APIs.\n */\n\nconst ALPHABET = \"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/\";\n\nconst DECODE: Int16Array = (() => {\n const table = new Int16Array(128).fill(-1);\n for (let i = 0; i < ALPHABET.length; i++) table[ALPHABET.charCodeAt(i)] = i;\n return table;\n})();\n\nfunction sextet(code: number): number {\n return code < 128 ? DECODE[code]! : -1;\n}\n\n/**\n * Decode canonical base64, or return null when the text is not canonical.\n *\n * # Description\n *\n * Accepts only the standard alphabet, with `=` padding to a multiple of four\n * characters, no whitespace, and zero unused bits in the last character. The\n * empty string decodes to zero bytes.\n *\n * # Inputs\n *\n * - text: the base64 text to decode\n *\n * # Outputs\n *\n * - Uint8Array: the decoded bytes, or null when `text` is not canonical\n *\n * # Example\n *\n * decodeCanonicalBase64(\"YQ==\") // Uint8Array [0x61]\n * decodeCanonicalBase64(\"YR==\") // null: unused bits not zero\n *\n * # Limitations\n *\n * - Never throws; the caller decides what a refusal means.\n *\n * # Assumptions\n *\n * - None.\n */\nexport function decodeCanonicalBase64(text: string): Uint8Array | null {\n const len = text.length;\n if (len % 4 !== 0) return null;\n if (len === 0) return new Uint8Array(0);\n\n let pad = 0;\n if (text.charCodeAt(len - 1) === 0x3d) pad = text.charCodeAt(len - 2) === 0x3d ? 2 : 1;\n const out = new Uint8Array((len / 4) * 3 - pad);\n\n let o = 0;\n for (let i = 0; i < len; i += 4) {\n const last = i + 4 === len;\n const a = sextet(text.charCodeAt(i));\n const b = sextet(text.charCodeAt(i + 1));\n if (a < 0 || b < 0) return null;\n if (last && pad === 2) {\n if ((b & 0x0f) !== 0) return null;\n out[o++] = (a << 2) | (b >> 4);\n break;\n }\n const c = sextet(text.charCodeAt(i + 2));\n if (c < 0) return null;\n if (last && pad === 1) {\n if ((c & 0x03) !== 0) return null;\n out[o++] = (a << 2) | (b >> 4);\n out[o++] = ((b & 0x0f) << 4) | (c >> 2);\n break;\n }\n const d = sextet(text.charCodeAt(i + 3));\n if (d < 0) return null;\n out[o++] = (a << 2) | (b >> 4);\n out[o++] = ((b & 0x0f) << 4) | (c >> 2);\n out[o++] = ((c & 0x03) << 6) | d;\n }\n return out;\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Anchor canonical bytes that need no keys (format-spec §9.2): the v6 form,\n * and the string and int64 encoders every version's form uses.\n *\n * Split out of `anchor.ts` so a module that only canonicalizes (the proof\n * bundle verifier) does not import `keys.ts` and its embedded key fixtures,\n * which would otherwise land in browser bundles. `anchor.ts` re-exports\n * `canonicalizeAnchorV6`, so its public API is unchanged.\n */\n\nimport { SEED_ANCHOR_HASH, SEED_ANCHOR_ID } from \"./anchorChainHash.js\";\nimport { AnchorVerificationError } from \"./errors.js\";\nimport type { Anchor } from \"./types.js\";\n\n/**\n * The ML-DSA context a v7 anchor signature is made with (format-spec §9.5).\n * v1-v6 use the empty context.\n */\nexport const ANCHOR_SIGNATURE_CONTEXT_V7 = \"aleutian.proof.anchor.v7\";\n\nconst HEX_128 = /^[0-9a-f]{128}$/;\nconst LONE_SURROGATE =\n /[\\ud800-\\udbff](?![\\udc00-\\udfff])|(?<![\\ud800-\\udbff])[\\udc00-\\udfff]/g;\n// The same, for a test: a /g regex keeps its lastIndex between calls.\nconst HAS_LONE_SURROGATE = new RegExp(LONE_SURROGATE.source);\n\n/**\n * Encode an `bigint | number` int64 field as a bare decimal token\n * suitable for direct concatenation into canonical JSON.\n *\n * `JSON.stringify` does NOT support `bigint` (throws TypeError) and\n * `Number.toString` silently truncates integers above\n * `Number.MAX_SAFE_INTEGER`. We accept either input, validate that\n * `number` inputs are safe integers, and emit the raw decimal text.\n *\n * Ticket: dsar_js_anchor_int64_widening.\n *\n * @internal\n */\nexport function encodeInt64Token(v: bigint | number): string {\n if (typeof v === \"bigint\") {\n return v.toString();\n }\n if (!Number.isFinite(v) || !Number.isInteger(v)) {\n throw new AnchorVerificationError(\n \"anchor int64 field: number must be a finite integer\"\n );\n }\n if (!Number.isSafeInteger(v)) {\n throw new AnchorVerificationError(\n \"anchor int64 field: number exceeds Number.MAX_SAFE_INTEGER; pass as bigint to avoid precision loss\"\n );\n }\n return v.toString();\n}\n\n/** Read an anchor int64 field exactly, or refuse the anchor. */\nfunction anchorInteger(v: unknown): bigint {\n if (typeof v === \"bigint\") return v;\n if (typeof v === \"number\" && Number.isSafeInteger(v)) return BigInt(v);\n throw new AnchorVerificationError(\n \"anchor int64 field: must be an integer (a bigint beyond Number.MAX_SAFE_INTEGER)\"\n );\n}\n\n/**\n * Refuse a malformed anchor (format-spec §9.3 and §9.8).\n *\n * # Description\n *\n * Checks what an anchor must satisfy before its canonical form is built or it\n * is bound to a chain:\n *\n * - `version` is 1, 2, 3, 4, 6 or 7. Version 5 is withdrawn and is refused\n * by name; any other version is refused, never treated as the closest form.\n * - v7 (§9.3, §9.8): a non-empty `subject`, `anchorId` and\n * `previousAnchorId`, each valid UTF-8 (no lone surrogate) as is\n * `signingKeyId`; `range.startSeq` and\n * `range.endSeq` integers from 0 to 2^63 - 1 with `startSeq <= endSeq`;\n * `entryCount = endSeq - startSeq + 1`; `previousAnchorHash` 128 lowercase\n * hex; `previousAnchorId` is the seed id exactly when `previousAnchorHash`\n * is the seed hash; `chainHash` 128 lowercase hex; `createdAtMs >= 0`; no\n * `verifiedThrough` and no entry-id range. v1-v6 carry no\n * `previousAnchorHash` and no sequence range.\n * - version invariants (§9.3): v1-v3 carry `verifiedThrough` 0; v4 and v6\n * carry it positive; v6 carries a non-empty `subject`.\n * - counts, v4 and v6 (§9.8): `entryCount >= 1`,\n * `0 < verifiedThrough <= entryCount`, `createdAtMs >= 0`.\n * - `signingKeyId` is not empty (§9.8).\n *\n * `version` is inside the signed bytes, so an anchor that breaks these carries\n * a valid signature over malformed content. That is reported as malformed, not\n * as tampering, and never as a bind outcome.\n *\n * # Inputs\n *\n * - anchor: The anchor to check\n *\n * # Outputs\n *\n * - void: Returns normally when the anchor is well formed\n * - AnchorVerificationError: Thrown otherwise. Messages name a field, never\n * its value.\n *\n * # Example\n *\n * checkAnchorWellFormed(parseAnchorText(text));\n *\n * # Limitations\n *\n * - Checks neither the signature nor the binding to a chain.\n *\n * # Assumptions\n *\n * - None.\n */\nexport function checkAnchorWellFormed(anchor: Anchor): void {\n const version: unknown = anchor.version;\n if (typeof version !== \"number\" || !Number.isInteger(version)) {\n throw new AnchorVerificationError(\"anchor version must be an integer\");\n }\n if (version === 5) {\n throw new AnchorVerificationError(\n \"unsupported anchor version: 5 is withdrawn and has no canonical form\"\n );\n }\n if (version < 1 || version > 7) {\n throw new AnchorVerificationError(\"unsupported anchor version\");\n }\n if (version === 7) {\n checkAnchorV7WellFormed(anchor);\n return;\n }\n // §9.8, the wrong range shape: a v1-v6 anchor names its range by entry id.\n if (\n anchor.range?.startSeq !== undefined ||\n anchor.range?.endSeq !== undefined ||\n anchor.previousAnchorHash !== undefined\n ) {\n throw new AnchorVerificationError(\n `Version=${version} anchor must not carry previous_anchor_hash, start_seq or end_seq`\n );\n }\n // Normalize to bigint so number-vs-bigint comparisons are well-defined\n // (strict `!== 0` would always be true for `0n`).\n const verifiedThrough = anchorInteger(anchor.verifiedThrough ?? 0);\n const entryCount = anchorInteger(anchor.entryCount);\n const createdAtMs = anchorInteger(anchor.createdAtMs);\n\n if (version <= 3) {\n if (verifiedThrough !== 0n) {\n throw new AnchorVerificationError(\n \"Version<=3 anchor must have verified_through=0\"\n );\n }\n } else {\n if (verifiedThrough <= 0n) {\n throw new AnchorVerificationError(\n `Version=${version} anchor must have positive verified_through`\n );\n }\n if (version === 6 && !anchor.subject) {\n // The subject is the replay protection: an anchor that does not commit to\n // one could be presented against another chain.\n throw new AnchorVerificationError(\n \"Version=6 anchor must have a non-empty subject\"\n );\n }\n if (entryCount < 1n) {\n throw new AnchorVerificationError(\"anchor entry_count must be at least 1\");\n }\n if (verifiedThrough > entryCount) {\n throw new AnchorVerificationError(\n \"anchor verified_through must not exceed entry_count\"\n );\n }\n if (createdAtMs < 0n) {\n throw new AnchorVerificationError(\"anchor created_at_ms must not be negative\");\n }\n }\n\n if (typeof anchor.signingKeyId !== \"string\" || anchor.signingKeyId === \"\") {\n throw new AnchorVerificationError(\"anchor signing_key_id must not be empty\");\n }\n}\n\nconst MAX_INT64 = 2n ** 63n - 1n;\n\n/** The v7 rules of format-spec §9.3 and §9.8. */\nfunction checkAnchorV7WellFormed(anchor: Anchor): void {\n if (typeof anchor.subject !== \"string\" || anchor.subject === \"\") {\n throw new AnchorVerificationError(\"Version=7 anchor must have a non-empty subject\");\n }\n if (typeof anchor.anchorId !== \"string\" || anchor.anchorId === \"\") {\n throw new AnchorVerificationError(\"Version=7 anchor must have a non-empty anchor_id\");\n }\n if (typeof anchor.previousAnchorId !== \"string\" || anchor.previousAnchorId === \"\") {\n throw new AnchorVerificationError(\n \"Version=7 anchor must have a non-empty previous_anchor_id\"\n );\n }\n // §9.3: these strings are signed and hashed as UTF-8. A lone surrogate has\n // no UTF-8 form, so the bytes signed would not be the string held.\n for (const [name, value] of [\n [\"subject\", anchor.subject],\n [\"anchor_id\", anchor.anchorId],\n [\"previous_anchor_id\", anchor.previousAnchorId],\n [\"signing_key_id\", anchor.signingKeyId],\n ] as const) {\n if (typeof value === \"string\" && HAS_LONE_SURROGATE.test(value)) {\n throw new AnchorVerificationError(`Version=7 anchor ${name} must be valid UTF-8`);\n }\n }\n if (anchor.range === undefined || anchor.range.startSeq === undefined || anchor.range.endSeq === undefined) {\n throw new AnchorVerificationError(\"Version=7 anchor must name its range by start_seq and end_seq\");\n }\n if (anchor.range.startEntryId || anchor.range.endEntryId) {\n throw new AnchorVerificationError(\"Version=7 anchor must not name its range by entry id\");\n }\n if (anchor.verifiedThrough !== undefined && anchorInteger(anchor.verifiedThrough) !== 0n) {\n throw new AnchorVerificationError(\"Version=7 anchor has no verified_through\");\n }\n const start = anchorInteger(anchor.range.startSeq);\n const end = anchorInteger(anchor.range.endSeq);\n const count = anchorInteger(anchor.entryCount);\n for (const n of [start, end, count]) {\n if (n < 0n || n > MAX_INT64) {\n throw new AnchorVerificationError(\n \"Version=7 anchor sequence numbers and entry_count must be from 0 to 2^63 - 1\"\n );\n }\n }\n if (start > end) {\n throw new AnchorVerificationError(\"Version=7 anchor start_seq must not exceed end_seq\");\n }\n if (count !== end - start + 1n) {\n throw new AnchorVerificationError(\n \"Version=7 anchor entry_count must equal end_seq - start_seq + 1\"\n );\n }\n const prevHash: unknown = anchor.previousAnchorHash;\n if (typeof prevHash !== \"string\" || !HEX_128.test(prevHash)) {\n throw new AnchorVerificationError(\n \"Version=7 anchor previous_anchor_hash must be 128 lowercase hex characters\"\n );\n }\n if ((anchor.previousAnchorId === SEED_ANCHOR_ID) !== (prevHash === SEED_ANCHOR_HASH)) {\n throw new AnchorVerificationError(\n \"Version=7 anchor names the seed id exactly when it names the seed hash\"\n );\n }\n if (typeof anchor.chainHash !== \"string\" || !HEX_128.test(anchor.chainHash)) {\n throw new AnchorVerificationError(\"Version=7 anchor chain_hash must be 128 lowercase hex characters\");\n }\n if (anchorInteger(anchor.createdAtMs) < 0n) {\n throw new AnchorVerificationError(\"anchor created_at_ms must not be negative\");\n }\n if (typeof anchor.signingKeyId !== \"string\" || anchor.signingKeyId === \"\") {\n throw new AnchorVerificationError(\"anchor signing_key_id must not be empty\");\n }\n}\n\n/**\n * JSON-encode a single string value exactly as Go's `encoding/json` does,\n * with HTML escaping on (its default, and how proof signs): format-spec §9.2.\n *\n * `JSON.stringify` leaves `<`, `>`, `&`, U+2028 and U+2029 as they are; Go\n * writes them as `\\u` escapes. Replacing them in the output is exact: none of\n * them is part of any escape `JSON.stringify` writes.\n *\n * @internal\n */\nexport function encodeJsonString(s: string): string {\n // A lone surrogate cannot be encoded as UTF-8: Go writes U+FFFD in its place,\n // where JSON.stringify would write a \"\\\\udXXX\" escape.\n const wellFormed = s.replace(LONE_SURROGATE, \"\\ufffd\");\n return JSON.stringify(wellFormed).replace(\n /[<>&\\u2028\\u2029]/g,\n (c) => \"\\\\u\" + c.charCodeAt(0).toString(16).padStart(4, \"0\")\n );\n}\n\n/**\n * Version=6 canonical form: v4's layout with `company_id` as `subject`.\n *\n * THE FIELD MOVES. Keys are alphabetical, as in every version, and\n * `\"signing_key_id\" < \"subject\" < \"verified_through\" < \"version\"` — so the\n * renamed field sorts EIGHTH where `company_id` sorted THIRD. That movement is\n * precisely why this is a new version and not an edit: the key is inside the\n * bytes the signature covers.\n *\n * Built on v4, NOT v5. v5 commits to a Merkle root that no implementation can\n * verify, so v6 carries no `root_hash`/`tree_size`.\n *\n * Cross-language byte equivalence with Go's `canonicalV6` and Python's\n * `canonicalize_anchor_v6` is mandatory.\n */\nexport function canonicalizeAnchorV6(anchor: Anchor): string {\n const verifiedThrough = anchor.verifiedThrough ?? 0;\n const parts: string[] = [\n `\"anchor_id\":${encodeJsonString(anchor.anchorId)}`,\n `\"chain_hash\":${encodeJsonString(anchor.chainHash)}`,\n `\"created_at_ms\":${encodeInt64Token(anchor.createdAtMs)}`,\n `\"entry_count\":${encodeInt64Token(anchor.entryCount)}`,\n `\"previous_anchor_id\":${encodeJsonString(anchor.previousAnchorId)}`,\n `\"range\":{\"end_entry_id\":${encodeJsonString(anchor.range.endEntryId)},\"start_entry_id\":${encodeJsonString(anchor.range.startEntryId)}}`,\n `\"signing_key_id\":${encodeJsonString(anchor.signingKeyId)}`,\n `\"subject\":${encodeJsonString(anchor.subject)}`,\n `\"verified_through\":${encodeInt64Token(verifiedThrough)}`,\n `\"version\":${anchor.version}`,\n ];\n return `{${parts.join(\",\")}}`;\n}\n\n/**\n * Version=7 canonical form (format-spec §9.2): the bytes a v7 signature covers.\n *\n * Ten fields, alphabetical: `anchor_id`, `chain_hash`, `created_at_ms`,\n * `entry_count`, `previous_anchor_hash`, `previous_anchor_id`, `range`\n * (`end_seq`, `start_seq`), `signing_key_id`, `subject`, `version`.\n * `previous_anchor_hash` sorts before `previous_anchor_id`. `entry_count`,\n * `end_seq` and `start_seq` are JSON STRINGS of their decimal value, so that a\n * value above 2^53 survives every JSON reader exactly.\n *\n * Builds bytes only: call `checkAnchorWellFormed` first (`verifyAnchorLocally`\n * does).\n */\nexport function canonicalizeAnchorV7(anchor: Anchor): string {\n const range = anchor.range;\n if (range.startSeq === undefined || range.endSeq === undefined) {\n throw new AnchorVerificationError(\"Version=7 anchor must name its range by start_seq and end_seq\");\n }\n const decimal = (v: bigint | number): string => JSON.stringify(encodeInt64Token(v));\n const parts: string[] = [\n `\"anchor_id\":${encodeJsonString(anchor.anchorId)}`,\n `\"chain_hash\":${encodeJsonString(anchor.chainHash)}`,\n `\"created_at_ms\":${encodeInt64Token(anchor.createdAtMs)}`,\n `\"entry_count\":${decimal(anchor.entryCount)}`,\n `\"previous_anchor_hash\":${encodeJsonString(anchor.previousAnchorHash ?? \"\")}`,\n `\"previous_anchor_id\":${encodeJsonString(anchor.previousAnchorId)}`,\n `\"range\":{\"end_seq\":${decimal(range.endSeq)},\"start_seq\":${decimal(range.startSeq)}}`,\n `\"signing_key_id\":${encodeJsonString(anchor.signingKeyId)}`,\n `\"subject\":${encodeJsonString(anchor.subject)}`,\n `\"version\":${anchor.version}`,\n ];\n return `{${parts.join(\",\")}}`;\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Anchor verification and parsing for the Aleutian verification SDK.\n *\n * This module provides functions to verify anchor signatures and parse\n * anchor data from JSON. Anchor verification uses ML-DSA-65 (FIPS 204).\n * No SHA-256 pre-hash — ML-DSA-65 handles hashing internally.\n */\n\nimport { ml_dsa65 } from \"@noble/post-quantum/ml-dsa.js\";\nimport { AnchorVerificationError } from \"./errors.js\";\nimport { decodeCanonicalBase64 } from \"./canonicalBase64.js\";\nimport {\n ANCHOR_SIGNATURE_CONTEXT_V7,\n canonicalizeAnchorV6,\n canonicalizeAnchorV7,\n checkAnchorWellFormed,\n encodeInt64Token,\n encodeJsonString,\n} from \"./anchorCanonical.js\";\nimport { getPublicKey, MLDSA_PUB_KEY_SIZE } from \"./keys.js\";\nimport type { Anchor, AnchorRange, ExportedEntry } from \"./types.js\";\n\n// The v6 canonical form and the encoders live in anchorCanonical.ts, which\n// imports no keys, so the bundle verifier can use them without pulling the\n// embedded keys into a browser bundle. Re-exported here unchanged.\nexport { ANCHOR_SIGNATURE_CONTEXT_V7, canonicalizeAnchorV6, canonicalizeAnchorV7, checkAnchorWellFormed };\n\nconst EMPTY_CONTEXT = new Uint8Array(0);\nconst CONTEXT_V7 = new TextEncoder().encode(ANCHOR_SIGNATURE_CONTEXT_V7);\n\n/**\n * Verify an anchor signature without network access.\n *\n * # Description\n *\n * Verifies the ML-DSA-65 (FIPS 204) signature of an anchor using embedded\n * or provided public keys. This enables fully offline anchor verification.\n *\n * No SHA-256 pre-hash is applied — ML-DSA-65 handles message hashing\n * internally per FIPS 204, matching the Cloud KMS signing path.\n *\n * # Inputs\n *\n * - anchor: The anchor to verify\n * - publicKey: Optional raw 1952-byte ML-DSA-65 public key. If undefined,\n * uses embedded keys based on anchor.signingKeyId\n *\n * # Outputs\n *\n * - void: Returns normally if verification succeeds\n * - AnchorVerificationError: Thrown if signature verification fails\n * - Error: Thrown if public key ID is not found in embedded keys\n *\n * # Example\n *\n * const anchor = await loadAnchor('anchor-2026-01-20.json');\n * try {\n * verifyAnchorLocally(anchor);\n * console.log('Anchor is cryptographically valid');\n * } catch (e) {\n * console.error('Verification failed:', e.message);\n * }\n *\n * # Limitations\n *\n * - Requires embedded keys to be non-placeholder for production use\n * - Does not verify anchor chain linkage (previousAnchorId), and takes no\n * predecessor hash: binding an anchor to a chain and to its predecessor is\n * `bindAnchorToEntries`\n * - Refuses a malformed anchor before any cryptography (format-spec §9.3,\n * §9.8): an unsupported or withdrawn version, a broken version invariant,\n * v4/v6 counts out of range, an empty signingKeyId\n *\n * # Assumptions\n *\n * - anchor.signature is the canonical base64 (standard alphabet, padded, no\n * line breaks, zero trailing bits) of an ML-DSA-65 signature (3309 bytes)\n * - publicKey, if provided, is exactly MLDSA_PUB_KEY_SIZE (1952) bytes\n */\nexport function verifyAnchorLocally(\n anchor: Anchor,\n publicKey?: Uint8Array\n): void {\n // Version-dispatch invariants (ui_chainops_18 C1/M5), the v4/v6 counts and\n // the key id rule (format-spec §9.3, §9.8).\n // MUST happen BEFORE canonicalization so a malicious anchor cannot\n // downgrade or upgrade the canonical form via the version field.\n checkAnchorWellFormed(anchor);\n\n const key = publicKey ?? getPublicKey(anchor.signingKeyId);\n\n if (key.length !== MLDSA_PUB_KEY_SIZE) {\n throw new AnchorVerificationError(\"Invalid public key size\");\n }\n\n // Canonicalize anchor — ML-DSA-65 signs directly over canonical JSON bytes.\n // Dispatch by version; never probe by signature prefix or field presence.\n const canonical = canonicalizeAnchorForVersion(anchor);\n const canonicalBytes = new TextEncoder().encode(canonical);\n\n // Decode signature. format-spec §9.5: standard base64 with padding, and no\n // other spelling of it. A lenient decoder (`atob`, `Buffer.from`) accepts a\n // line break, missing padding and non-zero trailing bits, so several texts\n // would pass for one signature.\n const sigBytes =\n typeof anchor.signature === \"string\" ? decodeCanonicalBase64(anchor.signature) : null;\n if (sigBytes === null) {\n throw new AnchorVerificationError(\"Invalid signature encoding\");\n }\n\n if (sigBytes.length !== 3309) {\n throw new AnchorVerificationError(\"Invalid signature length\");\n }\n\n // Verify ML-DSA-65 signature (pure, no pre-hash per FIPS 204). format-spec\n // §9.5: the context is chosen from the DECLARED version, never from the\n // signature: \"aleutian.proof.anchor.v7\" for v7, empty for v1-v6.\n // @noble/post-quantum API: verify(sig, msg, pubKey, { context }) → boolean\n const context = anchor.version === 7 ? CONTEXT_V7 : EMPTY_CONTEXT;\n let valid: boolean;\n try {\n valid = ml_dsa65.verify(sigBytes, canonicalBytes, key, { context });\n } catch {\n valid = false;\n }\n if (!valid) {\n throw new AnchorVerificationError(\"Signature verification failed\");\n }\n}\n\n/**\n * Return canonical JSON for signature verification.\n *\n * # Description\n *\n * Builds the canonical JSON representation of an anchor for signature\n * verification. Uses explicit alphabetical key ordering matching the\n * AnchorCanonicalJSON format defined by the backend. The `signature`\n * field is excluded. All SDKs (Go, Python, JS) must produce identical output.\n *\n * Key ordering (alphabetical):\n * anchor_id, chain_hash, company_id, created_at_ms, entry_count,\n * previous_anchor_id, range, signing_key_id, version\n * range sub-keys: end_entry_id, start_entry_id\n *\n * # Inputs\n *\n * - anchor: The anchor to canonicalize\n *\n * # Outputs\n *\n * - string: Canonical JSON string with no extra whitespace\n *\n * # Example\n *\n * const json = canonicalizeAnchor(anchor);\n * // '{\"anchor_id\":\"...\",\"chain_hash\":\"...\",\"company_id\":\"...\",...}'\n *\n * # Limitations\n *\n * - ES2015+ preserves insertion order for string keys; relies on this behavior\n *\n * # Assumptions\n *\n * - All anchor fields are populated (empty strings / zero values for missing)\n */\n/**\n * Dispatch by anchor.version to the right canonical form\n * (ui_chainops_18 C3/M5). NEVER probe by signature prefix or by\n * field presence; probing creates a downgrade oracle.\n */\nexport function canonicalizeAnchorForVersion(anchor: Anchor): string {\n switch (anchor.version) {\n case 7:\n return canonicalizeAnchorV7(anchor);\n case 6:\n return canonicalizeAnchorV6(anchor);\n case 4:\n return canonicalizeAnchorV4(anchor);\n case 1:\n case 2:\n case 3:\n return canonicalizeAnchor(anchor);\n default:\n // format-spec §9.2: any other version (5 is withdrawn) has no canonical\n // form. Never canonicalize it as the closest known one.\n throw new AnchorVerificationError(\"unsupported anchor version\");\n }\n}\n\nfunction subjectFrom(data: Record<string, unknown>): string {\n // v3-v5 spell it `company_id`; v6 spells it `subject`. Both are accepted so\n // an anchor of either version loads.\n //\n // Two DIFFERENT values under the two spellings is an error, never a\n // precedence rule: canonicalizing either reading produces bytes the signature\n // does not cover, so silently preferring one would turn a malformed anchor\n // into a confidently wrong verdict.\n const subject = ((data.subject ?? data.subjectId) as string) ?? \"\";\n const company = ((data.company_id ?? data.companyId) as string) ?? \"\";\n if (subject && company && subject !== company) {\n throw new AnchorVerificationError(\n \"anchor carries both 'subject' and 'company_id' with different values; \" +\n \"which one the signature covers cannot be determined\"\n );\n }\n return subject || company;\n}\n\n/**\n * Version=4 canonical form (ui_chainops_18). Adds verified_through to\n * the v3 layout. Fields remain in alphabetical order per RFC 8785;\n * verified_through sorts between range and signing_key_id.\n *\n * Cross-language byte equivalence with Go canonicalAnchorV4Data and\n * Python canonicalize_anchor_v4 is mandatory.\n */\nexport function canonicalizeAnchorV4(anchor: Anchor): string {\n // Manual assembly so int64 fields can be emitted with full precision\n // for `bigint` inputs. Key order is alphabetical per RFC 8785,\n // matching Go canonicalAnchorV4Data and Python canonicalize_anchor_v4.\n const verifiedThrough = anchor.verifiedThrough ?? 0;\n const parts: string[] = [\n `\"anchor_id\":${encodeJsonString(anchor.anchorId)}`,\n `\"chain_hash\":${encodeJsonString(anchor.chainHash)}`,\n `\"company_id\":${encodeJsonString(anchor.subject)}`,\n `\"created_at_ms\":${encodeInt64Token(anchor.createdAtMs)}`,\n `\"entry_count\":${encodeInt64Token(anchor.entryCount)}`,\n `\"previous_anchor_id\":${encodeJsonString(anchor.previousAnchorId)}`,\n `\"range\":{\"end_entry_id\":${encodeJsonString(anchor.range.endEntryId)},\"start_entry_id\":${encodeJsonString(anchor.range.startEntryId)}}`,\n `\"signing_key_id\":${encodeJsonString(anchor.signingKeyId)}`,\n `\"verified_through\":${encodeInt64Token(verifiedThrough)}`,\n `\"version\":${anchor.version}`,\n ];\n return `{${parts.join(\",\")}}`;\n}\n\nexport function canonicalizeAnchor(anchor: Anchor): string {\n // Manual assembly so int64 fields can be emitted with full precision\n // for `bigint` inputs. Key order matches AnchorCanonicalJSON (alphabetical).\n const parts: string[] = [\n `\"anchor_id\":${encodeJsonString(anchor.anchorId)}`,\n `\"chain_hash\":${encodeJsonString(anchor.chainHash)}`,\n `\"company_id\":${encodeJsonString(anchor.subject)}`,\n `\"created_at_ms\":${encodeInt64Token(anchor.createdAtMs)}`,\n `\"entry_count\":${encodeInt64Token(anchor.entryCount)}`,\n `\"previous_anchor_id\":${encodeJsonString(anchor.previousAnchorId)}`,\n `\"range\":{\"end_entry_id\":${encodeJsonString(anchor.range.endEntryId)},\"start_entry_id\":${encodeJsonString(anchor.range.startEntryId)}}`,\n `\"signing_key_id\":${encodeJsonString(anchor.signingKeyId)}`,\n `\"version\":${anchor.version}`,\n ];\n return `{${parts.join(\",\")}}`;\n}\n\n// =============================================================================\n// Parsing Functions\n// =============================================================================\n\n/**\n * Parse an anchor from a JSON object (flat snake_case format).\n *\n * # Description\n *\n * Parses an anchor from the flat JSON format delivered by the Aleutian\n * backend. Handles snake_case keys (primary) with camelCase as fallback\n * for backward compatibility.\n *\n * # Inputs\n *\n * - data: Dictionary containing anchor data with snake_case keys\n *\n * # Outputs\n *\n * - Anchor: Parsed Anchor object\n *\n * # Example\n *\n * const anchor = parseAnchor(JSON.parse(anchorJson));\n *\n * # Limitations\n *\n * - Does not validate field values beyond type coercion\n * - LENIENT, and so not a reader for anchor files: `data` has already been\n * through `JSON.parse`, which kept the last of any repeated member and\n * rounded integers above 2^53, and this function also accepts camelCase\n * names and unknown members. To read an anchor's text as format-spec §9.8\n * requires, use `parseAnchorText` (which `loadAnchor` does).\n *\n * # Assumptions\n *\n * - data is a flat object (not nested with chain_state/metadata sub-objects)\n */\n/**\n * Coerce a JSON int64-field value to `bigint | number`.\n *\n * Accepts:\n * - JS `number` ≤ `Number.MAX_SAFE_INTEGER` — returned as `number`\n * (legacy callers see no API change)\n * - JS `number` > `Number.MAX_SAFE_INTEGER` — promoted to `bigint`\n * to preserve the (possibly-lossy) parsed value\n * - JS `string` — parsed as `bigint` for full-precision int64 values\n * that exceed JSON's safe-integer range\n * - JS `bigint` — passed through unchanged\n * - `undefined`/`null` — returns the default\n *\n * Ticket: dsar_js_anchor_int64_widening.\n */\nfunction coerceInt64Field(\n v: unknown,\n defaultValue: bigint | number,\n): bigint | number {\n if (v === undefined || v === null) {\n return defaultValue;\n }\n if (typeof v === \"bigint\") {\n return v;\n }\n if (typeof v === \"number\") {\n if (!Number.isFinite(v)) {\n return defaultValue;\n }\n if (Number.isSafeInteger(v)) {\n return v;\n }\n // Above MAX_SAFE_INTEGER: the value is already lossy from JSON.parse,\n // but promote to bigint so downstream encoding does not double-degrade.\n return BigInt(Math.trunc(v));\n }\n if (typeof v === \"string\") {\n try {\n return BigInt(v);\n } catch {\n return defaultValue;\n }\n }\n return defaultValue;\n}\n\nexport function parseAnchor(data: Record<string, unknown>): Anchor {\n return {\n version: (data.version as number) ?? 2,\n anchorId: ((data.anchor_id ?? data.anchorId) as string) ?? \"\",\n subject: subjectFrom(data),\n chainHash: ((data.chain_hash ?? data.chainHash) as string) ?? \"\",\n range: parseRange((data.range ?? {}) as Record<string, unknown>),\n entryCount: coerceInt64Field(data.entry_count ?? data.entryCount, 0),\n signature: (data.signature as string) ?? \"\",\n signingKeyId: ((data.signing_key_id ?? data.signingKeyId) as string) ?? \"\",\n createdAtMs: coerceInt64Field(data.created_at_ms ?? data.createdAtMs, 0),\n previousAnchorId:\n ((data.previous_anchor_id ?? data.previousAnchorId) as string) ?? \"\",\n verifiedThrough: coerceInt64Field(\n data.verified_through ?? data.verifiedThrough,\n 0,\n ),\n ...optionalString(\"previousAnchorHash\", data.previous_anchor_hash ?? data.previousAnchorHash),\n };\n}\n\nfunction optionalString(name: string, v: unknown): Record<string, string> {\n return typeof v === \"string\" ? { [name]: v } : {};\n}\n\n/** A v7 sequence number (a decimal string on the wire) as a bigint; absent stays absent. */\nfunction optionalSeq(name: string, v: unknown): Record<string, bigint | number> {\n if (v === undefined || v === null) return {};\n return { [name]: coerceInt64Field(v, -1) };\n}\n\nfunction parseRange(r: Record<string, unknown>): AnchorRange {\n return {\n startEntryId:\n ((r.start_entry_id ?? r.startEntryId) as string) ?? \"\",\n endEntryId:\n ((r.end_entry_id ?? r.endEntryId) as string) ?? \"\",\n ...optionalSeq(\"startSeq\", r.start_seq ?? r.startSeq),\n ...optionalSeq(\"endSeq\", r.end_seq ?? r.endSeq),\n };\n}\n\n/**\n * Parse exported entries from JSON array.\n *\n * # Description\n *\n * Parses an array of exported entry objects into ExportedEntry values.\n * Handles both camelCase and snake_case field names.\n *\n * # Inputs\n *\n * - data: Array of entry objects from a data export JSON file\n *\n * # Outputs\n *\n * - ExportedEntry[]: Array of parsed ExportedEntry objects\n *\n * # Example\n *\n * const entries = parseExportedEntries(rawArray);\n *\n * # Limitations\n *\n * - Does not validate hash formats or entry ordering\n * - LENIENT, and so not a reader for entries files: `data` has already been\n * through `JSON.parse` (last duplicate member kept, integers above 2^53\n * rounded), and a missing member becomes \"\" or 0 here. To read an entries\n * file's text, use `parseEntriesText` (which `loadExportedEntries` does).\n *\n * # Assumptions\n *\n * - Each element has at least entry_id or entryId present\n */\nfunction formatVersionFrom(e: Record<string, unknown>): { formatVersion?: number } {\n const v = e.format_version ?? e.formatVersion;\n return v === undefined || v === null ? {} : { formatVersion: v as number };\n}\n\nexport function parseExportedEntries(\n data: readonly Record<string, unknown>[]\n): ExportedEntry[] {\n return data.map((e) => ({\n entryId: ((e.entry_id ?? e.entryId) as string) ?? \"\",\n entryType: ((e.entry_type ?? e.entryType) as string) ?? \"\",\n timestamp: (e.timestamp as string) ?? \"\",\n runId: ((e.run_id ?? e.runId) as string) ?? \"\",\n sequenceNum: ((e.sequence_num ?? e.sequenceNum) as number) ?? 0,\n globalSeq: ((e.global_seq ?? e.globalSeq) as number) ?? 0,\n contentHash: ((e.content_hash ?? e.contentHash) as string) ?? \"\",\n chainHash: ((e.chain_hash ?? e.chainHash) as string) ?? \"\",\n // Which preimage produced chainHash. Dropping it would have every v3\n // entry recomputed as v2 and reported as a hash mismatch.\n ...formatVersionFrom(e),\n // Chain format v4 (format-spec §2.0). Lenient: absent members are not\n // recorded, so an empty string counts as absent (see `presentMembers`).\n ...optionalString(\"salt\", e.salt),\n ...optionalString(\"leafHash\", e.leaf_hash ?? e.leafHash),\n ...(typeof e.erased === \"boolean\" ? { erased: e.erased } : {}),\n }));\n}\n\n// Node-only filesystem loaders (`loadAnchor`, `loadExportedEntries`)\n// live in `./anchorLoaders.ts` and are re-exported only from the Node\n// entry point (`src/index.ts`), NOT from here, so the browser bundle\n// does not pull `await import(\"fs/promises\")` into its reachable graph.\n// See `dsar_js_browser_target_audit`.\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * A strict JSON parser for proof bundles and checkpoint text\n * (bundle-format §3).\n *\n * `JSON.parse` cannot be used: it silently keeps the LAST of two duplicate\n * member names, rounds numbers above 2⁵³, and accepts lone surrogates; and\n * `TextDecoder` replaces invalid UTF-8 unless told not to, and strips a BOM.\n * This parser works on the raw bytes and:\n *\n * - accepts only valid UTF-8 (no overlong forms, no encoded surrogates, nothing\n * above U+10FFFF), and refuses a byte-order mark (it is not a JSON token);\n * - refuses a lone surrogate, raw or as a `\\u` escape;\n * - limits nesting depth (the top-level value is depth 1; each array or object\n * inside another adds one);\n * - keeps numbers as their source text (never a JS number), so nothing rounds;\n * - REPORTS duplicate member names, compared after unescaping, instead of\n * choosing one, so the caller can apply §9.1's precedence (a grammar error\n * anywhere in the document outranks a duplicate).\n *\n * The lexical layer, {@link StrictJsonScanner}, is shared with the streaming\n * bundle reader (`proofBundleReader.ts`), which checks the bundle's structure\n * as it scans instead of building a tree.\n *\n * Its failures carry no position and no input: a parser error must never quote\n * the bundle (§10). Browser-safe.\n */\n\n/** A JSON number, kept as its exact source text (RFC 8259 grammar). */\nexport class JsonNumber {\n constructor(readonly text: string) {}\n}\n\n/** A JSON object. Member names are compared exactly, case-sensitively. */\nexport class JsonObject {\n readonly members = new Map<string, JsonValue>();\n}\n\n/** Any parsed JSON value. Arrays are plain arrays. */\nexport type JsonValue = string | boolean | null | JsonNumber | JsonObject | JsonValue[];\n\n/** The outcome of {@link parseStrictJson}. */\nexport type StrictJsonResult =\n | { readonly ok: true; readonly value: JsonValue; readonly duplicateKey: boolean }\n | { readonly ok: false };\n\n/** Signals a grammar violation. Deliberately carries no detail. */\nclass GrammarViolation {}\nconst VIOLATION = new GrammarViolation();\n\nconst QUOTE = 0x22;\nconst BACKSLASH = 0x5c;\n\nfunction isDigit(c: number | undefined): boolean {\n return c !== undefined && c >= 0x30 && c <= 0x39;\n}\n\n/**\n * The lexical layer of §3: whitespace, literals, numbers and strings, over raw\n * bytes. Every method throws an opaque violation on a grammar error; run the\n * scan inside {@link runStrict} to turn that into a result.\n *\n * Not safe for concurrent use: a scanner holds its position. Make one per\n * document.\n *\n * @internal\n */\nexport class StrictJsonScanner {\n protected pos = 0;\n private readonly decoder = new TextDecoder(\"utf-8\", { fatal: true, ignoreBOM: true });\n /** Reused output buffer for strings that hold escapes (grows by doubling). */\n private scratch = new Uint8Array(0);\n private scratchLength = 0;\n\n constructor(\n protected readonly b: Uint8Array,\n protected readonly maxDepth: number\n ) {}\n\n /** Throw the opaque grammar violation. */\n protected fail(): never {\n throw VIOLATION;\n }\n\n protected peek(): number | undefined {\n return this.b[this.pos];\n }\n\n protected skipWhitespace(): void {\n const b = this.b;\n while (this.pos < b.length) {\n const c = b[this.pos]!;\n if (c !== 0x20 && c !== 0x09 && c !== 0x0a && c !== 0x0d) return;\n this.pos++;\n }\n }\n\n protected expect(c: number): void {\n if (this.b[this.pos] !== c) this.fail();\n this.pos++;\n }\n\n /** The end of the document: only whitespace may follow the top-level value. */\n protected expectEnd(): void {\n this.skipWhitespace();\n if (this.pos !== this.b.length) this.fail();\n }\n\n protected literal(word: string): void {\n for (let i = 0; i < word.length; i++) {\n if (this.b[this.pos + i] !== word.charCodeAt(i)) this.fail();\n }\n this.pos += word.length;\n }\n\n /** Skip a number, holding it to RFC 8259's grammar exactly. */\n protected skipNumber(): void {\n const b = this.b;\n let p = this.pos;\n if (b[p] === 0x2d) p++;\n if (b[p] === 0x30) p++;\n else if (isDigit(b[p]) && b[p] !== 0x30) while (isDigit(b[p])) p++;\n else this.fail();\n if (b[p] === 0x2e) {\n p++;\n if (!isDigit(b[p])) this.fail();\n while (isDigit(b[p])) p++;\n }\n if (b[p] === 0x65 || b[p] === 0x45) {\n p++;\n if (b[p] === 0x2b || b[p] === 0x2d) p++;\n if (!isDigit(b[p])) this.fail();\n while (isDigit(b[p])) p++;\n }\n // A number character right after a complete number (`01`, `1-2`) is\n // refused by whatever reads next: it cannot follow a value.\n this.pos = p;\n }\n\n /** Read a number as its source text (ASCII, so UTF-8 decoding is exact). */\n protected readNumber(): string {\n const start = this.pos;\n this.skipNumber();\n return this.decoder.decode(this.b.subarray(start, this.pos));\n }\n\n /** Read a string (the cursor is on its opening quote) and decode it. */\n protected readString(): string {\n return this.scanString(true);\n }\n\n /** Check a string (the cursor is on its opening quote) without decoding it. */\n protected skipString(): void {\n this.scanString(false);\n }\n\n /**\n * Scan one string. Raw runs are validated in place; escapes are written,\n * with the runs around them, into one reused byte buffer, so a string full of\n * escapes costs one decode, not one allocation per escape.\n */\n private scanString(decode: boolean): string {\n const b = this.b;\n this.pos++; // opening quote\n const start = this.pos;\n let runStart = start;\n let escaped = false;\n this.scratchLength = 0;\n for (;;) {\n const c = b[this.pos];\n if (c === undefined) this.fail();\n if (c === QUOTE) {\n const end = this.pos;\n this.pos++;\n if (!decode) return \"\";\n if (!escaped)\n return end === start ? \"\" : this.decoder.decode(b.subarray(start, end));\n this.put(b.subarray(runStart, end));\n return this.decoder.decode(this.scratch.subarray(0, this.scratchLength));\n }\n if (c < 0x20) this.fail();\n if (c < 0x80 && c !== BACKSLASH) {\n this.pos++;\n continue;\n }\n if (c >= 0x80) {\n this.pos += this.utf8Length(this.pos);\n continue;\n }\n // An escape.\n if (decode) {\n escaped = true;\n this.put(b.subarray(runStart, this.pos));\n }\n const e = b[this.pos + 1];\n this.pos += 2;\n let cp: number;\n switch (e) {\n case 0x22:\n cp = 0x22;\n break;\n case 0x5c:\n cp = 0x5c;\n break;\n case 0x2f:\n cp = 0x2f;\n break;\n case 0x62:\n cp = 0x08;\n break;\n case 0x66:\n cp = 0x0c;\n break;\n case 0x6e:\n cp = 0x0a;\n break;\n case 0x72:\n cp = 0x0d;\n break;\n case 0x74:\n cp = 0x09;\n break;\n case 0x75: {\n const unit = this.hex4(this.pos);\n this.pos += 4;\n if (unit >= 0xdc00 && unit <= 0xdfff) this.fail(); // lone low surrogate\n if (unit >= 0xd800 && unit <= 0xdbff) {\n // A high surrogate must be followed at once by an escaped low one.\n if (b[this.pos] !== BACKSLASH || b[this.pos + 1] !== 0x75) this.fail();\n const low = this.hex4(this.pos + 2);\n if (low < 0xdc00 || low > 0xdfff) this.fail();\n this.pos += 6;\n cp = 0x10000 + ((unit - 0xd800) << 10) + (low - 0xdc00);\n } else {\n cp = unit;\n }\n break;\n }\n default:\n this.fail();\n }\n if (decode) this.putCodePoint(cp);\n runStart = this.pos;\n }\n }\n\n private reserve(n: number): void {\n const need = this.scratchLength + n;\n if (need <= this.scratch.length) return;\n const grown = new Uint8Array(Math.max(need, this.scratch.length * 2, 256));\n grown.set(this.scratch.subarray(0, this.scratchLength));\n this.scratch = grown;\n }\n\n private put(run: Uint8Array): void {\n if (run.length === 0) return;\n this.reserve(run.length);\n this.scratch.set(run, this.scratchLength);\n this.scratchLength += run.length;\n }\n\n /** Append one code point as UTF-8 (escapes never yield a lone surrogate). */\n private putCodePoint(cp: number): void {\n this.reserve(4);\n const s = this.scratch;\n let n = this.scratchLength;\n if (cp < 0x80) {\n s[n++] = cp;\n } else if (cp < 0x800) {\n s[n++] = 0xc0 | (cp >> 6);\n s[n++] = 0x80 | (cp & 0x3f);\n } else if (cp < 0x10000) {\n s[n++] = 0xe0 | (cp >> 12);\n s[n++] = 0x80 | ((cp >> 6) & 0x3f);\n s[n++] = 0x80 | (cp & 0x3f);\n } else {\n s[n++] = 0xf0 | (cp >> 18);\n s[n++] = 0x80 | ((cp >> 12) & 0x3f);\n s[n++] = 0x80 | ((cp >> 6) & 0x3f);\n s[n++] = 0x80 | (cp & 0x3f);\n }\n this.scratchLength = n;\n }\n\n private hex4(at: number): number {\n let v = 0;\n for (let i = 0; i < 4; i++) {\n const c = this.b[at + i];\n let d: number;\n if (c === undefined) this.fail();\n if (c >= 0x30 && c <= 0x39) d = c - 0x30;\n else if (c >= 0x61 && c <= 0x66) d = c - 0x61 + 10;\n else if (c >= 0x41 && c <= 0x46) d = c - 0x41 + 10;\n else this.fail();\n v = v * 16 + d;\n }\n return v;\n }\n\n /** Validate one UTF-8 sequence starting at `at`; return its length. */\n private utf8Length(at: number): number {\n const b = this.b;\n const c0 = b[at]!;\n const cont = (i: number, lo = 0x80, hi = 0xbf): void => {\n const c = b[at + i];\n if (c === undefined || c < lo || c > hi) this.fail();\n };\n if (c0 >= 0xc2 && c0 <= 0xdf) {\n cont(1);\n return 2;\n }\n if (c0 >= 0xe0 && c0 <= 0xef) {\n if (c0 === 0xe0) cont(1, 0xa0, 0xbf);\n else if (c0 === 0xed)\n cont(1, 0x80, 0x9f); // no encoded surrogates\n else cont(1);\n cont(2);\n return 3;\n }\n if (c0 >= 0xf0 && c0 <= 0xf4) {\n if (c0 === 0xf0) cont(1, 0x90, 0xbf);\n else if (c0 === 0xf4) cont(1, 0x80, 0x8f);\n else cont(1);\n cont(2);\n cont(3);\n return 4;\n }\n this.fail();\n }\n}\n\n/**\n * Run a scan, turning a grammar violation into `{ ok: false }`.\n *\n * @internal\n */\nexport function runStrict<T>(scan: () => T): { ok: true; value: T } | { ok: false } {\n try {\n return { ok: true, value: scan() };\n } catch (err) {\n if (err === VIOLATION) return { ok: false };\n // TextDecoder (fatal) on bytes this scanner already validated cannot fail;\n // if it ever does, the input is still not valid UTF-8 JSON.\n if (err instanceof TypeError) return { ok: false };\n throw new Error(\"strict JSON parser: internal error\");\n }\n}\n\n/** Builds the whole tree. Used for checkpoint text (at most 1 MiB). */\nclass TreeParser extends StrictJsonScanner {\n duplicateKey = false;\n\n parseDocument(): JsonValue {\n this.skipWhitespace();\n const v = this.parseValue(1);\n this.expectEnd();\n return v;\n }\n\n private parseValue(depth: number): JsonValue {\n const c = this.peek();\n switch (c) {\n case 0x7b: // {\n return this.parseObject(depth);\n case 0x5b: // [\n return this.parseArray(depth);\n case QUOTE:\n return this.readString();\n case 0x74: // t\n this.literal(\"true\");\n return true;\n case 0x66: // f\n this.literal(\"false\");\n return false;\n case 0x6e: // n\n this.literal(\"null\");\n return null;\n default:\n return new JsonNumber(this.readNumber());\n }\n }\n\n private parseArray(depth: number): JsonValue[] {\n if (depth > this.maxDepth) this.fail();\n this.pos++; // [\n const items: JsonValue[] = [];\n this.skipWhitespace();\n if (this.peek() === 0x5d) {\n this.pos++;\n return items;\n }\n for (;;) {\n this.skipWhitespace();\n items.push(this.parseValue(depth + 1));\n this.skipWhitespace();\n const c = this.peek();\n if (c === 0x2c) {\n this.pos++;\n continue;\n }\n if (c === 0x5d) {\n this.pos++;\n return items;\n }\n this.fail();\n }\n }\n\n private parseObject(depth: number): JsonObject {\n if (depth > this.maxDepth) this.fail();\n this.pos++; // {\n const obj = new JsonObject();\n this.skipWhitespace();\n if (this.peek() === 0x7d) {\n this.pos++;\n return obj;\n }\n for (;;) {\n this.skipWhitespace();\n if (this.peek() !== QUOTE) this.fail();\n const name = this.readString();\n this.skipWhitespace();\n this.expect(0x3a); // :\n this.skipWhitespace();\n const value = this.parseValue(depth + 1);\n if (obj.members.has(name)) this.duplicateKey = true;\n else obj.members.set(name, value);\n this.skipWhitespace();\n const c = this.peek();\n if (c === 0x2c) {\n this.pos++;\n continue;\n }\n if (c === 0x7d) {\n this.pos++;\n return obj;\n }\n this.fail();\n }\n }\n}\n\n/**\n * Parse bytes as JSON under bundle-format §3.\n *\n * # Description\n *\n * Returns `{ ok: false }` for anything that is not valid UTF-8 JSON under §3\n * (including a BOM, a lone surrogate, and depth beyond `maxDepth`). Otherwise\n * returns the value and whether any object repeated a member name (compared\n * after unescaping). For a repeated name, the first value is kept; a caller\n * that sees `duplicateKey` must not trust the tree.\n *\n * # Inputs\n *\n * - bytes: the document\n * - maxDepth: the nesting limit (8 in bundle-format §3)\n *\n * # Outputs\n *\n * - StrictJsonResult: never throws on any input\n *\n * # Example\n *\n * const r = parseStrictJson(bytes, 8);\n * if (!r.ok) return \"json\";\n * if (r.duplicateKey) return \"duplicate-key\";\n *\n * # Limitations\n *\n * - Builds the whole tree: memory grows with the number of values. The\n * bundle itself is read by the streaming `readProofBundle`; this parser\n * reads checkpoint text, which is at most 1 MiB.\n * - Numbers are checked against RFC 8259 only; a caller applies any stricter\n * rule (checkpoint text's `0|[1-9][0-9]*`, at most 2⁵³−1).\n *\n * # Assumptions\n *\n * - None.\n */\nexport function parseStrictJson(bytes: Uint8Array, maxDepth: number): StrictJsonResult {\n const parser = new TreeParser(bytes, maxDepth);\n const r = runStrict(() => parser.parseDocument());\n return r.ok ? { ok: true, value: r.value, duplicateKey: parser.duplicateKey } : r;\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Strict readers for the TEXT of an entries file and of an anchor\n * (format-spec §9.8 and §11).\n *\n * `JSON.parse` cannot be used for either. It silently keeps the LAST of two\n * members with one name, so two readers of one file can see two different\n * documents; it rounds integers above 2^53, so a `global_seq` beyond that is\n * not the one on the wire; and it has no opinion about a member spelled in\n * another case, which a case-insensitive reader elsewhere would accept as the\n * real one. These readers work on `strictJson.ts`, which reports duplicates\n * and keeps numbers as their source text.\n *\n * Their failures name a member, never a value: an error must not quote the\n * file it refuses. Browser-safe: no Node APIs.\n */\n\nimport { AnchorVerificationError, EntriesFormatError } from \"./errors.js\";\nimport { JsonNumber, JsonObject, parseStrictJson } from \"./strictJson.js\";\nimport type { JsonValue } from \"./strictJson.js\";\nimport type { Anchor, ExportedEntry } from \"./types.js\";\n\n// An entry is an object of scalars, and an anchor an object holding one more.\n// Unknown entry members are tolerated (below), so allow them some structure.\nconst MAX_ENTRIES_DEPTH = 32;\nconst MAX_ANCHOR_DEPTH = 2;\n\n// A JSON integer as these formats write one: no fraction, no exponent, no\n// leading zeros, and no \"-0\".\nconst INTEGER_TEXT = /^(0|-?[1-9][0-9]*)$/;\nconst MIN_INT64 = -(2n ** 63n);\nconst MAX_INT64 = 2n ** 63n - 1n;\n\nconst ENCODER = new TextEncoder();\n\nfunction toBytes(text: string | Uint8Array): Uint8Array {\n return typeof text === \"string\" ? ENCODER.encode(text) : text;\n}\n\n/** Read a JSON number as an exact 64-bit integer, or null when it is not one. */\nfunction int64Of(value: JsonValue | undefined): bigint | null {\n if (!(value instanceof JsonNumber) || !INTEGER_TEXT.test(value.text)) return null;\n // The pattern bounds nothing; 20 digits is past int64 and cheap to refuse.\n if (value.text.length > 20) return null;\n const n = BigInt(value.text);\n return n < MIN_INT64 || n > MAX_INT64 ? null : n;\n}\n\n/** A `number` while it is exact, a `bigint` beyond that: never a rounded value. */\nfunction narrow(n: bigint): number | bigint {\n return n >= BigInt(Number.MIN_SAFE_INTEGER) && n <= BigInt(Number.MAX_SAFE_INTEGER)\n ? Number(n)\n : n;\n}\n\n/**\n * A member name under Unicode simple case folding, as far as it can reach a\n * format member: the known names are ASCII, and the only other characters\n * that fold to an ASCII letter are U+017F LATIN SMALL LETTER LONG S (to `s`)\n * and U+212A KELVIN SIGN (to `k`). `toLowerCase` alone leaves both alone.\n */\nfunction foldName(name: string): string {\n return name.replace(/\\u017f/g, \"s\").replace(/\\u212a/g, \"k\").toLowerCase();\n}\n\n/**\n * Report a member whose name folds to a known snake_case name without being it\n * (`CHAIN_HASH`, or `ſalt` with U+017F). A case-folding reader takes it for the\n * real member, an exact one does not, and the two then verify different\n * documents.\n */\nfunction hasMiscasedMember(\n obj: JsonObject,\n snake: ReadonlySet<string>,\n aliases: ReadonlySet<string>\n): boolean {\n for (const name of obj.members.keys()) {\n if (!snake.has(name) && !aliases.has(name) && snake.has(foldName(name))) return true;\n }\n return false;\n}\n\n/** Thrown by {@link pick}; each reader turns it into its own error type. */\nclass BothSpellings {\n constructor(readonly snake: string) {}\n}\n\n/**\n * Read a member under its snake_case name or its camelCase alias. A document\n * carrying BOTH spellings of one member is refused: two readers that each\n * prefer a different one would see two different documents.\n */\nfunction pick(obj: JsonObject, snake: string, ...aliases: string[]): JsonValue | undefined {\n let found: JsonValue | undefined;\n let seen = 0;\n for (const name of [snake, ...aliases]) {\n if (obj.members.has(name)) {\n seen++;\n found = obj.members.get(name);\n }\n }\n if (seen > 1) throw new BothSpellings(snake);\n return found;\n}\n\n// =============================================================================\n// Entries\n// =============================================================================\n\n// snake_case name -> the camelCase alias `parseExportedEntries` also accepts.\nconst ENTRY_ALIASES: Readonly<Record<string, string>> = {\n entry_id: \"entryId\",\n entry_type: \"entryType\",\n timestamp: \"timestamp\",\n run_id: \"runId\",\n sequence_num: \"sequenceNum\",\n global_seq: \"globalSeq\",\n content_hash: \"contentHash\",\n chain_hash: \"chainHash\",\n format_version: \"formatVersion\",\n salt: \"salt\",\n leaf_hash: \"leafHash\",\n erased: \"erased\",\n};\nconst ENTRY_SNAKE: ReadonlySet<string> = new Set(Object.keys(ENTRY_ALIASES));\nconst ENTRY_CAMEL: ReadonlySet<string> = new Set(Object.values(ENTRY_ALIASES));\n// Without these four an object is not an entry at all.\nconst ENTRY_REQUIRED = [\"entry_id\", \"timestamp\", \"content_hash\", \"chain_hash\"] as const;\n\nfunction notEntries(detail: string): EntriesFormatError {\n return new EntriesFormatError(`not an entries file: ${detail}`);\n}\n\nfunction entryMember(obj: JsonObject, snake: string): JsonValue | undefined {\n const alias = ENTRY_ALIASES[snake]!;\n try {\n return alias === snake ? obj.members.get(snake) : pick(obj, snake, alias);\n } catch (err) {\n if (err instanceof BothSpellings) {\n throw notEntries(`an entry carries ${snake} under two spellings`);\n }\n throw err;\n }\n}\n\nfunction entryString(obj: JsonObject, snake: string, required: boolean): string {\n const v = entryMember(obj, snake);\n if (v === undefined) {\n if (required) throw notEntries(`an entry has no ${snake}`);\n return \"\";\n }\n if (typeof v !== \"string\") throw notEntries(`an entry's ${snake} is not a string`);\n return v;\n}\n\nfunction entryInteger(obj: JsonObject, snake: string): bigint | undefined {\n const v = entryMember(obj, snake);\n if (v === undefined) return undefined;\n const n = int64Of(v);\n if (n === null) throw notEntries(`an entry's ${snake} is not an integer`);\n return n;\n}\n\n/** `salt` and `leaf_hash` when present (strings), and `erased` (a boolean). */\nfunction v4Members(obj: JsonObject): Pick<ExportedEntry, \"salt\" | \"leafHash\" | \"erased\"> {\n const out: { salt?: string; leafHash?: string; erased?: boolean } = {};\n if (entryMember(obj, \"salt\") !== undefined) out.salt = entryString(obj, \"salt\", true);\n if (entryMember(obj, \"leaf_hash\") !== undefined) {\n out.leafHash = entryString(obj, \"leaf_hash\", true);\n }\n const erased = entryMember(obj, \"erased\");\n if (erased !== undefined) {\n if (typeof erased !== \"boolean\") throw notEntries(\"an entry's erased is not a boolean\");\n out.erased = erased;\n }\n return out;\n}\n\n/**\n * A v4 entry (format-spec §2.0). Its id, type and content hash are absent\n * from an erased entry, so only `timestamp` and `chain_hash` are required to\n * make it an entry; which members it carries is recorded, because v4 tells an\n * absent member from an empty one and the verifier judges the two shapes.\n */\nfunction entryV4From(value: JsonObject, formatVersion: bigint): ExportedEntry {\n const present = new Set<string>();\n for (const snake of ENTRY_SNAKE) {\n if (entryMember(value, snake) !== undefined) present.add(snake);\n }\n const sequenceNum = narrow(entryInteger(value, \"sequence_num\") ?? 0n);\n if (typeof sequenceNum !== \"number\") {\n throw notEntries(\"an entry's sequence_num is out of range\");\n }\n return {\n entryId: entryString(value, \"entry_id\", false),\n entryType: entryString(value, \"entry_type\", false),\n timestamp: entryString(value, \"timestamp\", true),\n runId: entryString(value, \"run_id\", false),\n sequenceNum,\n globalSeq: narrow(entryInteger(value, \"global_seq\") ?? 0n),\n contentHash: entryString(value, \"content_hash\", false),\n chainHash: entryString(value, \"chain_hash\", true),\n formatVersion: Number(formatVersion),\n ...v4Members(value),\n presentMembers: present,\n };\n}\n\nfunction entryFrom(value: JsonValue): ExportedEntry {\n if (!(value instanceof JsonObject)) {\n throw notEntries(\"an entry is not a JSON object\");\n }\n if (hasMiscasedMember(value, ENTRY_SNAKE, ENTRY_CAMEL)) {\n throw notEntries(\"an entry member is spelled in another case\");\n }\n // Dispatch on the declared format only (format-spec §2.2).\n const declared = entryInteger(value, \"format_version\");\n if (declared === 4n) return entryV4From(value, declared);\n\n const [entryId, timestamp, contentHash, chainHash] = ENTRY_REQUIRED.map((name) =>\n entryString(value, name, true)\n ) as [string, string, string, string];\n\n // Optional members default to \"\" / 0 / absent. v3 exports always write\n // `\"run_id\": \"\"` and `\"sequence_num\": 0`; leaving them out means the same.\n const sequenceNum = narrow(entryInteger(value, \"sequence_num\") ?? 0n);\n if (typeof sequenceNum !== \"number\") {\n throw notEntries(\"an entry's sequence_num is out of range\");\n }\n // Absent means v2 (format-spec §2.2). An unknown version is carried through\n // for the verifier to report; it is never guessed here.\n const formatVersion = entryInteger(value, \"format_version\");\n\n return {\n entryId,\n entryType: entryString(value, \"entry_type\", false),\n timestamp,\n runId: entryString(value, \"run_id\", false),\n sequenceNum,\n globalSeq: narrow(entryInteger(value, \"global_seq\") ?? 0n),\n contentHash,\n chainHash,\n ...(formatVersion === undefined ? {} : { formatVersion: Number(formatVersion) }),\n // A v4 member on a v2 or v3 entry is carried through for the verifier to\n // report as format_field_misuse (format-spec §2.2), never dropped.\n ...v4Members(value),\n };\n}\n\nfunction strictDocument(bytes: Uint8Array): JsonValue | undefined {\n const r = parseStrictJson(bytes, MAX_ENTRIES_DEPTH);\n if (!r.ok) return undefined;\n if (r.duplicateKey) throw notEntries(\"a member name is repeated\");\n return r.value;\n}\n\nfunction strictValue(bytes: Uint8Array, what: string): JsonValue {\n const v = strictDocument(bytes);\n if (v === undefined) throw notEntries(`${what} is not valid JSON`);\n return v;\n}\n\nfunction firstNonSpace(b: Uint8Array): number | undefined {\n for (const c of b) {\n if (c !== 0x20 && c !== 0x09 && c !== 0x0a && c !== 0x0d) return c;\n }\n return undefined;\n}\n\n/**\n * Decode the text of an entries file, refusing anything that is not entries.\n *\n * # Description\n *\n * Accepts the three forms an export takes:\n *\n * - one JSON array of entry objects;\n * - JSONL: one entry object per line (blank lines are skipped);\n * - the hosted platform's wrapper: one JSON object with an `entries` member\n * whose value is an array of entry objects. The wrapper's other members\n * are ignored. Any other top-level object is refused.\n *\n * Every v2 or v3 entry must carry `entry_id`, `timestamp`, `content_hash` and\n * `chain_hash` as strings. A v4 entry (`format_version: 4`, format-spec §2.0)\n * must carry `timestamp` and `chain_hash`: an erased one has no id, type or\n * content hash. `salt`, `leaf_hash` (strings) and `erased` (a boolean) are\n * read on every entry when present, and on a v4 entry the names of the\n * members it carried are returned in `presentMembers`, so the verifier can\n * judge its shape (absent is not empty in v4). `entry_type` and `run_id` (strings), and\n * `sequence_num`, `global_seq` and `format_version` (integers) are read when\n * present and are \"\" / 0 / absent otherwise. Each member may be spelled in\n * snake_case or in the camelCase alias `parseExportedEntries` accepts\n * (`entryId`, `chainHash`, ...). Members with other names are ignored.\n *\n * Refused, as an error and never as a broken chain: text that is not JSON, an\n * empty document or an empty array, `{}`, `null`, an export bundle, an anchor,\n * two objects on one line, a member name repeated in any object, an entry\n * carrying both spellings of one member, a name that case-folds to a known\n * snake_case name (`CHAIN_HASH`, `ſalt` with U+017F), a missing required\n * member, and a member that is null or of the wrong type (a `global_seq`\n * written as a string, a fraction, an exponent or `-0`). Text that is not\n * valid UTF-8, or escapes a lone surrogate, is refused and never repaired.\n *\n * This checks that the text IS entries. Whether the entries verify (hash\n * shapes, timestamps, the chain) is `verifyChainOffline`'s to report as breaks.\n *\n * # Inputs\n *\n * - text: The file's content. Pass the raw bytes when you have them: a\n * string has already had invalid UTF-8 replaced by whatever decoded it.\n *\n * # Outputs\n *\n * - ExportedEntry[]: At least one entry. `globalSeq` is a `number` up to\n * `Number.MAX_SAFE_INTEGER` and a `bigint` beyond it.\n * - EntriesFormatError: Thrown when the text is not entries. The message\n * names a member, never a value.\n *\n * # Example\n *\n * const entries = parseEntriesText(await response.text());\n * const result = await verifyChainOffline(entries);\n *\n * # Limitations\n *\n * - Builds every entry in memory.\n * - A single entry object spread over several lines is neither a wrapper nor\n * JSONL, and is refused.\n *\n * # Assumptions\n *\n * - None.\n */\nexport function parseEntriesText(text: string | Uint8Array): ExportedEntry[] {\n const bytes = toBytes(text);\n const first = firstNonSpace(bytes);\n if (first === undefined) throw notEntries(\"the document is empty\");\n\n let values: JsonValue[] | undefined;\n if (first === 0x5b) {\n // \"[\": one JSON array.\n const doc = strictValue(bytes, \"the document\");\n if (!Array.isArray(doc)) throw notEntries(\"the document is not an array of entries\");\n values = doc;\n } else if (first === 0x7b) {\n // \"{\": the wrapper, when the whole text is one object holding an\n // `entries` array. Anything else falls through to JSONL.\n const doc = strictDocument(bytes);\n if (doc instanceof JsonObject) {\n const wrapped = doc.members.get(\"entries\");\n if (Array.isArray(wrapped)) values = wrapped;\n }\n }\n if (values === undefined) {\n // JSONL: every non-blank line is exactly one JSON value.\n values = [];\n let start = 0;\n while (start < bytes.length) {\n let end = bytes.indexOf(0x0a, start);\n if (end === -1) end = bytes.length;\n const line = bytes.subarray(start, end);\n if (firstNonSpace(line) !== undefined) values.push(strictValue(line, \"a line\"));\n start = end + 1;\n }\n }\n if (values.length === 0) throw notEntries(\"it holds no entries\");\n return values.map(entryFrom);\n}\n\n// =============================================================================\n// Anchor\n// =============================================================================\n\n// format-spec §9.1: snake_case name -> the camelCase aliases `parseAnchor`\n// also accepts. Both subject names are listed so neither is \"unknown\"; which\n// one an anchor may carry is decided by its version, below.\nconst ANCHOR_ALIASES: Readonly<Record<string, readonly string[]>> = {\n version: [],\n anchor_id: [\"anchorId\"],\n subject: [\"subjectId\"],\n company_id: [\"companyId\"],\n chain_hash: [\"chainHash\"],\n range: [],\n entry_count: [\"entryCount\"],\n signature: [],\n signing_key_id: [\"signingKeyId\"],\n created_at_ms: [\"createdAtMs\"],\n previous_anchor_id: [\"previousAnchorId\"],\n previous_anchor_hash: [\"previousAnchorHash\"],\n verified_through: [\"verifiedThrough\"],\n};\nconst RANGE_ALIASES: Readonly<Record<string, readonly string[]>> = {\n start_entry_id: [\"startEntryId\"],\n end_entry_id: [\"endEntryId\"],\n start_seq: [\"startSeq\"],\n end_seq: [\"endSeq\"],\n};\n\n// format-spec §9.1 for v7: every member is required, signature included.\nconst V7_REQUIRED = [\n \"version\",\n \"anchor_id\",\n \"subject\",\n \"chain_hash\",\n \"range\",\n \"entry_count\",\n \"signature\",\n \"signing_key_id\",\n \"created_at_ms\",\n \"previous_anchor_id\",\n \"previous_anchor_hash\",\n] as const;\n// format-spec §2.1's decimal grammar: no sign, no leading zeros, 0 to 2^63 - 1.\nconst DECIMAL_TEXT = /^(0|[1-9][0-9]*)$/;\n\nfunction nameSets(table: Readonly<Record<string, readonly string[]>>) {\n return {\n table,\n snake: new Set(Object.keys(table)) as ReadonlySet<string>,\n aliases: new Set(Object.values(table).flat()) as ReadonlySet<string>,\n };\n}\nconst ANCHOR_NAMES = nameSets(ANCHOR_ALIASES);\nconst RANGE_NAMES = nameSets(RANGE_ALIASES);\ntype Names = typeof ANCHOR_NAMES;\n\nfunction refused(detail: string): AnchorVerificationError {\n return new AnchorVerificationError(`anchor refused: ${detail}`);\n}\n\nfunction onlyKnownMembers(obj: JsonObject, names: Names, where: string): void {\n if (hasMiscasedMember(obj, names.snake, names.aliases)) {\n throw refused(`${where} has a member spelled in another case`);\n }\n for (const name of obj.members.keys()) {\n if (!names.snake.has(name) && !names.aliases.has(name)) {\n throw refused(`${where} has an unknown member`);\n }\n }\n}\n\nfunction anchorMember(obj: JsonObject, names: Names, snake: string): JsonValue | undefined {\n try {\n return pick(obj, snake, ...names.table[snake]!);\n } catch (err) {\n if (err instanceof BothSpellings) throw refused(`${snake} is given under two spellings`);\n throw err;\n }\n}\n\n/** An absent string member reads as \"\"; `checkAnchorWellFormed` judges it. */\nfunction stringMember(obj: JsonObject, names: Names, snake: string): string {\n const v = anchorMember(obj, names, snake);\n if (v === undefined) return \"\";\n if (typeof v !== \"string\") throw refused(`${snake} is not a string`);\n return v;\n}\n\n/** An absent integer member reads as 0; `checkAnchorWellFormed` judges it. */\nfunction integerMember(obj: JsonObject, names: Names, snake: string): bigint {\n const v = anchorMember(obj, names, snake);\n if (v === undefined) return 0n;\n const n = int64Of(v);\n if (n === null) throw refused(`${snake} is not an integer`);\n return n;\n}\n\n/** A v7 decimal string member (`entry_count`, `start_seq`, `end_seq`) as a bigint. */\nfunction decimalMember(obj: JsonObject, names: Names, snake: string): bigint {\n const v = anchorMember(obj, names, snake);\n if (v === undefined) throw refused(`a v7 anchor has no ${snake}`);\n if (typeof v !== \"string\") throw refused(`${snake} is not a string`);\n if (!DECIMAL_TEXT.test(v) || v.length > 19 || BigInt(v) > MAX_INT64) {\n throw refused(`${snake} is not a decimal integer from 0 to 2^63 - 1`);\n }\n return BigInt(v);\n}\n\n/** A v7 anchor (format-spec §9.1, §9.8): every member required, each with its own JSON type. */\nfunction anchorV7From(doc: JsonObject, range: JsonObject | undefined): Anchor {\n for (const name of V7_REQUIRED) {\n if (anchorMember(doc, ANCHOR_NAMES, name) === undefined) {\n throw refused(`a v7 anchor has no ${name}`);\n }\n }\n if (anchorMember(doc, ANCHOR_NAMES, \"verified_through\") !== undefined) {\n throw refused(\"a v7 anchor has no verified_through\");\n }\n if (range === undefined) throw refused(\"a v7 anchor has no range\");\n for (const name of [\"start_entry_id\", \"end_entry_id\"]) {\n if (anchorMember(range, RANGE_NAMES, name) !== undefined) {\n throw refused(\"a v7 range names start_seq and end_seq, not entry ids\");\n }\n }\n return {\n version: 7,\n anchorId: stringMember(doc, ANCHOR_NAMES, \"anchor_id\"),\n subject: stringMember(doc, ANCHOR_NAMES, \"subject\"),\n chainHash: stringMember(doc, ANCHOR_NAMES, \"chain_hash\"),\n range: {\n startEntryId: \"\",\n endEntryId: \"\",\n startSeq: decimalMember(range, RANGE_NAMES, \"start_seq\"),\n endSeq: decimalMember(range, RANGE_NAMES, \"end_seq\"),\n },\n entryCount: decimalMember(doc, ANCHOR_NAMES, \"entry_count\"),\n signature: stringMember(doc, ANCHOR_NAMES, \"signature\"),\n signingKeyId: stringMember(doc, ANCHOR_NAMES, \"signing_key_id\"),\n createdAtMs: narrow(integerMember(doc, ANCHOR_NAMES, \"created_at_ms\")),\n previousAnchorId: stringMember(doc, ANCHOR_NAMES, \"previous_anchor_id\"),\n previousAnchorHash: stringMember(doc, ANCHOR_NAMES, \"previous_anchor_hash\"),\n };\n}\n\n/**\n * Parse the text of an anchor strictly (format-spec §9.8).\n *\n * # Description\n *\n * An anchor is read strictly: only the member names of §9.1, each at most\n * once, and `range` likewise. The subject is under the name its version uses\n * (`subject` from v6, `company_id` before); an anchor carrying the other name,\n * or both, is refused. A lenient parser accepts members the signature does not\n * cover and lets two readers see two different anchors.\n *\n * Each member may be spelled in snake_case or in the camelCase alias\n * `parseAnchor` accepts (`anchorId`, `chainHash`, `subjectId`, ...). An anchor\n * carrying BOTH spellings of one member is refused, and so is a known\n * snake_case name in another letter case (`ENTRY_COUNT`).\n *\n * A member of the wrong JSON type is refused; integers are JSON integers (no\n * quotes, no fraction, no exponent, no `-0`, within 64 bits) and are never\n * rounded. An ABSENT member is not refused here: it reads as \"\" or 0 (an\n * absent `range` as two empty ids), and `checkAnchorWellFormed` judges the\n * result. Nor is the version judged here.\n *\n * A v7 anchor is read more strictly (§9.8): every member of §9.1 is\n * required, `signature` included; `verified_through` and an entry-id range\n * are refused; `entry_count`, `range.start_seq` and `range.end_seq` must be\n * JSON STRINGS in §2.1's decimal grammar (a JSON number is refused: it would\n * round above 2^53) and are returned as bigints. A v1-v6 anchor carrying\n * `previous_anchor_hash` or a sequence range is refused.\n *\n * This is PARSING. The version, its invariants and the counts (§9.3, §9.8)\n * are checked by `checkAnchorWellFormed`, which `verifyAnchorLocally` and\n * `bindAnchorToEntries` both call.\n *\n * # Inputs\n *\n * - text: The anchor's JSON. Pass the raw bytes when you have them.\n *\n * # Outputs\n *\n * - Anchor: The parsed anchor. int64 fields are `number` while exact and\n * `bigint` beyond `Number.MAX_SAFE_INTEGER`.\n * - AnchorVerificationError: Thrown when the anchor is refused. The message\n * names a member, never a value.\n *\n * # Example\n *\n * const anchor = parseAnchorText(await response.text());\n * verifyAnchorLocally(anchor, publicKey);\n *\n * # Limitations\n *\n * - Does not verify the signature or bind the anchor to a chain.\n * - Returns an anchor that may be malformed (a missing member, a withdrawn\n * version): parse, then check.\n *\n * # Assumptions\n *\n * - None.\n */\nexport function parseAnchorText(text: string | Uint8Array): Anchor {\n const r = parseStrictJson(toBytes(text), MAX_ANCHOR_DEPTH);\n if (!r.ok) throw refused(\"not valid JSON for an anchor\");\n if (r.duplicateKey) throw refused(\"a member name is repeated\");\n const doc = r.value;\n if (!(doc instanceof JsonObject)) throw refused(\"not a JSON object\");\n onlyKnownMembers(doc, ANCHOR_NAMES, \"the anchor\");\n\n // Dispatch on the declared version only (§9.2). A version that is an\n // integer but not one this format defines is checkAnchorWellFormed's to\n // refuse; clamp it so `Number()` cannot round it into a known one.\n const declared = integerMember(doc, ANCHOR_NAMES, \"version\");\n const version = declared < 0n || declared > 1000n ? -1 : Number(declared);\n\n const subjectName = version === 6 || version === 7 ? \"subject\" : \"company_id\";\n const otherName = subjectName === \"subject\" ? \"company_id\" : \"subject\";\n if (anchorMember(doc, ANCHOR_NAMES, otherName) !== undefined) {\n throw refused(`this version names its subject ${subjectName}, not ${otherName}`);\n }\n\n const rangeValue = anchorMember(doc, ANCHOR_NAMES, \"range\");\n let range = new JsonObject();\n if (rangeValue !== undefined) {\n if (!(rangeValue instanceof JsonObject)) throw refused(\"range is not an object\");\n range = rangeValue;\n onlyKnownMembers(range, RANGE_NAMES, \"range\");\n }\n\n if (version === 7) return anchorV7From(doc, rangeValue === undefined ? undefined : range);\n // §9.8, the wrong range shape: v1-v6 name the range by entry id, and carry\n // no predecessor hash (the caller supplies it).\n if (\n anchorMember(range, RANGE_NAMES, \"start_seq\") !== undefined ||\n anchorMember(range, RANGE_NAMES, \"end_seq\") !== undefined\n ) {\n throw refused(\"a v1-v6 range names start_entry_id and end_entry_id, not sequence numbers\");\n }\n if (anchorMember(doc, ANCHOR_NAMES, \"previous_anchor_hash\") !== undefined) {\n throw refused(\"only a v7 anchor carries previous_anchor_hash\");\n }\n\n return {\n version,\n anchorId: stringMember(doc, ANCHOR_NAMES, \"anchor_id\"),\n subject: stringMember(doc, ANCHOR_NAMES, subjectName),\n chainHash: stringMember(doc, ANCHOR_NAMES, \"chain_hash\"),\n range: {\n startEntryId: stringMember(range, RANGE_NAMES, \"start_entry_id\"),\n endEntryId: stringMember(range, RANGE_NAMES, \"end_entry_id\"),\n },\n entryCount: narrow(integerMember(doc, ANCHOR_NAMES, \"entry_count\")),\n signature: stringMember(doc, ANCHOR_NAMES, \"signature\"),\n signingKeyId: stringMember(doc, ANCHOR_NAMES, \"signing_key_id\"),\n createdAtMs: narrow(integerMember(doc, ANCHOR_NAMES, \"created_at_ms\")),\n previousAnchorId: stringMember(doc, ANCHOR_NAMES, \"previous_anchor_id\"),\n verifiedThrough: narrow(integerMember(doc, ANCHOR_NAMES, \"verified_through\")),\n };\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Node-only filesystem loaders for anchor / exported-entries JSON files.\n *\n * Split out of `anchor.ts` as part of `dsar_js_browser_target_audit` so\n * the browser bundle (`src/index.browser.ts` → `dist/browser/`) does not\n * pull the dynamic `import(\"fs/promises\")` call into its reachable\n * graph. esbuild's tree-shaker cannot prove a dynamic import is dead,\n * so simply not re-exporting these from the browser entry was\n * insufficient — the loaders had to live in a different file the\n * browser entry never imports.\n *\n * The strict text readers (`parseAnchorText`, `parseEntriesText`) live in\n * `strictText.ts` and are the surface browsers use after `fetch()`-ing the\n * file themselves. The loaders here read the file's bytes and go through the\n * same two readers, so a file is refused or accepted alike in both places.\n */\n\nimport type { Anchor, ExportedEntry } from \"./types.js\";\nimport { parseAnchorText, parseEntriesText } from \"./strictText.js\";\n\n/**\n * Load anchor from JSON file (Node.js only).\n *\n * # Description\n *\n * Reads an anchor JSON file from disk and parses it STRICTLY with\n * parseAnchorText (format-spec §9.8): only the anchor's own member names,\n * spelled exactly, none repeated, the subject under its version's name.\n *\n * # Inputs\n *\n * - path: Filesystem path to the anchor JSON file\n *\n * # Outputs\n *\n * - Promise<Anchor>: Resolves to the parsed Anchor object\n * - Error: Rejects if the file cannot be read\n * - AnchorVerificationError: Rejects if the anchor is refused\n *\n * # Example\n *\n * const anchor = await loadAnchor('anchor-2026-01-20.json');\n *\n * # Limitations\n *\n * - Node.js only (uses fs/promises). Browser consumers should\n * `fetch(...)` the file themselves and pass its text (or bytes) to\n * `parseAnchorText` directly.\n *\n * # Assumptions\n *\n * - File is valid UTF-8 JSON in flat snake_case format\n */\nexport async function loadAnchor(path: string): Promise<Anchor> {\n const fs = await import(\"fs/promises\");\n // The bytes, not a decoded string: decoding would replace invalid UTF-8 and\n // strip a byte-order mark before the strict reader could refuse them.\n return parseAnchorText(new Uint8Array(await fs.readFile(path)));\n}\n\n/**\n * Load exported entries from JSON file (Node.js only).\n *\n * # Description\n *\n * Reads an entries file from disk and decodes it STRICTLY with\n * parseEntriesText: a JSON array of entries, JSONL, or the platform's\n * `{\"entries\": [...]}` wrapper. A file that is not\n * entries (an export bundle, an anchor, `{}`, an entry with a repeated or\n * missing member) is an error, never a broken chain.\n *\n * # Inputs\n *\n * - path: Filesystem path to the entries JSON file\n *\n * # Outputs\n *\n * - Promise<ExportedEntry[]>: Resolves to array of parsed ExportedEntry objects\n * - Error: Rejects if the file cannot be read\n * - EntriesFormatError: Rejects if the file is not entries\n *\n * # Example\n *\n * const entries = await loadExportedEntries('export-2026-01.json');\n *\n * # Limitations\n *\n * - Node.js only (uses fs/promises). Browser consumers should\n * `fetch(...)` the file themselves and pass its text (or bytes) to\n * `parseEntriesText` directly.\n * - The hosted platform's `{\"entries\": [...]}` wrapper is unwrapped; any\n * other top-level object is refused.\n *\n * # Assumptions\n *\n * - File is valid UTF-8: a JSON array of entries, JSONL, or the wrapper\n */\nexport async function loadExportedEntries(path: string): Promise<ExportedEntry[]> {\n const fs = await import(\"fs/promises\");\n return parseEntriesText(new Uint8Array(await fs.readFile(path)));\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Chain format v4 (format-spec §2.0): the leaf hash and the chain hash.\n *\n * ```\n * leaf_hash = SHA-512(\"aleutian.chain.leaf.v4:\"\n * ‖ len(entry_id) ‖ entry_id ‖ len(entry_type) ‖ entry_type\n * ‖ content_hash ‖ salt)\n * chain_hash = SHA-512(\"aleutian.chain.v4:\"\n * ‖ previous_hash ‖ \"|\" ‖ global_seq ‖ \"|\" ‖ timestamp ‖ \"|\" ‖ leaf_hash)\n * ```\n *\n * `len` is a 4-byte big-endian byte count. `entry_id` and `entry_type` are\n * hashed as their UTF-8 bytes EXACTLY AS STORED, never normalised: two\n * spellings that hashed alike would be a field an editor could change without\n * detection. `content_hash` and `salt` are hashed as their lowercase hex text.\n *\n * v4 separates what links the chain (the leaf hash) from what erasure removes\n * (the id, type, content hash and salt), so an erased entry is still\n * recomputed from its stored leaf hash (format-spec §5.0): no chain hash is\n * ever taken on trust.\n *\n * Written from the format spec alone. Hashing is synchronous\n * (`@noble/hashes`); the `compute*` functions return promises only so they\n * read like the v2/v3 functions. Browser-safe.\n */\n\nimport { sha512 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex, utf8ToBytes } from \"@noble/hashes/utils.js\";\n\n/** Chain format version 4 (format-spec §2.2). */\nexport const FORMAT_V4 = 4;\n\n/** The leaf hash's domain string (format-spec §2.0). */\nexport const CHAIN_LEAF_DOMAIN_V4 = \"aleutian.chain.leaf.v4:\";\n\n/** The v4 chain hash's domain string (format-spec §2.0). */\nexport const CHAIN_HASH_PREFIX_V4 = \"aleutian.chain.v4:\";\n\nconst HEX_128 = /^[0-9a-f]{128}$/;\nconst HEX_64 = /^[0-9a-f]{64}$/;\nconst DECIMAL = /^(0|[1-9][0-9]*)$/;\nconst TIMESTAMP =\n /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})\\.[0-9]{6}Z$/;\nconst MAX_INT64 = 2n ** 63n - 1n;\n// format-spec §2.0: U+0000 to U+001F and U+007F. Matching them is the point.\n// eslint-disable-next-line no-control-regex\nconst CONTROL = /[\\u0000-\\u001f\\u007f]/;\nconst LONE_SURROGATE =\n /[\\ud800-\\udbff](?![\\udc00-\\udfff])|(?<![\\ud800-\\udbff])[\\udc00-\\udfff]/;\n\nconst LEAF_DOMAIN_BYTES = utf8ToBytes(CHAIN_LEAF_DOMAIN_V4);\n\n/**\n * Whether a value is an `entry_id` or `entry_type` as v4 allows it\n * (format-spec §2.0, §5.5): a string of 1 to 256 UTF-8 bytes, valid UTF-8 (no\n * lone surrogate), with no control character (U+0000 to U+001F, U+007F).\n *\n * `|` and every other printable character are allowed: the field is\n * length-prefixed in the leaf hash.\n *\n * @param value - The stored value; anything but a string is refused\n * @returns True when the value may be hashed into a leaf\n */\nexport function isLeafText(value: unknown): value is string {\n if (typeof value !== \"string\" || value === \"\") return false;\n if (LONE_SURROGATE.test(value) || CONTROL.test(value)) return false;\n // At most 256 bytes; every UTF-16 unit encodes to at least one byte, so a\n // longer string is refused before encoding it.\n if (value.length > 256) return false;\n return utf8ToBytes(value).length <= 256;\n}\n\n/** Whether a string is a salt as v4 writes it: exactly 64 lowercase hex. */\nexport function isSalt(value: unknown): value is string {\n return typeof value === \"string\" && HEX_64.test(value);\n}\n\n/**\n * Whether a v4 entry carries the shape of a v2/v3 tombstone (format-spec §2.0):\n * `entry_type` `tombstone`, an `entry_id` starting `tomb_`, or a `content_hash`\n * starting `TOMBSTONE:`. Any ONE of them is `format_field_misuse` in v4.\n */\nexport function hasTombstoneShapeV4(\n entryId: string | undefined,\n entryType: string | undefined,\n contentHash: string | undefined\n): boolean {\n return (\n entryType === \"tombstone\" ||\n (entryId?.startsWith(\"tomb_\") ?? false) ||\n (contentHash?.startsWith(\"TOMBSTONE:\") ?? false)\n );\n}\n\nfunction u32(n: number): Uint8Array {\n return new Uint8Array([(n >>> 24) & 0xff, (n >>> 16) & 0xff, (n >>> 8) & 0xff, n & 0xff]);\n}\n\nfunction concat(parts: readonly Uint8Array[]): Uint8Array {\n let size = 0;\n for (const p of parts) size += p.length;\n const out = new Uint8Array(size);\n let at = 0;\n for (const p of parts) {\n out.set(p, at);\n at += p.length;\n }\n return out;\n}\n\n/**\n * The exact bytes the v4 leaf hash covers, WITHOUT validating anything.\n *\n * @internal Use {@link computeLeafHashV4}; this exists for callers that have\n * checked every field already (the bundle verifier) and for tests that pin\n * the preimage.\n */\nexport function leafPreimageV4(\n entryId: string,\n entryType: string,\n contentHash: string,\n salt: string\n): Uint8Array {\n const id = utf8ToBytes(entryId);\n const type = utf8ToBytes(entryType);\n return concat([\n LEAF_DOMAIN_BYTES,\n u32(id.length),\n id,\n u32(type.length),\n type,\n utf8ToBytes(contentHash),\n utf8ToBytes(salt),\n ]);\n}\n\n/**\n * The v4 leaf hash over fields already checked, synchronously.\n *\n * @internal Validates nothing; see {@link computeLeafHashV4}.\n */\nexport function leafHashV4Sync(\n entryId: string,\n entryType: string,\n contentHash: string,\n salt: string\n): string {\n return bytesToHex(sha512(leafPreimageV4(entryId, entryType, contentHash, salt)));\n}\n\n/**\n * The v4 chain hash over fields already checked, synchronously.\n *\n * @internal Validates nothing; see {@link computeChainHashV4}.\n */\nexport function chainHashV4Sync(\n previousHash: string,\n globalSeq: string,\n timestamp: string,\n leafHash: string\n): string {\n return bytesToHex(\n sha512(\n utf8ToBytes(\n CHAIN_HASH_PREFIX_V4 + previousHash + \"|\" + globalSeq + \"|\" + timestamp + \"|\" + leafHash\n )\n )\n );\n}\n\n/** A `global_seq` as base-10 text, or an Error naming the field. */\nfunction globalSeqText(globalSeq: number | bigint | string): string {\n if (typeof globalSeq === \"string\") {\n if (!DECIMAL.test(globalSeq) || globalSeq.length > 19 || BigInt(globalSeq) > MAX_INT64) {\n throw new Error(\n \"globalSeq must be base-10 with no sign or leading zeros, from 0 to 2^63 - 1\"\n );\n }\n return globalSeq;\n }\n if (typeof globalSeq === \"number\") {\n if (!Number.isSafeInteger(globalSeq)) {\n throw new Error(\n \"globalSeq is not a safe integer; pass a bigint or a decimal string beyond 2^53\"\n );\n }\n globalSeq = BigInt(globalSeq);\n }\n if (typeof globalSeq !== \"bigint\" || globalSeq < 0n || globalSeq > MAX_INT64) {\n throw new Error(\"globalSeq must be an integer from 0 to 2^63 - 1\");\n }\n return globalSeq.toString();\n}\n\n/** format-spec §4's form; the calendar is not judged here (§4 is about spelling). */\nfunction isTimestampForm(value: string): boolean {\n const m = TIMESTAMP.exec(value);\n if (!m) return false;\n const year = Number(m[1]);\n const month = Number(m[2]);\n const day = Number(m[3]);\n if (month < 1 || month > 12 || day < 1) return false;\n const leap = (year % 4 === 0 && year % 100 !== 0) || year % 400 === 0;\n const days = [31, leap ? 29 : 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n if (day > days[month - 1]!) return false;\n return Number(m[4]) <= 23 && Number(m[5]) <= 59 && Number(m[6]) <= 59;\n}\n\n/**\n * Compute the v4 leaf hash of a live entry (format-spec §2.0).\n *\n * # Description\n *\n * Validates every field, then hashes the domain, the length-prefixed id and\n * type (UTF-8, as given), the content hash and the salt.\n *\n * # Inputs\n *\n * - entryId: 1 to 256 UTF-8 bytes, no control characters; not `tomb_…`\n * - entryType: as entryId; not `tombstone`\n * - contentHash: 128 lowercase hex (v4 has no tombstone value)\n * - salt: 64 lowercase hex\n *\n * # Outputs\n *\n * - Promise<string>: 128 lowercase hex\n * - Error: thrown (as a rejection) when a field is outside its shape. The\n * message names the field, never its value.\n *\n * # Example\n *\n * const leaf = await computeLeafHashV4(\"ent_0001\", \"event\", contentHash, salt);\n *\n * # Limitations\n *\n * - Does not mint salts: this SDK verifies, it never writes.\n *\n * # Assumptions\n *\n * - None: every field is validated.\n */\nexport function computeLeafHashV4(\n entryId: string,\n entryType: string,\n contentHash: string,\n salt: string\n): Promise<string> {\n // The executor's throw becomes the rejection.\n return new Promise((resolve) => resolve(leafHashV4Checked(entryId, entryType, contentHash, salt)));\n}\n\nfunction leafHashV4Checked(\n entryId: string,\n entryType: string,\n contentHash: string,\n salt: string\n): string {\n if (!isLeafText(entryId)) {\n throw new Error(\"entryId must be 1 to 256 UTF-8 bytes with no control character\");\n }\n if (!isLeafText(entryType)) {\n throw new Error(\"entryType must be 1 to 256 UTF-8 bytes with no control character\");\n }\n if (typeof contentHash !== \"string\" || !HEX_128.test(contentHash)) {\n throw new Error(\"contentHash must be exactly 128 lowercase hex characters\");\n }\n if (hasTombstoneShapeV4(entryId, entryType, contentHash)) {\n throw new Error(\"a v4 entry has no tombstone type or tomb_ id (format-spec §2.0)\");\n }\n if (!isSalt(salt)) {\n throw new Error(\"salt must be exactly 64 lowercase hex characters\");\n }\n return leafHashV4Sync(entryId, entryType, contentHash, salt);\n}\n\n/**\n * Compute the v4 chain hash of an entry (format-spec §2.0).\n *\n * # Description\n *\n * Validates the fields, including the first-entry rule (an empty\n * `previousHash` goes with `globalSeq` 0, a non-empty one with a `globalSeq`\n * above 0), then hashes the `|`-delimited preimage. For an erased entry, pass\n * its stored leaf hash: that is exactly what the verifier recomputes from.\n *\n * # Inputs\n *\n * - previousHash: \"\" for the chain's first entry, else 128 lowercase hex\n * - globalSeq: 0 to 2^63 - 1, as a bigint, a safe number, or base-10 text\n * - timestamp: exactly `YYYY-MM-DDTHH:MM:SS.ffffffZ` (format-spec §4)\n * - leafHash: 128 lowercase hex\n *\n * # Outputs\n *\n * - Promise<string>: 128 lowercase hex\n * - Error: thrown (as a rejection) when a field is malformed\n *\n * # Example\n *\n * const h = await computeChainHashV4(prev, 1n, \"2026-10-16T08:00:01.111111Z\", leaf);\n *\n * # Limitations\n *\n * - Checks one entry; linkage across entries is `verifyChainOffline`'s.\n *\n * # Assumptions\n *\n * - None: every field is validated.\n */\nexport function computeChainHashV4(\n previousHash: string,\n globalSeq: number | bigint | string,\n timestamp: string,\n leafHash: string\n): Promise<string> {\n // The executor's throw becomes the rejection.\n return new Promise((resolve) =>\n resolve(chainHashV4Checked(previousHash, globalSeq, timestamp, leafHash))\n );\n}\n\nfunction chainHashV4Checked(\n previousHash: string,\n globalSeq: number | bigint | string,\n timestamp: string,\n leafHash: string\n): string {\n if (typeof previousHash !== \"string\" || (previousHash !== \"\" && !HEX_128.test(previousHash))) {\n throw new Error(\"previousHash must be empty or exactly 128 lowercase hex characters\");\n }\n const seq = globalSeqText(globalSeq);\n if ((previousHash === \"\") !== (seq === \"0\")) {\n throw new Error(\n \"an entry with an empty previousHash has globalSeq 0, and only it (format-spec §2.0)\"\n );\n }\n if (typeof timestamp !== \"string\" || !isTimestampForm(timestamp)) {\n throw new Error(\"timestamp must be YYYY-MM-DDTHH:MM:SS.ffffffZ (UTC, six digits)\");\n }\n if (typeof leafHash !== \"string\" || !HEX_128.test(leafHash)) {\n throw new Error(\"leafHash must be exactly 128 lowercase hex characters\");\n }\n return chainHashV4Sync(previousHash, seq, timestamp, leafHash);\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Cross-runtime constant-time byte-array equality.\n *\n * Prefers the runtime's built-in constant-time comparator when one is\n * available (Node ≥ 16's `crypto.timingSafeEqual`, implemented at C\n * level), and falls back to a pure-JS implementation in browsers and\n * other runtimes that do not ship a built-in.\n *\n * This module is the single source of truth for constant-time\n * comparison across the SDK. Both `verifyV3.ts` and `consent.ts`\n * depend on it; `webhook.ts` is Node-only and continues to use the\n * Node `crypto` API directly.\n *\n * # Why it exists as a separate module\n *\n * `verifyV3.ts` shipped this logic first in the chain_f track. When\n * the browser-target audit revealed that `consent.ts` was still using\n * a top-level static `import { timingSafeEqual } from \"crypto\"` (a\n * module-load blocker in browsers), the cleanest fix was to lift the\n * dynamic-require pattern into a shared internal module rather than\n * duplicate it inline. See `dsar_js_browser_target_audit` Unit A.\n *\n * # Runtime caveat (browsers)\n *\n * The JS fallback iterates `max(a.length, b.length)` bytes and ORs\n * into an accumulator without short-circuiting — but JIT\n * optimizations and timer resolution on browser hosts can still\n * leak residual timing signal in adversarial conditions. The caveat\n * is documented in `sdk_threat_model_doc`; for high-assurance\n * deployments, prefer the Node runtime (which uses the built-in).\n */\n\nlet _nodeTimingSafeEqual:\n | ((a: Uint8Array, b: Uint8Array) => boolean)\n | null = null;\n\ntry {\n // Dynamic require so the module loads cleanly in browsers (where\n // `node:crypto` doesn't resolve). The bundler tree-shakes this\n // path out of browser builds.\n // eslint-disable-next-line @typescript-eslint/no-require-imports\n const nodeCrypto = require(\"node:crypto\") as {\n timingSafeEqual?: (a: Uint8Array, b: Uint8Array) => boolean;\n };\n if (typeof nodeCrypto.timingSafeEqual === \"function\") {\n _nodeTimingSafeEqual = nodeCrypto.timingSafeEqual;\n }\n} catch {\n // Browser / Deno / other runtimes — fall through to the pure-JS\n // fallback. No exception is propagated; the absence is the\n // expected detection signal.\n}\n\n/**\n * Constant-time byte-array equality. Returns `true` iff `a` and `b`\n * are byte-identical.\n *\n * # Why constant-time matters here\n *\n * A short-circuiting compare leaks the position of the first\n * differing byte via timing, which on a hash-comparison gate\n * becomes a forgery oracle: an attacker can brute-force the hash\n * one byte at a time.\n *\n * # Implementation\n *\n * Under Node 16+ this delegates to `crypto.timingSafeEqual` (the\n * built-in C implementation). Under browsers it uses a pure-JS\n * fallback that iterates the longer of the two inputs and ORs\n * into an accumulator.\n */\nexport function constantTimeEqual(a: Uint8Array, b: Uint8Array): boolean {\n // Length mismatch: Node's built-in throws RangeError on length\n // mismatch (it requires equal-length inputs), so we handle that\n // gate ourselves before delegating. The XOR-of-lengths variant\n // ensures the constant-time property survives the gate.\n if (a.length !== b.length) {\n // Still iterate over max length to avoid a length-leaking\n // early return that could be timeable. Then return false.\n let acc = 1; // non-zero baseline so result is always false\n const n = Math.max(a.length, b.length);\n for (let i = 0; i < n; i++) {\n const ai = i < a.length ? a[i]! : 0;\n const bi = i < b.length ? b[i]! : 0;\n acc |= ai ^ bi;\n }\n return acc === 0; // unreachable true given the seeded 1, but\n // structured for property clarity\n }\n if (_nodeTimingSafeEqual !== null) {\n return _nodeTimingSafeEqual(a, b);\n }\n // Pure-JS fallback (browsers / non-Node runtimes).\n let diff = 0;\n for (let i = 0; i < a.length; i++) {\n diff |= a[i]! ^ b[i]!;\n }\n return diff === 0;\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Chain verification for the Aleutian verification SDK.\n *\n * This module provides functions to verify chain integrity using exported\n * entries without requiring network access to Aleutian APIs.\n */\n\nimport { AnchorVerificationError, ChainVerificationError } from \"./errors.js\";\nimport {\n computeChainHash,\n computeChainHashV3,\n isChainDigest,\n isChainTimestamp,\n normalizeFormatVersion,\n FORMAT_V2,\n FORMAT_V3,\n} from \"./chain.js\";\nimport {\n chainHashV4Sync,\n FORMAT_V4,\n hasTombstoneShapeV4,\n isLeafText,\n isSalt,\n leafHashV4Sync,\n} from \"./chainV4.js\";\nimport { checkAnchorWellFormed } from \"./anchorCanonical.js\";\nimport {\n SEED_ANCHOR_HASH,\n SEED_ANCHOR_ID,\n anchorChainHashV7Sync,\n computeAnchorChainHash,\n} from \"./anchorChainHash.js\";\nimport { constantTimeEqual } from \"./internal/constantTime.js\";\nimport { isTombstone, validateTombstoneContentHash } from \"./tombstone.js\";\nimport type {\n Anchor,\n AnchorBindExpectations,\n AnchorBindOutcome,\n AnchorBindResult,\n BreakType,\n ExportedEntry,\n OfflineVerificationResult,\n OfflineBreak,\n ChainVerifyOptions,\n} from \"./types.js\";\n\n// Reuse a single TextEncoder for hex-string → byte encoding; the encoder\n// is stateless and safe to share. Used only to feed the shared\n// constant-time comparator (which operates on Uint8Array).\nconst HEX_ENCODER = new TextEncoder();\n\n/**\n * Constant-time equality of two ASCII/hex strings.\n *\n * Delegates to the shared `internal/constantTime.ts` byte comparator\n * (which prefers Node's C-level `crypto.timingSafeEqual` when\n * available and uses a non-short-circuiting pure-JS fallback\n * elsewhere). Hex hashes encode 1:1 ASCII so byte-length matches\n * char-length and the comparator's length-mismatch handling stays\n * constant-time. Replaces the local string-XOR variant that used\n * to live here; see dsar_js_verify_consolidate_constant_time.\n */\nfunction chainHashEqual(a: string, b: string): boolean {\n return constantTimeEqual(HEX_ENCODER.encode(a), HEX_ENCODER.encode(b));\n}\n\n// global_seq is a signed 64-bit integer in every implementation (format-spec §2.1).\nconst MAX_INT64 = 2n ** 63n - 1n;\n\n/**\n * Read a global_seq as an exact integer, or null when it is not one.\n *\n * A `number` that is not a safe integer has already been rounded (or was never\n * an integer), so it is not the value on the wire and is not compared.\n */\nfunction exactInteger(value: unknown): bigint | null {\n if (typeof value === \"bigint\") return value;\n if (typeof value === \"number\" && Number.isSafeInteger(value)) return BigInt(value);\n return null;\n}\n\n/**\n * The ONE rule that decides whether an entry is a tombstone (format-spec §5,\n * §5.5): `entryType === \"tombstone\"` AND `entryId` starts with `tomb_`. A\n * `TOMBSTONE:` content hash on any other entry does not make it one.\n */\nfunction isTombstoneEntry(entry: ExportedEntry): boolean {\n return (\n typeof entry.entryType === \"string\" &&\n typeof entry.entryId === \"string\" &&\n isTombstone(entry.entryType, entry.entryId)\n );\n}\n\n/** What a walk of the entries found. */\ninterface ChainWalk {\n readonly breaks: OfflineBreak[];\n readonly tombstonesFound: number;\n readonly lastTombstone: number;\n /** Every position read as a tombstone, ascending. */\n readonly tombstonePositions: readonly number[];\n readonly erasedFound: number;\n}\n\n/**\n * Whether an entry carried a member (format-spec §2.0 tells absent from\n * empty). Exact for entries `parseEntriesText` read (`presentMembers`); for an\n * entry built in code, an empty string or a zero `sequenceNum` counts as\n * absent, as does an undefined optional field.\n */\nfunction carries(entry: ExportedEntry, snake: string): boolean {\n const present = entry.presentMembers;\n if (present !== undefined) return present.has(snake);\n const e = entry as unknown as Record<string, unknown>;\n switch (snake) {\n case \"entry_id\":\n return e.entryId !== undefined && e.entryId !== \"\";\n case \"entry_type\":\n return e.entryType !== undefined && e.entryType !== \"\";\n case \"content_hash\":\n return e.contentHash !== undefined && e.contentHash !== \"\";\n case \"run_id\":\n return e.runId !== undefined && e.runId !== \"\";\n case \"sequence_num\":\n return e.sequenceNum !== undefined && e.sequenceNum !== 0;\n case \"salt\":\n return e.salt !== undefined;\n case \"leaf_hash\":\n return e.leafHash !== undefined;\n case \"erased\":\n return e.erased !== undefined;\n case \"global_seq\":\n return e.globalSeq !== undefined;\n default:\n return true;\n }\n}\n\n/** The two v4 entry shapes of format-spec §2.0, beyond the members every entry has. */\nconst V4_LIVE_ONLY = [\"entry_id\", \"entry_type\", \"content_hash\", \"salt\"] as const;\n\n/**\n * The first §2.0 / §5.5 shape rule a v4 entry breaks (step 7), or null.\n * `linkedFrom` is the hash the entry links from: \"\" for a chain's first entry.\n */\nfunction v4ShapeProblem(\n entry: ExportedEntry,\n seq: bigint | null,\n hasPredecessor: boolean\n): { field: string; detail: string } | null {\n if (!carries(entry, \"global_seq\") || !carries(entry, \"leaf_hash\")) {\n return { field: \"shape\", detail: \"a v4 entry carries global_seq and leaf_hash\" };\n }\n if (entry.erased !== undefined || carries(entry, \"erased\")) {\n if (entry.erased !== true) {\n return { field: \"erased\", detail: \"a live v4 entry carries no erased member\" };\n }\n for (const name of V4_LIVE_ONLY) {\n if (carries(entry, name)) {\n return {\n field: \"shape\",\n detail: \"an erased v4 entry carries no entry_id, entry_type, content_hash or salt\",\n };\n }\n }\n } else {\n for (const name of V4_LIVE_ONLY) {\n if (!carries(entry, name)) {\n return {\n field: \"shape\",\n detail: \"a live v4 entry carries entry_id, entry_type, content_hash and salt\",\n };\n }\n }\n if (!isLeafText(entry.entryId)) {\n return {\n field: \"entryId\",\n detail: \"entryId must be 1 to 256 UTF-8 bytes with no control character\",\n };\n }\n if (!isLeafText(entry.entryType)) {\n return {\n field: \"entryType\",\n detail: \"entryType must be 1 to 256 UTF-8 bytes with no control character\",\n };\n }\n if (!isChainDigest(entry.contentHash)) {\n return {\n field: \"contentHash\",\n detail: \"a v4 contentHash must be exactly 128 lowercase hex characters\",\n };\n }\n if (!isSalt(entry.salt)) {\n return { field: \"salt\", detail: \"salt must be exactly 64 lowercase hex characters\" };\n }\n }\n if (!isChainDigest(entry.leafHash)) {\n return { field: \"leafHash\", detail: \"leafHash must be exactly 128 lowercase hex characters\" };\n }\n if (seq === null || seq < 0n || seq > MAX_INT64) {\n return {\n field: \"globalSeq\",\n detail: \"globalSeq must be an integer from 0 to 2^63 - 1 (a bigint beyond 2^53)\",\n };\n }\n // §2.0, the first entry: an empty previous hash goes with global_seq 0, and\n // a previous hash with a global_seq above 0.\n if (hasPredecessor !== seq > 0n) {\n return {\n field: \"globalSeq\",\n detail: hasPredecessor\n ? \"an entry with a predecessor has a globalSeq above 0\"\n : \"a v4 entry with no predecessor has globalSeq 0: walk a segment from its predecessor hash\",\n };\n }\n return null;\n}\n\n/**\n * Walk entries and collect every break (format-spec §2, §4, §5.0, §5.5).\n *\n * The order of checks is fixed (§5.5), so every implementation names the same\n * FIRST break for an entry with several defects:\n *\n * 1. `sequence_gap`: `globalSeq` is not the previous entry's plus one\n * (recorded, and the entry is still checked)\n * 2. `invalid_field`: `chainHash` is not a digest, on every entry\n * 3. `format_field_misuse`: a v2 or v3 entry after a v4 entry (§2.5), a v4\n * member (`salt`, `leaf_hash`, `erased`) on a v2 or v3 entry (§2.2), or a\n * v4 entry with run fields or a tombstone shape (§2.0)\n * 4. (v2 and v3) a tombstone's own checks, and then nothing else\n * 5. `invalid_timestamp`\n * 6. the declared format: `unknown_format`, or a v3 entry with run fields\n * 7. `invalid_field`: field shapes; for v4 the two entry shapes and the\n * first-entry rule of §2.0\n * 8. `hash_mismatch`: for v4 the leaf hash first, then the chain hash\n *\n * After a break in steps 2 to 7 the walk continues from the entry's stored\n * chain hash. After a v4 leaf mismatch it continues from the chain hash the\n * RECOMPUTED leaf gives (§5.0); after a chain mismatch, from the expected one.\n *\n * Counts (§5.5): `tombstonesFound` counts entries read as tombstones and not\n * refused at step 3; `erasedFound` counts v4 entries with `erased: true`,\n * whatever else is wrong with them. Neither counts an entry whose chain_hash\n * is out of shape (step 2). Both count every entry walked.\n *\n * The shape is checked on its own because a hash recomputed over malformed\n * fields can equal the stored one (§5.5).\n */\nasync function walkChain(\n entries: readonly ExportedEntry[],\n startHash: string,\n maxBreaks: number\n): Promise<ChainWalk> {\n const breaks: OfflineBreak[] = [];\n // format-spec §3, §5.5: the supplied predecessor hash is a digest too. It\n // is the one unvalidated field that could shift a preimage boundary.\n const startMalformed = startHash !== \"\" && !isChainDigest(startHash);\n // null: the hash to link from is not known (a malformed predecessor), so the\n // next entry cannot be recomputed. Its own break has been reported.\n let previousHash: string | null = startMalformed ? null : startHash;\n let previousSeq: bigint | null = null;\n let tombstonesFound = 0;\n let lastTombstone = -1;\n const tombstonePositions: number[] = [];\n let erasedFound = 0;\n // §2.5: from the first v4 entry on, every entry is v4.\n let seenV4 = false;\n\n const report = (\n position: number,\n entry: ExportedEntry,\n breakType: BreakType,\n context: Record<string, string>,\n expectedHash = \"\"\n ): void => {\n breaks.push({\n position,\n entryId: typeof entry.entryId === \"string\" ? entry.entryId : \"\",\n expectedHash,\n actualHash: isChainDigest(entry.chainHash) ? entry.chainHash : \"\",\n breakType,\n context,\n });\n };\n\n for (let i = 0; i < entries.length; i++) {\n // M-10: Stop early if too many breaks found\n if (maxBreaks > 0 && breaks.length >= maxBreaks) {\n break;\n }\n\n const entry = entries[i]!;\n const seq = exactInteger(entry.globalSeq);\n\n // The formats cannot be told apart by looking at a digest, so the entry\n // has to say which preimage produced it (§2.2). Absent means v2.\n const declared: unknown = entry.formatVersion;\n const entryFormat =\n declared === undefined || typeof declared === \"number\"\n ? normalizeFormatVersion(declared)\n : Number.NaN;\n const isV4 = entryFormat === FORMAT_V4;\n const isV2orV3 = entryFormat === FORMAT_V2 || entryFormat === FORMAT_V3;\n const formatKnown = isV2orV3 || isV4;\n\n // Step 3's condition, decided before anything is reported: it also\n // decides whether a tombstone is counted.\n let crossFormat: string | null = null;\n if (isV2orV3 && seenV4) {\n crossFormat = \"a v2 or v3 entry after a v4 entry: a chain never goes back from v4\";\n } else if (isV2orV3 && (carries(entry, \"salt\") || carries(entry, \"leaf_hash\") || carries(entry, \"erased\"))) {\n crossFormat = \"a v2 or v3 entry must not carry salt, leaf_hash or erased\";\n } else if (isV4 && (carries(entry, \"run_id\") || carries(entry, \"sequence_num\"))) {\n crossFormat = \"a v4 entry carries no run_id and no sequence_num\";\n } else if (\n isV4 &&\n hasTombstoneShapeV4(\n carries(entry, \"entry_id\") ? entry.entryId : undefined,\n carries(entry, \"entry_type\") ? entry.entryType : undefined,\n carries(entry, \"content_hash\") ? entry.contentHash : undefined\n )\n ) {\n crossFormat = \"a v4 entry has no tombstone type, tomb_ id or TOMBSTONE: content hash\";\n }\n if (isV4) seenV4 = true;\n\n // 1. Sequence continuity. The FIRST global_seq is not constrained here\n // (§5.5; v4's first-entry rule is step 7). From there it rises by one.\n if (previousSeq !== null && seq !== null && seq !== previousSeq + 1n) {\n report(i, entry, \"sequence_gap\", {\n expectedSeq: (previousSeq + 1n).toString(),\n actualSeq: seq.toString(),\n });\n }\n previousSeq = seq;\n\n // 2. chain_hash is a digest on EVERY entry. A tombstone's is taken as\n // stored, so an unchecked one would flow straight into the next preimage.\n if (!isChainDigest(entry.chainHash)) {\n report(i, entry, \"invalid_field\", {\n field: \"chainHash\",\n detail: \"chainHash must be exactly 128 lowercase hex characters\",\n });\n previousHash = null;\n continue;\n }\n // Counted once step 2 passes, whatever else is wrong with it (§5.5).\n if (isV4 && entry.erased === true) erasedFound++;\n\n // Every break below leaves the stored hash as the one to link from: it is\n // a digest (checked above), and the entry itself cannot be recomputed.\n const stop = (breakType: BreakType, context: Record<string, string>): void => {\n report(i, entry, breakType, context);\n previousHash = entry.chainHash;\n };\n\n // 3.\n if (crossFormat !== null) {\n stop(\"format_field_misuse\", { detail: crossFormat });\n continue;\n }\n\n const unknownFormat = (): void => {\n // A format this build cannot recompute is NOT evidence of tampering.\n const shown =\n typeof declared === \"number\" && Number.isSafeInteger(declared)\n ? String(declared)\n : \"(not an integer)\";\n stop(\"unknown_format\", {\n detail: `chain hash format version ${shown} is not implemented by this build`,\n });\n };\n // v3 binds NEITHER run field.\n const runFieldMisuse = entryFormat === FORMAT_V3 && Boolean(entry.runId || entry.sequenceNum);\n const fieldMisuse = (): void =>\n stop(\"format_field_misuse\", {\n detail:\n \"a v3 entry must not carry runId or sequenceNum; neither is bound into its hash\",\n });\n const seqInvalid = seq === null || seq < 0n || seq > MAX_INT64;\n const invalidSeq = (): void =>\n stop(\"invalid_field\", {\n field: \"globalSeq\",\n detail: \"globalSeq must be an integer from 0 to 2^63 - 1 (a bigint beyond 2^53)\",\n });\n const invalidStart = (): void =>\n stop(\"invalid_field\", {\n field: \"previousHash\",\n detail: \"previousHash must be empty or exactly 128 lowercase hex characters\",\n });\n\n // 4. Tombstones (v2 and v3): validate, then advance on the stored hash.\n //\n // A tombstone retains the ORIGINAL entry's chainHash, computed from that\n // entry's real contentHash before erasure. Its chain hash is therefore NOT\n // reproducible from its own fields, and recomputing it here reports\n // hash_mismatch on every lawfully erased entry — telling a customer their\n // chain is broken precisely when they are demonstrating that they honoured a\n // deletion request (sdk_verify_01).\n //\n // The preservation is deliberate: anchors sign the chain hash. Recomputing on\n // erasure would invalidate every anchor covering that range, so exercising a\n // right to erasure would destroy the proof the data ever existed. Preserving\n // it keeps erasure and provability compatible.\n //\n // What a tombstone DECLARES is still checked (§5.5): its content-hash\n // format, its format version, and its sequence. Its timestamp form and the\n // v2 runId / sequenceNum rules are not. v4 has no tombstones (step 3).\n if (!isV4 && isTombstoneEntry(entry)) {\n tombstonesFound++;\n lastTombstone = i;\n tombstonePositions.push(i);\n if (!validateTombstoneContentHash(entry.contentHash)) {\n stop(\"invalid_tombstone\", {\n detail: 'a tombstone contentHash must be \"TOMBSTONE:\" + 64 lowercase hex',\n });\n } else if (!formatKnown) {\n unknownFormat();\n } else if (runFieldMisuse) {\n fieldMisuse();\n } else if (seqInvalid) {\n invalidSeq();\n } else if (i === 0 && startMalformed) {\n // Not needed to carry a tombstone forward, but a malformed supplied\n // predecessor hash is a break at position 0 whatever sits there.\n invalidStart();\n } else {\n // Subsequent entries were chained against the stored value, so that\n // is what the next iteration must link from.\n previousHash = entry.chainHash;\n }\n continue;\n }\n\n // 5. The timestamp is stored as exactly the string that was hashed.\n if (!isChainTimestamp(entry.timestamp)) {\n stop(\"invalid_timestamp\", {\n detail: \"timestamp must be YYYY-MM-DDTHH:MM:SS.ffffffZ (UTC, six digits)\",\n });\n continue;\n }\n // 6.\n if (!formatKnown) {\n unknownFormat();\n continue;\n }\n if (runFieldMisuse) {\n fieldMisuse();\n continue;\n }\n // 7. Field shapes.\n if (i === 0 && startMalformed) {\n invalidStart();\n continue;\n }\n\n if (isV4) {\n const problem = v4ShapeProblem(entry, seq, i > 0 || startHash !== \"\");\n if (problem !== null) {\n stop(\"invalid_field\", problem);\n continue;\n }\n if (previousHash === null) {\n // Nothing to link from: the entry before had no usable hash, and said so.\n previousHash = entry.chainHash;\n continue;\n }\n // 8. The leaf hash first (live entries; an erased one keeps its stored\n // leaf hash, checked for shape only), then the chain hash. No stored\n // chain hash is taken on trust (§5.0).\n const storedLeaf = entry.leafHash!;\n const leaf =\n entry.erased === true\n ? storedLeaf\n : leafHashV4Sync(entry.entryId, entry.entryType, entry.contentHash, entry.salt!);\n const expectedHash = chainHashV4Sync(previousHash, seq!.toString(), entry.timestamp, leaf);\n if (!chainHashEqual(leaf, storedLeaf)) {\n report(i, entry, \"hash_mismatch\", { field: \"leafHash\" }, expectedHash);\n } else if (!chainHashEqual(entry.chainHash, expectedHash)) {\n report(i, entry, \"hash_mismatch\", {}, expectedHash);\n }\n // As v3 does after a mismatch: continue from the RECOMPUTED hash, so one\n // altered entry does not cascade into false breaks after it.\n previousHash = expectedHash;\n continue;\n }\n\n if (\n !isChainDigest(entry.contentHash) &&\n !(typeof entry.contentHash === \"string\" && validateTombstoneContentHash(entry.contentHash))\n ) {\n // A well-formed TOMBSTONE: value on an ordinary entry passes the shape\n // and then fails the recompute: the content hash alone does not make a\n // tombstone (§5.5).\n stop(\"invalid_field\", {\n field: \"contentHash\",\n detail:\n 'contentHash must be 128 lowercase hex characters, or a tombstone value (\"TOMBSTONE:\" + 64 lowercase hex)',\n });\n continue;\n }\n if (seqInvalid) {\n invalidSeq();\n continue;\n }\n if (entryFormat === FORMAT_V2) {\n if (typeof entry.runId !== \"string\" || entry.runId === \"\") {\n stop(\"invalid_field\", {\n field: \"runId\",\n detail: \"a v2 entry's runId must not be empty\",\n });\n continue;\n }\n const sequenceNum: unknown = entry.sequenceNum;\n if (\n typeof sequenceNum !== \"number\" ||\n !Number.isSafeInteger(sequenceNum) ||\n sequenceNum < 0\n ) {\n stop(\"invalid_field\", {\n field: \"sequenceNum\",\n detail: \"a v2 entry's sequenceNum must be a non-negative integer\",\n });\n continue;\n }\n }\n\n if (previousHash === null) {\n // Nothing to link from: the entry before had no usable hash, and said so.\n previousHash = entry.chainHash;\n continue;\n }\n\n // 8.\n const expectedHash =\n entryFormat === FORMAT_V2\n ? await computeChainHash(\n previousHash,\n entry.runId,\n entry.sequenceNum,\n entry.timestamp,\n entry.contentHash\n )\n : await computeChainHashV3(previousHash, seq, entry.timestamp, entry.contentHash);\n\n if (!chainHashEqual(entry.chainHash, expectedHash)) {\n report(i, entry, \"hash_mismatch\", {}, expectedHash);\n }\n\n // Advance using the computed hash, not the stored one. If entry.chainHash\n // was tampered, using it would cause every subsequent entry to fail\n // (cascade false positives). Using expectedHash keeps the chain on the\n // correct trajectory so only genuinely broken entries produce breaks.\n previousHash = expectedHash;\n }\n\n return { breaks, tombstonesFound, lastTombstone, tombstonePositions, erasedFound };\n}\n\nfunction walkResult(\n walk: ChainWalk,\n processed: number,\n durationMs: number,\n anchorOutcome?: AnchorBindOutcome\n): OfflineVerificationResult {\n const entriesNotVerified = walk.lastTombstone + 1;\n return {\n valid: walk.breaks.length === 0,\n entriesVerified: processed - entriesNotVerified,\n entriesProcessed: processed,\n tombstonesFound: walk.tombstonesFound,\n erasedFound: walk.erasedFound,\n lastTombstone: walk.lastTombstone,\n entriesNotVerified,\n breaks: walk.breaks,\n durationMs,\n ...(anchorOutcome === undefined ? {} : { anchorOutcome }),\n };\n}\n\n/**\n * Decide what an anchor binds to, given entries that have been walked from the\n * chain's first entry (format-spec §9.4, §9.7, §9.8).\n *\n * EXACTLY the entries given: the first is the range start, the last is the\n * range end, and their number is the height. The order of checks is fixed so\n * every implementation names the same outcome.\n */\nasync function bindOutcome(\n anchor: Anchor,\n entries: readonly ExportedEntry[],\n chainValid: boolean,\n previousAnchorHash: string\n): Promise<AnchorBindOutcome> {\n if (!chainValid) return \"chain_broken\";\n\n const tip = entries[entries.length - 1]!;\n if (entries[0]!.entryId !== anchor.range.startEntryId) return \"range_start_mismatch\";\n if (tip.entryId !== anchor.range.endEntryId) return \"range_end_mismatch\";\n if (BigInt(anchor.entryCount) !== BigInt(entries.length)) return \"height_mismatch\";\n\n // §9.8: the predecessor is named twice, by id and by hash. The seed id goes\n // with the seed hash and with nothing else.\n const namesSeed = anchor.previousAnchorId === SEED_ANCHOR_ID;\n const usesSeed = previousAnchorHash === SEED_ANCHOR_HASH;\n if (namesSeed !== usesSeed) return \"predecessor_mismatch\";\n\n // The chain verified, so the stored hash of the tip IS its chain hash\n // (recomputed, or for a tombstone carried as stored).\n const expected = await computeAnchorChainHash(\n previousAnchorHash,\n anchor.subject,\n anchor.range.startEntryId,\n anchor.range.endEntryId,\n tip.chainHash\n );\n return chainHashEqual(expected, anchor.chainHash) ? \"bound\" : \"head_mismatch\";\n}\n\n/**\n * Bind an anchor to the entries it covers, without a key.\n *\n * # Description\n *\n * Verifies the entries as a WHOLE chain (from its first entry: a segment\n * cannot be bound, format-spec §9.8), then checks that the anchor describes\n * EXACTLY those entries, in this order: the chain verifies, the first entry is\n * `range.startEntryId`, the last is `range.endEntryId`, their number is\n * `entryCount`, the predecessor is named consistently (§9.8), and the anchor\n * chain hash recomputes (§9.4).\n *\n * A v7 anchor names its range by sequence and carries its predecessor's hash:\n * it is bound by `bindAnchorV7ToEntries`, to which this delegates, with\n * `previousAnchorHash` as the EXPECTED predecessor (§9.7 step 4) and no\n * expected subject (`subjectChecked` false). What follows is v1-v6.\n *\n * PASS THE COVERED PREFIX. An anchor is bound against the entries it covered,\n * as the chain was when it was signed (§9.7): entries `0 … entryCount - 1`.\n * This function does not slice. Given a chain that has grown since the anchor,\n * it reports `range_end_mismatch`.\n *\n * KEYLESS: the signature is NOT checked. Use `verifyAnchorLocally` for that; a\n * bind without a signature check says only that the anchor's fields describe\n * these entries, not who wrote them.\n *\n * WHAT A TOMBSTONE LEAVES UNBOUND (§5.5). A tombstone's chain hash is taken as\n * stored, so nothing links the entries before it to the anchored tip. Whoever\n * can write the store can replace every entry up to a tombstone and the bind\n * still succeeds. `entriesNotBound` counts those entries. Never describe them\n * as verified or as bound.\n *\n * # Inputs\n *\n * - anchor: The anchor, as `parseAnchorText` returns it\n * - entries: The entries the anchor covers, from the chain's first entry\n * - previousAnchorHash: The previous anchor's `chainHash`, or\n * `SEED_ANCHOR_HASH` for the first anchor. Never guessed.\n *\n * # Outputs\n *\n * - Promise<AnchorBindResult>: the outcome; `bound` is true only for\n * `\"bound\"`. `tombstones` and `entriesNotBound` are what the walk found,\n * in every outcome.\n * - AnchorVerificationError: the anchor is malformed (§9.3, §9.8 counts and\n * key id), or `previousAnchorHash` is not a digest. An error, not an outcome.\n * - ChainVerificationError: `entries` is empty\n *\n * # Example\n *\n * const anchor = parseAnchorText(anchorText);\n * const entries = parseEntriesText(entriesText);\n * const covered = entries.slice(0, Number(anchor.entryCount));\n * const r = await bindAnchorToEntries(anchor, covered, SEED_ANCHOR_HASH);\n * if (r.bound && r.entriesNotBound > 0) {\n * console.log(`bound, except the first ${r.entriesNotBound} entries`);\n * }\n *\n * # Limitations\n *\n * - Does not verify the signature, and does not check a series of anchors\n * against each other.\n * - Cannot detect a rewrite of the entries before a tombstone.\n *\n * # Assumptions\n *\n * - `entries[0]` is the chain's first entry.\n */\nexport async function bindAnchorToEntries(\n anchor: Anchor,\n entries: readonly ExportedEntry[],\n previousAnchorHash: string\n): Promise<AnchorBindResult> {\n if (anchor.version === 7) {\n // A v7 anchor carries its predecessor's hash; the one given is checked\n // against it (format-spec §9.7 step 4).\n return bindAnchorV7ToEntries(anchor, entries, { previousAnchorHash });\n }\n checkAnchorWellFormed(anchor);\n if (!isChainDigest(previousAnchorHash)) {\n throw new AnchorVerificationError(\n \"previousAnchorHash must be exactly 128 lowercase hex characters \" +\n \"(SEED_ANCHOR_HASH for the first anchor)\"\n );\n }\n if (entries.length === 0) {\n throw new ChainVerificationError(\"entries array cannot be empty\");\n }\n\n const startTime = performance.now();\n const walk = await walkChain(entries, \"\", 0);\n const outcome = await bindOutcome(\n anchor,\n entries,\n walk.breaks.length === 0,\n previousAnchorHash\n );\n const chain = walkResult(walk, entries.length, performance.now() - startTime, outcome);\n return {\n outcome,\n bound: outcome === \"bound\",\n tombstones: chain.tombstonesFound,\n entriesNotBound: chain.entriesNotVerified,\n chain,\n };\n}\n\n/** A v7 bind's outcome, and the index of its tip entry (-1 when there is none). */\ninterface V7Bind {\n readonly outcome: AnchorBindOutcome;\n readonly tipIndex: number;\n}\n\n/**\n * Decide what a v7 anchor binds to (format-spec §9.7), given entries walked\n * from the chain's first entry. The first check that fails is the outcome.\n */\nfunction bindOutcomeV7(\n anchor: Anchor,\n entries: readonly ExportedEntry[],\n chainValid: boolean,\n expect: AnchorBindExpectations\n): V7Bind {\n // 1. The chain.\n if (!chainValid) return { outcome: \"chain_broken\", tipIndex: -1 };\n // checkAnchorWellFormed has established both are integers in range.\n const startSeq = BigInt(anchor.range.startSeq!);\n const endSeq = BigInt(anchor.range.endSeq!);\n // 2. The start: the first entry of a walk that is not a segment is the\n // chain's first entry.\n const firstSeq = exactInteger(entries[0]!.globalSeq);\n if (firstSeq === null || firstSeq !== startSeq) {\n return { outcome: \"range_start_mismatch\", tipIndex: -1 };\n }\n // 3. The end. The chain verified, so global_seq rises by one from the first\n // entry: the entry at end_seq, if given, is at index end_seq - start_seq.\n const offset = endSeq - startSeq;\n const tipIndex = offset < BigInt(entries.length) ? Number(offset) : -1;\n if (tipIndex < 0 || exactInteger(entries[tipIndex]!.globalSeq) !== endSeq) {\n return { outcome: \"height_mismatch\", tipIndex: -1 };\n }\n // 4. The predecessor, when the caller expected one.\n const expectedPrev = expect.previousAnchorHash ?? \"\";\n if (expectedPrev !== \"\" && !chainHashEqual(expectedPrev, anchor.previousAnchorHash!)) {\n return { outcome: \"predecessor_mismatch\", tipIndex };\n }\n // 5. The subject, byte for byte, when the caller expected one.\n const expectedSubject = expect.subject ?? \"\";\n if (expectedSubject !== \"\" && expectedSubject !== anchor.subject) {\n return { outcome: \"tenant_mismatch\", tipIndex };\n }\n // 6. The head, over the anchor's own predecessor hash. The chain verified,\n // so the tip's stored hash IS its chain hash (recomputed; an erased v4\n // entry's too, §5.0).\n const expected = anchorChainHashV7Sync(\n anchor.previousAnchorHash!,\n anchor.subject,\n startSeq.toString(),\n endSeq.toString(),\n entries[tipIndex]!.chainHash\n );\n return {\n outcome: chainHashEqual(expected, anchor.chainHash) ? \"bound\" : \"head_mismatch\",\n tipIndex,\n };\n}\n\n/** Entries up to and including the last tombstone at or before `tipIndex`. */\nfunction notBoundThrough(walk: ChainWalk, tipIndex: number): number {\n let last = -1;\n for (const p of walk.tombstonePositions) if (p <= tipIndex) last = p;\n return last + 1;\n}\n\n/**\n * Bind a v7 anchor to the entries it covers, without a key (format-spec §9.7).\n *\n * # Description\n *\n * Refuses, as errors with no outcome, an anchor that breaks format-spec §9.3\n * or §9.8 and entries given as a segment (`expect.previousHash`). Then walks\n * the entries from the chain's first entry and checks, in this order, the\n * first failure being the outcome:\n *\n * 1. the chain verifies (§5.5): otherwise `chain_broken`;\n * 2. the first entry's `globalSeq` is `range.startSeq`: otherwise\n * `range_start_mismatch`;\n * 3. an entry has `globalSeq` `range.endSeq`: otherwise `height_mismatch`\n * (the anchor covers entries not given). Entries after it are not the\n * anchor's concern: a chain that has grown since still binds;\n * 4. `expect.previousAnchorHash`, if given, equals the anchor's\n * `previousAnchorHash`: otherwise `predecessor_mismatch`;\n * 5. `expect.subject`, if given, equals the anchor's `subject` byte for\n * byte: otherwise `tenant_mismatch`;\n * 6. the v7 anchor chain hash (§9.4) recomputes to `chainHash`: otherwise\n * `head_mismatch`. All six: `bound`.\n *\n * A v7 anchor carries its predecessor's hash in its signed bytes, so no\n * predecessor hash is needed to bind it; `expect.previousAnchorHash` only\n * CHECKS it against the one the caller holds.\n *\n * KEYLESS: the signature is NOT checked. Use `verifyAnchorLocally`.\n *\n * WHAT IS NOT CHECKED, SAID SO. Without `expect.subject`, `subjectChecked` is\n * false: the anchor may be about another chain. `entriesNotBound` counts the\n * entries up to and including the last v2/v3 tombstone at or before the tip\n * (a v3 prefix continued in v4 keeps exactly its guarantee, §2.5). Never\n * describe those entries as bound.\n *\n * # Inputs\n *\n * - anchor: a v7 anchor, as `parseAnchorText` returns it\n * - entries: the chain from its first entry (it may have grown since)\n * - expect: the subject and predecessor hash the caller expects; empty or\n * omitted means not given\n *\n * # Outputs\n *\n * - Promise<AnchorBindResult>: `bound` only for `\"bound\"`; `subjectChecked`\n * always set\n * - AnchorVerificationError: the anchor is not v7 or is malformed,\n * `expect.previousHash` is given, or `expect.previousAnchorHash` is not a\n * digest\n * - ChainVerificationError: `entries` is empty\n *\n * # Example\n *\n * const r = await bindAnchorV7ToEntries(parseAnchorText(text), entries, {\n * subject: \"orders\",\n * });\n *\n * # Limitations\n *\n * - Does not verify the signature, and does not check a series of anchors.\n *\n * # Assumptions\n *\n * - `entries[0]` is the chain's first entry.\n */\nexport async function bindAnchorV7ToEntries(\n anchor: Anchor,\n entries: readonly ExportedEntry[],\n expect: AnchorBindExpectations = {}\n): Promise<AnchorBindResult> {\n if (anchor.version !== 7) {\n throw new AnchorVerificationError(\n \"bindAnchorV7ToEntries binds a v7 anchor; bind v1-v6 with bindAnchorToEntries\"\n );\n }\n checkAnchorWellFormed(anchor);\n if ((expect.previousHash ?? \"\") !== \"\") {\n // §9.8: entry_count is counted from the chain's first entry.\n throw new AnchorVerificationError(\n \"an anchor cannot be bound to a segment: pass the chain from its first entry\"\n );\n }\n const expectedPrev = expect.previousAnchorHash ?? \"\";\n if (expectedPrev !== \"\" && !isChainDigest(expectedPrev)) {\n throw new AnchorVerificationError(\n \"the expected previousAnchorHash must be exactly 128 lowercase hex characters\"\n );\n }\n if (entries.length === 0) {\n throw new ChainVerificationError(\"entries array cannot be empty\");\n }\n\n const startTime = performance.now();\n const walk = await walkChain(entries, \"\", 0);\n const { outcome, tipIndex } = bindOutcomeV7(anchor, entries, walk.breaks.length === 0, expect);\n const chain = walkResult(walk, entries.length, performance.now() - startTime, outcome);\n return {\n outcome,\n bound: outcome === \"bound\",\n tombstones: chain.tombstonesFound,\n entriesNotBound: notBoundThrough(walk, tipIndex < 0 ? entries.length - 1 : tipIndex),\n chain,\n subjectChecked: (expect.subject ?? \"\") !== \"\",\n };\n}\n\n/**\n * Verify a complete chain from exported data.\n *\n * Performs full chain verification using exported entries without\n * requiring network access to Aleutian APIs. Verifies field shapes, chain hash\n * continuity and tombstone format validity (format-spec §2, §4, §5), and\n * optionally binds the result to an anchor.\n *\n * The first `globalSeq` is not constrained: a chain may start at 0, at 1, or\n * (for a segment, with `options.previousHash`) anywhere.\n *\n * WHAT A TOMBSTONE LEAVES UNVERIFIED (format-spec §5.5). `valid` says the\n * entries are consistent with each other. It does NOT say the entries before a\n * tombstone are the ones originally written: a tombstone's chain hash is taken\n * as stored, so whoever can write the store can replace every entry up to it.\n * `entriesNotVerified` (and `lastTombstone`) report how many entries that is.\n * Never describe them as verified.\n *\n * WARNING (M-4): OfflineBreak contains entryId and hashes that may correlate\n * to PII. Consider truncating hashes before logging: hash.slice(0, 8) is sufficient.\n *\n * @param entries - Array of entries in globalSeq order\n * @param options - Verification options (anchor, previousHash, maxEntries, maxBreaks)\n * @returns Verification result with validity, breaks, and statistics\n *\n * @throws ChainVerificationError for unrecoverable errors (empty entries, or\n * an anchor together with `previousHash`)\n * @throws AnchorVerificationError when `options.anchor` is malformed\n * (format-spec §9.3, §9.8): an error, not a break\n *\n * @example\n * ```typescript\n * import {\n * loadExportedEntries,\n * loadAnchor,\n * verifyChainOffline\n * } from '@aleutian/verification';\n *\n * const entries = await loadExportedEntries('export-2026-01.json');\n * const anchor = await loadAnchor('anchor-2026-01-20.json');\n *\n * const result = await verifyChainOffline(entries, {\n * anchor,\n * previousAnchorHash: SEED_ANCHOR_HASH, // genesis; else prior anchor's chainHash\n * maxBreaks: 100, // Stop early if chain is severely corrupted\n * });\n *\n * if (result.valid) {\n * console.log(\n * `Chain consistent: ${result.entriesVerified} entries verified, ` +\n * `${result.entriesNotVerified} not verified (up to the last tombstone)`\n * );\n * } else {\n * console.log(`Chain invalid: ${result.breaks.length} breaks`);\n * }\n * ```\n */\nexport async function verifyChainOffline(\n entries: readonly ExportedEntry[],\n options: ChainVerifyOptions = {}\n): Promise<OfflineVerificationResult> {\n if (entries.length === 0) {\n throw new ChainVerificationError(\"entries array cannot be empty\");\n }\n const startHash = options.previousHash ?? \"\";\n if (options.anchor && startHash !== \"\") {\n // format-spec §9.8: entry_count is counted from the chain's first entry,\n // so an anchor is never bound to entries verified from a predecessor hash.\n throw new ChainVerificationError(\n \"an anchor cannot be bound to a segment: omit previousHash and pass the chain from its first entry\"\n );\n }\n if (options.anchor) {\n checkAnchorWellFormed(options.anchor);\n }\n\n // M-10: Resource bounds - limit entries processed\n const maxEntries = options.maxEntries ?? 0;\n const entriesToProcess =\n maxEntries > 0 && entries.length > maxEntries\n ? entries.slice(0, maxEntries)\n : entries;\n\n const startTime = performance.now();\n const walk = await walkChain(entriesToProcess, startHash, options.maxBreaks ?? 0);\n const breaks = walk.breaks;\n const lastEntry = entriesToProcess[entriesToProcess.length - 1]!;\n let anchorOutcome: AnchorBindOutcome | undefined;\n\n // Anchor binding: when caller supplied an Anchor, bind it exactly as\n // `bindAnchorToEntries` does. The legacy expectedLastHash path below\n // cannot bind to real anchors because anchor.chain_hash and the tip\n // entry's chain_hash live in different SHA-512 domain separators.\n if (options.anchor) {\n const anchor = options.anchor;\n let prevAnchorHash = options.previousAnchorHash ?? \"\";\n if (prevAnchorHash === \"\" && anchor.previousAnchorId === SEED_ANCHOR_ID) {\n prevAnchorHash = SEED_ANCHOR_HASH;\n }\n if (anchor.version === 7) {\n // v7 carries its predecessor hash; a given one is the expected one.\n const expectedPrev = options.previousAnchorHash ?? \"\";\n anchorOutcome =\n expectedPrev !== \"\" && !isChainDigest(expectedPrev)\n ? breaks.length === 0\n ? \"predecessor_mismatch\"\n : \"chain_broken\"\n : bindOutcomeV7(anchor, entriesToProcess, breaks.length === 0, {\n previousAnchorHash: expectedPrev,\n }).outcome;\n } else if (!isChainDigest(prevAnchorHash)) {\n // No usable predecessor hash: no trust can be established.\n anchorOutcome = breaks.length === 0 ? \"predecessor_mismatch\" : \"chain_broken\";\n } else {\n anchorOutcome = await bindOutcome(\n anchor,\n entriesToProcess,\n breaks.length === 0,\n prevAnchorHash\n );\n }\n if (anchorOutcome !== \"bound\" && anchorOutcome !== \"chain_broken\") {\n breaks.push({\n position: entriesToProcess.length - 1,\n entryId: typeof lastEntry.entryId === \"string\" ? lastEntry.entryId : \"\",\n expectedHash: \"\",\n actualHash: \"\",\n breakType: \"anchor_mismatch\",\n context: { outcome: anchorOutcome },\n });\n }\n } else {\n // Deprecated legacy path; will be removed in the next minor release.\n const expectedLastHash = options.expectedLastHash ?? \"\";\n const tipHash = isChainDigest(lastEntry.chainHash) ? lastEntry.chainHash : \"\";\n if (expectedLastHash && !chainHashEqual(tipHash, expectedLastHash)) {\n breaks.push({\n position: entriesToProcess.length - 1,\n entryId: typeof lastEntry.entryId === \"string\" ? lastEntry.entryId : \"\",\n expectedHash: expectedLastHash,\n actualHash: tipHash,\n breakType: \"anchor_mismatch\",\n context: {},\n });\n }\n }\n\n return walkResult(walk, entriesToProcess.length, performance.now() - startTime, anchorOutcome);\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Trust-manifest freshness verdicts (chainlinker_modernization_12f_e).\n *\n * A verifier holding a trust manifest can only reflect revocations known\n * AT the manifest's generation date: a key revoked afterwards is invisible\n * (\"the CRL problem\" for offline verification). This module makes that\n * limitation explicit rather than emitting a bare \"valid\".\n *\n * v1 semantics (ADR-029 §D5): advisory report + warn, never hard-fail.\n * Byte-identical to the Go (`EvaluateManifestFreshness`) and Python\n * (`evaluate_manifest_freshness`) SDK helpers via the shared golden\n * vectors in `sdk/testdata/manifest_freshness_golden.json`.\n *\n * Browser-safe: depends only on `Date` + string ops (no Node built-ins).\n */\n\n/**\n * Soft-warn threshold (ADR-029 §D5). A manifest older than this many days\n * is reported STALE — advisory only; never changes validity, never fails.\n */\nexport const MANIFEST_FRESHNESS_MAX_AGE_DAYS = 30;\n\nconst MS_PER_DAY = 24 * 60 * 60 * 1000;\n\n/**\n * Structured, advisory freshness verdict for a trust manifest. All fields\n * are advisory in v1: they inform the verdict string and let a STATEFUL\n * caller act on `rollbackDetected`, but the SDK never converts any of them\n * into a hard verification failure.\n */\nexport interface ManifestFreshness {\n /** The manifest's monotonic version integer. */\n readonly version: number;\n /** The manifest's generation wall-clock time (UnixMilli, UTC). */\n readonly generatedAtMs: number;\n /**\n * floor((now - generatedAtMs) / 1 day), clamped to 0 for a manifest\n * whose generation stamp is in the future relative to `now`.\n */\n readonly ageDays: number;\n /** True when `ageDays > MANIFEST_FRESHNESS_MAX_AGE_DAYS`. Advisory. */\n readonly stale: boolean;\n /**\n * True only for a STATEFUL evaluation (a non-negative `lastSeenVersion`\n * was supplied) where `version` is LOWER than the last version this\n * verifier saw — a suppressed/rolled-back update that could hide a\n * revocation. A stateless one-shot verifier cannot detect this and\n * always reports false; its only defense is the reported date.\n */\n readonly rollbackDetected: boolean;\n}\n\n/**\n * Compute the advisory freshness verdict for a trust manifest.\n *\n * Pure function over the manifest's signed `version` + `generatedAtMs` and\n * a caller-supplied reference clock. Never fetches, never mutates, never\n * throws.\n *\n * @param version - the manifest's monotonic version integer.\n * @param generatedAtMs - the manifest's generation time (UnixMilli, UTC).\n * @param nowMs - reference clock (UnixMilli, UTC).\n * @param lastSeenVersion - the highest manifest version this verifier has\n * previously observed, for anti-rollback. Pass a NEGATIVE value (e.g.\n * `-1`) for a STATELESS verifier — rollback detection is then disabled.\n */\nexport function evaluateManifestFreshness(\n version: number,\n generatedAtMs: number,\n nowMs: number,\n lastSeenVersion: number,\n): ManifestFreshness {\n const ageMs = nowMs - generatedAtMs;\n const ageDays = ageMs > 0 ? Math.floor(ageMs / MS_PER_DAY) : 0;\n return {\n version,\n generatedAtMs,\n ageDays,\n stale: ageDays > MANIFEST_FRESHNESS_MAX_AGE_DAYS,\n rollbackDetected: lastSeenVersion >= 0 && version < lastSeenVersion,\n };\n}\n\n/**\n * Return the manifest generation date as a UTC `YYYY-MM-DD` string. This is\n * the exact date form embedded in the verdict line and is byte-identical\n * across the Go/Python/JS SDKs.\n */\nexport function manifestGeneratedDate(f: ManifestFreshness): string {\n return new Date(f.generatedAtMs).toISOString().slice(0, 10);\n}\n\n/**\n * Return the freshness caveat WITHOUT asserting signature validity. Use in\n * a context that reports manifest freshness but does not itself establish\n * that a signature verified — e.g. the offline chain CLI, which checks\n * chain continuity + anchor binding, not signatures against the manifest.\n */\nexport function manifestRevocationNote(f: ManifestFreshness): string {\n let note =\n `Revocation checked against trust manifest v${f.version} ` +\n `dated ${manifestGeneratedDate(f)} — a key revoked after that date ` +\n `is not reflected.`;\n if (f.stale) {\n note += ` [WARNING: manifest is ${f.ageDays} days old]`;\n }\n return note;\n}\n\n/**\n * Return the exact ADR-029 §D5 verdict line for a VALID signature:\n *\n * Signature valid. Revocation checked against trust manifest v{N} dated\n * {YYYY-MM-DD} — a key revoked after that date is not reflected.\n *\n * with ` [WARNING: manifest is {age} days old]` appended when stale. Never\n * a bare \"valid\". Only emit this where signature validity has already been\n * established; otherwise use {@link manifestRevocationNote}.\n */\nexport function manifestVerdictLine(f: ManifestFreshness): string {\n return \"Signature valid. \" + manifestRevocationNote(f);\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Processing mode canonical encoder for Aleutian AI v=2 chain entries.\n *\n * Cross-language byte-equality contract\n * ======================================\n * The output of {@link encodeProcessingModeCanonicalFields} is guaranteed to\n * be byte-identical to the Go function `EncodeProcessingModeCanonicalFields`\n * in `internal/storage/processing_mode_canonical.go` for the same inputs.\n *\n * This invariant is enforced by the shared golden vectors in\n * `sdk/testdata/processing_mode_golden.json`, which are generated by the\n * Go encoder and verified by the Go, Python, and TypeScript test suites.\n *\n * TLV encoding format (v=2)\n * ==========================\n * Each field is `u32 BE byte-length || raw UTF-8 bytes`, with the two\n * fields concatenated in alphabetical key order:\n *\n * 1. `processing_mode_at_write`: u32 BE length prefix + mode bytes\n * 2. `processing_mode_set_by_event_id`: u32 BE length prefix + event id bytes\n *\n * All length prefixes are big-endian unsigned 32-bit integers.\n *\n * Ticket reference: 18_05i\n * Finding reference: C-B4-F5 (Phase 4 review)\n *\n * @module\n */\n\n/** Canonical wire string for the zero-knowledge processing mode. */\nexport const ZK = \"zk\" as const;\n\n/** Canonical wire string for the PII inspection processing mode. */\nexport const PII_INSPECTION = \"pii_inspection\" as const;\n\n/** Union of the two valid processing mode wire strings. */\nexport type ProcessingModeWire = typeof ZK | typeof PII_INSPECTION;\n\nconst KNOWN_MODES: ReadonlySet<string> = new Set([ZK, PII_INSPECTION]);\n\n/**\n * Reject strings that contain lone (unpaired) UTF-16 surrogates.\n *\n * `TextEncoder().encode(s)` silently substitutes U+FFFD for lone\n * surrogates, which would diverge from Go/Python producer-side\n * encoders. The error message does NOT echo caller input\n * (Privacy Invariant 4 — the field name is SDK-controlled).\n *\n * Mirrors V3 H10 and the matching gate in `consent.ts`.\n * Ticket: dsar_js_consent_lone_surrogate_gate.\n */\nfunction assertNoLoneSurrogatesProcessingMode(s: string): void {\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i);\n if (c >= 0xd800 && c <= 0xdbff) {\n const next = i + 1 < s.length ? s.charCodeAt(i + 1) : 0;\n if (next < 0xdc00 || next > 0xdfff) {\n throw new Error(\n \"processing_mode_set_by_event_id contains lone surrogate (input redacted)\",\n );\n }\n i++;\n } else if (c >= 0xdc00 && c <= 0xdfff) {\n throw new Error(\n \"processing_mode_set_by_event_id contains lone surrogate (input redacted)\",\n );\n }\n }\n}\n\n/**\n * Thrown when a string is not a known processing mode.\n *\n * The error message is a fixed string and never contains the rejected\n * input — this enforces Privacy Invariant 4 (no caller-supplied bytes\n * in SDK error messages) at the SDK boundary so callers cannot\n * accidentally surface untrusted input through logs.\n */\nexport class InvalidProcessingMode extends Error {\n constructor(_mode: string) {\n super(\"unknown processing mode (input redacted)\");\n this.name = \"InvalidProcessingMode\";\n // Maintain correct prototype chain in transpiled ES5.\n Object.setPrototypeOf(this, InvalidProcessingMode.prototype);\n }\n}\n\n/**\n * Byte-strict parser for the processing mode field.\n *\n * Accepts only the exact canonical wire strings `\"zk\"` and\n * `\"pii_inspection\"`. No trimming, no case folding, and no Unicode\n * normalization is applied. Mirrors `ParseProcessingMode` in\n * `internal/storage/processing_mode_types.go` (ticket 18_01, Clarification 5).\n *\n * @param s - The raw string to validate.\n * @returns The input string typed as `ProcessingModeWire`.\n * @throws {@link InvalidProcessingMode} if `s` is not a known mode.\n *\n * @example\n * ```typescript\n * parseProcessingMode(\"zk\"); // returns \"zk\"\n * parseProcessingMode(\"pii_inspection\"); // returns \"pii_inspection\"\n * parseProcessingMode(\"ZK\"); // throws InvalidProcessingMode\n * ```\n */\nexport function parseProcessingMode(s: string): ProcessingModeWire {\n if (!KNOWN_MODES.has(s)) {\n throw new InvalidProcessingMode(s);\n }\n return s as ProcessingModeWire;\n}\n\n/**\n * Encode the two v=2 canonical-form processing mode TLV fields.\n *\n * Produces the deterministic byte sequence for the\n * `processing_mode_at_write` and `processing_mode_set_by_event_id` fields\n * in a v=2 Aleutian consent chain entry. Output is byte-identical to\n * `EncodeProcessingModeCanonicalFields` in\n * `internal/storage/processing_mode_canonical.go` for the same inputs.\n *\n * Output format (alphabetical TLV):\n * ```\n * [u32 BE] len(mode bytes)\n * [bytes] mode bytes (UTF-8)\n * [u32 BE] len(setByEventId bytes)\n * [bytes] setByEventId bytes (UTF-8)\n * ```\n *\n * @param mode - The processing mode wire string; must be `\"zk\"` or\n * `\"pii_inspection\"` exactly.\n * @param setByEventId - The event id that set the processing mode. Any\n * non-empty string accepted by the internal `ValidateProcessingModeEventID`\n * (UUIDv4 or a recognised system sentinel). This function does NOT replicate\n * Go's event id validation — use the Go encoder at write time.\n * @returns A `Uint8Array` containing the TLV-encoded bytes.\n * @throws {@link InvalidProcessingMode} if `mode` is not a known mode.\n *\n * @example\n * ```typescript\n * const b = encodeProcessingModeCanonicalFields(\"zk\", \"system:bootstrap\");\n * console.log(b.length); // 26 (4+2+4+16)\n * ```\n */\nexport function encodeProcessingModeCanonicalFields(\n mode: string,\n setByEventId: string,\n): Uint8Array {\n parseProcessingMode(mode); // validate; throws InvalidProcessingMode if unknown\n // Mode is whitelist-validated above (no surrogates possible in \"zk\" or\n // \"pii_inspection\"), but setByEventId is caller-supplied. A lone UTF-16\n // surrogate would be silently replaced with U+FFFD by TextEncoder,\n // breaking byte equality with Go/Python producers. Refuse rather than\n // silently mis-encode. Ticket: dsar_js_consent_lone_surrogate_gate.\n assertNoLoneSurrogatesProcessingMode(setByEventId);\n\n const encoder = new TextEncoder();\n const modeBytes = encoder.encode(mode);\n const eventBytes = encoder.encode(setByEventId);\n\n const buf = new Uint8Array(4 + modeBytes.length + 4 + eventBytes.length);\n const view = new DataView(buf.buffer);\n\n view.setUint32(0, modeBytes.length, false); // big-endian\n buf.set(modeBytes, 4);\n\n view.setUint32(4 + modeBytes.length, eventBytes.length, false); // big-endian\n buf.set(eventBytes, 4 + modeBytes.length + 4);\n\n return buf;\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Consent chain entry canonical encoder and ML-DSA-65 signature verifier.\n *\n * Cross-language byte-equality contract\n * ======================================\n * {@link consentCanonical} produces output byte-identical to\n * internal/consent.ConsentCanonical and sdk/verification-python consent_canonical\n * for the same field values. Validated against sdk/testdata/consent_canonical_golden.json.\n *\n * Canonical form (v2 — locked)\n * ==============================\n * 15 fields in STRICT ALPHABETICAL ORDER. Reordering is a breaking schema change.\n *\n * Encoding rules:\n * - String field: u32 big-endian byte-length (4 bytes) || raw UTF-8 bytes\n * - int64 field (expires_at_ms, timestamp_ms): u64 big-endian (8 bytes), cast from JS number\n *\n * Fields 12–13 (processing_mode_at_write, processing_mode_set_by_event_id) are\n * encoded by delegating to {@link encodeProcessingModeCanonicalFields} from\n * processingMode.ts — not re-implemented here.\n *\n * Ticket reference: pqc_05c-d4\n *\n * @module\n */\n\nimport { ml_dsa65 } from \"@noble/post-quantum/ml-dsa.js\";\nimport { InvalidConsentEntryError, ConsentVerificationError } from \"./errors.js\";\nimport { sha512HexRaw } from \"./hash.js\";\nimport { constantTimeEqual } from \"./internal/constantTime.js\";\nimport { getPublicKey } from \"./keys.js\";\nimport { encodeProcessingModeCanonicalFields } from \"./processingMode.js\";\n\n/** Domain-separation prefix for consent entry SHA-512 hashes. */\nexport const CONSENT_ENTRY_HASH_PREFIX = \"aleutian.consent.entry.v2:\" as const;\n\n/** Domain-separation prefix for raw template SHA-512 hashes (hashTemplate).\n * Mirrors the Go constant consentTextHashPrefix.\n *\n * WARNING: Part of the signed consent record format. Do NOT change without\n * a versioned migration.\n */\nexport const CONSENT_TEXT_HASH_PREFIX = \"aleutian.consent.text.v2:\" as const;\n\n/**\n * Domain-separation prefix for rendered consent text SHA-512 hashes\n * (hashRendered). Mirrors the Go constant consentRenderedHashPrefix in\n * internal/consent/canonical.go.\n *\n * 18_20 review finding B4: this prefix was split from CONSENT_TEXT_HASH_PREFIX\n * so hashTemplate(b) != hashRendered(b) for any input b, closing a\n * cross-protocol confusion attack. Use this prefix when re-deriving\n * consent_rendered_hash for GDPR Art. 7 verification.\n *\n * WARNING: Part of the GET /v1/consent/text response and POST\n * /v1/consent/grant verification contract. Do NOT change without a\n * versioned migration.\n */\nexport const CONSENT_RENDERED_HASH_PREFIX = \"aleutian.consent.rendered.v2:\" as const;\n\n/** Exact byte length of an ML-DSA-65 signature per FIPS 204. */\nconst MLDSA65_SIG_SIZE = 3309;\n\n/** Per-field byte length cap. Mirrors maxConsentStringFieldBytes in Go SDK. */\nconst MAX_CONSENT_FIELD_BYTES = 1024;\n\n/** Known processing mode wire strings. */\nconst KNOWN_MODES: ReadonlySet<string> = new Set([\"pii_inspection\", \"zk\"]);\n\n/** Known consent entry type strings. */\nconst KNOWN_ENTRY_TYPES: ReadonlySet<string> = new Set([\n \"consent_granted\",\n \"consent_revoked\",\n \"processing_mode_change\",\n \"consent_expired\",\n]);\n\n/**\n * The 15 canonical fields of a consent chain entry.\n *\n * Field names use snake_case (matching JSON storage) and mirror\n * internal/consent.ConsentChainEntry and the Python ConsentChainEntry dataclass.\n *\n * `entry_type` and `event_type` MUST be equal; both are included in the\n * canonical encoding for historical schema reasons. {@link consentCanonical}\n * throws {@link InvalidConsentEntryError} if they differ.\n *\n * `expires_at_ms` and `timestamp_ms` are JS `number`. Unix milliseconds for\n * dates through 2286 fit in Number.MAX_SAFE_INTEGER (2^53 − 1 ≈ 9e15 > 10^13).\n * Do NOT use bigint — it would prevent direct construction from JSON.parse output.\n *\n * WARNING (Privacy Inv 4): every field on this interface is at least\n * correlation-grade (`actor_pseudonym`, `consent_id`, `idempotency_key_hash`,\n * `signing_key_id`, content-policy signals) and several are outright PII\n * carriers. Do NOT pass a `ConsentChainEntry` to `console.log`,\n * `JSON.stringify`, structured loggers, or template strings. Wrap with\n * `redactedConsentChainEntry(entry)` from `./redactedView` first. The\n * interface is a plain object literal, so it cannot own a `toJSON`\n * override the way the Python dataclass owns `__repr__` — the wrap\n * step is the only sanctioned logging path.\n */\nexport interface ConsentChainEntry {\n readonly actor_pseudonym: string;\n readonly actor_pseudonym_key_version: string;\n readonly company_id: string;\n readonly consent_id: string;\n readonly consent_rendered_hash: string;\n readonly consent_template_hash: string;\n readonly consent_text_version: string;\n readonly entry_type: string;\n readonly event_type: string;\n readonly expires_at_ms: number;\n readonly idempotency_key_hash: string;\n readonly processing_mode_at_write: string;\n readonly processing_mode_set_by_event_id: string;\n readonly signing_key_id: string;\n readonly timestamp_ms: number;\n}\n\n// =============================================================================\n// Internal helpers\n// =============================================================================\n\n/**\n * Encode a string field as u32 big-endian byte-length || UTF-8 bytes.\n */\nfunction encStr(s: string): Uint8Array {\n const encoder = new TextEncoder();\n const b = encoder.encode(s);\n const out = new Uint8Array(4 + b.length);\n const view = new DataView(out.buffer);\n view.setUint32(0, b.length, false); // big-endian\n out.set(b, 4);\n return out;\n}\n\n/**\n * Encode a JS number as u64 big-endian (8 bytes).\n *\n * Avoids BigInt to keep the public API compatible with JSON.parse output.\n * Splits the value into high and low 32-bit halves and writes them in\n * big-endian order. Safe for Unix millisecond timestamps through year 2286\n * (all fit within Number.MAX_SAFE_INTEGER).\n */\nfunction encI64(v: number): Uint8Array {\n const out = new Uint8Array(8);\n const view = new DataView(out.buffer);\n const hi = Math.floor(v / 0x100000000);\n const lo = v >>> 0; // unsigned 32-bit\n view.setUint32(0, hi, false); // big-endian high word\n view.setUint32(4, lo, false); // big-endian low word\n return out;\n}\n\n/**\n * Concatenate multiple Uint8Arrays into a single new Uint8Array.\n *\n * Pre-computes total length and performs a single allocation.\n * Avoids Buffer.concat — Uint8Array is the native cross-env type.\n */\nfunction concatUint8Arrays(parts: Uint8Array[]): Uint8Array {\n let totalLen = 0;\n for (const p of parts) {\n totalLen += p.length;\n }\n const out = new Uint8Array(totalLen);\n let offset = 0;\n for (const p of parts) {\n out.set(p, offset);\n offset += p.length;\n }\n return out;\n}\n\n/**\n * Reject C0 control bytes except HT (0x09), LF (0x0A), CR (0x0D).\n *\n * 0x7F (DEL) is intentionally NOT rejected — mirrors internal/consent/canonical.go\n * for byte-identical behaviour. Any change here requires a coordinated update\n * to the internal encoder first.\n */\nfunction checkDisallowedControlBytes(fieldName: string, b: Uint8Array): void {\n for (const byte of b) {\n if (byte < 0x20 && byte !== 0x09 && byte !== 0x0a && byte !== 0x0d) {\n throw new InvalidConsentEntryError(\n `consent_canonical: ${fieldName} contains a disallowed control byte`,\n );\n }\n }\n}\n\n/**\n * Reject strings that contain lone (unpaired) UTF-16 surrogates.\n *\n * `TextEncoder().encode(s)` silently substitutes U+FFFD for any lone\n * surrogate, which would diverge from Go and Python producer-side\n * encoders that reject the same input outright. The field name is\n * included in the error (it is SDK-controlled, never caller input);\n * the offending bytes are NEVER echoed (Privacy Invariant 4).\n *\n * Mirrors V3 H10 (`assertNoLoneSurrogates` in chain entry encoder).\n * Ticket: dsar_js_consent_lone_surrogate_gate.\n */\nfunction assertNoLoneSurrogates(fieldName: string, s: string): void {\n for (let i = 0; i < s.length; i++) {\n const c = s.charCodeAt(i);\n if (c >= 0xd800 && c <= 0xdbff) {\n // High surrogate must be followed by a low surrogate.\n const next = i + 1 < s.length ? s.charCodeAt(i + 1) : 0;\n if (next < 0xdc00 || next > 0xdfff) {\n throw new InvalidConsentEntryError(\n `consent_canonical: ${fieldName} contains lone surrogate`,\n );\n }\n i++; // skip the validated low surrogate\n } else if (c >= 0xdc00 && c <= 0xdfff) {\n throw new InvalidConsentEntryError(\n `consent_canonical: ${fieldName} contains lone surrogate`,\n );\n }\n }\n}\n\n/**\n * Validate all 15 fields of a ConsentChainEntry before canonical encoding.\n *\n * Mirrors validateConsentCanonical in the Go SDK and _validate_consent_canonical\n * in the Python SDK. Throws InvalidConsentEntryError on the first failure.\n * Field values are never included in error messages to prevent log injection.\n */\nfunction validateConsentEntry(entry: ConsentChainEntry): void {\n const encoder = new TextEncoder();\n\n // Required string fields (all entry types).\n const alwaysRequired: Array<[string, string]> = [\n [\"company_id\", entry.company_id],\n [\"consent_id\", entry.consent_id],\n [\"entry_type\", entry.entry_type],\n [\"event_type\", entry.event_type],\n [\"idempotency_key_hash\", entry.idempotency_key_hash],\n [\"processing_mode_at_write\", entry.processing_mode_at_write],\n [\"signing_key_id\", entry.signing_key_id],\n ];\n\n // actor_pseudonym + actor_pseudonym_key_version: required for entries\n // that represent a human action. consent_expired (pqc_05g) is\n // system-generated by the retention scanner and carries empty actor fields.\n if (entry.entry_type !== \"consent_expired\") {\n alwaysRequired.push(\n [\"actor_pseudonym\", entry.actor_pseudonym],\n [\"actor_pseudonym_key_version\", entry.actor_pseudonym_key_version],\n );\n }\n\n // consent_rendered_hash, consent_template_hash, consent_text_version are\n // required for grant only. revoke, processing_mode_change, and\n // consent_expired all carry empty hash/version fields.\n if (entry.entry_type === \"consent_granted\") {\n alwaysRequired.push(\n [\"consent_rendered_hash\", entry.consent_rendered_hash],\n [\"consent_template_hash\", entry.consent_template_hash],\n [\"consent_text_version\", entry.consent_text_version],\n );\n }\n\n for (const [name, value] of alwaysRequired) {\n if (!value) {\n throw new InvalidConsentEntryError(`consent_canonical: ${name} is empty`);\n }\n assertNoLoneSurrogates(name, value);\n const b = encoder.encode(value);\n if (b.length > MAX_CONSENT_FIELD_BYTES) {\n throw new InvalidConsentEntryError(\n `consent_canonical: ${name} exceeds 1024 bytes`,\n );\n }\n checkDisallowedControlBytes(name, b);\n }\n\n // consent_expired entries: enforce empty document/actor fields. Mirrors\n // the server-side validateForCanonical guard so cross-language verifiers\n // reject any entry mis-built with stray bytes in those slots.\n if (entry.entry_type === \"consent_expired\") {\n const empties: Array<[string, string]> = [\n [\"actor_pseudonym\", entry.actor_pseudonym],\n [\"actor_pseudonym_key_version\", entry.actor_pseudonym_key_version],\n [\"consent_rendered_hash\", entry.consent_rendered_hash],\n [\"consent_template_hash\", entry.consent_template_hash],\n [\"consent_text_version\", entry.consent_text_version],\n ];\n for (const [name, value] of empties) {\n if (value !== \"\") {\n throw new InvalidConsentEntryError(\n `consent_canonical: ${name} must be empty for consent_expired entries`,\n );\n }\n }\n }\n\n // Optional: processing_mode_set_by_event_id\n if (entry.processing_mode_set_by_event_id) {\n assertNoLoneSurrogates(\n \"processing_mode_set_by_event_id\",\n entry.processing_mode_set_by_event_id,\n );\n const b = encoder.encode(entry.processing_mode_set_by_event_id);\n if (b.length > MAX_CONSENT_FIELD_BYTES) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: processing_mode_set_by_event_id exceeds 1024 bytes\",\n );\n }\n checkDisallowedControlBytes(\"processing_mode_set_by_event_id\", b);\n }\n\n // Processing mode validity.\n if (!KNOWN_MODES.has(entry.processing_mode_at_write)) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: processing_mode_at_write is not a known mode\",\n );\n }\n if (\n entry.processing_mode_at_write === \"pii_inspection\" &&\n !entry.processing_mode_set_by_event_id\n ) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: processing_mode_set_by_event_id must be non-empty \" +\n \"when processing_mode_at_write is pii_inspection\",\n );\n }\n\n // Entry type validity.\n if (!KNOWN_ENTRY_TYPES.has(entry.entry_type)) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: entry_type is not a known ConsentEntryType\",\n );\n }\n if (!KNOWN_ENTRY_TYPES.has(entry.event_type)) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: event_type is not a known ConsentEntryType\",\n );\n }\n if (entry.entry_type !== entry.event_type) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: entry_type !== event_type\",\n );\n }\n\n // Timestamps.\n if (!Number.isSafeInteger(entry.timestamp_ms) || entry.timestamp_ms <= 0) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: timestamp_ms must be > 0\",\n );\n }\n if (!Number.isSafeInteger(entry.expires_at_ms) || entry.expires_at_ms < 0) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: expires_at_ms must be >= 0\",\n );\n }\n\n // Per-entry-type semantic constraints.\n if (entry.entry_type === \"consent_revoked\" && entry.expires_at_ms !== 0) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: consent_revoked entry must have expires_at_ms === 0\",\n );\n }\n if (\n entry.entry_type === \"consent_granted\" &&\n entry.expires_at_ms !== 0 &&\n entry.expires_at_ms <= entry.timestamp_ms\n ) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: consent_granted expires_at_ms must be > timestamp_ms (or 0)\",\n );\n }\n if (entry.entry_type === \"consent_expired\") {\n if (entry.expires_at_ms === 0) {\n throw new InvalidConsentEntryError(\n \"consent_canonical: consent_expired entry requires expires_at_ms !== 0\",\n );\n }\n if (entry.processing_mode_at_write !== \"zk\") {\n throw new InvalidConsentEntryError(\n \"consent_canonical: consent_expired entry requires processing_mode_at_write === zk\",\n );\n }\n if (entry.processing_mode_set_by_event_id !== \"\") {\n throw new InvalidConsentEntryError(\n \"consent_canonical: consent_expired entry must have empty processing_mode_set_by_event_id\",\n );\n }\n }\n}\n\n// =============================================================================\n// Exported functions\n// =============================================================================\n\n/**\n * Return hex(SHA-512(CONSENT_TEXT_HASH_PREFIX + b)).\n *\n * # Description\n *\n * Mirrors internal/consent.HashTemplate exactly. Used by external callers to\n * independently verify a chain entry's consent_template_hash against a\n * template fetched from docs.aleutian.ai.\n *\n * Async because WebCrypto's digest API is always async (same constraint as\n * {@link deriveConsentContentHash}).\n *\n * # Inputs\n *\n * - b: Raw template bytes. The SDK does NOT normalize; caller must pass\n * exactly the bytes the server hashed.\n *\n * # Outputs\n *\n * - Promise<string>: 128 lowercase hex characters (SHA-512 output).\n *\n * # Assumptions\n *\n * - CONSENT_TEXT_HASH_PREFIX is stable (locked by the v2 schema).\n */\nexport async function hashTemplate(b: Uint8Array): Promise<string> {\n const prefixBytes = new TextEncoder().encode(CONSENT_TEXT_HASH_PREFIX);\n const buf = new Uint8Array(prefixBytes.length + b.length);\n buf.set(prefixBytes, 0);\n buf.set(b, prefixBytes.length);\n return sha512HexRaw(buf);\n}\n\n// hashRendered moved to consentRenderedHash.ts (Node-only, consent_rendered_hash_06):\n// its new signature takes a SECRET tenant pepper, which must never ship into\n// browser-executable code, unlike this file's other (public-bytes-only) hashers.\n// See that file's module doc for the full rationale.\n\n/**\n * Serialize a ConsentChainEntry to the deterministic 15-field TLV byte sequence.\n *\n * # Description\n *\n * Byte-identical to internal/consent.ConsentCanonical and Python consent_canonical\n * for the same field values. Synchronous — no crypto; pure byte assembly.\n *\n * Fields are written in the locked alphabetical order (15 fields total).\n * Fields 12–13 (processing_mode_at_write, processing_mode_set_by_event_id) are\n * encoded by delegating to {@link encodeProcessingModeCanonicalFields}.\n *\n * # Inputs\n *\n * - entry: The ConsentChainEntry to serialize. All 15 fields must be populated.\n *\n * # Outputs\n *\n * - Uint8Array: Deterministic TLV bytes; always non-empty on success.\n * - InvalidConsentEntryError: Thrown on any field validation failure.\n *\n * # Limitations\n *\n * - Does not perform cross-tenant check; caller's responsibility.\n * - string fields must not exceed 1024 bytes (UTF-8 encoded).\n *\n * # Assumptions\n *\n * - All 15 fields are populated with valid values.\n */\nexport function consentCanonical(entry: ConsentChainEntry): Uint8Array {\n validateConsentEntry(entry);\n\n const pmBytes = encodeProcessingModeCanonicalFields(\n entry.processing_mode_at_write,\n entry.processing_mode_set_by_event_id,\n );\n\n // Fields in strict alphabetical order (locked canonical form v2).\n const parts: Uint8Array[] = [\n encStr(entry.actor_pseudonym), // 1. actor_pseudonym\n encStr(entry.actor_pseudonym_key_version), // 2. actor_pseudonym_key_version\n encStr(entry.company_id), // 3. company_id\n encStr(entry.consent_id), // 4. consent_id\n encStr(entry.consent_rendered_hash), // 5. consent_rendered_hash\n encStr(entry.consent_template_hash), // 6. consent_template_hash\n encStr(entry.consent_text_version), // 7. consent_text_version\n encStr(entry.entry_type), // 8. entry_type\n encStr(entry.event_type), // 9. event_type\n encI64(entry.expires_at_ms), // 10. expires_at_ms\n encStr(entry.idempotency_key_hash), // 11. idempotency_key_hash\n pmBytes, // 12–13. processing_mode_at_write + processing_mode_set_by_event_id\n encStr(entry.signing_key_id), // 14. signing_key_id\n encI64(entry.timestamp_ms), // 15. timestamp_ms\n ];\n\n return concatUint8Arrays(parts);\n}\n\n/**\n * Return hex(SHA-512(CONSENT_ENTRY_HASH_PREFIX + canonical)).\n *\n * # Description\n *\n * Async because WebCrypto's digest API is always async (mirrors chain.ts pattern).\n *\n * # Inputs\n *\n * - canonical: TLV bytes from consentCanonical for this entry.\n *\n * # Outputs\n *\n * - Promise<string>: 128 lowercase hex characters (SHA-512 output).\n *\n * # Assumptions\n *\n * - canonical is the output of consentCanonical for the same entry.\n */\nexport async function deriveConsentContentHash(\n canonical: Uint8Array,\n): Promise<string> {\n const prefixBytes = new TextEncoder().encode(CONSENT_ENTRY_HASH_PREFIX);\n const buf = new Uint8Array(prefixBytes.length + canonical.length);\n buf.set(prefixBytes, 0);\n buf.set(canonical, prefixBytes.length);\n return sha512HexRaw(buf);\n}\n\n/**\n * Verify the ML-DSA-65 signature over canonical bytes.\n *\n * # Description\n *\n * Uses getPublicKey(keyId) from keys.ts to look up the embedded public key,\n * then calls ml_dsa65.verify(sigBytes, canonical, pubKey).\n *\n * Note the @noble/post-quantum API arg order: verify(sig, msg, pubKey).\n * This differs from many other libraries — do not swap.\n *\n * # Inputs\n *\n * - canonical: TLV bytes from consentCanonical for the entry.\n * - sigBytes: Raw ML-DSA-65 signature bytes (must be exactly 3309 bytes).\n * - keyId: The signing key ID from the consent_chain_entries row.\n *\n * # Outputs\n *\n * - Promise<void>: Resolves normally if verification succeeds.\n * - ConsentVerificationError: Thrown on unknown keyId, wrong sig length,\n * or failed ML-DSA-65 verification.\n *\n * # Limitations\n *\n * - Cross-tenant check is the caller's responsibility.\n *\n * # Assumptions\n *\n * - canonical is the output of consentCanonical for the same entry.\n * - sigBytes is the raw ML-DSA-65 signature (not base64).\n */\nexport async function verifyConsentSignature(\n canonical: Uint8Array,\n sigBytes: Uint8Array,\n keyId: string,\n): Promise<void> {\n // Signature length check BEFORE key lookup to avoid key-ID oracle timing attacks.\n if (sigBytes.length !== MLDSA65_SIG_SIZE) {\n throw new ConsentVerificationError(\n \"verifyConsentSignature: invalid signature length (want 3309)\",\n );\n }\n\n let pubKey: Uint8Array;\n try {\n pubKey = getPublicKey(keyId);\n } catch {\n throw new ConsentVerificationError(\n \"verifyConsentSignature: unknown key_id\",\n );\n }\n\n // @noble/post-quantum API: verify(sig, msg, pubKey) — note arg order.\n const valid = ml_dsa65.verify(sigBytes, canonical, pubKey);\n if (!valid) {\n throw new ConsentVerificationError(\n \"verifyConsentSignature: ML-DSA-65 signature invalid\",\n );\n }\n}\n\n/**\n * Verify a consent chain entry: canonicalize, check content hash, verify signature.\n *\n * # Description\n *\n * This is the primary entry point for consent entry verification. Mirrors\n * VerifyConsentEntry in the Go SDK and verify_consent_entry in the Python SDK.\n *\n * Steps (order is invariant — do not reorder):\n * 1. consentCanonical(entry) — derive canonical bytes.\n * 2. deriveConsentContentHash(canonical) — re-derive expected hash.\n * 3. Constant-time compare expected hash against storedContentHash.\n * MUST precede key lookup (step 4) to prevent key-ID oracle timing attacks.\n * 4. verifyConsentSignature(canonical, sigBytes, keyId) — ML-DSA-65 verify.\n *\n * # Inputs\n *\n * - entry: The ConsentChainEntry to verify.\n * - storedContentHash: 128-char hex string from audit_entries.content_hash.\n * - sigBytes: Raw ML-DSA-65 signature bytes (exactly 3309 bytes).\n * - keyId: The signing key ID from the consent_chain_entries row.\n *\n * # Outputs\n *\n * - Promise<void>: Resolves normally if verification succeeds.\n * - InvalidConsentEntryError: Thrown if entry field validation fails.\n * - ConsentVerificationError: Thrown if content hash mismatches or\n * signature verification fails.\n *\n * # Limitations\n *\n * - Cross-tenant check is the caller's responsibility:\n * ```typescript\n * if (entry.company_id !== owningChainCompanyId) throw new CrossTenantReplayError();\n * await verifyConsentEntry(entry, storedContentHash, sigBytes, keyId);\n * ```\n *\n * # Assumptions\n *\n * - storedContentHash is a 128-char lowercase hex string.\n * - sigBytes is the raw ML-DSA-65 signature (not base64).\n */\nexport async function verifyConsentEntry(\n entry: ConsentChainEntry,\n storedContentHash: string,\n sigBytes: Uint8Array,\n keyId: string,\n): Promise<void> {\n const canonical = consentCanonical(entry);\n const expectedHash = await deriveConsentContentHash(canonical);\n\n // Constant-time compare — MUST happen before key lookup (key-ID oracle prevention).\n // Both strings are 128 hex chars so byte-lengths are always equal when valid.\n // `constantTimeEqual` handles unequal-length inputs internally without\n // length-leaking early return (returns false constant-time).\n //\n // `TextEncoder` is the cross-runtime way to turn a string into UTF-8 bytes;\n // it works identically in Node and in browsers. This replaced an older\n // `Buffer.from(s, \"utf8\")` pattern as part of `dsar_js_browser_target_audit`.\n const encoder = new TextEncoder();\n const expected = encoder.encode(expectedHash);\n const stored = encoder.encode(storedContentHash);\n const hashesMatch = constantTimeEqual(expected, stored);\n if (!hashesMatch) {\n throw new ConsentVerificationError(\n \"verifyConsentEntry: content hash mismatch\",\n );\n }\n\n await verifyConsentSignature(canonical, sigBytes, keyId);\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Keyed consent_rendered_hash re-derivation (consent_rendered_hash_06).\n *\n * NODE-ONLY. This module uses Node's `crypto.createHmac`, the same\n * synchronous, server-side-only primitive `webhook.ts` uses to verify\n * webhook signatures — not `hashTemplate`'s WebCrypto-async path.\n *\n * `hashRendered`'s input includes a SECRET tenant pepper (the per-tenant\n * consent_rendered_hash sub-key revealed by consent_rendered_hash_04). That\n * is the same shape as verifying a webhook signature — an inherently\n * server-side operation — not the shape of `hashTemplate`, whose input\n * (public template bytes) is safe to run in a browser. A secret must never\n * ship into browser-executable code regardless of which crypto API computes\n * it, so this function is deliberately excluded from `index.browser.ts`\n * exactly as `webhook.ts` is.\n *\n * @module\n */\n\nimport { createHmac } from \"crypto\";\nimport { CONSENT_RENDERED_HASH_PREFIX } from \"./consent.js\";\n\n/**\n * Return hex(HMAC-SHA512(tenantPepper, CONSENT_RENDERED_HASH_PREFIX + b)).\n *\n * # Description\n *\n * Mirrors internal/consent.NewKeyedRenderedHasher(tenantPepper).Hash(b)\n * exactly. Used by external callers to independently verify a chain entry's\n * consent_rendered_hash against the exact bytes they saw at grant time\n * (returned by GET /v1/consent/text).\n *\n * BREAKING CHANGE (consent_rendered_hash epic): prior releases computed\n * unkeyed SHA-512, which has never matched server output — the server has\n * HMAC-keyed this hash since 2026-04-16 (18_20_review_01). There is no\n * unkeyed variant to fall back to; a caller must obtain tenantPepper via the\n * consent-pepper reveal endpoint\n * (POST /v1/internal/consent/rendered-pepper/reveal, consent_rendered_hash_04)\n * before this function can produce a value that verifies anything.\n *\n * Domain-separated from hashTemplate via the distinct prefix\n * CONSENT_RENDERED_HASH_PREFIX so hashTemplate(b) !== hashRendered(b, p) for\n * any input b and any key p (18_20 review finding B4).\n *\n * Synchronous, unlike hashTemplate — Node's createHmac has no async\n * constraint, and this function is Node-only regardless.\n *\n * # Inputs\n *\n * - b: Raw rendered bytes — the exact body returned by GET /v1/consent/text.\n * - tenantPepper: The tenant's revealed consent-rendered-hash sub-key\n * (consent_rendered_hash_04). Must be the exact bytes the reveal\n * endpoint returned; any other value produces a digest that does not\n * match the server's stored consent_rendered_hash.\n *\n * # Outputs\n *\n * - string: 128 lowercase hex characters (HMAC-SHA512 output).\n *\n * # Limitations\n *\n * - Node-only — not exported from the browser bundle (dist/browser/).\n * - Independently verifiable ONLY with the tenant's revealed pepper — not\n * from the public bytes alone. This is deliberate: it is the fix for the\n * rainbow-table oracle an unkeyed hash of PII-adjacent bytes created.\n *\n * # Assumptions\n *\n * - CONSENT_RENDERED_HASH_PREFIX is stable (locked by the v2 schema).\n */\nexport function hashRendered(b: Uint8Array, tenantPepper: Uint8Array): string {\n const mac = createHmac(\"sha512\", tenantPepper);\n mac.update(new TextEncoder().encode(CONSENT_RENDERED_HASH_PREFIX));\n mac.update(b);\n return mac.digest(\"hex\");\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Webhook signature verification for the Aleutian verification SDK.\n *\n * C-3 IMPORTANT: This module uses Node.js crypto.timingSafeEqual for\n * constant-time comparison. It requires Node.js and will not work in browsers.\n *\n * Aleutian signs webhook payloads with HMAC-SHA-512 using a per-endpoint secret.\n * This module provides functions to verify these signatures.\n *\n * Signature format: X-Aleutian-Signature: t={unix_timestamp},v1={hex_hmac}\n * Signed payload: \"{timestamp}.{raw_http_body}\"\n *\n * Security properties:\n * - HMAC-SHA-512 with 256-bit secret\n * - Constant-time comparison (crypto.timingSafeEqual)\n * - Replay protection via timestamp validation\n * - Asymmetric tolerance: 5 minutes past, 30 seconds future\n */\n\nimport { createHmac, timingSafeEqual } from \"crypto\";\nimport { WebhookVerificationError } from \"./errors.js\";\nimport type { WebhookVerifyOptions } from \"./types.js\";\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/** HTTP header containing the signature. */\nexport const WEBHOOK_SIGNATURE_HEADER = \"X-Aleutian-Signature\";\n\n/** Current signature version. */\nexport const WEBHOOK_SIGNATURE_VERSION = \"v1\";\n\n/** Default tolerance values (in seconds). */\nexport const WEBHOOK_DEFAULT_TOLERANCE_PAST = 300; // 5 minutes\nexport const WEBHOOK_DEFAULT_TOLERANCE_FUTURE = 30; // 30 seconds\n\n/** Required length of webhook secrets (32 bytes = 256 bits). */\nconst WEBHOOK_SECRET_LENGTH = 32;\n\n/** Maximum number of secrets allowed for rotation. */\nconst MAX_SECRETS_FOR_ROTATION = 10;\n\n/** Maximum years in the future for timestamp validation. */\nconst MAX_TIMESTAMP_YEARS = 100;\n\n// =============================================================================\n// Simple API (Recommended for most users)\n// =============================================================================\n\n/**\n * Check if a webhook is valid. Returns true/false, never throws.\n *\n * This is the simplest way to verify webhooks - just pass the signature\n * header, raw body, and your secret from the dashboard.\n *\n * M-2: Only catches WebhookVerificationError and expected errors.\n * Programming errors will propagate.\n *\n * @param signatureHeader - Value of X-Aleutian-Signature header\n * @param payload - Raw HTTP request body (do NOT parse JSON first)\n * @param secret - Secret from Aleutian dashboard (base64 or hex, auto-detected)\n * @returns True if webhook is valid, false otherwise\n *\n * @example\n * ```typescript\n * // Express example\n * app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {\n * if (!isValidWebhook(\n * req.headers['x-aleutian-signature'] as string,\n * req.body,\n * process.env.WEBHOOK_SECRET!\n * )) {\n * return res.status(401).send('Invalid signature');\n * }\n * // Process webhook...\n * res.sendStatus(200);\n * });\n * ```\n */\nexport function isValidWebhook(\n signatureHeader: string,\n payload: string | Buffer,\n secret: string\n): boolean {\n try {\n const secretBytes = decodeSecret(secret);\n if (!secretBytes) {\n return false;\n }\n\n verifyWebhookSignature(signatureHeader, payload, secretBytes);\n return true;\n } catch (e) {\n // M-2: Only catch expected verification errors\n if (e instanceof WebhookVerificationError) {\n return false;\n }\n if (e instanceof Error && e.message.includes(\"32 bytes\")) {\n // Secret validation error\n return false;\n }\n // Re-throw unexpected errors (programming bugs)\n throw e;\n }\n}\n\n/**\n * Decode a webhook secret from the dashboard (base64 or hex).\n *\n * The dashboard displays secrets in either base64 (shorter) or hex format.\n * This function auto-detects the format and returns the raw bytes.\n *\n * @param secret - Secret string from dashboard (base64 or hex)\n * @returns Buffer with 32 bytes, or null if invalid format\n *\n * @example\n * ```typescript\n * const secretBytes = decodeSecret(process.env.WEBHOOK_SECRET!);\n * if (!secretBytes) {\n * throw new Error('Invalid WEBHOOK_SECRET format');\n * }\n * ```\n */\nexport function decodeSecret(secret: string): Buffer | null {\n const trimmed = secret.trim();\n\n // Try base64 first (44 chars with padding for 32 bytes)\n if (trimmed.length === 44 && trimmed.endsWith(\"=\")) {\n try {\n const decoded = Buffer.from(trimmed, \"base64\");\n if (decoded.length === WEBHOOK_SECRET_LENGTH) {\n return decoded;\n }\n } catch {\n // Fall through to hex\n }\n }\n\n // Try hex (64 chars for 32 bytes)\n if (trimmed.length === 64 && /^[0-9a-fA-F]+$/.test(trimmed)) {\n try {\n const decoded = Buffer.from(trimmed, \"hex\");\n if (decoded.length === WEBHOOK_SECRET_LENGTH) {\n return decoded;\n }\n } catch {\n // Invalid hex\n }\n }\n\n return null;\n}\n\n// =============================================================================\n// Advanced API\n// =============================================================================\n\n/**\n * Verify a webhook signature with a single secret.\n *\n * Verifies that the webhook payload was signed by Aleutian using the\n * customer's endpoint secret. Includes replay protection.\n *\n * @param signatureHeader - Value of X-Aleutian-Signature header\n * @param payload - Raw HTTP request body (string or Buffer, do NOT parse JSON)\n * @param secret - 256-bit webhook secret (exactly 32 bytes)\n * @param options - Verification options\n *\n * @throws Error if secret is not exactly 32 bytes (M-1)\n * @throws WebhookVerificationError if verification fails\n *\n * @example\n * ```typescript\n * import express from 'express';\n * import { verifyWebhookSignature } from '@aleutian/verification';\n *\n * app.post('/webhook', express.raw({ type: 'application/json' }), (req, res) => {\n * try {\n * verifyWebhookSignature(\n * req.headers['x-aleutian-signature'] as string,\n * req.body,\n * Buffer.from(process.env.WEBHOOK_SECRET!, 'hex')\n * );\n * } catch (e) {\n * if (e instanceof WebhookVerificationError) {\n * return res.status(401).json({ error: e.code });\n * }\n * throw e;\n * }\n * // Process verified webhook...\n * });\n * ```\n */\nexport function verifyWebhookSignature(\n signatureHeader: string,\n payload: string | Buffer,\n secret: Buffer,\n options: WebhookVerifyOptions = {}\n): void {\n // M-1: Validate secret length\n if (secret.length !== WEBHOOK_SECRET_LENGTH) {\n throw new WebhookVerificationError(\n \"SECRET_TOO_SHORT\",\n \"secret must be exactly 32 bytes\"\n );\n }\n\n // H-1: Parse signature - uses constant-time pattern internally\n const parts = parseWebhookSignature(signatureHeader);\n\n const now = options.now ?? Math.floor(Date.now() / 1000);\n const tolerancePast = options.tolerancePast ?? WEBHOOK_DEFAULT_TOLERANCE_PAST;\n const toleranceFuture = options.toleranceFuture ?? WEBHOOK_DEFAULT_TOLERANCE_FUTURE;\n\n // L-3: Validate timestamp bounds (reject absurd timestamps)\n const maxFutureTs = now + MAX_TIMESTAMP_YEARS * 365 * 24 * 60 * 60;\n if (parts.timestamp < 0 || parts.timestamp > maxFutureTs) {\n throw new WebhookVerificationError(\n \"INVALID_TIMESTAMP\",\n \"timestamp out of bounds\"\n );\n }\n\n // Validate timestamp (replay protection)\n const age = now - parts.timestamp;\n\n if (tolerancePast > 0 && age > tolerancePast) {\n throw new WebhookVerificationError(\"EXPIRED\", \"signature timestamp too old\");\n }\n if (toleranceFuture > 0 && age < -toleranceFuture) {\n throw new WebhookVerificationError(\n \"FUTURE\",\n \"signature timestamp too far in future\"\n );\n }\n\n // Compute expected signature\n const expectedSig = computeWebhookSignatureHex(secret, parts.timestamp, payload);\n\n // Constant-time comparison (CRITICAL for security)\n const actualBuf = Buffer.from(parts.signature, \"hex\");\n const expectedBuf = Buffer.from(expectedSig, \"hex\");\n\n if (\n actualBuf.length !== expectedBuf.length ||\n !timingSafeEqual(actualBuf, expectedBuf)\n ) {\n throw new WebhookVerificationError(\n \"INVALID_SIGNATURE\",\n \"signature does not match\"\n );\n }\n}\n\n/**\n * Verify a webhook with multiple secrets (for rotation).\n *\n * During secret rotation, both old and new secrets may be valid.\n * Returns the index of the matching secret.\n *\n * H-5 SECURITY: Verifies against ALL secrets to prevent timing side-channel\n * that would reveal which secret position matched.\n *\n * @param signatureHeader - Value of X-Aleutian-Signature header\n * @param payload - Raw HTTP request body\n * @param secrets - Array of secrets to try (newest first recommended)\n * @param options - Verification options\n * @returns Index of the matching secret (0-based)\n *\n * @throws Error if any secret is not exactly 32 bytes (M-1)\n * @throws WebhookVerificationError if no secret matches\n *\n * @example\n * ```typescript\n * const secrets = [\n * Buffer.from(process.env.WEBHOOK_SECRET_NEW!, 'hex'),\n * Buffer.from(process.env.WEBHOOK_SECRET_OLD!, 'hex'),\n * ];\n * const idx = verifyWebhookWithSecrets(sig, body, secrets);\n * if (idx === 1) {\n * console.warn('Verified with old secret; rotation incomplete');\n * }\n * ```\n */\nexport function verifyWebhookWithSecrets(\n signatureHeader: string,\n payload: string | Buffer,\n secrets: readonly Buffer[],\n options: WebhookVerifyOptions = {}\n): number {\n if (secrets.length === 0) {\n throw new WebhookVerificationError(\n \"NO_MATCHING_SECRET\",\n \"no secrets provided\"\n );\n }\n if (secrets.length > MAX_SECRETS_FOR_ROTATION) {\n throw new Error(\n `Too many secrets: maximum ${MAX_SECRETS_FOR_ROTATION}, got ${secrets.length}`\n );\n }\n\n // M-1: Validate all secret lengths\n for (let i = 0; i < secrets.length; i++) {\n if (secrets[i]!.length !== WEBHOOK_SECRET_LENGTH) {\n throw new Error(`secret at index ${i} must be exactly 32 bytes`);\n }\n }\n\n // H-1: Parse signature - uses constant-time pattern internally\n const parts = parseWebhookSignature(signatureHeader);\n\n const now = options.now ?? Math.floor(Date.now() / 1000);\n const tolerancePast = options.tolerancePast ?? WEBHOOK_DEFAULT_TOLERANCE_PAST;\n const toleranceFuture = options.toleranceFuture ?? WEBHOOK_DEFAULT_TOLERANCE_FUTURE;\n\n // L-3: Validate timestamp bounds\n const maxFutureTs = now + MAX_TIMESTAMP_YEARS * 365 * 24 * 60 * 60;\n if (parts.timestamp < 0 || parts.timestamp > maxFutureTs) {\n throw new WebhookVerificationError(\n \"INVALID_TIMESTAMP\",\n \"timestamp out of bounds\"\n );\n }\n\n const age = now - parts.timestamp;\n\n if (tolerancePast > 0 && age > tolerancePast) {\n throw new WebhookVerificationError(\"EXPIRED\", \"signature timestamp too old\");\n }\n if (toleranceFuture > 0 && age < -toleranceFuture) {\n throw new WebhookVerificationError(\n \"FUTURE\",\n \"signature timestamp too far in future\"\n );\n }\n\n const actualBuf = Buffer.from(parts.signature, \"hex\");\n\n // H-5: Verify ALL secrets to prevent timing side-channel.\n // Do NOT early-return on match - attacker could time which position matched.\n let matchedIdx = -1;\n for (let i = 0; i < secrets.length; i++) {\n const expectedSig = computeWebhookSignatureHex(\n secrets[i]!,\n parts.timestamp,\n payload\n );\n const expectedBuf = Buffer.from(expectedSig, \"hex\");\n\n if (\n actualBuf.length === expectedBuf.length &&\n timingSafeEqual(actualBuf, expectedBuf)\n ) {\n if (matchedIdx < 0) {\n matchedIdx = i;\n }\n // Continue checking remaining secrets to ensure constant time\n }\n }\n\n if (matchedIdx < 0) {\n throw new WebhookVerificationError(\n \"NO_MATCHING_SECRET\",\n \"no secret produced a valid signature\"\n );\n }\n return matchedIdx;\n}\n\n/**\n * Compute a webhook signature header (for testing/debugging).\n *\n * Returns the full signature header value in the format: \"t={ts},v1={hex}\"\n *\n * This function is primarily intended for testing purposes. Production\n * webhook signing is performed by Aleutian's servers.\n *\n * @param secret - 32-byte webhook secret\n * @param timestamp - Unix timestamp in seconds\n * @param payload - Raw payload\n * @returns Full signature header value\n *\n * @example\n * ```typescript\n * const sig = computeWebhookSignature(secret, Math.floor(Date.now()/1000), '{\"event\":\"test\"}');\n * // Returns: \"t=1706097600,v1=a1b2c3d4...\"\n * ```\n */\nexport function computeWebhookSignature(\n secret: Buffer,\n timestamp: number,\n payload: string | Buffer\n): string {\n const sig = computeWebhookSignatureHex(secret, timestamp, payload);\n return `t=${timestamp},${WEBHOOK_SIGNATURE_VERSION}=${sig}`;\n}\n\n// =============================================================================\n// Internal Functions\n// =============================================================================\n\ninterface SignatureParts {\n timestamp: number;\n version: string;\n signature: string;\n}\n\n/**\n * Parse signature header format: t={timestamp},v1={hex}\n *\n * H-1: Uses constant-time pattern - always performs full parse before\n * returning any error. Does not echo user-controlled input in errors.\n */\nfunction parseWebhookSignature(header: string): SignatureParts {\n // Parse all fields before returning any error (constant-time pattern)\n const segments = header.split(\",\");\n const segmentCountValid = segments.length === 2;\n\n let timestamp = 0;\n let tsValid = false;\n if (segmentCountValid && segments[0]!.startsWith(\"t=\")) {\n const parsed = parseInt(segments[0]!.slice(2), 10);\n if (!isNaN(parsed)) {\n timestamp = parsed;\n tsValid = true;\n }\n }\n\n let version = \"\";\n let signature = \"\";\n let versionValid = false;\n let sigLenValid = false;\n let sigHexValid = false;\n\n if (segmentCountValid && segments[1]) {\n const eqIdx = segments[1].indexOf(\"=\");\n if (eqIdx > 0) {\n version = segments[1].slice(0, eqIdx);\n signature = segments[1].slice(eqIdx + 1);\n versionValid = version === WEBHOOK_SIGNATURE_VERSION;\n // HMAC-SHA-512 = 64 bytes = 128 hex chars (post SHA-256 → SHA-512 upgrade).\n sigLenValid = signature.length === 128;\n sigHexValid = sigLenValid && /^[0-9a-f]{128}$/.test(signature);\n }\n }\n\n // Now determine the error (if any) - always after full parsing\n if (!segmentCountValid) {\n throw new WebhookVerificationError(\"INVALID_FORMAT\", \"invalid header format\");\n }\n if (!segments[0]!.startsWith(\"t=\")) {\n throw new WebhookVerificationError(\"INVALID_FORMAT\", \"missing timestamp prefix\");\n }\n if (!tsValid) {\n throw new WebhookVerificationError(\n \"INVALID_TIMESTAMP\",\n \"timestamp is not a valid integer\"\n );\n }\n if (!versionValid) {\n // L-1: Don't echo user-controlled version string\n throw new WebhookVerificationError(\n \"INVALID_FORMAT\",\n \"unsupported signature version\"\n );\n }\n if (!sigLenValid || !sigHexValid) {\n throw new WebhookVerificationError(\"INVALID_FORMAT\", \"invalid signature format\");\n }\n\n return { timestamp, version, signature };\n}\n\n/**\n * Compute HMAC-SHA-512 signature as hex string.\n *\n * Was HMAC-SHA-256 before the project-wide SHA-256 → SHA-512 upgrade.\n * Producer (`internal/...`) + Go SDK + Python SDK all use SHA-512;\n * the JS SDK lagged until 2026-05-18 when the cross-SDK fixture\n * drift surfaced via the f_01 work. 128 hex chars = 64-byte\n * HMAC-SHA-512 output.\n *\n * L-5: Properly handles Buffer payloads without lossy string conversion.\n */\nfunction computeWebhookSignatureHex(\n secret: Buffer,\n timestamp: number,\n payload: string | Buffer\n): string {\n // Build signed payload by concatenating timestamp prefix with raw payload\n const prefix = Buffer.from(`${timestamp}.`);\n const payloadBuf = typeof payload === \"string\" ? Buffer.from(payload) : payload;\n const signedPayload = Buffer.concat([prefix, payloadBuf]);\n return createHmac(\"sha512\", secret).update(signedPayload).digest(\"hex\");\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Standalone FIPS 204 (ML-DSA-65) signature verifier.\n *\n * Wraps `@noble/post-quantum`'s `ml_dsa65` in a minimal API suitable for\n * auditors and downstream consumers who want to verify an Aleutian-signed\n * artifact without importing the full verification SDK surface. The\n * primitive is framework-free: it accepts raw byte arrays and throws a\n * sentinel error on failure.\n *\n * All three Aleutian verification SDKs (Go, Python, JS) converge on\n * identical semantics, enforced by the shared KAT vectors at\n * `sdk/testdata/mldsa_vectors.json`.\n *\n * Wire format:\n * - publicKey: raw 1952-byte ML-DSA-65 public key (FIPS 204 §5.2)\n * - message: arbitrary bytes; no pre-hashing — ML-DSA-65 hashes internally\n * - signature: raw 3309-byte ML-DSA-65 signature (FIPS 204 §5.3)\n * - context: empty (FIPS 204 pure mode; matches Cloud KMS PQ_SIGN_ML_DSA_65)\n *\n * @example\n * ```ts\n * import { verify, MLDSAVerificationError } from \"@aleutian/verification/mldsa\";\n * try {\n * verify(publicKey, canonicalBytes, signature);\n * } catch (e) {\n * if (e instanceof MLDSAVerificationError) {\n * // branch on e.code: \"invalid_public_key\" | \"invalid_signature_length\"\n * // | \"signature_verification_failed\"\n * }\n * }\n * ```\n */\n\nimport { ml_dsa65 } from \"@noble/post-quantum/ml-dsa.js\";\n\n/** Byte length of an ML-DSA-65 public key (FIPS 204). */\nexport const PUBLIC_KEY_SIZE = 1952;\n\n/** Byte length of an ML-DSA-65 signature (FIPS 204). */\nexport const SIGNATURE_SIZE = 3309;\n\n/** Discriminant codes for {@link MLDSAVerificationError}. */\nexport type MLDSAErrorCode =\n | \"invalid_public_key\"\n | \"invalid_signature_length\"\n | \"signature_verification_failed\";\n\n/**\n * Base error thrown by {@link verify} on any failure. Branch on `code`.\n */\nexport class MLDSAVerificationError extends Error {\n public readonly code: MLDSAErrorCode;\n\n constructor(code: MLDSAErrorCode, message: string) {\n super(message);\n this.name = \"MLDSAVerificationError\";\n this.code = code;\n // Preserve prototype chain for instanceof across transpilation targets.\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nfunction assertUint8Array(value: unknown, field: string): Uint8Array {\n if (!(value instanceof Uint8Array)) {\n throw new MLDSAVerificationError(\n \"invalid_public_key\",\n `${field} must be a Uint8Array`,\n );\n }\n return value;\n}\n\n/**\n * Verify an ML-DSA-65 signature in FIPS 204 pure mode.\n *\n * No pre-hashing is applied — the scheme hashes the message internally per\n * FIPS 204 §5.3. The empty context string matches Cloud KMS\n * PQ_SIGN_ML_DSA_65 and the Go and Python SDK counterparts. Do not change\n * without coordinated updates across every signing path.\n *\n * @param publicKey - Raw 1952-byte ML-DSA-65 public key.\n * @param message - Exact bytes that were signed (e.g., RFC 8785 canonical JSON).\n * @param signature - Raw 3309-byte ML-DSA-65 signature.\n * @throws {MLDSAVerificationError} with `code`:\n * - `invalid_public_key` if `publicKey` is not a Uint8Array of length\n * {@link PUBLIC_KEY_SIZE}.\n * - `invalid_signature_length` if `signature` is not a Uint8Array of\n * length {@link SIGNATURE_SIZE}.\n * - `signature_verification_failed` if the signature does not verify\n * against the given public key and message.\n *\n * Limitations:\n * - Does not resolve key IDs; callers provide raw public-key bytes.\n * - Does not check revocation status; that is the trust-store loader's job.\n * - No context string is supported; pure FIPS 204 mode only.\n *\n * Assumptions:\n * - `message` bytes are already canonicalized to match what was signed.\n * - `publicKey` is the raw 1952-byte encoding, not PEM or DER-wrapped.\n */\nexport function verify(\n publicKey: Uint8Array,\n message: Uint8Array,\n signature: Uint8Array,\n): void {\n const pk = assertUint8Array(publicKey, \"publicKey\");\n const msg = assertUint8Array(message, \"message\");\n const sig = (() => {\n if (!(signature instanceof Uint8Array)) {\n throw new MLDSAVerificationError(\n \"invalid_signature_length\",\n \"signature must be a Uint8Array\",\n );\n }\n return signature;\n })();\n\n if (pk.length !== PUBLIC_KEY_SIZE) {\n throw new MLDSAVerificationError(\n \"invalid_public_key\",\n `publicKey is ${pk.length} bytes, want ${PUBLIC_KEY_SIZE}`,\n );\n }\n if (sig.length !== SIGNATURE_SIZE) {\n throw new MLDSAVerificationError(\n \"invalid_signature_length\",\n `signature is ${sig.length} bytes, want ${SIGNATURE_SIZE}`,\n );\n }\n\n // @noble/post-quantum API: verify(sig, msg, pubKey) → boolean.\n // Any thrown error is treated as a verification failure.\n let ok: boolean;\n try {\n ok = ml_dsa65.verify(sig, msg, pk);\n } catch (err) {\n throw new MLDSAVerificationError(\n \"signature_verification_failed\",\n `ML-DSA-65 verify raised: ${err instanceof Error ? err.message : String(err)}`,\n );\n }\n if (!ok) {\n throw new MLDSAVerificationError(\n \"signature_verification_failed\",\n \"ML-DSA-65 signature verification failed\",\n );\n }\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Key ids, as proof computes them (format-spec §9.6).\n *\n * A key id only NAMES a key: whether to trust that key is the verifier's\n * decision. A verifier that checks a signature row naming key id K must make\n * sure the public key it verifies with really has id K\n * (`await keyIdMLDSA65(pk) === K`); otherwise a row could name one key and be\n * checked with another.\n *\n * - ML-DSA-65: the first 16 bytes of\n * `SHA-512(\"proof.keyid.v1:\" || SubjectPublicKeyInfo DER)`, as 32 lowercase\n * hex. The SPKI follows RFC 9881: the AlgorithmIdentifier is the ML-DSA-65\n * OID with parameters ABSENT, and the BIT STRING holds the raw public key.\n * - X-Wing, a legacy rule: the first 16 bytes of `SHA-512(raw public key)`, no\n * domain string.\n *\n * Vectors: `testdata/keyid_vectors.json` (computed independently, in Python,\n * from the spec).\n */\n\nimport { hexToUint8Array, sha512HexRaw } from \"./hash.js\";\n\n/** The domain string hashed before an ML-DSA SubjectPublicKeyInfo. */\nexport const KEYID_DOMAIN = \"proof.keyid.v1:\";\n\n/** ML-DSA-65 public key size (FIPS 204). */\nexport const MLDSA65_PUBLIC_KEY_SIZE = 1952;\n\n// RFC 9881: id-ml-dsa-65 = 2.16.840.1.101.3.4.3.18, parameters absent.\nconst MLDSA65_ALGORITHM_IDENTIFIER = hexToUint8Array(\"300b0609608648016503040312\");\n\nfunction derLength(n: number): Uint8Array {\n if (n < 0x80) return Uint8Array.of(n);\n const body: number[] = [];\n for (let v = n; v > 0; v = Math.floor(v / 256)) body.unshift(v % 256);\n return Uint8Array.of(0x80 | body.length, ...body);\n}\n\nfunction concat(...parts: Uint8Array[]): Uint8Array {\n const out = new Uint8Array(parts.reduce((n, p) => n + p.length, 0));\n let at = 0;\n for (const p of parts) {\n out.set(p, at);\n at += p.length;\n }\n return out;\n}\n\n/**\n * The SubjectPublicKeyInfo DER of a raw ML-DSA-65 public key.\n *\n * @throws Error when the key is not exactly 1952 bytes.\n */\nexport function mldsa65Spki(publicKey: Uint8Array): Uint8Array {\n if (publicKey.length !== MLDSA65_PUBLIC_KEY_SIZE) {\n throw new Error(\n `an ML-DSA-65 public key is ${MLDSA65_PUBLIC_KEY_SIZE} bytes, got ${publicKey.length}`\n );\n }\n const bitString = concat(\n Uint8Array.of(0x03),\n derLength(publicKey.length + 1),\n Uint8Array.of(0x00),\n publicKey\n );\n const body = concat(MLDSA65_ALGORITHM_IDENTIFIER, bitString);\n return concat(Uint8Array.of(0x30), derLength(body.length), body);\n}\n\n/**\n * The key id of a raw ML-DSA-65 public key: 32 lowercase hex.\n *\n * @throws Error when the key is not exactly 1952 bytes.\n */\nexport async function keyIdMLDSA65(publicKey: Uint8Array): Promise<string> {\n const input = concat(new TextEncoder().encode(KEYID_DOMAIN), mldsa65Spki(publicKey));\n return (await sha512HexRaw(input)).slice(0, 32);\n}\n\n/**\n * The key id of a raw X-Wing public key (the legacy rule, no domain).\n *\n * @throws Error when the key is empty.\n */\nexport async function keyIdXWing(publicKey: Uint8Array): Promise<string> {\n if (publicKey.length === 0) throw new Error(\"an X-Wing public key cannot be empty\");\n return (await sha512HexRaw(publicKey)).slice(0, 32);\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * SAR (Data Subject Access Request) v3 chain entry types — TS verifier port.\n *\n * Cross-language reference\n * ========================\n * Mirror of {@link \"../../verification-go/sar_entries_v3.go\"} and\n * {@link \"../../verification-python/src/aleutian_verification/sar_entries.py\"}.\n * Field order in each interface MUST match the alphabetical body-field order\n * from `pqc_05c v3 §4.5–4.9`. The canonical encoder in `canonicalV3.ts`\n * (ticket dsar_chain_f_02) relies on declaration ordering — silent reorder\n * is a wire-format break.\n *\n * Sealed discriminated union\n * ==========================\n * TypeScript cannot enforce protocol sealing at the type-system level the\n * way Go can (no unexported parameter types). Instead this module defines\n * `CONCRETE_SAR_ENTRY_TYPE_TAGS` — an authoritative set of `entryType`\n * literal values — and the public encoder / verifier dispatch chain\n * (canonicalV3.chainCanonicalV3 in `_02`, verifyV3.verifyChainEntryV3\n * in `_04`) checks the tag at runtime before any work. Structural-typing\n * impostors that duck-type `ChainEntryV3` are refused at that boundary.\n * The `ChainEntryV3` discriminated union remains the static type for\n * annotation purposes; it is NOT the security boundary — the tag set is.\n *\n * Privacy posture (OQ-11, locked)\n * ================================\n * SAR entries are systematically actor-anonymous on chain. NONE of these\n * interfaces carry actor pseudonyms or email-derived hashes. Verifiers\n * cannot identify the data subject from the chain entry alone.\n *\n * Field naming\n * ============\n * camelCase per TS convention. The on-the-wire JSON form is snake_case;\n * the canonical encoder operates on these typed objects directly, NOT\n * on the JSON. Callers loading from chain rows should convert via the\n * snake-case→camel-case helper in `chainRowDecode.ts` (future ticket)\n * before passing entries into the encoder/verifier.\n *\n * @module\n */\n\n// =============================================================================\n// Enums (string literal unions)\n// =============================================================================\n\n/** Chain entry discriminating tag (pqc_05c v3 §3.2). */\nexport type EventTypeV3 =\n | \"sar_intent\"\n | \"sar_acknowledged\"\n | \"sar_fulfilled\"\n | \"sar_rejected\"\n | \"sar_extended\";\n\n/** Surface that originated a SAR intent (canonical on chain, only on intent). */\nexport type SARSourceChannelV3 = \"portal\" | \"api\";\n\n/** GDPR right being exercised. */\nexport type SARTypeV3 = \"access\" | \"erasure\" | \"both\";\n\n/** What the controller actually did at fulfillment time. */\nexport type SARFulfillmentKindV3 = \"access\" | \"erasure\" | \"both\";\n\n// =============================================================================\n// TenantHMACDigestV3\n// =============================================================================\n\nconst _HMAC_DIGEST_LEN = 64 as const;\n\n/**\n * Internal brand for nominal-typing on TenantHMACDigestV3.\n *\n * The brand is TYPE-ONLY — there is no runtime property of this name on\n * the value. `declare const ... unique symbol` is erased at runtime, so\n * the constructed object has only `hex` at runtime. The compile-time\n * brand prevents external code from forging a digest via plain object\n * literal: `{ hex: \"...\" } as TenantHMACDigestV3` fails type-check\n * because the synthetic brand property is unsatisfiable outside this\n * module.\n */\ndeclare const _digestBrand: unique symbol;\n\n/**\n * HMAC-SHA-512 digest under a per-tenant PII subkey (pqc_05c v3 §4.0).\n *\n * Stored as a hex string (or empty string for the zero / unset sentinel) —\n * matches Go SDK's `TenantHMACDigestV3` byte-for-byte so the canonical\n * encoder produces parity output. The encoder calls `.hex`; empty\n * string emits a 0-length TLV (sentinel for \"caller did not supply\n * cleartext\"), and 128-hex emits a 128-byte string.\n *\n * Construct via {@link tenantHMACDigestFromHex}, {@link tenantHMACDigestFromRaw},\n * or {@link tenantHMACDigestZero}. The type-only brand prevents\n * external code from forging a digest via `{} as TenantHMACDigestV3` —\n * the brand property is unsatisfiable outside this module.\n */\nexport interface TenantHMACDigestV3 {\n readonly hex: string;\n // Phase 3 review M1: brand is `: never` (NOT `?: never`). The\n // optional form `?:` was bypassable via `{ hex } as TenantHMACDigestV3`\n // because TS treats an absent optional property as satisfying\n // `never`. With the required form, the cast fails compilation —\n // the brand actually carries weight beyond documentation.\n readonly [_digestBrand]: never;\n}\n\n/**\n * Compile-time-only attached \"brand\" so the constructor functions\n * can satisfy the required `[_digestBrand]: never` slot without\n * actually creating that property at runtime. Type-erased at emit.\n */\nconst _digestBrandStamp = {} as { [_digestBrand]: never };\n\n/**\n * H4 redaction methods (Phase 3 review pre-emptive ticket): every\n * TenantHMACDigestV3 instance carries non-enumerable methods that\n * redact the full HMAC hex when the value is logged or serialized\n * by accident. The methods cover all four JS surfaces a developer\n * might hit:\n *\n * - `toString()` — used by template literals, `String(d)`, `d + \"\"`\n * - `toJSON()` — used by `JSON.stringify(d)`\n * - `[Symbol.toPrimitive]` — used by coercion and runtime introspection\n * - `[Symbol.for(\"nodejs.util.inspect.custom\")]` — used by Node's\n * `util.inspect` (and `console.log` under Node)\n *\n * The redacted form shows only the first 8 hex chars + \"...\". A zero\n * digest renders as `TenantHMACDigestV3(unset)`. The raw `.hex`\n * property remains accessible for verifier code that legitimately\n * needs the bytes (the encoder calls `.hex` directly).\n *\n * Methods are non-enumerable and non-writable so they don't leak\n * into `Object.keys(d)` or `JSON.stringify(...{...d})` spreads, and\n * can't be deleted to bypass the redaction.\n */\nfunction _stampRedactionMethods(d: TenantHMACDigestV3): TenantHMACDigestV3 {\n const redacted = (): string =>\n d.hex === \"\"\n ? \"TenantHMACDigestV3(unset)\"\n : `TenantHMACDigestV3(${d.hex.slice(0, 8)}…)`;\n const define = (key: PropertyKey, value: unknown): void => {\n Object.defineProperty(d, key, {\n value,\n enumerable: false,\n writable: false,\n configurable: false,\n });\n };\n define(\"toString\", redacted);\n define(\"toJSON\", redacted);\n define(Symbol.toPrimitive, redacted);\n define(Symbol.for(\"nodejs.util.inspect.custom\"), redacted);\n return d;\n}\n\n/** Construct from a 128-char lowercase hex string. Empty string → zero digest. */\nexport function tenantHMACDigestFromHex(hex: string): TenantHMACDigestV3 {\n // Combined length + charset check via a single anchored regex\n // (Phase 3 review LOW: collapses the two prior conditions).\n if (hex !== \"\" && !/^[0-9a-f]{128}$/.test(hex)) {\n throw new Error(\n `TenantHMACDigestV3 hex must be empty OR exactly ${_HMAC_DIGEST_LEN * 2} lowercase hex chars`,\n );\n }\n return _stampRedactionMethods({ hex, ..._digestBrandStamp });\n}\n\n/** Construct from 64 raw bytes. */\nexport function tenantHMACDigestFromRaw(raw: Uint8Array): TenantHMACDigestV3 {\n if (!(raw instanceof Uint8Array)) {\n throw new TypeError(\"TenantHMACDigestV3.fromRaw expects Uint8Array\");\n }\n if (raw.length !== _HMAC_DIGEST_LEN) {\n throw new Error(`TenantHMACDigestV3.fromRaw expects ${_HMAC_DIGEST_LEN} bytes`);\n }\n // Phase 3 review LOW: idiomatic Array.from(...).join instead of\n // per-byte string concatenation.\n const hex = Array.from(raw, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n return _stampRedactionMethods({ hex, ..._digestBrandStamp });\n}\n\n/** Zero / unset digest — encodes as empty string on chain. */\nexport function tenantHMACDigestZero(): TenantHMACDigestV3 {\n return _stampRedactionMethods({ hex: \"\", ..._digestBrandStamp });\n}\n\n/** True iff the digest is the zero / unset sentinel. */\nexport function tenantHMACDigestIsZero(d: TenantHMACDigestV3): boolean {\n return d.hex === \"\";\n}\n\n// =============================================================================\n// V3 SAR chain entry interfaces — 5 discriminated-union members\n//\n// Header (alphabetical):\n// 1. companyId — comp_<26-char ULID>\n// 2. entryType — discriminating tag (EventTypeV3)\n// 3. signingKeyId — KMS key identifier\n// 4. timestampMs — Unix milliseconds\n//\n// Body order per type follows pqc_05c v3 §4.5–4.9 alphabetical.\n// =============================================================================\n\n/**\n * Common header — present on every v3 chain entry.\n *\n * # Number vs BigInt typing (Phase 3 review H1)\n *\n * Int64 fields (`timestampMs`, `tombstoneCount`, `extendedDueAtMs`)\n * accept `bigint | number`. JS `Number` is double-precision IEEE-754,\n * so values above `Number.MAX_SAFE_INTEGER` (2^53 - 1) silently lose\n * precision. Realistic v3 values fit comfortably (e.g., year-3000\n * UnixMilli is ~3.3 × 10^13, well under 2^53 ≈ 9 × 10^15), but a\n * future caller pulling row data from BigQuery — where int64 may\n * surface as `bigint` — should be able to pass it through without a\n * cast or precision-loss risk.\n *\n * The encoder (`canonicalV3.appendU64`) accepts either form and\n * routes through `DataView.setBigUint64` for byte-identical BE\n * encoding regardless of the source representation.\n */\ninterface _ChainEntryHeaderV3<T extends EventTypeV3> {\n readonly companyId: string;\n readonly entryType: T;\n readonly signingKeyId: string;\n readonly timestampMs: bigint | number;\n}\n\n/**\n * Filed-SAR entry. Header + 5 body fields (pqc_05c v3 §4.5).\n *\n * `piiDigestKeyVersion` (pii_hmac_key_rotation_R4): source-namespaced\n * PII-HMAC key version (\"sm:v1\") under which `reasonHash` was computed.\n * OPTIONAL on intent (reason_hash itself is optional). Empty string is\n * the legacy / pre-rotation sentinel — encoded ONLY when non-empty so a\n * legacy leaf hashes byte-identically to its original signing. Matches\n * the Go SDK's `SARIntentEntryV3.PIIDigestKeyVersion` (json\n * `pii_digest_key_version`).\n */\nexport interface SARIntentEntryV3 extends _ChainEntryHeaderV3<\"sar_intent\"> {\n readonly piiDigestKeyVersion: string;\n readonly reasonHash: TenantHMACDigestV3;\n readonly requestId: string;\n readonly sarType: SARTypeV3;\n readonly scope: string;\n readonly sourceChannel: SARSourceChannelV3;\n}\n\n/** Acknowledged-SAR entry. Header + 2 body fields (pqc_05c v3 §4.6). */\nexport interface SARAcknowledgedEntryV3\n extends _ChainEntryHeaderV3<\"sar_acknowledged\"> {\n readonly intentEntryId: string;\n readonly requestId: string;\n}\n\n/**\n * Fulfilled-SAR entry. Header + 7 body fields (pqc_05c v3 §4.7).\n *\n * `certificateId` was added 2026-05-16 by `dsar_fulfill_b_pre_02e` as the\n * alphabetical-first body field. Per-kind shape rules:\n *\n * - fulfillmentKind=access → certificateId MUST be empty\n * - fulfillmentKind=erasure → certificateId MUST match cert_<32-hex>\n * - fulfillmentKind=both → certificateId MUST match cert_<32-hex>\n */\nexport interface SARFulfilledEntryV3\n extends _ChainEntryHeaderV3<\"sar_fulfilled\"> {\n readonly certificateId: string;\n readonly fulfillmentKind: SARFulfillmentKindV3;\n readonly intentEntryId: string;\n readonly legalBasis: string;\n readonly manifestRoot: string;\n readonly requestId: string;\n readonly tombstoneCount: bigint | number;\n}\n\n/**\n * Rejected-SAR entry. Header + 4 body fields (pqc_05c v3 §4.8).\n *\n * `piiDigestKeyVersion` (pii_hmac_key_rotation_R4): PII-HMAC key version\n * (\"sm:v1\") under which `rationaleHash` was computed. REQUIRED in the\n * sense that rationale_hash is required on rejection, so a non-empty\n * version always has a digest to apply it to. Empty string is the legacy\n * sentinel — encoded ONLY when non-empty. Matches Go\n * `SARRejectedEntryV3.PIIDigestKeyVersion`.\n */\nexport interface SARRejectedEntryV3 extends _ChainEntryHeaderV3<\"sar_rejected\"> {\n readonly intentEntryId: string;\n readonly legalBasis: string;\n readonly piiDigestKeyVersion: string;\n readonly rationaleHash: TenantHMACDigestV3;\n readonly requestId: string;\n}\n\n/**\n * Extended-SAR entry. Header + 4 body fields (pqc_05c v3 §4.9).\n *\n * Body alphabetical: extendedDueAtMs, intentEntryId, piiDigestKeyVersion\n * (R4, iff non-empty), reasonHash, requestId.\n * `originalDueAtMs` is NOT bound — derivable from the intent entry.\n */\nexport interface SARExtendedEntryV3 extends _ChainEntryHeaderV3<\"sar_extended\"> {\n readonly extendedDueAtMs: bigint | number;\n readonly intentEntryId: string;\n /**\n * `piiDigestKeyVersion` (pii_hmac_key_rotation_R4): PII-HMAC key\n * version (\"sm:v1\") under which `reasonHash` was computed. reason_hash\n * is required on extension, so a non-empty version always has a digest\n * to apply it to. Empty string is the legacy sentinel — encoded ONLY\n * when non-empty. Matches Go `SARExtendedEntryV3.PIIDigestKeyVersion`.\n */\n readonly piiDigestKeyVersion: string;\n readonly reasonHash: TenantHMACDigestV3;\n readonly requestId: string;\n}\n\n/**\n * Discriminated union of all 5 v3 SAR chain entry types.\n *\n * The `entryType` literal field is the discriminant — TypeScript narrows\n * to a specific interface when you switch on it:\n *\n * ```ts\n * function describe(e: ChainEntryV3): string {\n * switch (e.entryType) {\n * case \"sar_intent\": return `intent ${e.requestId}`;\n * case \"sar_fulfilled\": return `fulfilled ${e.manifestRoot.slice(0, 8)}…`;\n * // ... compiler errors if you forget a case\n * }\n * }\n * ```\n */\nexport type ChainEntryV3 =\n | SARIntentEntryV3\n | SARAcknowledgedEntryV3\n | SARFulfilledEntryV3\n | SARRejectedEntryV3\n | SARExtendedEntryV3;\n\n// =============================================================================\n// Concrete-tag set for runtime dispatch (the actual security boundary).\n//\n// Used by canonicalV3.chainCanonicalV3 (in _02) and verifyV3.verifyChainEntryV3\n// (in _04) as the allowlist that refuses structural-typing impostors.\n// Mirrors Python's CONCRETE_SAR_ENTRY_TYPES dispatch.\n// =============================================================================\n\n/**\n * Phase 3 review M3: exhaustiveness pin between the `ChainEntryV3`\n * union and the runtime tag allowlist. Adding a new entry variant\n * to `EventTypeV3` without updating the Set below now FAILS\n * COMPILATION on this `Record<EventTypeV3, true>` literal — the\n * compiler reports the missing key. Older versions of this code\n * relied on a runtime `.size === 5` test that would silently lag\n * behind a new variant addition.\n */\nconst _CONCRETE_TAG_EXHAUSTIVE_PIN: Record<EventTypeV3, true> = {\n sar_intent: true,\n sar_acknowledged: true,\n sar_fulfilled: true,\n sar_rejected: true,\n sar_extended: true,\n};\n\n/**\n * Phase 3 review M2: a transitively-loaded module cannot corrupt\n * the security boundary by calling `.add(\"evil_tag\")` etc. Note:\n * `Object.freeze` alone is INSUFFICIENT here — `Set.prototype.add`\n * is a prototype method that mutates internal slots, not a property\n * assignment the freeze can block. So the mutating methods are\n * explicitly overridden on the instance to throw, AND the instance\n * is frozen so the overrides themselves can't be deleted.\n *\n * `ReadonlySet` at the type level just suppresses TS access to the\n * mutating method names; runtime callers casting to `Set` would\n * otherwise bypass it. This wrapper makes the runtime match the\n * type-level contract.\n */\nfunction _buildImmutableTagSet(tags: EventTypeV3[]): ReadonlySet<EventTypeV3> {\n const s = new Set<EventTypeV3>(tags);\n const throwMutation = (op: string): never => {\n throw new TypeError(\n `CONCRETE_SAR_ENTRY_TYPE_TAGS is immutable — refusing ${op}()`,\n );\n };\n Object.defineProperty(s, \"add\", {\n value: () => throwMutation(\"add\"),\n writable: false,\n configurable: false,\n });\n Object.defineProperty(s, \"delete\", {\n value: () => throwMutation(\"delete\"),\n writable: false,\n configurable: false,\n });\n Object.defineProperty(s, \"clear\", {\n value: () => throwMutation(\"clear\"),\n writable: false,\n configurable: false,\n });\n return Object.freeze(s);\n}\n\nexport const CONCRETE_SAR_ENTRY_TYPE_TAGS: ReadonlySet<EventTypeV3> =\n _buildImmutableTagSet(\n Object.keys(_CONCRETE_TAG_EXHAUSTIVE_PIN) as EventTypeV3[],\n );\n\n/**\n * Runtime check that an unknown value carries a valid v3 SAR chain\n * entry TAG. Verifies the `entryType` discriminant is in the\n * concrete-tag allowlist; does NOT shape-check body fields — that\n * happens in `validateV3Entry` (see `_03`).\n *\n * Phase 3 review M4: renamed from the previous `isChainEntryV3` to\n * accurately reflect what it does. Code paths that need full shape\n * validation should call `validateV3Entry` from `canonicalV3.ts`.\n */\nexport function hasValidChainEntryTag(value: unknown): value is ChainEntryV3 {\n if (typeof value !== \"object\" || value === null) {\n return false;\n }\n const tag = (value as { entryType?: unknown }).entryType;\n return (\n typeof tag === \"string\" &&\n CONCRETE_SAR_ENTRY_TYPE_TAGS.has(tag as EventTypeV3)\n );\n}\n\n/**\n * @deprecated Renamed to `hasValidChainEntryTag` (Phase 3 review M4)\n * to accurately describe the tag-only check. Will be removed in a\n * future minor version; switch call sites to the new name.\n */\nexport const isChainEntryV3 = hasValidChainEntryTag;\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Capture-entry V3 encoder — TS port of the producer\n * (`internal/captureentry/canonical_v3.go`) and Go SDK\n * (`sdk/verification-go/capture_entry_v3.go`).\n *\n * Produces byte-identical canonical bytes for the `capture.request.v3` leaf so\n * cross-language verification works. The load-bearing test\n * (`test/goldenCaptureV3.test.ts`) drives this against the shared producer\n * golden vectors (`internal/captureentry/testdata/v3_golden_capture_request.json`).\n *\n * Reuses the shared `V3Encoder` + the load-bearing string-field / signing-key\n * validators from `canonicalV3.ts` (same primitives the SAR encoders use);\n * re-states only the capture-specific vocabularies/charsets — mirroring the Go\n * SDK's `capture_entry_v3.go`.\n *\n * # Two orthogonal mode fields\n *\n * `encryptionMode` {zero-knowledge|aleutian-managed|cmek} is KEY CUSTODY;\n * `processingMode` {zk|pii_inspection} is INSPECTION AUTHORIZATION. They are\n * independent. `processingMode === \"zk\"` requires an empty compliance surface\n * (`piiDetected` false, `piiAction` \"none\", `piiCategories`/`dlp` empty) —\n * enforced so a verifier rejects a self-contradictory zk leaf.\n */\n\nimport {\n DOMAIN_PREFIX_V3_BYTES,\n ErrInvalidEntryV3,\n V3Encoder,\n validateV3SigningKeyId,\n validateV3StringField,\n} from \"./canonicalV3.js\";\n\n// =============================================================================\n// Constants + capture-specific vocabularies — MUST match Go/Python byte-for-byte.\n// =============================================================================\n\n/**\n * The capture entry_type tag. Shares DOMAIN_PREFIX_V3 with the SAR entries;\n * domain separation is via this length-prefixed value at the fixed header offset.\n *\n * # WARNING — load-bearing constant\n * Changing this string re-domains every capture leaf and breaks signature\n * verification for all history.\n */\nexport const EVENT_TYPE_CAPTURE_REQUEST_V3 = \"capture.request.v3\";\n\n/** ~year 2200 far-future sanity ceiling for the server-stamped anchor clock. */\nconst MAX_PLAUSIBLE_TIMESTAMP_MS = 7258118400000;\n\nconst ENCRYPTION_MODE_ALLOWED: ReadonlySet<string> = new Set([\n \"zero-knowledge\",\n \"aleutian-managed\",\n \"cmek\",\n]);\nconst PROCESSING_MODE_ALLOWED: ReadonlySet<string> = new Set([\"zk\", \"pii_inspection\"]);\nconst PII_ACTION_ALLOWED: ReadonlySet<string> = new Set([\n \"none\",\n \"flagged\",\n \"blocked\",\n \"redacted\",\n]);\n\n// `^...$` (strict end-of-string in JS default mode) per the canonicalV3\n// cross-language regex discipline. Re-stated locally (the originals are\n// module-private to canonicalV3.ts); these are trivial enough that sharing\n// would add export surface for no safety gain — unlike the string-field\n// validator, which IS shared.\nconst RE_COMPANY_ID = /^comp_[0-9A-HJKMNP-TV-Z]{26}$/;\nconst RE_SHA512_HEX = /^[0-9a-f]{128}$/;\n// Hyphen REQUIRED: real TrustLevel includes \"self-reported\".\nconst RE_PROVENANCE = /^[a-z0-9_-]{0,32}$/;\nconst RE_PROVIDER = /^[a-z0-9_.-]{0,64}$/;\nconst RE_MODEL = /^[A-Za-z0-9_./-]{0,128}$/;\nconst RE_REGION = /^[a-z0-9-]{0,16}$/;\n// pii_digest_key_version (pii_hmac_key_rotation_R3): source-namespaced ids like \"sm:v1\".\n//\n// Exported for intra-package reuse by the SAR leaf family (canonicalV3.ts,\n// pii_hmac_key_rotation_R4). One regex for both leaf families — same\n// source-namespaced contract, same BQ column shape — mirroring the Go SDK's\n// single `v3PIIDigestKeyVersionReSDK` symbol shared across capture + SAR. NOT\n// re-exported from index.ts, so it stays internal to the package.\nexport const RE_PII_DIGEST_KEY_VERSION = /^[a-z0-9:_.-]{0,64}$/;\n\n// =============================================================================\n// Typed entry\n// =============================================================================\n\n/**\n * A capture-chain AI-request leaf. camelCase fields per JS convention; the\n * cross-language fixture `input` is snake_case (the golden test maps them).\n * entry_type is a constant, not a field.\n *\n * All hash/digest fields (`contentHash`, `userId`, `piiCategories`, `dlp`) are\n * 128 lowercase hex (SHA-512 / HMAC-SHA512), or empty for the optional digests.\n * The verifier checks SHAPE only; per-tenant HMAC keying is producer-side.\n */\nexport interface CaptureRequestEntryV3 {\n readonly companyId: string;\n readonly signingKeyId: string;\n /** Server-stamped ingested_at (UnixMilli). Always < 2^53 for real anchors. */\n readonly timestampMs: number;\n readonly captureMethod: string;\n readonly contentHash: string;\n readonly dlp: string;\n readonly encryptionMode: string;\n readonly model: string;\n readonly piiAction: string;\n readonly piiCategories: string;\n readonly piiDetected: boolean;\n readonly piiDigestKeyVersion: string;\n readonly processingMode: string;\n readonly provider: string;\n readonly region: string;\n readonly sourceType: string;\n readonly trustLevel: string;\n readonly userId: string;\n}\n\n// =============================================================================\n// Validation (mirror of the producer + Go/Python SDK)\n// =============================================================================\n\nfunction validateOptionalHexDigest(name: string, value: string): void {\n if (value === \"\") {\n return;\n }\n if (!RE_SHA512_HEX.test(value)) {\n throw new ErrInvalidEntryV3(\n `${name} must be empty or exactly 128 lowercase hex chars (HMAC-SHA512 digest)`,\n );\n }\n}\n\n/**\n * Validate a capture leaf against the cross-language invariants. Throws\n * `ErrInvalidEntryV3` on the first failure. Exported so customers can validate\n * without encoding.\n */\nexport function validateCaptureEntryV3(e: CaptureRequestEntryV3): void {\n // --- Header ---\n if (e.companyId === \"\") {\n throw new ErrInvalidEntryV3(\"company_id empty\");\n }\n if (!RE_COMPANY_ID.test(e.companyId)) {\n throw new ErrInvalidEntryV3(\n \"company_id must match comp_<26-char Crockford-base32 ULID>\",\n );\n }\n validateV3StringField(\"company_id\", e.companyId);\n validateV3SigningKeyId(e.signingKeyId);\n if (!Number.isInteger(e.timestampMs) || e.timestampMs <= 0) {\n throw new ErrInvalidEntryV3(\"timestamp_ms must be a positive integer\");\n }\n if (e.timestampMs > MAX_PLAUSIBLE_TIMESTAMP_MS) {\n throw new ErrInvalidEntryV3(\n \"timestamp_ms exceeds the year-2200 sanity ceiling\",\n );\n }\n\n // --- Body: required hex fields ---\n if (!RE_SHA512_HEX.test(e.contentHash)) {\n throw new ErrInvalidEntryV3(\n \"content_hash must be exactly 128 lowercase hex chars (SHA-512)\",\n );\n }\n if (!RE_SHA512_HEX.test(e.userId)) {\n throw new ErrInvalidEntryV3(\n \"user_id must be exactly 128 lowercase hex chars (HMAC-SHA512 pseudonym)\",\n );\n }\n\n // --- Body: optional hex digests ---\n validateOptionalHexDigest(\"dlp\", e.dlp);\n validateOptionalHexDigest(\"pii_categories\", e.piiCategories);\n\n // pii_digest_key_version (pii_hmac_key_rotation_R3): present iff a digest is present.\n if (!RE_PII_DIGEST_KEY_VERSION.test(e.piiDigestKeyVersion)) {\n throw new ErrInvalidEntryV3(\n \"pii_digest_key_version must match ^[a-z0-9:_.-]{0,64}$\",\n );\n }\n {\n const hasDigest = e.piiCategories !== \"\" || e.dlp !== \"\";\n if (hasDigest && e.piiDigestKeyVersion === \"\") {\n throw new ErrInvalidEntryV3(\n \"pii_digest_key_version required when pii_categories or dlp is present\",\n );\n }\n if (!hasDigest && e.piiDigestKeyVersion !== \"\") {\n throw new ErrInvalidEntryV3(\n \"pii_digest_key_version must be empty when no pii/dlp digest is present\",\n );\n }\n }\n\n // --- Body: closed-vocabulary enums ---\n if (!ENCRYPTION_MODE_ALLOWED.has(e.encryptionMode)) {\n throw new ErrInvalidEntryV3(\n \"encryption_mode must be one of {zero-knowledge, aleutian-managed, cmek}\",\n );\n }\n if (!PROCESSING_MODE_ALLOWED.has(e.processingMode)) {\n throw new ErrInvalidEntryV3(\n \"processing_mode must be one of {zk, pii_inspection}\",\n );\n }\n if (!PII_ACTION_ALLOWED.has(e.piiAction)) {\n throw new ErrInvalidEntryV3(\n \"pii_action must be one of {none, flagged, blocked, redacted}\",\n );\n }\n\n // zk cross-field invariant: processingMode === \"zk\" ⇒ empty compliance surface.\n if (e.processingMode === \"zk\") {\n if (e.piiDetected) {\n throw new ErrInvalidEntryV3(\n \"processing_mode=zk forbids pii_detected=true (inspection not authorized)\",\n );\n }\n if (e.piiAction !== \"none\") {\n throw new ErrInvalidEntryV3(\"processing_mode=zk requires pii_action=none\");\n }\n if (e.piiCategories !== \"\") {\n throw new ErrInvalidEntryV3(\"processing_mode=zk requires empty pii_categories\");\n }\n if (e.dlp !== \"\") {\n throw new ErrInvalidEntryV3(\"processing_mode=zk requires empty dlp\");\n }\n }\n\n // --- Body: charset-pinned open-vocabulary fields (empty permitted) ---\n if (!RE_PROVIDER.test(e.provider)) {\n throw new ErrInvalidEntryV3(\"provider must match ^[a-z0-9_.-]{0,64}$\");\n }\n if (!RE_MODEL.test(e.model)) {\n throw new ErrInvalidEntryV3(\"model must match ^[A-Za-z0-9_./-]{0,128}$\");\n }\n if (!RE_REGION.test(e.region)) {\n throw new ErrInvalidEntryV3(\"region must match ^[a-z0-9-]{0,16}$\");\n }\n if (!RE_PROVENANCE.test(e.captureMethod)) {\n throw new ErrInvalidEntryV3(\"capture_method must match ^[a-z0-9_-]{0,32}$\");\n }\n if (!RE_PROVENANCE.test(e.sourceType)) {\n throw new ErrInvalidEntryV3(\"source_type must match ^[a-z0-9_-]{0,32}$\");\n }\n if (!RE_PROVENANCE.test(e.trustLevel)) {\n throw new ErrInvalidEntryV3(\"trust_level must match ^[a-z0-9_-]{0,32}$\");\n }\n\n // Defense-in-depth surrogate / NFC-cap / control-byte guard on every string\n // body field (the shared, load-bearing validator).\n validateV3StringField(\"capture_method\", e.captureMethod);\n validateV3StringField(\"content_hash\", e.contentHash);\n validateV3StringField(\"dlp\", e.dlp);\n validateV3StringField(\"encryption_mode\", e.encryptionMode);\n validateV3StringField(\"model\", e.model);\n validateV3StringField(\"pii_action\", e.piiAction);\n validateV3StringField(\"pii_categories\", e.piiCategories);\n validateV3StringField(\"processing_mode\", e.processingMode);\n validateV3StringField(\"provider\", e.provider);\n validateV3StringField(\"region\", e.region);\n validateV3StringField(\"source_type\", e.sourceType);\n validateV3StringField(\"trust_level\", e.trustLevel);\n validateV3StringField(\"user_id\", e.userId);\n}\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/**\n * Validate + encode a capture leaf to canonical TLV bytes (4-field header +\n * 14-field alphabetical body). Byte-identical to the Go producer/SDK + Python.\n *\n * @throws {ErrInvalidEntryV3} On validation/encoder-invariant failure.\n */\nexport function chainCanonicalV3Capture(entry: CaptureRequestEntryV3): Uint8Array {\n validateCaptureEntryV3(entry);\n\n // The shared encoder's appendStr re-normalizes NFC by default; validate has\n // already enforced NFC form, but capture passes the safe default (no\n // assumeNormalized) since the byte result is identical (NFC idempotent).\n const enc = new V3Encoder();\n enc.appendV3Header(\n entry.companyId,\n EVENT_TYPE_CAPTURE_REQUEST_V3,\n entry.signingKeyId,\n entry.timestampMs,\n );\n enc.appendStr(entry.captureMethod); // 1\n enc.appendStr(entry.contentHash); // 2\n enc.appendStr(entry.dlp); // 3\n enc.appendStr(entry.encryptionMode); // 4\n enc.appendStr(entry.model); // 5\n enc.appendStr(entry.piiAction); // 6\n enc.appendStr(entry.piiCategories); // 7\n enc.appendU64(entry.piiDetected ? 1 : 0); // 8 (bool → u64 0/1)\n enc.appendStr(entry.piiDigestKeyVersion); // 9 (pii_hmac_key_rotation_R3)\n enc.appendStr(entry.processingMode); // 10\n enc.appendStr(entry.provider); // 11\n enc.appendStr(entry.region); // 12\n enc.appendStr(entry.sourceType); // 13\n enc.appendStr(entry.trustLevel); // 14\n enc.appendStr(entry.userId); // 15\n return enc.bytes();\n}\n\n/**\n * Compute the capture leaf's content hash: SHA-512(DOMAIN_PREFIX_V3 || canonical),\n * returned as the raw 64-byte digest. Hex-encode with `bytesToHex` (canonicalV3.ts).\n */\nexport async function computeCaptureContentHash(\n entry: CaptureRequestEntryV3,\n): Promise<Uint8Array> {\n const canonical = chainCanonicalV3Capture(entry);\n const preimage = new Uint8Array(DOMAIN_PREFIX_V3_BYTES.length + canonical.length);\n preimage.set(DOMAIN_PREFIX_V3_BYTES, 0);\n preimage.set(canonical, DOMAIN_PREFIX_V3_BYTES.length);\n const digest = await crypto.subtle.digest(\"SHA-512\", preimage);\n return new Uint8Array(digest);\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Canonical V3 encoder — TS port of `sdk/verification-go/canonical_v3.go`.\n *\n * Produces byte-identical canonical bytes for the 5 SAR entry types so\n * cross-language signature verification works. The load-bearing test\n * (`canonicalV3.goldenVectors.test.ts` in _05) drives this against the\n * Go-baked golden fixtures.\n *\n * # Encoding (per pqc_05c v3 §3 + §4 + §7)\n *\n * - 4-field common header, alphabetical: company_id, entry_type,\n * signing_key_id, timestamp_ms (NO schema_version per OQ-13)\n * - Per-event-type body, alphabetical within the body\n * - Strings: NFC-normalize via `.normalize(\"NFC\")`, then u32 BE\n * length prefix, then UTF-8 bytes (post-NFC byte length per §7)\n * - int64 / uint64: u64 BE encoding; v3 fields are non-negative\n * - String length cap: 256 bytes post-NFC per spec §7\n *\n * # BigInt vs Number\n *\n * `appendU64` accepts `bigint | number` and routes through\n * `DataView.setBigUint64` to dodge JS `Number` precision loss above\n * 2^53. Current v3 fields (`timestampMs`, `tombstoneCount`,\n * `extendedDueAtMs`) are all comfortably under 2^53 for realistic\n * inputs, but we route via BigInt for safety + future-proofing.\n *\n * # Privacy Invariant 4 (no caller-input echo)\n *\n * Per `sdk_privacy_invariants_spec`, error messages NEVER echo the\n * caller-supplied value — operators have it in their producer-side\n * logs. Mirrors Go SDK posture (chain_d_go_review_followup 2026-05-28).\n *\n * # Does NOT validate\n *\n * Encoder assumes pre-validated inputs. Validators ship in `_03`.\n * The encoder still enforces the 256-byte post-NFC cap and rejects\n * negative integers because those are encoder-internal invariants\n * (silently truncating or wrapping would produce wrong bytes).\n */\n\nimport { RE_PII_DIGEST_KEY_VERSION } from \"./captureEntryV3.js\";\nimport {\n CONCRETE_SAR_ENTRY_TYPE_TAGS,\n type ChainEntryV3,\n type EventTypeV3,\n type SARAcknowledgedEntryV3,\n type SARExtendedEntryV3,\n type SARFulfilledEntryV3,\n type SARFulfillmentKindV3,\n type SARIntentEntryV3,\n type SARRejectedEntryV3,\n type SARSourceChannelV3,\n type SARTypeV3,\n type TenantHMACDigestV3,\n tenantHMACDigestIsZero,\n} from \"./sarEntries.js\";\n\n// =============================================================================\n// Constants\n// =============================================================================\n\n/**\n * Locked V3 domain prefix used for content-hash and signature\n * derivation. See Go SDK `DomainPrefixV3` for the producer-side\n * counterpart.\n *\n * # WARNING — load-bearing constant\n *\n * Changing this byte sequence invalidates every signed v3 chain\n * entry across all language ports.\n */\nexport const DOMAIN_PREFIX_V3 = \"aleutian.chain.entry.v3:\";\n\n/** Pre-computed `Uint8Array` form to avoid per-hash allocation. */\nexport const DOMAIN_PREFIX_V3_BYTES: Uint8Array = new TextEncoder().encode(\n DOMAIN_PREFIX_V3,\n);\n\n/**\n * v3 spec §7 byte cap on string fields post-NFC. Cross-language\n * locked value; matches Go's `maxV3StringFieldBytesSDK` and Python's\n * `_MAX_V3_STRING_FIELD_BYTES`.\n */\nexport const MAX_V3_STRING_FIELD_BYTES = 256;\n\n/** SHA-512 hex digest length (cross-language constant). */\nexport const V3_SHA512_HEX_LEN = 128;\n\n/**\n * Maximum canonical-byte sum per entry (cross-language locked\n * value; matches Go's `MaxCanonicalBytesV3` and Python's\n * `MAX_CANONICAL_BYTES_V3`). The widest current v3 SAR entry fits\n * comfortably under 1 KiB; 4× headroom absorbs future field\n * additions without forcing a SemVer-breaking bound bump.\n *\n * # Cross-language consistency is load-bearing\n *\n * A divergent value in any one SDK becomes a per-tenant DoS vector\n * against customers using the laxer SDK — they'd do unbounded work\n * on adversarial inputs. Pinned in\n * `verifyV3.test.ts::MAX_CANONICAL_BYTES_V3_LockedAtCrossLanguageValue`.\n */\nexport const MAX_CANONICAL_BYTES_V3 = 4096;\n\n/**\n * 14-month sanity bound for `extendedDueAtMs` past `timestampMs`.\n * Mirror of Go's `420 * 24 * 60 * 60 * 1000` literal.\n */\nexport const EXTENDED_SANITY_BOUND_MS = 420 * 24 * 60 * 60 * 1000;\n\n// =============================================================================\n// Validation regexes (precompiled at module load, mirror of Go SDK patterns)\n// =============================================================================\n\n/**\n * Cross-SDK regex parity note: JS regex literal uses `^...$` because\n * the JS regex engine treats `$` as strict end-of-string in default\n * mode (no `m` flag). This matches Go's default behavior. Python\n * uses `\\A...\\Z` to force strict end-of-string because Python's `$`\n * accepts trailing `\\n` (the chain_d H8 finding). All three SDKs\n * reject the same input set.\n */\nconst RE_COMPANY_ID = /^comp_[0-9A-HJKMNP-TV-Z]{26}$/;\nconst RE_REQUEST_ID = /^[0-9A-HJKMNP-TV-Z]{26}$/;\nconst RE_INTENT_ENTRY_ID =\n /^[0-9a-f]{8}-[0-9a-f]{4}-7[0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/;\nconst RE_LEGAL_BASIS = /^[a-z0-9_+]{1,64}$/;\nconst RE_SOURCE_CHANNEL = /^[a-z0-9_+]{1,64}$/;\nconst RE_SCOPE = /^(all|grant_[A-Za-z0-9_-]{1,64})$/;\nconst RE_SIGNING_KEY_ID = /^[A-Za-z0-9_./-]{1,128}$/;\nconst RE_SHA512_HEX = /^[0-9a-f]{128}$/;\nconst RE_CERTIFICATE_ID = /^cert_[0-9a-f]{32}$/;\n\nconst SAR_TYPE_ALLOWED: ReadonlySet<SARTypeV3> = new Set<SARTypeV3>([\n \"access\",\n \"erasure\",\n \"both\",\n]);\n\nconst SAR_FULFILLMENT_KIND_ALLOWED: ReadonlySet<SARFulfillmentKindV3> =\n new Set<SARFulfillmentKindV3>([\"access\", \"erasure\", \"both\"]);\n\n// =============================================================================\n// Error types\n// =============================================================================\n\n/**\n * Wrapped sentinel for encoder validation failures. Customer code\n * can `err instanceof ErrInvalidEntryV3` to distinguish encoder\n * rejections from signature/content-hash failures (which use\n * distinct sentinels; see verifyV3.ts).\n *\n * Per `sdk_error_hierarchy_spec`, this is the V3 entry-shape error.\n */\nexport class ErrInvalidEntryV3 extends Error {\n // Typed as `string` (not the literal `\"ErrInvalidEntryV3\"`) so\n // subclasses (`ErrUnknownSigningKeyV3`, etc. in verifyV3.ts) can\n // override the name without a TS2416 mismatch.\n override readonly name: string = \"ErrInvalidEntryV3\";\n constructor(message: string) {\n super(`CanonicalBytesV3: ${message}`);\n if ((Error as { captureStackTrace?: unknown }).captureStackTrace) {\n (\n Error as unknown as {\n captureStackTrace: (target: object, ctor: unknown) => void;\n }\n ).captureStackTrace(this, ErrInvalidEntryV3);\n }\n }\n}\n\n// =============================================================================\n// Validators (mirror of Go's `validateV3*` family)\n// =============================================================================\n\n/**\n * Strict UTF-8 string field validator. Checks NFC byte cap, rejects\n * disallowed control bytes (< 0x20 or 0x7F), AND rejects lone\n * surrogates (H10).\n *\n * Mirror of Go's `validateV3StringFieldSDK`. Privacy Inv 4: errors\n * do NOT echo the value or the post-NFC byte length.\n *\n * # H10 — lone-surrogate detection (Phase 3 review pre-emptive)\n *\n * JS strings are UTF-16; a \"string\" containing a lone high\n * (U+D800-U+DBFF) or low (U+DC00-U+DFFF) surrogate is technically\n * ill-formed UTF-16. `TextEncoder.encode` silently substitutes\n * U+FFFD for such code units, which would produce canonical bytes\n * different from what the caller's source actually contains —\n * breaking cross-language byte parity. We detect and reject these\n * explicitly rather than letting TextEncoder absorb them. Equivalent\n * to Go's `utf8.ValidString` gate on the source side.\n *\n * `String.prototype.isWellFormed` is ECMAScript 2024+ and not yet\n * universally available in browsers / older Node; the manual\n * surrogate scan below is the portable fallback.\n */\n// Exported for intra-package reuse by the capture-entry mirror\n// (captureEntryV3.ts). NOT re-exported from index.ts, so it stays internal to\n// the package — the capture mirror shares this load-bearing surrogate/NFC/\n// control-byte validator rather than duplicating it (drift hazard).\nexport function validateV3StringField(name: string, value: string): void {\n // H10: scan UTF-16 code units for lone surrogates BEFORE any other\n // processing. A well-formed pair is (high, low) adjacent; anything\n // else (high without low, low without preceding high, low first)\n // is ill-formed.\n for (let i = 0; i < value.length; i++) {\n const u = value.charCodeAt(i);\n if (u >= 0xd800 && u <= 0xdbff) {\n // High surrogate — must be followed by a low surrogate\n const next = i + 1 < value.length ? value.charCodeAt(i + 1) : 0;\n if (next < 0xdc00 || next > 0xdfff) {\n throw new ErrInvalidEntryV3(\n `${name} contains a lone surrogate (ill-formed UTF-16)`,\n );\n }\n i++; // skip the low surrogate we just validated\n } else if (u >= 0xdc00 && u <= 0xdfff) {\n // Low surrogate without preceding high\n throw new ErrInvalidEntryV3(\n `${name} contains a lone surrogate (ill-formed UTF-16)`,\n );\n }\n }\n const nfc = value.normalize(\"NFC\");\n // M6 (2026-05-29): require inputs to already be in NFC form so the\n // canonical-bytes pipeline can skip the redundant per-field\n // re-normalization in `V3Encoder.appendStr`. NFC is what every\n // mainstream OS / browser / editor produces by default, so this\n // tightens the contract without affecting realistic callers. Cross-\n // language note: Go's encoder normalizes opaquely; differing on this\n // gate is intentional — both pipelines emit byte-identical canonical\n // bytes for NFC inputs, which is the only contract that matters for\n // cross-language verification.\n if (value !== nfc) {\n throw new ErrInvalidEntryV3(\n `${name} is not in Unicode NFC form; normalize with .normalize(\"NFC\") before passing to the SDK`,\n );\n }\n const utf8Len = new TextEncoder().encode(nfc).length;\n if (utf8Len > MAX_V3_STRING_FIELD_BYTES) {\n throw new ErrInvalidEntryV3(\n `${name} exceeds ${MAX_V3_STRING_FIELD_BYTES} bytes after NFC`,\n );\n }\n // Disallowed control bytes: any byte < 0x20 (C0 controls + NUL) or\n // 0x7F (DEL). Iterate code points rather than UTF-16 units so a\n // surrogate pair (4 UTF-8 bytes for U+10000+) isn't misread.\n for (const ch of nfc) {\n const cp = ch.codePointAt(0)!;\n if (cp < 0x20 || cp === 0x7f) {\n throw new ErrInvalidEntryV3(\n `${name} contains a disallowed control byte`,\n );\n }\n }\n}\n\n// Exported for intra-package reuse by captureEntryV3.ts (see note on\n// validateV3StringField). Not part of the public API (index.ts is selective).\nexport function validateV3SigningKeyId(s: string): void {\n if (s === \"\") {\n throw new ErrInvalidEntryV3(\"signing_key_id empty\");\n }\n if (!RE_SIGNING_KEY_ID.test(s)) {\n throw new ErrInvalidEntryV3(\n \"signing_key_id must match ^[A-Za-z0-9_./-]{1,128}$\",\n );\n }\n validateV3StringField(\"signing_key_id\", s);\n}\n\nfunction validateV3CommonHeader(\n companyId: string,\n signingKeyId: string,\n timestampMs: bigint | number,\n entryType: EventTypeV3,\n expected: EventTypeV3,\n): void {\n if (companyId === \"\") {\n throw new ErrInvalidEntryV3(\"company_id empty\");\n }\n if (!RE_COMPANY_ID.test(companyId)) {\n throw new ErrInvalidEntryV3(\n \"company_id must match comp_<26-char Crockford-base32 ULID>\",\n );\n }\n validateV3StringField(\"company_id\", companyId);\n if (entryType !== expected) {\n // Privacy Inv 4: do NOT echo the caller-supplied entry_type value.\n throw new ErrInvalidEntryV3(\n \"entry_type does not match expected for this variant\",\n );\n }\n validateV3SigningKeyId(signingKeyId);\n const ts =\n typeof timestampMs === \"bigint\" ? timestampMs : BigInt(timestampMs);\n if (ts <= 0n) {\n // Privacy Inv 4: do NOT echo the value.\n throw new ErrInvalidEntryV3(\"timestamp_ms must be positive\");\n }\n}\n\nfunction validateV3RequestId(s: string): void {\n if (!RE_REQUEST_ID.test(s)) {\n throw new ErrInvalidEntryV3(\n \"request_id must match ULID regex (Crockford-base32, 26 chars)\",\n );\n }\n}\n\nfunction validateV3IntentEntryId(s: string): void {\n if (!RE_INTENT_ENTRY_ID.test(s)) {\n throw new ErrInvalidEntryV3(\"intent_entry_id must match UUIDv7 regex\");\n }\n}\n\nfunction validateV3LegalBasis(s: string): void {\n if (s === \"\") {\n throw new ErrInvalidEntryV3(\"legal_basis empty\");\n }\n if (!RE_LEGAL_BASIS.test(s)) {\n throw new ErrInvalidEntryV3(\n \"legal_basis must match ^[a-z0-9_+]{1,64}$ (spec §6.0 charset)\",\n );\n }\n}\n\nfunction validateV3ManifestRoot(s: string): void {\n if (!RE_SHA512_HEX.test(s)) {\n throw new ErrInvalidEntryV3(\n `manifest_root must be exactly ${V3_SHA512_HEX_LEN} lowercase hex chars (SHA-512)`,\n );\n }\n}\n\nfunction validateV3OptionalDigest(\n name: string,\n d: TenantHMACDigestV3,\n): void {\n if (tenantHMACDigestIsZero(d)) {\n return;\n }\n if (!RE_SHA512_HEX.test(d.hex)) {\n throw new ErrInvalidEntryV3(\n `${name} digest violates shape invariant (constructor regression?)`,\n );\n }\n}\n\nfunction validateV3RequiredDigest(\n name: string,\n d: TenantHMACDigestV3,\n): void {\n if (tenantHMACDigestIsZero(d)) {\n // Phase 3 review HIGH: prior wording said \"rejection without\n // rationale is invalid\" — misleading on the sar_extended path\n // where the same helper is used for `reason_hash` (extension\n // without reason). Generic wording covers both call sites.\n throw new ErrInvalidEntryV3(`${name} required (must be non-zero)`);\n }\n validateV3OptionalDigest(name, d);\n}\n\n/**\n * Validates `pii_digest_key_version` on a SAR entry\n * (pii_hmac_key_rotation_R4). RELAXED invariant — mirror of Go's\n * `validateV3PIIDigestKeyVersionSDK`: charset (empty allowed) + strict\n * UTF-8 string-field checks + the ONLY hard rule\n * `version !== \"\" ⇒ digestPresent`.\n *\n * A non-empty digest with an EMPTY version is a LEGAL pre-rotation legacy\n * leaf, NOT an error — do not reject it (that would break verification of\n * every historical SAR row). This is the deliberate asymmetry vs the\n * STRICT capture-leaf (R3) contract, which rejects both directions of\n * mismatch.\n *\n * Privacy Inv 4: the error does NOT echo the offending version value.\n *\n * @param version - The `piiDigestKeyVersion` field value (\"\" allowed).\n * @param digestPresent - Whether the entry's PII digest is non-zero\n * (`reason_hash` for intent/extended; `rationale_hash` for rejected).\n */\nfunction validateV3PIIDigestKeyVersion(\n version: string,\n digestPresent: boolean,\n): void {\n if (!RE_PII_DIGEST_KEY_VERSION.test(version)) {\n // Privacy Inv 4: do NOT echo the offending value.\n throw new ErrInvalidEntryV3(\n \"pii_digest_key_version must match ^[a-z0-9:_.-]{0,64}$\",\n );\n }\n validateV3StringField(\"pii_digest_key_version\", version);\n if (version !== \"\" && !digestPresent) {\n throw new ErrInvalidEntryV3(\n \"pii_digest_key_version present but no PII digest to apply it to\",\n );\n }\n}\n\n/**\n * Per-kind `certificate_id` matrix (chain_writer_certificate_id mirror):\n * - access → certificate_id MUST be empty\n * - erasure → certificate_id MUST match cert_<32-hex>\n * - both → certificate_id MUST match cert_<32-hex>\n *\n * Mirror of Go's `validateV3SARFulfilledCertificateIDSDK`.\n */\nfunction validateV3SARFulfilledCertificateId(\n kind: SARFulfillmentKindV3,\n certId: string,\n): void {\n switch (kind) {\n case \"access\":\n if (certId !== \"\") {\n throw new ErrInvalidEntryV3(\n \"certificate_id must be empty when fulfillment_kind=access\",\n );\n }\n return;\n case \"erasure\":\n case \"both\":\n if (certId === \"\") {\n throw new ErrInvalidEntryV3(\n `certificate_id is required when fulfillment_kind=${kind}`,\n );\n }\n if (!RE_CERTIFICATE_ID.test(certId)) {\n throw new ErrInvalidEntryV3(\"certificate_id must match cert_<32-hex>\");\n }\n return;\n default: {\n // Defense-in-depth: a future SARFulfillmentKindV3 addition\n // without updating this switch would silently accept any\n // cert_id. The vocabulary check upstream catches this today\n // but pinning here too.\n const _exhaustive: never = kind;\n throw new ErrInvalidEntryV3(\n `unknown fulfillment_kind in certificate_id validator: ${String(_exhaustive)}`,\n );\n }\n }\n}\n\n// =============================================================================\n// Per-entry validators\n// =============================================================================\n\nfunction validateSarIntent(e: SARIntentEntryV3): void {\n validateV3CommonHeader(\n e.companyId,\n e.signingKeyId,\n e.timestampMs,\n e.entryType,\n \"sar_intent\",\n );\n validateV3OptionalDigest(\"reason_hash\", e.reasonHash);\n // R4: relaxed pii_digest_key_version contract — digest is reason_hash.\n validateV3PIIDigestKeyVersion(\n e.piiDigestKeyVersion,\n !tenantHMACDigestIsZero(e.reasonHash),\n );\n validateV3RequestId(e.requestId);\n if (!SAR_TYPE_ALLOWED.has(e.sarType)) {\n throw new ErrInvalidEntryV3(\"sar_type must be access|erasure|both\");\n }\n if (!RE_SCOPE.test(e.scope)) {\n // Privacy Inv 4: do NOT echo the offending caller value.\n throw new ErrInvalidEntryV3(\n \"scope must match ^(all|grant_[A-Za-z0-9_-]{1,64})$\",\n );\n }\n // Phase 3 review LOW: dropped gratuitous `as string` cast — the\n // SARSourceChannelV3 union is already string-typed so direct\n // equality + RE_SOURCE_CHANNEL.test() are fine without bypass.\n if (e.sourceChannel === (\"\" as SARSourceChannelV3)) {\n throw new ErrInvalidEntryV3(\"source_channel empty\");\n }\n if (!RE_SOURCE_CHANNEL.test(e.sourceChannel)) {\n throw new ErrInvalidEntryV3(\n \"source_channel must match ^[a-z0-9_+]{1,64}$ (spec §6.0 charset)\",\n );\n }\n}\n\nfunction validateSarAcknowledged(e: SARAcknowledgedEntryV3): void {\n validateV3CommonHeader(\n e.companyId,\n e.signingKeyId,\n e.timestampMs,\n e.entryType,\n \"sar_acknowledged\",\n );\n validateV3IntentEntryId(e.intentEntryId);\n validateV3RequestId(e.requestId);\n}\n\nfunction validateSarFulfilled(e: SARFulfilledEntryV3): void {\n validateV3CommonHeader(\n e.companyId,\n e.signingKeyId,\n e.timestampMs,\n e.entryType,\n \"sar_fulfilled\",\n );\n if (!SAR_FULFILLMENT_KIND_ALLOWED.has(e.fulfillmentKind)) {\n throw new ErrInvalidEntryV3(\n \"fulfillment_kind must be access|erasure|both\",\n );\n }\n validateV3SARFulfilledCertificateId(e.fulfillmentKind, e.certificateId);\n validateV3IntentEntryId(e.intentEntryId);\n validateV3LegalBasis(e.legalBasis);\n validateV3ManifestRoot(e.manifestRoot);\n validateV3RequestId(e.requestId);\n if (e.tombstoneCount < 0) {\n throw new ErrInvalidEntryV3(\"tombstone_count must be >= 0\");\n }\n}\n\nfunction validateSarRejected(e: SARRejectedEntryV3): void {\n validateV3CommonHeader(\n e.companyId,\n e.signingKeyId,\n e.timestampMs,\n e.entryType,\n \"sar_rejected\",\n );\n validateV3IntentEntryId(e.intentEntryId);\n validateV3LegalBasis(e.legalBasis);\n validateV3RequiredDigest(\"rationale_hash\", e.rationaleHash);\n // R4: relaxed pii_digest_key_version contract — digest is rationale_hash.\n validateV3PIIDigestKeyVersion(\n e.piiDigestKeyVersion,\n !tenantHMACDigestIsZero(e.rationaleHash),\n );\n validateV3RequestId(e.requestId);\n}\n\nfunction validateSarExtended(e: SARExtendedEntryV3): void {\n validateV3CommonHeader(\n e.companyId,\n e.signingKeyId,\n e.timestampMs,\n e.entryType,\n \"sar_extended\",\n );\n validateV3IntentEntryId(e.intentEntryId);\n validateV3RequestId(e.requestId);\n // Phase 3 review H1 follow-up: timestampMs and extendedDueAtMs\n // are `bigint | number`. Mixed-type arithmetic throws TypeError\n // in JS, so normalize both to bigint for the sanity-bound check.\n // Relational mixed comparison (`<= 0`) is permitted by JS for\n // both number AND bigint with a plain `0`, so that check is fine\n // as-is.\n if (e.extendedDueAtMs <= 0) {\n throw new ErrInvalidEntryV3(\"extended_due_at_ms must be > 0\");\n }\n const dueAt =\n typeof e.extendedDueAtMs === \"bigint\"\n ? e.extendedDueAtMs\n : BigInt(e.extendedDueAtMs);\n const ts =\n typeof e.timestampMs === \"bigint\" ? e.timestampMs : BigInt(e.timestampMs);\n if (dueAt > ts + BigInt(EXTENDED_SANITY_BOUND_MS)) {\n throw new ErrInvalidEntryV3(\n \"extended_due_at_ms exceeds 14-month sanity bound from timestamp\",\n );\n }\n validateV3RequiredDigest(\"reason_hash\", e.reasonHash);\n // R4: relaxed pii_digest_key_version contract — digest is reason_hash.\n validateV3PIIDigestKeyVersion(\n e.piiDigestKeyVersion,\n !tenantHMACDigestIsZero(e.reasonHash),\n );\n}\n\n/**\n * Validates a V3 chain entry by dispatching to the per-type\n * validator. Throws `ErrInvalidEntryV3` on any failure. Called\n * automatically by `chainCanonicalV3` before encoding.\n *\n * Exported so customers can validate without encoding.\n */\nexport function validateV3Entry(entry: ChainEntryV3): void {\n if (entry == null) {\n throw new ErrInvalidEntryV3(\"entry is null/undefined\");\n }\n if (!CONCRETE_SAR_ENTRY_TYPE_TAGS.has(entry.entryType)) {\n throw new ErrInvalidEntryV3(\n \"unrecognised entry_type; only the 5 concrete SAR entry types are accepted\",\n );\n }\n switch (entry.entryType) {\n case \"sar_intent\":\n validateSarIntent(entry);\n return;\n case \"sar_acknowledged\":\n validateSarAcknowledged(entry);\n return;\n case \"sar_fulfilled\":\n validateSarFulfilled(entry);\n return;\n case \"sar_rejected\":\n validateSarRejected(entry);\n return;\n case \"sar_extended\":\n validateSarExtended(entry);\n return;\n default: {\n const _exhaustive: never = entry;\n throw new ErrInvalidEntryV3(\n `dispatch: unhandled entry variant ${String((_exhaustive as { entryType?: string }).entryType ?? \"unknown\")}`,\n );\n }\n }\n}\n\n// =============================================================================\n// Encoder helper\n// =============================================================================\n\n/**\n * `V3Encoder` bundles a growing `Uint8Array` buffer. Per-event-type\n * body encoders append fields without explicit error plumbing — the\n * encoder throws synchronously on invariant violations (256-byte\n * cap, negative u64).\n *\n * Mirror of Go's `v3EncoderSDK`.\n *\n * Exported for the explicit purpose of unit-testing the encoder\n * mechanics (NFC normalization, BE encoding, length cap) without\n * routing through the full `chainCanonicalV3` pipeline (which\n * validates regex/vocabulary constraints first). Customers writing\n * normal verification code should call `chainCanonicalV3`.\n */\nexport class V3Encoder {\n private buf: Uint8Array;\n private pos: number;\n // Phase 3 review LOW: cache the DataView so we don't allocate one\n // per appendStr/appendU64 call. The view is invalidated + rebuilt\n // inside `grow()` whenever the underlying buffer is reallocated.\n private view: DataView;\n // Phase 3 review LOW: reuse a single TextEncoder to avoid the\n // per-call allocation in `appendStr`.\n private readonly textEncoder = new TextEncoder();\n // M6 (post-review follow-up 2026-05-29): when true, `appendStr`\n // SKIPS the `s.normalize(\"NFC\")` call on the assumption that the\n // caller (typically the internal `chainCanonicalV3` pipeline) has\n // already run `validateV3Entry`, which calls `s.normalize(\"NFC\")`\n // on every string field. NFC is idempotent so the result is\n // identical byte-for-byte; this saves one `String.normalize` call\n // per field on the hot path. Defaults to `false` so the\n // exported-for-unit-tests surface remains safe.\n private readonly assumeNormalized: boolean;\n\n constructor(initialCapacity = 640, options?: { assumeNormalized?: boolean }) {\n this.buf = new Uint8Array(initialCapacity);\n this.pos = 0;\n this.view = new DataView(this.buf.buffer, this.buf.byteOffset, this.buf.byteLength);\n this.assumeNormalized = options?.assumeNormalized ?? false;\n }\n\n /** Final byte slice (a fresh allocation; safe to share with callers). */\n bytes(): Uint8Array {\n return this.buf.slice(0, this.pos);\n }\n\n private grow(want: number): void {\n if (this.pos + want <= this.buf.length) {\n return;\n }\n let cap = this.buf.length;\n while (this.pos + want > cap) {\n cap *= 2;\n }\n const next = new Uint8Array(cap);\n next.set(this.buf);\n this.buf = next;\n this.view = new DataView(this.buf.buffer, this.buf.byteOffset, this.buf.byteLength);\n }\n\n /**\n * Writes a length-prefixed UTF-8 string with the spec's \"post-NFC,\n * post-UTF-8 byte length\" semantics (pqc_05c v3 §7).\n *\n * Privacy Inv 4: errors do NOT echo the offending field length.\n *\n * # Double-NFC posture (M6, 2026-05-29)\n *\n * When called via `chainCanonicalV3`, `validateV3Entry` has\n * already NFC-normalized this field. NFC is idempotent so the\n * re-normalization here is a no-op semantically, but it does pay\n * one `String.normalize(\"NFC\")` call per field. Construct the\n * encoder with `{ assumeNormalized: true }` to skip the redundant\n * call when the caller has already validated. Defaults to `false`\n * so direct unit-test use of `V3Encoder` remains safe.\n */\n appendStr(s: string): void {\n const nfc = this.assumeNormalized ? s : s.normalize(\"NFC\");\n const utf8 = this.textEncoder.encode(nfc);\n if (utf8.length > MAX_V3_STRING_FIELD_BYTES) {\n throw new ErrInvalidEntryV3(\n `appendStr: field exceeds ${MAX_V3_STRING_FIELD_BYTES} bytes after NFC`,\n );\n }\n this.grow(4 + utf8.length);\n // u32 BE length prefix (cached DataView, rebuilt by grow on realloc)\n this.view.setUint32(this.pos, utf8.length, false);\n this.pos += 4;\n this.buf.set(utf8, this.pos);\n this.pos += utf8.length;\n }\n\n /**\n * Writes a u64 BE non-negative integer. v3 has no signed-int\n * fields; callers attempting to emit negative values indicate a\n * validator bug — the encoder traps it as a distinct invariant\n * violation.\n *\n * Accepts `bigint` or `number`. `number` inputs are checked for\n * `Number.isSafeInteger`; if you have a value above 2^53, pass it\n * as `bigint` (e.g. `BigInt(value)`).\n */\n appendU64(v: bigint | number): void {\n let big: bigint;\n if (typeof v === \"bigint\") {\n big = v;\n } else {\n if (!Number.isFinite(v) || !Number.isInteger(v)) {\n throw new ErrInvalidEntryV3(\n \"appendU64: non-integer number reached encoder (validator bug)\",\n );\n }\n if (!Number.isSafeInteger(v)) {\n throw new ErrInvalidEntryV3(\n \"appendU64: number exceeds Number.MAX_SAFE_INTEGER; pass as bigint\",\n );\n }\n big = BigInt(v);\n }\n if (big < 0n) {\n throw new ErrInvalidEntryV3(\n \"appendU64: encoder invariant violated (negative value reached encoder; validator must have rejected)\",\n );\n }\n if (big > 0xffffffffffffffffn) {\n throw new ErrInvalidEntryV3(\n \"appendU64: value exceeds u64 max\",\n );\n }\n this.grow(8);\n this.view.setBigUint64(this.pos, big, false);\n this.pos += 8;\n }\n\n /**\n * Writes the 4-field common header in alphabetical order:\n * company_id, entry_type, signing_key_id, timestamp_ms.\n */\n appendV3Header(\n companyId: string,\n entryType: string,\n signingKeyId: string,\n timestampMs: bigint | number,\n ): void {\n this.appendStr(companyId);\n this.appendStr(entryType);\n this.appendStr(signingKeyId);\n this.appendU64(timestampMs);\n }\n}\n\n// =============================================================================\n// Per-entry encode functions (mirror of Go's `encodeCanonicalV3` methods)\n// =============================================================================\n\nfunction encodeSARIntentV3(enc: V3Encoder, e: SARIntentEntryV3): void {\n enc.appendV3Header(e.companyId, e.entryType, e.signingKeyId, e.timestampMs);\n // Alphabetical body: pii_digest_key_version (R4, iff non-empty),\n // reason_hash, request_id, sar_type, scope, source_channel.\n // pii_digest_key_version is alphabetical-first; emitted IFF non-empty so a\n // pre-rotation legacy leaf (empty version) hashes byte-identically to its\n // original signing.\n if (e.piiDigestKeyVersion !== \"\") {\n enc.appendStr(e.piiDigestKeyVersion);\n }\n enc.appendStr(e.reasonHash.hex);\n enc.appendStr(e.requestId);\n enc.appendStr(e.sarType);\n enc.appendStr(e.scope);\n enc.appendStr(e.sourceChannel);\n}\n\nfunction encodeSARAcknowledgedV3(\n enc: V3Encoder,\n e: SARAcknowledgedEntryV3,\n): void {\n enc.appendV3Header(e.companyId, e.entryType, e.signingKeyId, e.timestampMs);\n // Alphabetical body: intent_entry_id, request_id\n enc.appendStr(e.intentEntryId);\n enc.appendStr(e.requestId);\n}\n\nfunction encodeSARFulfilledV3(enc: V3Encoder, e: SARFulfilledEntryV3): void {\n enc.appendV3Header(e.companyId, e.entryType, e.signingKeyId, e.timestampMs);\n // Alphabetical body (7 fields):\n // certificate_id, fulfillment_kind, intent_entry_id, legal_basis,\n // manifest_root, request_id, tombstone_count\n enc.appendStr(e.certificateId); // 1 (alphabetical-first; dsar_fulfill_b_pre_02e 2026-05-16)\n enc.appendStr(e.fulfillmentKind); // 2\n enc.appendStr(e.intentEntryId); // 3\n enc.appendStr(e.legalBasis); // 4\n enc.appendStr(e.manifestRoot); // 5\n enc.appendStr(e.requestId); // 6\n enc.appendU64(e.tombstoneCount); // 7\n}\n\nfunction encodeSARRejectedV3(enc: V3Encoder, e: SARRejectedEntryV3): void {\n enc.appendV3Header(e.companyId, e.entryType, e.signingKeyId, e.timestampMs);\n // Alphabetical body: intent_entry_id, legal_basis,\n // pii_digest_key_version (R4, iff non-empty), rationale_hash, request_id\n enc.appendStr(e.intentEntryId);\n enc.appendStr(e.legalBasis);\n if (e.piiDigestKeyVersion !== \"\") {\n enc.appendStr(e.piiDigestKeyVersion);\n }\n enc.appendStr(e.rationaleHash.hex);\n enc.appendStr(e.requestId);\n}\n\nfunction encodeSARExtendedV3(enc: V3Encoder, e: SARExtendedEntryV3): void {\n enc.appendV3Header(e.companyId, e.entryType, e.signingKeyId, e.timestampMs);\n // Alphabetical body: extended_due_at_ms, intent_entry_id,\n // pii_digest_key_version (R4, iff non-empty), reason_hash, request_id\n enc.appendU64(e.extendedDueAtMs);\n enc.appendStr(e.intentEntryId);\n if (e.piiDigestKeyVersion !== \"\") {\n enc.appendStr(e.piiDigestKeyVersion);\n }\n enc.appendStr(e.reasonHash.hex);\n enc.appendStr(e.requestId);\n}\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/**\n * Encode a typed V3 chain entry to canonical bytes per pqc_05c v3\n * §3 + §4. The single entry-point for cross-language byte-identical\n * encoding.\n *\n * Mirror of Go's `CanonicalBytesV3`.\n *\n * @param entry - A typed v3 chain entry (one of the 5 SAR variants).\n * @returns Canonical TLV bytes.\n * @throws {ErrInvalidEntryV3} On encoder invariant violation.\n */\nexport function chainCanonicalV3(entry: ChainEntryV3): Uint8Array {\n // Validate FIRST (mirror of Go SDK ordering): a malformed entry\n // returning an encoder-side TLV error instead of a typed\n // ErrInvalidEntryV3 would be confusing. `validateV3Entry` covers\n // the null/undefined guard and the entry_type allowlist.\n validateV3Entry(entry);\n // M6 (2026-05-29): validateV3Entry has already NFC-normalized every\n // string field; skip the redundant per-field re-normalization in\n // `appendStr` on this hot path.\n const enc = new V3Encoder(640, { assumeNormalized: true });\n switch (entry.entryType) {\n case \"sar_intent\":\n encodeSARIntentV3(enc, entry);\n break;\n case \"sar_acknowledged\":\n encodeSARAcknowledgedV3(enc, entry);\n break;\n case \"sar_fulfilled\":\n encodeSARFulfilledV3(enc, entry);\n break;\n case \"sar_rejected\":\n encodeSARRejectedV3(enc, entry);\n break;\n case \"sar_extended\":\n encodeSARExtendedV3(enc, entry);\n break;\n default: {\n // Exhaustiveness check — adding a new variant without a case\n // becomes a compile error.\n const _exhaustive: never = entry;\n throw new ErrInvalidEntryV3(\n `dispatch: unhandled entry variant ${String((_exhaustive as { entryType?: string }).entryType ?? \"unknown\")}`,\n );\n }\n }\n return enc.bytes();\n}\n\n/**\n * Compute the V3 content hash: SHA-512(DOMAIN_PREFIX_V3_BYTES || canonical).\n *\n * Mirror of Go's `ContentHashV3` (which returns hex). This JS version\n * returns the raw 64-byte digest; hex encoding is the caller's job\n * via `bytesToHex` (caller-side utility).\n *\n * Uses `crypto.subtle.digest(\"SHA-512\", ...)` from the Web Crypto API,\n * which is available in Node ≥16 (via `globalThis.crypto`) and all\n * modern browsers.\n *\n * @param canonical - Canonical bytes from `chainCanonicalV3`.\n * @returns The 64-byte SHA-512 digest.\n */\nexport async function computeV3ContentHash(\n canonical: Uint8Array,\n): Promise<Uint8Array> {\n const preimage = new Uint8Array(\n DOMAIN_PREFIX_V3_BYTES.length + canonical.length,\n );\n preimage.set(DOMAIN_PREFIX_V3_BYTES, 0);\n preimage.set(canonical, DOMAIN_PREFIX_V3_BYTES.length);\n const digest = await crypto.subtle.digest(\"SHA-512\", preimage);\n return new Uint8Array(digest);\n}\n\n/**\n * Convenience: encode + hash in one call. Mirror of Go's\n * `EncodeAndHashV3`.\n */\nexport async function encodeAndHashV3(\n entry: ChainEntryV3,\n): Promise<{ canonical: Uint8Array; contentHash: Uint8Array }> {\n const canonical = chainCanonicalV3(entry);\n const contentHash = await computeV3ContentHash(canonical);\n return { canonical, contentHash };\n}\n\n/**\n * Lowercase hex encoder for digests. Mirror of Go's\n * `hex.EncodeToString`. Useful for cross-language hash comparison\n * tests (golden vectors carry hex strings).\n */\nexport function bytesToHex(bytes: Uint8Array): string {\n // Phase 3 review LOW: array-join instead of per-byte string\n // concatenation. Negligible for 64-byte SHA-512 digests but\n // idiomatic and protects future callers that hand larger inputs.\n return Array.from(bytes, (b) => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * V3 chain entry signature verifier — TS port of\n * `sdk/verification-go/verify_v3.go::VerifyChainEntryV3`.\n *\n * # Pipeline\n *\n * 1. `validateV3Entry(entry)` — typed validation per pqc_05c v3 §3-§4.\n * 2. `chainCanonicalV3(entry)` — re-encode canonical bytes.\n * 3. `len(canonical) ≤ MAX_CANONICAL_BYTES_V3` — DoS bound.\n * 4. Bound input sizes on the CLAIM (`contentHash` 64 bytes,\n * `signature` 3309 bytes) BEFORE expensive ops.\n * 5. Recompute `SHA-512(prefix || canonical)`; constant-time\n * compare to the claimed `contentHash`.\n * 6. Resolve `signingKeyId` via the trust manifest.\n * 7. Verify ML-DSA-65 signature over `prefix || canonical`\n * (NOT over `contentHash` — pqc_05c v3 §9.1 option A).\n *\n * # Error contract (chain_d H2 — strict opacity)\n *\n * Error messages are intentionally content-agnostic. They surface\n * the typed error class only; never echo:\n * - claimed hash bytes,\n * - computed hash bytes,\n * - signingKeyId,\n * - raw ML-DSA library error strings.\n *\n * A public verifier (e.g. verify.aleutian.ai) leaking any of those\n * gives:\n * - a forgery oracle (computed hash echoed back lets attacker\n * pass the hash gate trivially, focusing on signature alone),\n * - operator-metadata leakage (signingKeyId reveals KMS key\n * version / rotation date / tenant region to anyone who\n * triggers a bad signature).\n *\n * Callers needing structured access for ops dashboards branch on\n * `err instanceof Err...V3` not on `.message` scraping.\n */\n\nimport {\n chainCanonicalV3,\n computeV3ContentHash,\n DOMAIN_PREFIX_V3_BYTES,\n ErrInvalidEntryV3,\n MAX_CANONICAL_BYTES_V3,\n validateV3Entry,\n} from \"./canonicalV3.js\";\nimport {\n type CaptureRequestEntryV3,\n chainCanonicalV3Capture,\n} from \"./captureEntryV3.js\";\nimport { MLDSAVerificationError, PUBLIC_KEY_SIZE, SIGNATURE_SIZE, verify as mldsaVerify } from \"./mldsa.js\";\nimport {\n type ChainEntryV3,\n type EventTypeV3,\n type SARAcknowledgedEntryV3,\n type SARExtendedEntryV3,\n type SARFulfilledEntryV3,\n type SARIntentEntryV3,\n type SARRejectedEntryV3,\n} from \"./sarEntries.js\";\n\n// =============================================================================\n// Cross-language constant pins (mirror of Go + Python)\n// =============================================================================\n\n/** SHA-512 byte length — cross-language constant. */\nexport const CONTENT_HASH_V3_BYTES = 64;\n\n// =============================================================================\n// Error hierarchy (mirror of Python's verify_v3 + Go's errors_v3)\n// =============================================================================\n\n/**\n * Trust manifest does not contain the entry's signingKeyId.\n *\n * Mirror of Go's `ErrKeyNotInTrustManifestV3` / Python's\n * `ErrUnknownSigningKeyV3`.\n */\nexport class ErrUnknownSigningKeyV3 extends ErrInvalidEntryV3 {\n override readonly name = \"ErrUnknownSigningKeyV3\";\n}\n\n/** Re-encoded `content_hash` does not match the supplied claim. */\nexport class ErrContentHashMismatchV3 extends ErrInvalidEntryV3 {\n override readonly name = \"ErrContentHashMismatchV3\";\n}\n\n/** Signature parses + correct length, but does not verify under the key. */\nexport class ErrSignatureInvalidV3 extends ErrInvalidEntryV3 {\n override readonly name = \"ErrSignatureInvalidV3\";\n}\n\n/** Signature bytes don't have a valid shape (wrong length, etc.). */\nexport class ErrSignatureMalformedV3 extends ErrInvalidEntryV3 {\n override readonly name = \"ErrSignatureMalformedV3\";\n}\n\n/** A trust-manifest public key has malformed bytes. */\nexport class ErrPublicKeyMalformedV3 extends ErrInvalidEntryV3 {\n override readonly name = \"ErrPublicKeyMalformedV3\";\n}\n\n// =============================================================================\n// Trust manifest (V3 verify-time lookup surface)\n// =============================================================================\n\n/**\n * Lookup surface a verifier uses to resolve `signingKeyId` →\n * ML-DSA-65 public key. Mirror of Go's `TrustManifestV3` interface\n * and Python's `TrustManifestV3` dataclass.\n *\n * # Required guarantees (per pqc_05c v3 §3.1.1)\n *\n * - Append-only: once a `signingKeyId` is bound to a public key,\n * the binding MUST NOT change. Rotating a key requires minting\n * a NEW `signingKeyId` value.\n * - One-to-one: a `signingKeyId` MUST resolve to exactly one\n * public key over the manifest's lifetime.\n *\n * # Construction-time validation (chain_d H3)\n *\n * Each public key is validated against the ML-DSA-65 byte length\n * (1952) at construction. Operators detect misconfiguration at\n * manifest-load time, not lazily per-verify.\n *\n * # Concurrency\n *\n * Read-only after construction. Safe for concurrent reads.\n */\nexport class TrustManifestV3 {\n private readonly _keys: ReadonlyMap<string, Uint8Array>;\n\n private constructor(keys: ReadonlyMap<string, Uint8Array>) {\n this._keys = keys;\n }\n\n /**\n * Build a manifest from a `Record<signingKeyId, publicKey>`. Each\n * public key is shape-validated at construction time. Each key\n * is defensively copied — post-construction mutation of the\n * caller's `Uint8Array` does not affect the manifest.\n *\n * Throws `ErrInvalidEntryV3` for empty signingKeyIds; throws\n * `ErrPublicKeyMalformedV3` for keys whose byte length is not\n * exactly `PUBLIC_KEY_SIZE`.\n */\n static fromMap(keys: Record<string, Uint8Array>): TrustManifestV3 {\n const out = new Map<string, Uint8Array>();\n for (const [id, pub] of Object.entries(keys)) {\n if (id === \"\") {\n // Don't echo the empty id (operator metadata-shape leak).\n throw new ErrInvalidEntryV3(\n \"TrustManifestV3.fromMap: empty signingKeyId\",\n );\n }\n if (!(pub instanceof Uint8Array)) {\n throw new ErrPublicKeyMalformedV3(\n \"TrustManifestV3.fromMap: public key is not Uint8Array\",\n );\n }\n if (pub.length !== PUBLIC_KEY_SIZE) {\n // Don't echo id or pub bytes — operator metadata + raw key.\n throw new ErrPublicKeyMalformedV3(\n \"TrustManifestV3.fromMap: public key has wrong byte length\",\n );\n }\n // Defensive copy (Uint8Array.from materializes new memory).\n out.set(id, Uint8Array.from(pub));\n }\n // H6 (Phase 3 review pre-emptive): the internal key map is made\n // truly immutable at runtime by overriding the mutating Map\n // methods to throw, then freezing the instance. Same pattern as\n // the CONCRETE_SAR_ENTRY_TYPE_TAGS hardening in sarEntries.ts —\n // `ReadonlyMap` alone is a type-level fiction, not a runtime\n // guarantee. The defensive copy on each `publicKeyForSigningKeyId`\n // lookup is a second line of defense; this is the first.\n const throwMutation = (op: string): never => {\n throw new TypeError(\n `TrustManifestV3 internal key map is immutable — refusing ${op}()`,\n );\n };\n Object.defineProperty(out, \"set\", {\n value: () => throwMutation(\"set\"),\n writable: false,\n configurable: false,\n });\n Object.defineProperty(out, \"delete\", {\n value: () => throwMutation(\"delete\"),\n writable: false,\n configurable: false,\n });\n Object.defineProperty(out, \"clear\", {\n value: () => throwMutation(\"clear\"),\n writable: false,\n configurable: false,\n });\n Object.freeze(out);\n return new TrustManifestV3(out);\n }\n\n /**\n * Returns the public key bytes for `signingKeyId`. Throws\n * `ErrUnknownSigningKeyV3` if missing.\n *\n * The returned slice is a DEFENSIVE COPY — callers may mutate it\n * without affecting subsequent lookups.\n */\n publicKeyForSigningKeyId(signingKeyId: string): Uint8Array {\n const pub = this._keys.get(signingKeyId);\n if (pub === undefined) {\n // Don't echo signingKeyId — operator metadata leak.\n throw new ErrUnknownSigningKeyV3(\n \"VerifyChainEntryV3: signingKeyId not in trust manifest\",\n );\n }\n return Uint8Array.from(pub);\n }\n\n /** Number of bound keys (for ops dashboards / sanity checks). */\n get size(): number {\n return this._keys.size;\n }\n}\n\n// =============================================================================\n// Constant-time comparison\n// =============================================================================\n\n/**\n * Constant-time byte-array equality. Returns `true` iff `a` and `b`\n * are byte-identical.\n *\n * H12 (Phase 3 review pre-emptive): prefer the runtime-provided\n * constant-time compare when available. Node 16+ exposes\n * `crypto.timingSafeEqual`, which is implemented at C level and\n * audited. The hand-rolled JS fallback only runs in browsers and\n * other runtimes that don't ship a built-in.\n *\n * Implementation lives in {@link ./internal/constantTime} so that\n * `consent.ts` can share the same logic without duplicating the\n * dynamic-require pattern — see `dsar_js_browser_target_audit`. This\n * re-export preserves the public symbol for back-compat.\n */\nimport { constantTimeEqual } from \"./internal/constantTime.js\";\nexport { constantTimeEqual };\n\n// =============================================================================\n// signingKeyId extraction\n// =============================================================================\n\n/**\n * Type guard distinguishing a capture leaf from the SAR union.\n *\n * The capture leaf (`CaptureRequestEntryV3`) carries NO `entryType`\n * field (its tag, `capture.request.v3`, is a constant emitted by the\n * encoder, not a struct field) — whereas every SAR variant has an\n * `entryType` discriminant. The absence of `entryType` is therefore\n * the discriminant. We additionally check for the capture-only\n * `captureMethod` field so a malformed `{}` object routes to the SAR\n * validator (which fails loudly) rather than the capture path.\n */\nfunction isCaptureEntryV3(\n entry: ChainEntryV3 | CaptureRequestEntryV3,\n): entry is CaptureRequestEntryV3 {\n return (\n !(\"entryType\" in entry) &&\n typeof (entry as CaptureRequestEntryV3).captureMethod === \"string\"\n );\n}\n\n/**\n * Returns the `signingKeyId` from a typed v3 entry. Mirror of Go's\n * `signingKeyIDOf` — the explicit per-variant switch refuses\n * structural-typing impostors that satisfy the union shape but\n * carry an unrecognized `entryType`.\n *\n * chainlinker_modernization_01i: capture leaves carry their\n * signingKeyId on the same field name; the caller resolves them via\n * the dedicated capture branch before reaching this switch.\n */\nfunction signingKeyIdOf(entry: ChainEntryV3): string {\n switch (entry.entryType) {\n case \"sar_intent\":\n return (entry as SARIntentEntryV3).signingKeyId;\n case \"sar_acknowledged\":\n return (entry as SARAcknowledgedEntryV3).signingKeyId;\n case \"sar_fulfilled\":\n return (entry as SARFulfilledEntryV3).signingKeyId;\n case \"sar_rejected\":\n return (entry as SARRejectedEntryV3).signingKeyId;\n case \"sar_extended\":\n return (entry as SARExtendedEntryV3).signingKeyId;\n default: {\n const _exhaustive: never = entry;\n throw new ErrInvalidEntryV3(\n `signingKeyIdOf: unrecognised entry variant ${String((_exhaustive as { entryType?: EventTypeV3 }).entryType ?? \"unknown\")}`,\n );\n }\n }\n}\n\n// =============================================================================\n// Public verifier\n// =============================================================================\n\n/**\n * Options-object form of {@link verifyChainEntryV3} (M1, added 0.3.1).\n *\n * Preferred over the positional form going forward. Positional form\n * remains accepted on the 0.3.x track and emits a one-shot\n * `console.warn` deprecation notice on first call; removed in 0.4.0.\n */\nexport interface VerifyChainEntryV3Options {\n signature: Uint8Array;\n contentHash: Uint8Array;\n trustManifest: TrustManifestV3;\n}\n\n// One-shot deprecation warning gate for the positional form of\n// `verifyChainEntryV3`. Process-lifetime; not reset across calls.\nlet positionalDeprecationWarned = false;\n\n/**\n * @internal Test-only hook to reset the one-shot deprecation gate so\n * unit tests can re-observe the warning. Not part of the public API.\n */\nexport function _resetPositionalDeprecationWarningForTests(): void {\n positionalDeprecationWarned = false;\n}\n\n/**\n * Verify a v3 chain entry's `content_hash` + ML-DSA-65 signature.\n *\n * # Inputs\n *\n * Two call shapes are accepted on the 0.3.x track:\n *\n * 1. **Options-object (preferred, added 0.3.1):**\n *\n * ```ts\n * verifyChainEntryV3(entry, { signature, contentHash, trustManifest })\n * ```\n *\n * 2. **Positional (deprecated, removed in 0.4.0):**\n *\n * ```ts\n * verifyChainEntryV3(entry, signature, contentHash, trustManifest)\n * ```\n *\n * Emits a one-shot `console.warn` deprecation notice on first use.\n *\n * Field semantics (identical across both shapes):\n *\n * - entry: one of the 5 concrete SAR entry variants.\n * - signature: raw ML-DSA-65 signature bytes (3309 bytes).\n * - contentHash: raw SHA-512 bytes (64 bytes). Callers with a\n * hex-encoded claim should decode (`hexToBytes(...)`) first.\n * - trustManifest: lookup surface for signingKeyId.\n *\n * # Outputs\n *\n * - Promise resolves on successful verification.\n * - Throws one of:\n * - `ErrInvalidEntryV3` (validation, oversized canonical, missing args)\n * - `ErrContentHashMismatchV3` (claimed hash does not match recompute)\n * - `ErrSignatureMalformedV3` (signature wrong length / not Uint8Array)\n * - `ErrSignatureInvalidV3` (ML-DSA verify failed)\n * - `ErrUnknownSigningKeyV3` (signingKeyId not in manifest)\n * - `ErrPublicKeyMalformedV3` (manifest contains corrupt key)\n *\n * # Concurrency\n *\n * Pure function over its inputs. Safe for concurrent use.\n */\nexport async function verifyChainEntryV3(\n entry: ChainEntryV3 | CaptureRequestEntryV3,\n options: VerifyChainEntryV3Options,\n): Promise<void>;\nexport async function verifyChainEntryV3(\n entry: ChainEntryV3 | CaptureRequestEntryV3,\n signature: Uint8Array,\n contentHash: Uint8Array,\n trustManifest: TrustManifestV3,\n): Promise<void>;\nexport async function verifyChainEntryV3(\n entry: ChainEntryV3 | CaptureRequestEntryV3,\n signatureOrOptions: Uint8Array | VerifyChainEntryV3Options,\n contentHashPositional?: Uint8Array,\n trustManifestPositional?: TrustManifestV3,\n): Promise<void> {\n let signature: Uint8Array;\n let contentHash: Uint8Array;\n let trustManifest: TrustManifestV3;\n // Discriminate by argument count: 4 arguments → positional form\n // (deprecated); 2 arguments → options-object form (preferred). This\n // is robust to non-Uint8Array signature values in the positional\n // path so existing negative-path tests still surface\n // `ErrSignatureMalformedV3` from the downstream type guard, not a\n // dispatch-shape error here.\n // eslint-disable-next-line prefer-rest-params\n const argCount = arguments.length;\n if (argCount >= 3) {\n // Positional form (deprecated 0.3.1, removed 0.4.0).\n if (!positionalDeprecationWarned) {\n positionalDeprecationWarned = true;\n // eslint-disable-next-line no-console\n console.warn(\n \"[@aleutian/verification] verifyChainEntryV3(entry, signature, contentHash, trustManifest) positional form is deprecated and will be removed in 0.4.0. Use verifyChainEntryV3(entry, { signature, contentHash, trustManifest }) instead.\",\n );\n }\n signature = signatureOrOptions as Uint8Array;\n contentHash = contentHashPositional as Uint8Array;\n trustManifest = trustManifestPositional as TrustManifestV3;\n } else {\n // Options-object form (preferred, 0.3.1+).\n if (\n signatureOrOptions == null ||\n typeof signatureOrOptions !== \"object\" ||\n signatureOrOptions instanceof Uint8Array\n ) {\n throw new ErrInvalidEntryV3(\n \"VerifyChainEntryV3: second argument must be an options object { signature, contentHash, trustManifest }\",\n );\n }\n signature = signatureOrOptions.signature;\n contentHash = signatureOrOptions.contentHash;\n trustManifest = signatureOrOptions.trustManifest;\n }\n\n // Null guards on the trust-manifest pointer — `validateV3Entry`\n // covers the entry-null case.\n if (trustManifest == null) {\n throw new ErrInvalidEntryV3(\"VerifyChainEntryV3: trustManifest is nil\");\n }\n if (!(trustManifest instanceof TrustManifestV3)) {\n throw new ErrInvalidEntryV3(\n \"VerifyChainEntryV3: trustManifest must be a TrustManifestV3 instance\",\n );\n }\n\n // Validate + re-encode FIRST so callers learn about a malformed\n // entry struct before we touch their claims about it. A bad\n // entry returning ErrContentHashMismatchV3 instead of\n // ErrInvalidEntryV3 would be confusing.\n //\n // chainlinker_modernization_01i: dispatch on the entry kind. The\n // capture leaf has its own validator + encoder\n // (chainCanonicalV3Capture); the SAR family shares chainCanonicalV3.\n // This mirrors the Go SDK, where CanonicalBytesV3 polymorphically\n // dispatches to the capture encoder and only the signingKeyIDOf /\n // timestampMsOf switches needed the explicit CaptureRequestEntryV3\n // case. The rest of the flow (content-hash compare → manifest lookup\n // → ML-DSA-65 verify over DOMAIN_PREFIX_V3‖canonical) is identical.\n // chainCanonicalV3Capture runs validateCaptureEntryV3 internally,\n // matching chainCanonicalV3's internal validateV3Entry — both throw\n // ErrInvalidEntryV3 on a malformed struct. The inline guard call\n // (not a const alias) lets TS narrow `entry` to the correct member\n // in each branch.\n let canonical: Uint8Array;\n let signingKeyId: string;\n if (isCaptureEntryV3(entry)) {\n canonical = chainCanonicalV3Capture(entry);\n // The capture leaf carries signingKeyId on the same field name;\n // resolve it directly rather than through the SAR entryType switch\n // (which has no capture case by design).\n signingKeyId = entry.signingKeyId;\n } else {\n canonical = chainCanonicalV3(entry);\n signingKeyId = signingKeyIdOf(entry);\n }\n\n // Phase 1 review (M4) mirror: refuse pathologically large entries\n // before invoking the ML-DSA-65 verifier. Opaque error per\n // Privacy Inv 4.\n if (canonical.length > MAX_CANONICAL_BYTES_V3) {\n throw new ErrInvalidEntryV3(\n \"VerifyChainEntryV3: canonical bytes exceed verifier bound\",\n );\n }\n\n // chain_d M1+M2 mirror: bound input sizes on the CLAIMS BEFORE\n // expensive ops (constant-time compare, ML-DSA verify). Mismatch\n // returns the typed sentinel without echoing length.\n if (!(contentHash instanceof Uint8Array)) {\n throw new ErrContentHashMismatchV3(\n \"VerifyChainEntryV3: contentHash must be Uint8Array\",\n );\n }\n if (contentHash.length !== CONTENT_HASH_V3_BYTES) {\n throw new ErrContentHashMismatchV3(\n \"VerifyChainEntryV3: contentHash has wrong length\",\n );\n }\n if (!(signature instanceof Uint8Array)) {\n throw new ErrSignatureMalformedV3(\n \"VerifyChainEntryV3: signature must be Uint8Array\",\n );\n }\n if (signature.length !== SIGNATURE_SIZE) {\n throw new ErrSignatureMalformedV3(\n \"VerifyChainEntryV3: signature has wrong length\",\n );\n }\n\n // Recompute hash + constant-time compare. This catches tampering\n // BEFORE the ~50-200ms ML-DSA-65 verify so a verifier exposed to\n // adversarial inputs doesn't waste CPU on garbage.\n const computedHash = await computeV3ContentHash(canonical);\n if (!constantTimeEqual(computedHash, contentHash)) {\n throw new ErrContentHashMismatchV3(\n \"VerifyChainEntryV3: content_hash mismatch\",\n );\n }\n\n // signingKeyId was resolved above in the entry-kind dispatch.\n if (signingKeyId === \"\") {\n throw new ErrInvalidEntryV3(\"VerifyChainEntryV3: signingKeyId empty\");\n }\n let publicKey: Uint8Array;\n try {\n publicKey = trustManifest.publicKeyForSigningKeyId(signingKeyId);\n } catch (e) {\n // Map unknown-key to its sentinel without echoing the underlying\n // error (which might carry KMS/Vault operator details). Other\n // error classes propagate.\n if (e instanceof ErrUnknownSigningKeyV3) {\n throw new ErrUnknownSigningKeyV3(\n \"VerifyChainEntryV3: signingKeyId not in trust manifest\",\n );\n }\n throw e;\n }\n\n // Construct the signing preimage: `prefix || canonical` per\n // pqc_05c v3 §9.1 option A. NOT `content_hash` — the signature is\n // over the preimage directly, deterministically.\n const signingInput = new Uint8Array(\n DOMAIN_PREFIX_V3_BYTES.length + canonical.length,\n );\n signingInput.set(DOMAIN_PREFIX_V3_BYTES, 0);\n signingInput.set(canonical, DOMAIN_PREFIX_V3_BYTES.length);\n\n // Final ML-DSA verify. Wrap library errors in the opaque sentinel\n // — never propagate stdlib/library text up to the verifier UI.\n try {\n mldsaVerify(publicKey, signingInput, signature);\n } catch (e) {\n if (e instanceof MLDSAVerificationError) {\n if (e.code === \"invalid_public_key\") {\n throw new ErrPublicKeyMalformedV3(\n \"VerifyChainEntryV3: trust-manifest public key is malformed\",\n );\n }\n // invalid_signature_length OR signature_verification_failed\n // both collapse to ErrSignatureInvalidV3 here — the malformed\n // length was already caught by the size gate above, so this\n // reach indicates a legitimately invalid signature.\n throw new ErrSignatureInvalidV3(\n \"VerifyChainEntryV3: ML-DSA-65 signature verification failed\",\n );\n }\n throw e;\n }\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Stable opaque views for entry / anchor / break objects.\n *\n * Privacy Invariant 4 forbids the SDK from leaking caller-supplied bytes\n * into logs, error messages, or `JSON.stringify` output. The producer\n * types in this SDK (`Anchor`, `ConsentChainEntry`, `ExportedEntry`,\n * `OfflineBreak`) are plain object-literal interfaces, so they cannot\n * own a `toJSON` override the way the Python dataclasses own a\n * `__repr__`. Instead, callers who need to log one of these objects\n * MUST first wrap it with the matching `redacted*` helper below.\n *\n * Each helper returns an immutable, fully-opaque view of the form\n * `{ __type: \"<TypeName>\", __redacted: true }` — symmetric to the\n * Python H4 pattern (`<TypeName>(<redacted>)`). No field value is\n * disclosed, even prefixed/hashed, because correlation-grade\n * identifiers (company_id, consent_id, actor_pseudonym, chain_hash)\n * can leak business volume and audit-chain structure even at 8-char\n * prefixes.\n *\n * Ticket: dsar_js_consent_anchor_json_stringify_leak\n * Symmetric to: V3 H4 (Python `SARIntentEntryV3.__repr__`) — see\n * `tickets/code_complete/dsar_chain_e_review_followup.md`.\n *\n * @module\n */\n\n/** Fully-opaque marker view returned by every redactor in this module. */\nexport interface RedactedView {\n readonly __type: string;\n readonly __redacted: true;\n}\n\nfunction opaque(typeName: string): RedactedView {\n return Object.freeze({ __type: typeName, __redacted: true as const });\n}\n\n/**\n * Opaque view of an `Anchor` for safe logging.\n *\n * Returns `{ __type: \"Anchor\", __redacted: true }`. The original\n * anchor object is not mutated. No anchor field is disclosed.\n */\nexport function redactedAnchor(_anchor: unknown): RedactedView {\n return opaque(\"Anchor\");\n}\n\n/**\n * Opaque view of a `ConsentChainEntry` for safe logging.\n *\n * Returns `{ __type: \"ConsentChainEntry\", __redacted: true }`. No\n * entry field is disclosed; actor pseudonym, processing mode, and\n * idempotency hash are all correlation-grade and never appear.\n */\nexport function redactedConsentChainEntry(_entry: unknown): RedactedView {\n return opaque(\"ConsentChainEntry\");\n}\n\n/**\n * Opaque view of an `ExportedEntry` for safe logging.\n */\nexport function redactedExportedEntry(_entry: unknown): RedactedView {\n return opaque(\"ExportedEntry\");\n}\n\n/**\n * Opaque view of an `OfflineBreak` for safe logging.\n *\n * Breaks carry the offending `entryId` and chain hashes, which can be\n * used to correlate with audit-chain state. Use this redactor before\n * passing breaks into structured loggers.\n */\nexport function redactedOfflineBreak(_brk: unknown): RedactedView {\n return opaque(\"OfflineBreak\");\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * `@aleutian/verification/tier2` — customer-side unseal for Tier-2\n * Standard-mode audit bundles. Browser- and Node-safe.\n *\n * Per ADR-024 Amendment (2026-05-31), bundles ship with N=2 X-Wing\n * recipient envelopes (primary + backup). `openBundle` accepts a\n * single seed and locates the matching envelope via constant-time\n * fingerprint compare.\n *\n * @example\n *\n * ```ts\n * import { openBundle, deriveFingerprint } from \"@aleutian/verification/tier2\";\n *\n * const seed = hexToBytes(myXWingPrimarySeed);\n * const bundle = parseManifest(downloadedManifestJSON);\n * const { cek, matchedEnvelopeIndex } = await openBundle(seed, bundle);\n * console.log(`unsealed via envelope ${matchedEnvelopeIndex}`);\n * ```\n */\n\nexport type {\n Bundle,\n CEKWrapEnvelope,\n Manifest,\n OpenBundleResult,\n Tier2Manifest,\n} from \"./bundle.js\";\n\nexport {\n BundleMalformedError,\n NoMatchingRecipientError,\n OpenFailedError,\n SeedInvalidError,\n Tier2Error,\n} from \"./errors.js\";\n\nexport { deriveFingerprint, openBundle } from \"./unseal.js\";\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Exception hierarchy for Tier-2 unseal.\n *\n * Mirrors the Go SDK sentinels and the Python SDK exception classes.\n * Catch `Tier2Error` to handle any unseal failure uniformly.\n */\n\n/** Base class for all Tier-2 unseal failures. */\nexport class Tier2Error extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"Tier2Error\";\n }\n}\n\n/**\n * Raised when the supplied seed is not exactly 32 bytes.\n */\nexport class SeedInvalidError extends Tier2Error {\n constructor(message: string) {\n super(message);\n this.name = \"SeedInvalidError\";\n }\n}\n\n/**\n * Raised when the bundle is structurally invalid: missing or empty\n * `id`, `tier2.mode` not `\"standard\"`, empty `cek_envelopes`, or a\n * `pubkey_count` value that disagrees with `len(cek_envelopes)`.\n */\nexport class BundleMalformedError extends Tier2Error {\n constructor(message: string) {\n super(message);\n this.name = \"BundleMalformedError\";\n }\n}\n\n/**\n * Raised when the seed's fingerprint matches no envelope in the bundle.\n *\n * SECURITY: deliberately opaque. Does NOT include the seed's fingerprint,\n * the bundle's recipient list, or any slot label — a distinguishing\n * error would leak which envelopes a bundle carries to an attacker who\n * controls the seed.\n */\nexport class NoMatchingRecipientError extends Tier2Error {\n constructor(message: string) {\n super(message);\n this.name = \"NoMatchingRecipientError\";\n }\n}\n\n/**\n * Raised when the matched envelope's AEAD decryption fails. The single-\n * sentinel design (wrong seed, tampered ciphertext, AAD mismatch all\n * collapse here) mirrors the Go/Python SDKs' anti-oracle posture.\n */\nexport class OpenFailedError extends Tier2Error {\n constructor(message: string) {\n super(message);\n this.name = \"OpenFailedError\";\n }\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Customer-side unseal pipeline for Tier-2 Standard-mode bundles.\n *\n * Browser- and Node-safe: uses only `@noble/post-quantum` (ML-KEM-768),\n * `tweetnacl` (X25519 via scalarMult), `@noble/hashes` (SHA3-256 +\n * SHAKE256), and the Web Crypto API (AES-256-GCM, HKDF-SHA-512,\n * SHA-512). No `node:crypto`, no `Buffer`.\n *\n * Wire-format constants and AAD / KDF construction mirror the\n * proprietary `internal/crypto/tier2envelope` and the Go SDK\n * (`sdk/verification-go/tier2`) byte-for-byte. The cross-language\n * fixture `src/fixtures/tier2_dual_v1.json` is the byte-parity\n * contract — break it in any SDK and that SDK's fixture test fails.\n *\n * SECURITY: openBundle short-circuits at multiple internal stages\n * whose latency differs by orders of magnitude. Do NOT expose this\n * directly as a network-facing service without a fixed-latency\n * wrapper — the timing differences are a remote oracle.\n */\n\nimport { ml_kem768 } from \"@noble/post-quantum/ml-kem.js\";\nimport { sha3_256, shake256 } from \"@noble/hashes/sha3.js\";\nimport nacl from \"tweetnacl\";\n\nimport type { Bundle, CEKWrapEnvelope, OpenBundleResult } from \"./bundle.js\";\nimport {\n BundleMalformedError,\n NoMatchingRecipientError,\n OpenFailedError,\n SeedInvalidError,\n} from \"./errors.js\";\n\n// -----------------------------------------------------------------------------\n// Wire-format constants — IMMUTABLE. Must match the Go SDK + Python SDK +\n// proprietary internal/crypto/tier2envelope byte-for-byte.\n// -----------------------------------------------------------------------------\n\nconst XWING_SEED_SIZE = 32;\nconst XWING_PUBKEY_SIZE = 1216; // 1184 ML-KEM EK + 32 X25519 PK\nconst XWING_CIPHERTEXT_WIRE_SIZE = 1088 + 32;\nconst FINGERPRINT_HEX_LEN = 32;\nconst AES_KEY_SIZE = 32;\nconst NONCE_SIZE = 12;\nconst AEAD_TAG_SIZE = 16;\nconst MAX_CEK_WRAP_BYTES = AES_KEY_SIZE + AEAD_TAG_SIZE;\nconst TIER_MODE_STANDARD = \"standard\";\nconst ENVELOPE_KIND_CEK = \"cek\";\nconst AAD_PREFIX = \"aleutian.tier2.row.v1:\";\nconst HKDF_INFO_CEK_WRAP = \"aleutian.tier2.cek_wrap.v1:\";\n\n/**\n * 6-byte X-Wing combiner domain separator per IETF\n * draft-connolly-cfrg-xwing-kem §5.3. ASCII: `\\././^\\` (the X-Wing emoticon).\n */\nconst XWING_LABEL = new Uint8Array([0x5c, 0x2e, 0x2f, 0x2f, 0x5e, 0x5c]);\n\n// -----------------------------------------------------------------------------\n// Public API\n// -----------------------------------------------------------------------------\n\n/**\n * Unseal a Tier-2 Standard-mode bundle using one of the customer's\n * X-Wing private-key seeds.\n *\n * Per ADR-024 Amendment (2026-05-31), bundles ship with N=2\n * cek_envelopes (primary + backup). Either seed unseals; the function\n * is slot-agnostic. Inspect `matchedEnvelopeIndex` to determine which\n * slot was used.\n *\n * @param seed - Exactly 32 bytes of X-Wing private-key seed.\n * @param bundle - Parsed bundle with `manifest.tier2.cek_envelopes` populated.\n * @returns Recovered CEK and matched envelope metadata.\n * @throws {SeedInvalidError} If seed length !== 32.\n * @throws {BundleMalformedError} On structural rejection.\n * @throws {NoMatchingRecipientError} If no envelope matches the seed's fingerprint.\n * @throws {OpenFailedError} If envelope AEAD open fails.\n */\nexport async function openBundle(\n seed: Uint8Array,\n bundle: Bundle,\n): Promise<OpenBundleResult> {\n if (!(seed instanceof Uint8Array) || seed.length !== XWING_SEED_SIZE) {\n throw new SeedInvalidError(\n `seed must be exactly ${XWING_SEED_SIZE} bytes; got ${seed?.length ?? 0}`,\n );\n }\n if (bundle === null || bundle === undefined || !bundle.id) {\n throw new BundleMalformedError(\"bundle is null or has empty id\");\n }\n if (bundle.manifest?.tier2?.mode !== TIER_MODE_STANDARD) {\n throw new BundleMalformedError(\n `tier2.mode must be ${JSON.stringify(TIER_MODE_STANDARD)}; got ${JSON.stringify(bundle.manifest?.tier2?.mode)}`,\n );\n }\n const envs = bundle.manifest.tier2.cek_envelopes;\n if (!envs || envs.length === 0) {\n throw new BundleMalformedError(\"no cek_envelopes\");\n }\n const pubkeyCount = bundle.manifest.tier2.pubkey_count ?? 0;\n if (pubkeyCount !== 0 && pubkeyCount !== envs.length) {\n throw new BundleMalformedError(\n `pubkey_count=${pubkeyCount} disagrees with cek_envelopes.length=${envs.length}`,\n );\n }\n\n const myFP = await deriveFingerprint(seed);\n\n // Constant-time scan: visit EVERY envelope so loop time is O(N)\n // regardless of which slot matches. constantTimeStringEqual ensures\n // each per-envelope compare is itself constant-time over the\n // fingerprint hex string.\n let matchIdx = -1;\n for (let i = 0; i < envs.length; i++) {\n const env = envs[i]!;\n if (env.pubkey_fingerprint.length !== FINGERPRINT_HEX_LEN) {\n // Skip malformed entries — but don't break the loop so the\n // timing signature doesn't betray which slots are well-formed.\n continue;\n }\n if (constantTimeStringEqual(env.pubkey_fingerprint, myFP)) {\n matchIdx = i;\n // Do NOT break — continue scanning to keep the loop O(N).\n }\n }\n\n if (matchIdx < 0) {\n throw new NoMatchingRecipientError(\n \"no envelope matches this seed's fingerprint\",\n );\n }\n\n const matched = envs[matchIdx]!;\n const cek = await openCEKWrap(matched, bundle.id, matchIdx, seed);\n return {\n cek,\n matchedEnvelopeIndex: matchIdx,\n matchedFingerprint: matched.pubkey_fingerprint,\n };\n}\n\n/**\n * Compute the 32-char lowercase hex fingerprint from a 32-byte X-Wing\n * private-key seed.\n *\n * Matches `hex(SHA-512(canonical_pubkey_1216)[:16])` — the form stored\n * in `CEKWrapEnvelope.pubkey_fingerprint`.\n *\n * @throws {SeedInvalidError} If seed length !== 32.\n */\nexport async function deriveFingerprint(seed: Uint8Array): Promise<string> {\n if (!(seed instanceof Uint8Array) || seed.length !== XWING_SEED_SIZE) {\n throw new SeedInvalidError(\n `seed must be exactly ${XWING_SEED_SIZE} bytes; got ${seed?.length ?? 0}`,\n );\n }\n const pub = derivePubkey(seed);\n const digest = await crypto.subtle.digest(\"SHA-512\", pub);\n return bytesToHex(new Uint8Array(digest).subarray(0, FINGERPRINT_HEX_LEN / 2));\n}\n\n// -----------------------------------------------------------------------------\n// Unexported helpers\n// -----------------------------------------------------------------------------\n\nasync function openCEKWrap(\n env: CEKWrapEnvelope,\n bundleID: string,\n envelopeIndex: number,\n seed: Uint8Array,\n): Promise<Uint8Array> {\n let nonce: Uint8Array;\n let wrapCT: Uint8Array;\n let kemCT: Uint8Array;\n try {\n nonce = base64ToBytes(env.wrap_nonce);\n if (nonce.length !== NONCE_SIZE) {\n throw new OpenFailedError(\"wrap_nonce wrong length\");\n }\n wrapCT = base64ToBytes(env.wrap_ciphertext);\n if (wrapCT.length !== MAX_CEK_WRAP_BYTES) {\n throw new OpenFailedError(\"wrap_ciphertext wrong length\");\n }\n kemCT = base64ToBytes(env.kem_ciphertext);\n if (kemCT.length !== XWING_CIPHERTEXT_WIRE_SIZE) {\n throw new OpenFailedError(\"kem_ciphertext wrong length\");\n }\n } catch (e) {\n if (e instanceof OpenFailedError) throw e;\n throw new OpenFailedError(\"malformed envelope encoding\");\n }\n\n const aad = buildAAD({\n bundleID,\n rowID: \"\",\n envelopeKind: ENVELOPE_KIND_CEK,\n rowIndex: 0n,\n envelopeIndex: BigInt(envelopeIndex),\n });\n\n let ss: Uint8Array;\n try {\n ss = xwingDecapsulate(seed, kemCT);\n } catch {\n throw new OpenFailedError(\"x-wing decapsulate failed\");\n }\n\n let wrapKey: Uint8Array;\n try {\n wrapKey = await deriveCEKWrapKey(ss, bundleID, env.pubkey_fingerprint);\n } catch {\n throw new OpenFailedError(\"derive wrap key failed\");\n }\n\n let cek: Uint8Array;\n try {\n cek = await aeadOpen(wrapKey, nonce, wrapCT, aad);\n } catch {\n throw new OpenFailedError(\"aead open failed\");\n }\n\n if (cek.length !== AES_KEY_SIZE) {\n throw new OpenFailedError(\"recovered cek wrong size\");\n }\n return cek;\n}\n\n/**\n * Build the canonical Standard-mode AAD blob per spec §2.2.\n *\n * Layout (IMMUTABLE):\n *\n * aad_prefix ||\n * u32_be(len(bundle_id)) || bundle_id ||\n * u32_be(len(tier_mode)) || tier_mode ||\n * u32_be(len(row_id)) || row_id ||\n * u32_be(len(envelope_kind)) || envelope_kind ||\n * u64_be(row_index) ||\n * u64_be(envelope_index)\n */\nfunction buildAAD(args: {\n bundleID: string;\n rowID: string;\n envelopeKind: string;\n rowIndex: bigint;\n envelopeIndex: bigint;\n}): Uint8Array {\n if (!args.bundleID) throw new Error(\"aad: bundle_id required\");\n if (args.envelopeKind !== ENVELOPE_KIND_CEK) {\n throw new Error(`aad: envelope_kind ${args.envelopeKind} unsupported in SDK`);\n }\n if (args.rowID !== \"\") throw new Error(\"aad: row_id must be empty for kind=cek\");\n if (args.rowIndex < 0n || args.envelopeIndex < 0n) {\n throw new Error(\"aad: indices must be >= 0\");\n }\n\n const enc = new TextEncoder();\n const prefix = enc.encode(AAD_PREFIX);\n const bundleBytes = enc.encode(args.bundleID);\n const tierBytes = enc.encode(TIER_MODE_STANDARD);\n const rowBytes = enc.encode(args.rowID);\n const kindBytes = enc.encode(args.envelopeKind);\n\n const total =\n prefix.length +\n 4 + bundleBytes.length +\n 4 + tierBytes.length +\n 4 + rowBytes.length +\n 4 + kindBytes.length +\n 8 + 8;\n\n const out = new Uint8Array(total);\n const view = new DataView(out.buffer);\n let off = 0;\n out.set(prefix, off); off += prefix.length;\n view.setUint32(off, bundleBytes.length, false); off += 4;\n out.set(bundleBytes, off); off += bundleBytes.length;\n view.setUint32(off, tierBytes.length, false); off += 4;\n out.set(tierBytes, off); off += tierBytes.length;\n view.setUint32(off, rowBytes.length, false); off += 4;\n out.set(rowBytes, off); off += rowBytes.length;\n view.setUint32(off, kindBytes.length, false); off += 4;\n out.set(kindBytes, off); off += kindBytes.length;\n view.setBigUint64(off, args.rowIndex, false); off += 8;\n view.setBigUint64(off, args.envelopeIndex, false); off += 8;\n return out;\n}\n\n/**\n * Derive the AEAD wrap-key from the X-Wing shared secret per spec §2.3.\n *\n * ikm = ss\n * salt = hex.decode(fp_hex) (16 raw bytes)\n * info = HKDF_INFO_CEK_WRAP || LP(bundle_id) || LP(fp_hex)\n * output_len = 32\n * wrap_key = HKDF-SHA-512(ikm, salt, info, 32)\n */\nasync function deriveCEKWrapKey(\n ss: Uint8Array,\n bundleID: string,\n fpHex: string,\n): Promise<Uint8Array> {\n if (!bundleID) throw new Error(\"kdf: bundle_id required\");\n if (fpHex.length !== FINGERPRINT_HEX_LEN) {\n throw new Error(`kdf: fpHex len ${fpHex.length} != ${FINGERPRINT_HEX_LEN}`);\n }\n const fpRaw = hexToBytes(fpHex);\n\n const enc = new TextEncoder();\n const prefix = enc.encode(HKDF_INFO_CEK_WRAP);\n const bundleBytes = enc.encode(bundleID);\n const fpBytes = enc.encode(fpHex);\n const info = new Uint8Array(\n prefix.length + 4 + bundleBytes.length + 4 + fpBytes.length,\n );\n const view = new DataView(info.buffer);\n let off = 0;\n info.set(prefix, off); off += prefix.length;\n view.setUint32(off, bundleBytes.length, false); off += 4;\n info.set(bundleBytes, off); off += bundleBytes.length;\n view.setUint32(off, fpBytes.length, false); off += 4;\n info.set(fpBytes, off); off += fpBytes.length;\n\n // Web Crypto HKDF. importKey for HKDF requires raw IKM.\n const ikm = await crypto.subtle.importKey(\"raw\", ss, \"HKDF\", false, [\n \"deriveBits\",\n ]);\n const derived = await crypto.subtle.deriveBits(\n {\n name: \"HKDF\",\n hash: \"SHA-512\",\n salt: fpRaw,\n info,\n },\n ikm,\n AES_KEY_SIZE * 8,\n );\n return new Uint8Array(derived);\n}\n\n/** AES-256-GCM open via Web Crypto. */\nasync function aeadOpen(\n key: Uint8Array,\n nonce: Uint8Array,\n ciphertext: Uint8Array,\n aad: Uint8Array,\n): Promise<Uint8Array> {\n const cryptoKey = await crypto.subtle.importKey(\n \"raw\",\n key,\n \"AES-GCM\",\n false,\n [\"decrypt\"],\n );\n const pt = await crypto.subtle.decrypt(\n { name: \"AES-GCM\", iv: nonce, additionalData: aad, tagLength: AEAD_TAG_SIZE * 8 },\n cryptoKey,\n ciphertext,\n );\n return new Uint8Array(pt);\n}\n\n/**\n * X-Wing KEM decapsulation per IETF draft-connolly-cfrg-xwing-kem §5.4.\n *\n * 1. SHAKE256-expand seed → (mlkem_d || mlkem_z || x25519_priv).\n * 2. ML-KEM-768 decapsulate(mlkem_seed, mlkem_ct) → ss_M (32 bytes).\n * 3. X25519(x25519_priv, x25519_epk) → ss_X (32 bytes).\n * 4. SHA3-256(ss_M || ss_X || ct_X || pk_X || label) → 32-byte ss.\n */\nfunction xwingDecapsulate(seed: Uint8Array, ct: Uint8Array): Uint8Array {\n if (ct.length !== XWING_CIPHERTEXT_WIRE_SIZE) {\n throw new Error(\"xwing: ct wrong length\");\n }\n const mlkemCT = ct.subarray(0, 1088);\n const x25519EPK = ct.subarray(1088);\n\n const { mlkemSeed, x25519Priv } = expandSeed(seed);\n\n // ml_kem768.keygen(seed) accepts the 64-byte d||z and returns the\n // full secret key needed for decapsulate.\n const { secretKey: mlkemSK } = ml_kem768.keygen(mlkemSeed);\n const mlkemSS = ml_kem768.decapsulate(mlkemCT, mlkemSK);\n\n // X25519 DH(priv, epk). Low-order points MUST NOT cause failure per\n // spec §4.2 — substitute zeros on error to match server-side\n // behavior. tweetnacl's scalarMult does not throw for low-order\n // inputs; it returns the (correct under spec) all-zero shared secret\n // in that case, which is exactly what we want.\n const x25519SS = nacl.scalarMult(x25519Priv, x25519EPK);\n const ownPub = nacl.scalarMult.base(x25519Priv);\n\n const h = sha3_256.create();\n h.update(mlkemSS);\n h.update(x25519SS);\n h.update(x25519EPK);\n h.update(ownPub);\n h.update(XWING_LABEL);\n return h.digest();\n}\n\n/**\n * Derive the 1216-byte canonical X-Wing public key from a 32-byte seed.\n * Layout: ek_mlkem (1184) || pk_x25519 (32).\n */\nfunction derivePubkey(seed: Uint8Array): Uint8Array {\n const { mlkemSeed, x25519Priv } = expandSeed(seed);\n const { publicKey: mlkemEK } = ml_kem768.keygen(mlkemSeed);\n if (mlkemEK.length !== 1184) {\n throw new Error(`mlkem ek len ${mlkemEK.length} != 1184`);\n }\n const pkX25519 = nacl.scalarMult.base(x25519Priv);\n const out = new Uint8Array(XWING_PUBKEY_SIZE);\n out.set(mlkemEK, 0);\n out.set(pkX25519, 1184);\n return out;\n}\n\n/**\n * SHAKE256(seed, 96) → (mlkem_seed_64, x25519_priv_32).\n * Mirrors IETF draft-connolly-cfrg-xwing-kem §5.2.\n */\nfunction expandSeed(seed: Uint8Array): {\n mlkemSeed: Uint8Array;\n x25519Priv: Uint8Array;\n} {\n const expanded = shake256(seed, { dkLen: 96 });\n return {\n mlkemSeed: expanded.subarray(0, 64),\n x25519Priv: expanded.subarray(64, 96),\n };\n}\n\n/**\n * Constant-time string equality. Both inputs must be the same length;\n * length-mismatch returns false in non-constant time, but the\n * fingerprint scan guards by length BEFORE calling this so the\n * timing-leaky path is unreachable in practice.\n */\nfunction constantTimeStringEqual(a: string, b: string): boolean {\n if (a.length !== b.length) return false;\n let diff = 0;\n for (let i = 0; i < a.length; i++) {\n diff |= a.charCodeAt(i) ^ b.charCodeAt(i);\n }\n return diff === 0;\n}\n\n// -----------------------------------------------------------------------------\n// Encoding helpers (browser-safe — no Buffer / no node:crypto).\n// -----------------------------------------------------------------------------\n\nfunction base64ToBytes(b64: string): Uint8Array {\n // Use the platform's atob (available in browsers, Node 16+, Deno).\n const bin = atob(b64);\n const out = new Uint8Array(bin.length);\n for (let i = 0; i < bin.length; i++) out[i] = bin.charCodeAt(i);\n return out;\n}\n\nfunction hexToBytes(hex: string): Uint8Array {\n if (hex.length % 2 !== 0) throw new Error(\"hex: odd length\");\n const out = new Uint8Array(hex.length / 2);\n for (let i = 0; i < out.length; i++) {\n const byte = parseInt(hex.substring(i * 2, i * 2 + 2), 16);\n if (Number.isNaN(byte)) throw new Error(\"hex: non-hex character\");\n out[i] = byte;\n }\n return out;\n}\n\nfunction bytesToHex(bytes: Uint8Array): string {\n let s = \"\";\n for (let i = 0; i < bytes.length; i++) {\n s += bytes[i]!.toString(16).padStart(2, \"0\");\n }\n return s;\n}\n\n/**\n * For test/xwingSpecVectors.test.ts only, which holds the decapsulation to the\n * X-Wing specification's official vectors. Not re-exported from tier2/index.ts,\n * and not part of the package API (package.json exports only \".\" and\n * \"./browser\").\n *\n * @internal\n */\nexport { xwingDecapsulate as _xwingDecapsulate, derivePubkey as _derivePubkey };\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The streaming bundle reader: one pass over the bytes that checks §3's\n * grammar, §5's limits and §4's structure as it goes, and builds only what a\n * readable bundle needs (bundle-format revision 3.2).\n *\n * Why not parse a tree first: a tree of tiny values costs far more memory than\n * the bytes that encode them (16 MiB of `{}` is about a gigabyte of objects).\n * This reader knows each value's §4 position as it begins, so it can:\n *\n * - count every JSON value as it begins (§5's value limit, §9.1 position 3).\n * Past it, it keeps neither values nor member names, and only checks the rest\n * of the input against §3 (position 2 can still apply);\n * - detect a structure violation at once: an unknown member or a wrong type\n * when the value begins, missing members when an object closes, an empty\n * `entries` when it closes. After the first one it builds nothing, but keeps\n * tracking member names (duplicate-key outranks structure) and the top-level\n * `format` value (format outranks it too);\n * - count chains, entries and checkpoints as they stream, and stop building\n * past a count limit (structure still outranks it).\n *\n * Once the outcome is unreadable, nothing more is built and what was built is\n * dropped, so memory on hostile input stays below that of the largest\n * readable bundle. The §9.1 reason is chosen only after the whole input has\n * been scanned, so a grammar error anywhere outranks everything but the size.\n *\n * NO-LEAK RULE (§10): the outcome is a reason code, never a value or position.\n * Browser-safe.\n */\n\nimport type { ProofBundleLimits, ProofBundleUnreadableReason } from \"./proofBundle.js\";\nimport { runStrict, StrictJsonScanner } from \"./strictJson.js\";\n\n/** The bundle format string (§4.1). */\nexport const BUNDLE_FORMAT_V1 = \"aleutian.proof.bundle.v1\";\n\n/** The v2 bundle format string (§16): chain format v4, v7 checkpoints, record.v2. */\nexport const BUNDLE_FORMAT_V2 = \"aleutian.proof.bundle.v2\";\n\n/** Which bundle format a readable bundle declared. */\nexport type BundleFormatVersion = 1 | 2;\n\n/** Nesting depth limit (§3, §5). */\nexport const BUNDLE_MAX_DEPTH = 8;\n\n/** One entry, as §4.3 requires it (shapes are judged later, §7.1). */\nexport interface BundleEntry {\n readonly entryId: string;\n readonly entryType: string;\n readonly globalSeq: string;\n readonly previousHash: string;\n readonly timestamp: string;\n readonly contentHash: string;\n readonly chainHash: string;\n /** v2 only (§16 §4.3): 64 lowercase hex, judged in §7.1. */\n readonly salt?: string;\n /** v2 only (§16 §4.3): 128 lowercase hex, judged in §7.1. */\n readonly leafHash?: string;\n readonly recordSignature?: { readonly keyId: string; readonly signature: string };\n readonly disclosed?: { readonly content: string; readonly nonce: string };\n}\n\n/** One chain, as §4.2 requires it. */\nexport interface BundleChain {\n readonly chainId: string;\n readonly entries: BundleEntry[];\n readonly checkpoints: string[];\n}\n\n/** The outcome of {@link readProofBundle}. */\nexport type BundleReadOutcome =\n | { readonly ok: true; readonly format: BundleFormatVersion; readonly chains: BundleChain[] }\n | { readonly ok: false; readonly reason: ProofBundleUnreadableReason };\n\nconst LBRACE = 0x7b;\nconst RBRACE = 0x7d;\nconst LBRACKET = 0x5b;\nconst RBRACKET = 0x5d;\nconst QUOTE = 0x22;\nconst COMMA = 0x2c;\nconst COLON = 0x3a;\n\n/** §4.3's required entry members, in BundleEntry order; bit i is member i. */\nconst ENTRY_MEMBERS = [\n \"entry_id\",\n \"entry_type\",\n \"global_seq\",\n \"previous_hash\",\n \"timestamp\",\n \"content_hash\",\n \"chain_hash\",\n] as const;\nconst ENTRY_INDEX = new Map<string, number>(ENTRY_MEMBERS.map((name, i) => [name, i]));\nconst ENTRY_ALL = (1 << ENTRY_MEMBERS.length) - 1;\n\n/**\n * The longest raw text a format string can have: every character as a\n * six-byte `\\u` escape, plus the quotes. Anything longer is neither, unread.\n */\nconst FORMAT_MAX_RAW = 6 * Math.max(BUNDLE_FORMAT_V1.length, BUNDLE_FORMAT_V2.length) + 2;\n\nclass BundleReader extends StrictJsonScanner {\n private values = 0;\n private valueLimitHit = false;\n private duplicateKey = false;\n private topIsObject = false;\n private formatOk = false;\n private formatVersion: BundleFormatVersion = 1;\n /**\n * Whether an entry carried a v2-only member (`salt`, `leaf_hash`), and\n * whether one lacked either. Members may come in any order, `format` last,\n * so which of the two is a structure violation is decided at the end.\n */\n private sawV2Member = false;\n private missedV2Member = false;\n private structureBad = false;\n private countExceeded = false;\n private chainCount = 0;\n private entryCount = 0;\n private checkpointCount = 0;\n /** False once the outcome cannot be readable: nothing more is built. */\n private building = true;\n\n private readonly anyMember = (_name: string, depth: number): void => this.any(depth);\n private readonly anyElement = (depth: number): void => this.any(depth);\n\n constructor(\n bytes: Uint8Array,\n private readonly limits: ProofBundleLimits\n ) {\n super(bytes, BUNDLE_MAX_DEPTH);\n }\n\n /** Scan the whole document; the chains, while still building. */\n document(): BundleChain[] | undefined {\n this.skipWhitespace();\n const chains = this.root();\n this.expectEnd();\n return chains;\n }\n\n /** The lowest-numbered §9.1 reason after positions 1 and 2, or the chains. */\n outcome(chains: BundleChain[] | undefined): BundleReadOutcome {\n // §5 / §16 §5: the value limit is the declared format's (v2 entries have\n // two more values). A bundle declaring neither format is held to v1's.\n const v2 = this.formatOk && this.formatVersion === 2;\n if (this.valueLimitHit || this.values > (v2 ? this.v2ValueLimit : this.limits.values)) {\n return { ok: false, reason: \"too-large\" };\n }\n if (this.duplicateKey) return { ok: false, reason: \"duplicate-key\" };\n if (this.topIsObject && !this.formatOk) return { ok: false, reason: \"format\" };\n if (this.structureBad) return { ok: false, reason: \"structure\" };\n // §4.3 / §16 §4.3: a v1 entry has no salt or leaf_hash; a v2 entry has both.\n if (v2 ? this.missedV2Member : this.sawV2Member) return { ok: false, reason: \"structure\" };\n if (this.countExceeded || chains === undefined)\n return { ok: false, reason: \"too-large\" };\n return { ok: true, format: this.formatVersion, chains };\n }\n\n /** §16 §5's value limit (17,000,000); v1's when none is given. */\n private get v2ValueLimit(): number {\n return this.limits.valuesV2 ?? this.limits.values;\n }\n\n /**\n * Past this many values no outcome can be readable under either format, so\n * nothing more is built or kept (the format may come last).\n */\n private get valueCutoff(): number {\n return Math.max(this.limits.values, this.v2ValueLimit);\n }\n\n /** Whether §4 is still being checked: no structure violation, under the value limit. */\n private get checking(): boolean {\n return !this.structureBad && !this.valueLimitHit;\n }\n\n private violate(): void {\n this.structureBad = true;\n this.building = false;\n }\n\n /** A value begins: count it (§5). Past the higher of the two formats' limits, stop building. */\n private begin(): void {\n this.values++;\n if (!this.valueLimitHit && this.values > this.valueCutoff) {\n this.valueLimitHit = true;\n this.building = false;\n }\n }\n\n // ---------------------------------------------------------------------------\n // Grammar only\n // ---------------------------------------------------------------------------\n\n /** Any value, checked against §3 only (its names still tracked). */\n private any(depth: number): void {\n this.begin();\n this.skipBody(depth);\n }\n\n /** The value at the cursor, already counted, checked against §3 only. */\n private skipBody(depth: number): void {\n const c = this.peek();\n if (c === LBRACE) this.object(depth, this.anyMember);\n else if (c === LBRACKET) this.array(depth, this.anyElement);\n else if (c === QUOTE) this.skipString();\n else if (c === 0x74) this.literal(\"true\");\n else if (c === 0x66) this.literal(\"false\");\n else if (c === 0x6e) this.literal(\"null\");\n else this.skipNumber();\n }\n\n /**\n * An object: grammar, depth and duplicate names (until the value limit).\n * `member` reads each first-seen member's value; a repeated name's value is\n * only scanned, since the outcome is already duplicate-key or worse.\n */\n private object(depth: number, member: (name: string, depth: number) => void): void {\n if (depth > this.maxDepth) this.fail();\n this.pos++; // {\n this.skipWhitespace();\n if (this.peek() === RBRACE) {\n this.pos++;\n return;\n }\n let names: Set<string> | undefined;\n for (;;) {\n this.skipWhitespace();\n if (this.peek() !== QUOTE) this.fail();\n if (this.valueLimitHit) {\n // Past the value limit only §3 can still matter: no names kept.\n names = undefined;\n this.skipString();\n this.colon();\n this.any(depth + 1);\n } else {\n const name = this.readString();\n names ??= new Set<string>();\n const fresh = !names.has(name);\n if (fresh) {\n names.add(name);\n } else {\n this.duplicateKey = true;\n this.building = false;\n }\n this.colon();\n if (fresh) member(name, depth + 1);\n else this.any(depth + 1);\n }\n this.skipWhitespace();\n const c = this.peek();\n if (c === COMMA) {\n this.pos++;\n continue;\n }\n if (c === RBRACE) {\n this.pos++;\n return;\n }\n this.fail();\n }\n }\n\n /** The colon after a member name, with the whitespace around it. */\n private colon(): void {\n this.skipWhitespace();\n this.expect(COLON);\n this.skipWhitespace();\n }\n\n /** An array: grammar and depth; `element` reads each element. Returns the length. */\n private array(depth: number, element: (depth: number) => void): number {\n if (depth > this.maxDepth) this.fail();\n this.pos++; // [\n this.skipWhitespace();\n if (this.peek() === RBRACKET) {\n this.pos++;\n return 0;\n }\n let n = 0;\n for (;;) {\n this.skipWhitespace();\n element(depth + 1);\n n++;\n this.skipWhitespace();\n const c = this.peek();\n if (c === COMMA) {\n this.pos++;\n continue;\n }\n if (c === RBRACKET) {\n this.pos++;\n return n;\n }\n this.fail();\n }\n }\n\n // ---------------------------------------------------------------------------\n // §4 positions. Each begins by counting its value; when §4 is no longer\n // checked, it only scans. A wrong JSON type is a structure violation.\n // ---------------------------------------------------------------------------\n\n /** Scan a value of the wrong type for its position. */\n private wrongType(depth: number): void {\n this.violate();\n this.skipBody(depth);\n }\n\n /** §4.1: the top-level object. */\n private root(): BundleChain[] | undefined {\n this.begin();\n if (this.peek() !== LBRACE) {\n this.wrongType(1);\n return undefined;\n }\n this.topIsObject = true;\n let chains: BundleChain[] | undefined;\n let hasChains = false;\n this.object(1, (name, depth) => {\n if (name === \"format\") this.format(depth);\n else if (!this.checking) this.any(depth);\n else if (name === \"chains\") {\n hasChains = true;\n chains = this.chains(depth);\n } else {\n this.violate();\n this.any(depth);\n }\n });\n if (this.checking && !hasChains) this.violate();\n return this.building ? chains : undefined;\n }\n\n /** `format`: judged even after a structure violation (position 5 outranks 6). */\n private format(depth: number): void {\n this.begin();\n if (this.valueLimitHit || this.peek() !== QUOTE) {\n this.building = false;\n this.skipBody(depth);\n return;\n }\n const start = this.pos;\n this.skipString();\n if (this.pos - start <= FORMAT_MAX_RAW) {\n this.pos = start;\n const format = this.readString();\n if (format === BUNDLE_FORMAT_V1) {\n this.formatOk = true;\n this.formatVersion = 1;\n } else if (format === BUNDLE_FORMAT_V2) {\n this.formatOk = true;\n this.formatVersion = 2;\n }\n }\n if (!this.formatOk) this.building = false;\n }\n\n /** A string member or checkpoint text; undefined unless building. */\n private str(depth: number): string | undefined {\n this.begin();\n if (!this.checking) {\n this.skipBody(depth);\n return undefined;\n }\n if (this.peek() !== QUOTE) {\n this.wrongType(depth);\n return undefined;\n }\n if (!this.building) {\n this.skipString();\n return undefined;\n }\n return this.readString();\n }\n\n /** §4.1 `chains`. */\n private chains(depth: number): BundleChain[] | undefined {\n this.begin();\n if (!this.checking) {\n this.skipBody(depth);\n return undefined;\n }\n if (this.peek() !== LBRACKET) {\n this.wrongType(depth);\n return undefined;\n }\n let out: BundleChain[] | undefined = this.building ? [] : undefined;\n this.array(depth, (d) => {\n if (!this.checking) return this.any(d);\n if (++this.chainCount > this.limits.chains) this.overCount();\n const chain = this.chain(d);\n if (this.building && out !== undefined && chain !== undefined) out.push(chain);\n else out = undefined;\n });\n return this.building ? out : undefined;\n }\n\n private overCount(): void {\n this.countExceeded = true;\n this.building = false;\n }\n\n /** §4.2 a chain. */\n private chain(depth: number): BundleChain | undefined {\n this.begin();\n if (!this.checking) {\n this.skipBody(depth);\n return undefined;\n }\n if (this.peek() !== LBRACE) {\n this.wrongType(depth);\n return undefined;\n }\n let chainId: string | undefined;\n let entries: BundleEntry[] | undefined;\n let checkpoints: string[] | undefined;\n let seen = 0;\n this.object(depth, (name, d) => {\n if (!this.checking) return this.any(d);\n if (name === \"chain_id\") {\n seen |= 1;\n chainId = this.str(d);\n } else if (name === \"entries\") {\n seen |= 2;\n entries = this.entries(d);\n } else if (name === \"checkpoints\") {\n seen |= 4;\n checkpoints = this.checkpoints(d);\n } else {\n this.violate();\n this.any(d);\n }\n });\n if (this.checking && seen !== 7) this.violate();\n if (\n !this.building ||\n chainId === undefined ||\n entries === undefined ||\n checkpoints === undefined\n ) {\n return undefined;\n }\n return { chainId, entries, checkpoints };\n }\n\n /** §4.2 `entries`: not empty. */\n private entries(depth: number): BundleEntry[] | undefined {\n this.begin();\n if (!this.checking) {\n this.skipBody(depth);\n return undefined;\n }\n if (this.peek() !== LBRACKET) {\n this.wrongType(depth);\n return undefined;\n }\n let out: BundleEntry[] | undefined = this.building ? [] : undefined;\n const n = this.array(depth, (d) => {\n if (!this.checking) return this.any(d);\n if (++this.entryCount > this.limits.entries) this.overCount();\n const entry = this.entry(d);\n if (this.building && out !== undefined && entry !== undefined) out.push(entry);\n else out = undefined;\n });\n if (this.checking && n === 0) this.violate();\n return this.building ? out : undefined;\n }\n\n /** §4.2 `checkpoints`: strings. */\n private checkpoints(depth: number): string[] | undefined {\n this.begin();\n if (!this.checking) {\n this.skipBody(depth);\n return undefined;\n }\n if (this.peek() !== LBRACKET) {\n this.wrongType(depth);\n return undefined;\n }\n let out: string[] | undefined = this.building ? [] : undefined;\n this.array(depth, (d) => {\n if (!this.checking) return this.any(d);\n if (++this.checkpointCount > this.limits.checkpoints) this.overCount();\n const text = this.str(d);\n if (this.building && out !== undefined && text !== undefined) out.push(text);\n else out = undefined;\n });\n return this.building ? out : undefined;\n }\n\n /** §4.3 an entry. */\n private entry(depth: number): BundleEntry | undefined {\n this.begin();\n if (!this.checking) {\n this.skipBody(depth);\n return undefined;\n }\n if (this.peek() !== LBRACE) {\n this.wrongType(depth);\n return undefined;\n }\n const fields: (string | undefined)[] = [];\n let seen = 0;\n let recordSignature: BundleEntry[\"recordSignature\"];\n let disclosed: BundleEntry[\"disclosed\"];\n let salt: string | undefined;\n let leafHash: string | undefined;\n let v2Seen = 0;\n this.object(depth, (name, d) => {\n if (!this.checking) return this.any(d);\n const i = ENTRY_INDEX.get(name);\n if (i !== undefined) {\n seen |= 1 << i;\n fields[i] = this.str(d);\n } else if (name === \"salt\") {\n v2Seen |= 1;\n salt = this.str(d);\n } else if (name === \"leaf_hash\") {\n v2Seen |= 2;\n leafHash = this.str(d);\n } else if (name === \"record_signature\") {\n const p = this.pair(d, \"key_id\", \"signature\");\n if (p !== undefined) recordSignature = { keyId: p[0], signature: p[1] };\n } else if (name === \"disclosed\") {\n const p = this.pair(d, \"content\", \"nonce\");\n if (p !== undefined) disclosed = { content: p[0], nonce: p[1] };\n } else {\n this.violate();\n this.any(d);\n }\n });\n if (this.checking && seen !== ENTRY_ALL) this.violate();\n if (v2Seen !== 0) this.sawV2Member = true;\n if (v2Seen !== 3) this.missedV2Member = true;\n if (!this.building) return undefined;\n const [\n entryId,\n entryType,\n globalSeq,\n previousHash,\n timestamp,\n contentHash,\n chainHash,\n ] = fields as [string, string, string, string, string, string, string];\n return {\n entryId,\n entryType,\n globalSeq,\n previousHash,\n timestamp,\n contentHash,\n chainHash,\n ...(salt === undefined ? {} : { salt }),\n ...(leafHash === undefined ? {} : { leafHash }),\n recordSignature,\n disclosed,\n };\n }\n\n /** `record_signature` or `disclosed`: exactly its two string members (§4.3). */\n private pair(depth: number, a: string, b: string): [string, string] | undefined {\n this.begin();\n if (!this.checking) {\n this.skipBody(depth);\n return undefined;\n }\n if (this.peek() !== LBRACE) {\n this.wrongType(depth);\n return undefined;\n }\n let x: string | undefined;\n let y: string | undefined;\n let seen = 0;\n this.object(depth, (name, d) => {\n if (!this.checking) return this.any(d);\n if (name === a) {\n seen |= 1;\n x = this.str(d);\n } else if (name === b) {\n seen |= 2;\n y = this.str(d);\n } else {\n this.violate();\n this.any(d);\n }\n });\n if (this.checking && seen !== 3) this.violate();\n return this.building && x !== undefined && y !== undefined ? [x, y] : undefined;\n }\n}\n\n/**\n * Read a bundle under bundle-format §3–§5 and §9.1.\n *\n * # Description\n *\n * Scans the bundle once. Returns its chains when it is readable, or the\n * lowest-numbered §9.1 reason that applies (format `aleutian.proof.bundle.v1`\n * or `.v2`, §16): 1 too-large (size), 2 json,\n * 3 too-large (values), 4 duplicate-key, 5 format, 6 structure, 7 too-large\n * (counts). Every reason is determined over the whole input before one is\n * chosen.\n *\n * # Inputs\n *\n * - bytes: the bundle file's exact bytes\n * - limits: the §5 limits (tests may lower them)\n *\n * # Outputs\n *\n * - BundleReadOutcome: never throws on any input\n *\n * # Example\n *\n * const read = readProofBundle(bytes, PROOF_BUNDLE_LIMITS);\n * if (!read.ok) return read.reason;\n *\n * # Limitations\n *\n * - Holds the input and the built chains in memory; building stops as soon\n * as the outcome cannot be readable.\n *\n * # Assumptions\n *\n * - None.\n */\nexport function readProofBundle(\n bytes: Uint8Array,\n limits: ProofBundleLimits\n): BundleReadOutcome {\n if (bytes.length > limits.bundleBytes) return { ok: false, reason: \"too-large\" };\n const reader = new BundleReader(bytes, limits);\n const scanned = runStrict(() => reader.document());\n if (!scanned.ok) return { ok: false, reason: \"json\" };\n return reader.outcome(scanned.value);\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Salted commitments (format-spec §8).\n *\n * ```\n * commitment = SHA-512( \"aleutian.commit.v1:\" ‖ nonce ‖ SHA-512(content) )\n * ```\n *\n * The nonce is exactly 32 bytes; any other length is refused, never hashed.\n * The content is hashed first, so the outer input is always 115 bytes. The\n * result is 128 lowercase hex and compares exactly: an uppercase commitment\n * does not match.\n *\n * Vectors: `testdata/commitment_vectors.json` (computed independently, in\n * Python, from the spec). Browser-safe: WebCrypto only.\n */\n\nimport { sha512HexRaw } from \"./hash.js\";\n\n/** The commitment domain string (format-spec §8). */\nexport const COMMITMENT_DOMAIN = \"aleutian.commit.v1:\";\n\n/** The only nonce length a commitment accepts, in bytes. */\nexport const COMMITMENT_NONCE_SIZE = 32;\n\nconst DOMAIN_BYTES = new TextEncoder().encode(COMMITMENT_DOMAIN);\n\n/**\n * Compute a salted commitment.\n *\n * # Description\n *\n * Returns `hex(SHA-512(\"aleutian.commit.v1:\" ‖ nonce ‖ SHA-512(content)))`.\n *\n * # Inputs\n *\n * - nonce: exactly 32 bytes\n * - content: the committed bytes, any length\n *\n * # Outputs\n *\n * - string: 128 lowercase hex characters\n * - Error: thrown when the nonce is not exactly 32 bytes\n *\n * # Example\n *\n * const c = await computeCommitment(nonce, new TextEncoder().encode(\"consent: yes\"));\n *\n * # Limitations\n *\n * - Imposes no content size limit; a caller that has one enforces it.\n *\n * # Assumptions\n *\n * - WebCrypto (`crypto.subtle`) is available.\n */\nexport async function computeCommitment(\n nonce: Uint8Array,\n content: Uint8Array\n): Promise<string> {\n if (nonce.length !== COMMITMENT_NONCE_SIZE) {\n throw new Error(`a commitment nonce is exactly ${COMMITMENT_NONCE_SIZE} bytes`);\n }\n const inner = new Uint8Array(await crypto.subtle.digest(\"SHA-512\", content));\n const outer = new Uint8Array(DOMAIN_BYTES.length + nonce.length + inner.length);\n outer.set(DOMAIN_BYTES, 0);\n outer.set(nonce, DOMAIN_BYTES.length);\n outer.set(inner, DOMAIN_BYTES.length + nonce.length);\n return sha512HexRaw(outer);\n}\n\n/**\n * Check whether a nonce and content open a commitment.\n *\n * # Description\n *\n * True exactly when the nonce is 32 bytes and the recomputed commitment equals\n * `commitment` character for character. A nonce of any other length is a\n * refusal (false), not an error.\n *\n * # Inputs\n *\n * - nonce: the disclosed nonce\n * - content: the disclosed content\n * - commitment: the expected commitment (an entry's `content_hash`)\n *\n * # Outputs\n *\n * - boolean: whether the commitment opens\n *\n * # Example\n *\n * if (!(await openCommitment(nonce, content, entry.content_hash))) { ... }\n *\n * # Limitations\n *\n * - Not constant-time; commitments and disclosures are public values.\n *\n * # Assumptions\n *\n * - WebCrypto (`crypto.subtle`) is available.\n */\nexport async function openCommitment(\n nonce: Uint8Array,\n content: Uint8Array,\n commitment: string\n): Promise<boolean> {\n if (nonce.length !== COMMITMENT_NONCE_SIZE) return false;\n return (await computeCommitment(nonce, content)) === commitment;\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Synchronous SHA-512 hashes for the proof bundle verifier.\n *\n * The SDK's general primitives (`computeChainHashV3`, `computeAnchorChainHash`,\n * `openCommitment`) use WebCrypto, which is always async. The bundle verifier\n * hashes several times per entry over up to a million entries, and awaiting\n * WebCrypto each time dominates its run time. These are the same preimages,\n * hashed with `@noble/hashes`' synchronous SHA-512, and used only by the\n * bundle verifier. They take inputs already checked for shape (§7.1), so they\n * validate nothing; the domain strings are imported from the general\n * primitives so the two cannot drift.\n *\n * Browser-safe.\n */\n\nimport { sha512 } from \"@noble/hashes/sha2.js\";\nimport { bytesToHex, utf8ToBytes } from \"@noble/hashes/utils.js\";\n\nimport { ANCHOR_CHAIN_DOMAIN_V2 } from \"./anchorChainHash.js\";\nimport { CHAIN_HASH_PREFIX_V3 } from \"./chain.js\";\nimport { COMMITMENT_DOMAIN, COMMITMENT_NONCE_SIZE } from \"./commitment.js\";\n\nconst COMMITMENT_DOMAIN_BYTES = utf8ToBytes(COMMITMENT_DOMAIN);\n\n/**\n * SHA-512 of a string's UTF-8 bytes, as 128 lowercase hex.\n *\n * # Description\n *\n * Synchronous counterpart of `sha512Hex` (`hash.ts`).\n *\n * # Inputs\n *\n * - text: the string to hash (UTF-8 encoded)\n *\n * # Outputs\n *\n * - string: 128 lowercase hex characters\n *\n * # Example\n *\n * const h = sha512HexSync(\"aleutian.sink.erasure.v1:\" + record);\n *\n * # Limitations\n *\n * - Holds the whole input in memory.\n *\n * # Assumptions\n *\n * - None.\n */\nexport function sha512HexSync(text: string): string {\n return bytesToHex(sha512(utf8ToBytes(text)));\n}\n\n/**\n * The v3 chain hash (format-spec §2.1), synchronously.\n *\n * # Description\n *\n * `SHA-512(\"aleutian.chain.v3:\" ‖ previous ‖ \"|\" ‖ globalSeq ‖ \"|\" ‖ timestamp\n * ‖ \"|\" ‖ contentHash)`, the preimage `computeChainHashV3` hashes.\n *\n * # Inputs\n *\n * - previousHash: empty, or 128 lowercase hex\n * - globalSeq: the stored base-10 sequence (no sign or leading zeros)\n * - timestamp: `YYYY-MM-DDTHH:MM:SS.ffffffZ`\n * - contentHash: 128 lowercase hex\n *\n * # Outputs\n *\n * - string: 128 lowercase hex characters\n *\n * # Example\n *\n * if (chainHashV3Sync(e.previousHash, e.globalSeq, e.timestamp, e.contentHash) !== e.chainHash) ...\n *\n * # Limitations\n *\n * - Validates nothing: a malformed field would shift a \"|\" boundary.\n *\n * # Assumptions\n *\n * - Every field is already in its §4.3 shape (the caller checked §7.1).\n */\nexport function chainHashV3Sync(\n previousHash: string,\n globalSeq: string,\n timestamp: string,\n contentHash: string\n): string {\n return sha512HexSync(\n CHAIN_HASH_PREFIX_V3 +\n previousHash +\n \"|\" +\n globalSeq +\n \"|\" +\n timestamp +\n \"|\" +\n contentHash\n );\n}\n\n/**\n * The anchor-of-anchors chain hash, synchronously.\n *\n * # Description\n *\n * `SHA-512(\"aleutian.anchor.v2:\" ‖ previousAnchorHash ‖ \"|\" ‖ subject ‖ \"|\" ‖\n * startEntryId ‖ \"|\" ‖ endEntryId ‖ \"|\" ‖ tipChainHash)`, the preimage\n * `computeAnchorChainHash` hashes.\n *\n * # Inputs\n *\n * - previousAnchorHash: the previous checkpoint's chain hash, or the seed\n * - subject: the chain id\n * - startEntryId, endEntryId: the range\n * - tipChainHash: the chain hash of the range's last entry\n *\n * # Outputs\n *\n * - string: 128 lowercase hex characters\n *\n * # Example\n *\n * const h = anchorChainHashSync(SEED_ANCHOR_HASH, chainId, first, last, tip);\n *\n * # Limitations\n *\n * - Validates nothing.\n *\n * # Assumptions\n *\n * - The inputs hold no \"|\" (sink ids and hex never do).\n */\nexport function anchorChainHashSync(\n previousAnchorHash: string,\n subject: string,\n startEntryId: string,\n endEntryId: string,\n tipChainHash: string\n): string {\n return sha512HexSync(\n ANCHOR_CHAIN_DOMAIN_V2 +\n previousAnchorHash +\n \"|\" +\n subject +\n \"|\" +\n startEntryId +\n \"|\" +\n endEntryId +\n \"|\" +\n tipChainHash\n );\n}\n\n/**\n * Whether a nonce and content open a salted commitment (format-spec §8),\n * synchronously.\n *\n * # Description\n *\n * True exactly when the nonce is 32 bytes and\n * `hex(SHA-512(\"aleutian.commit.v1:\" ‖ nonce ‖ SHA-512(content)))` equals\n * `commitment`, as `openCommitment` decides.\n *\n * # Inputs\n *\n * - nonce: the disclosed nonce\n * - content: the disclosed content\n * - commitment: the entry's `content_hash`\n *\n * # Outputs\n *\n * - boolean: whether the commitment opens\n *\n * # Example\n *\n * if (!openCommitmentSync(nonce, content, e.contentHash)) problems.add(\"modified\", i);\n *\n * # Limitations\n *\n * - Not constant-time; commitments and disclosures are public values.\n *\n * # Assumptions\n *\n * - None.\n */\nexport function openCommitmentSync(\n nonce: Uint8Array,\n content: Uint8Array,\n commitment: string\n): boolean {\n if (nonce.length !== COMMITMENT_NONCE_SIZE) return false;\n const inner = sha512(content);\n const outer = new Uint8Array(\n COMMITMENT_DOMAIN_BYTES.length + nonce.length + inner.length\n );\n outer.set(COMMITMENT_DOMAIN_BYTES, 0);\n outer.set(nonce, COMMITMENT_DOMAIN_BYTES.length);\n outer.set(inner, COMMITMENT_DOMAIN_BYTES.length + nonce.length);\n return bytesToHex(sha512(outer)) === commitment;\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Value shapes of proof's sink format (sink-format §1, format-spec §2.1, §4).\n *\n * Shared by the record envelope (sink-format §9.1) and the bundle verifier\n * (bundle-format §4.3), which hold the same values to the same shapes.\n *\n * Every pattern is anchored at both ends. JavaScript's `$` (without the `m`\n * flag) matches only at the end of input, never before a trailing newline, and\n * `[0-9]` is ASCII only. Browser-safe.\n */\n\n/** A sink chain id: `<class>.<32 lowercase hex>` (sink-format §1). */\nexport const SINK_CHAIN_ID = /^[a-z0-9][a-z0-9_-]{0,30}\\.[0-9a-f]{32}$/;\n\n/** A sink entry id: `sink-` and 32 lowercase hex (sink-format §1). */\nexport const SINK_ENTRY_ID = /^sink-[0-9a-f]{32}$/;\n\n/** A SHA-512 digest as hex: exactly 128 lowercase hex characters. */\nexport const HEX_128 = /^[0-9a-f]{128}$/;\n\n/** A 32-byte value as hex (a nonce): exactly 64 lowercase hex characters. */\nexport const HEX_64 = /^[0-9a-f]{64}$/;\n\n/** A key id (format-spec §9.6): exactly 32 lowercase hex characters. */\nexport const HEX_32 = /^[0-9a-f]{32}$/;\n\nconst DECIMAL = /^(0|[1-9][0-9]*)$/;\nconst MAX_GLOBAL_SEQ = 2n ** 63n - 1n;\nconst TIMESTAMP =\n /^([0-9]{4})-([0-9]{2})-([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})\\.[0-9]{6}Z$/;\n\n/**\n * Whether a string is a `global_seq`: base-10, no sign, no leading zeros,\n * 0 ≤ n ≤ 2⁶³−1 (format-spec §2.1). Compared as a BigInt, never a Number.\n */\nexport function isGlobalSeq(s: string): boolean {\n if (!DECIMAL.test(s)) return false;\n // 2^63-1 has 19 digits: a longer string is out of range without parsing it.\n return s.length <= 19 && BigInt(s) <= MAX_GLOBAL_SEQ;\n}\n\nfunction daysInMonth(year: number, month: number): number {\n if (month === 2) {\n const leap = year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);\n return leap ? 29 : 28;\n }\n return month === 4 || month === 6 || month === 9 || month === 11 ? 30 : 31;\n}\n\n/**\n * Whether a string is a sink timestamp: exactly `YYYY-MM-DDTHH:MM:SS.ffffffZ`\n * (format-spec §4) AND a real UTC instant: year 0001–9999, a valid month and\n * day (leap years included), hour ≤ 23, minute ≤ 59, second ≤ 59\n * (bundle-format §4.3, sink-format §9.1).\n */\nexport function isSinkTimestamp(s: string): boolean {\n const m = TIMESTAMP.exec(s);\n if (!m) return false;\n const year = Number(m[1]);\n const month = Number(m[2]);\n const day = Number(m[3]);\n const hour = Number(m[4]);\n const minute = Number(m[5]);\n const second = Number(m[6]);\n if (year < 1 || month < 1 || month > 12) return false;\n if (day < 1 || day > daysInMonth(year, month)) return false;\n return hour <= 23 && minute <= 59 && second <= 59;\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * The record-signature envelopes `aleutian.proof.record.v1` and `.v2`\n * (sink-format §9.1), and their ML-DSA-65 signature checks.\n *\n * record.v2 (over a chain-format-v4 entry) adds field 0x09, the entry's leaf\n * hash, and is signed with the ML-DSA context `aleutian.proof.record.v2`;\n * record.v1 below uses the empty context.\n *\n * ```\n * envelope = \"aleutian.proof.record.v1\" 0x00\n * ‖ field(0x01, chain_id) ‖ field(0x02, entry_id)\n * ‖ field(0x03, entry_type) ‖ field(0x04, global_seq)\n * ‖ field(0x05, previous_hash) ‖ field(0x06, timestamp)\n * ‖ field(0x07, content_hash) ‖ field(0x08, signing_key_id)\n * field(tag, v) = tag (1 byte) ‖ uint32 big-endian length of v ‖ v\n * ```\n *\n * The signature is pure ML-DSA-65 with an EMPTY context: the domain is in the\n * message. `record.v1` is ML-DSA-65 only.\n *\n * Vectors: `testdata/record_v1_vectors.json`. Browser-safe.\n */\n\nimport { ml_dsa65 } from \"@noble/post-quantum/ml-dsa.js\";\n\nimport {\n HEX_128,\n HEX_32,\n isGlobalSeq,\n isSinkTimestamp,\n SINK_CHAIN_ID,\n SINK_ENTRY_ID,\n} from \"./sinkShapes.js\";\n\n/** The envelope's domain string; a 0x00 byte follows it. */\nexport const RECORD_ENVELOPE_DOMAIN = \"aleutian.proof.record.v1\";\n\n/** ML-DSA-65 public key size in bytes (FIPS 204). */\nconst MLDSA65_PUBLIC_KEY_SIZE = 1952;\n\n/** ML-DSA-65 signature size in bytes (FIPS 204). */\nconst MLDSA65_SIGNATURE_SIZE = 3309;\n\nconst EMPTY_CONTEXT = new Uint8Array(0);\n\n/** The eight values a record signature covers, as stored strings. */\nexport interface RecordEnvelopeFields {\n /** A sink chain id (sink-format §1). */\n readonly chainId: string;\n /** `sink-` and 32 lowercase hex. */\n readonly entryId: string;\n /** `sink.event` or `sink.erasure`. */\n readonly entryType: string;\n /** Base-10, no sign or leading zeros, 0 ≤ n ≤ 2⁶³−1. */\n readonly globalSeq: string;\n /** 128 lowercase hex; empty exactly when `globalSeq` is \"0\". */\n readonly previousHash: string;\n /** `YYYY-MM-DDTHH:MM:SS.ffffffZ`, a real instant, year 0001–9999. */\n readonly timestamp: string;\n /** 128 lowercase hex. */\n readonly contentHash: string;\n /** The signing key's id: 32 lowercase hex. */\n readonly signingKeyId: string;\n}\n\n/**\n * Whether every value is inside sink-format §9.1's table, so an envelope may\n * be built from it.\n */\nexport function isValidRecordEnvelopeFields(f: RecordEnvelopeFields): boolean {\n if (!SINK_CHAIN_ID.test(f.chainId)) return false;\n if (!SINK_ENTRY_ID.test(f.entryId)) return false;\n if (f.entryType !== \"sink.event\" && f.entryType !== \"sink.erasure\") return false;\n if (!isGlobalSeq(f.globalSeq)) return false;\n if (f.globalSeq === \"0\") {\n if (f.previousHash !== \"\") return false;\n } else if (!HEX_128.test(f.previousHash)) {\n return false;\n }\n if (!isSinkTimestamp(f.timestamp)) return false;\n if (!HEX_128.test(f.contentHash)) return false;\n return HEX_32.test(f.signingKeyId);\n}\n\n/**\n * Build the exact bytes a record signature covers.\n *\n * # Description\n *\n * Writes the domain, a 0x00 byte, then the eight tagged, length-prefixed\n * fields in order. Values are the stored strings, never re-formatted.\n *\n * # Inputs\n *\n * - fields: the eight envelope values\n *\n * # Outputs\n *\n * - Uint8Array: the envelope bytes\n * - Error: thrown, with a fixed message that quotes no value, when any value\n * is outside sink-format §9.1's table (no envelope may be built)\n *\n * # Example\n *\n * const envelope = buildRecordEnvelopeV1({ chainId, entryId, ... });\n *\n * # Limitations\n *\n * - Builds bytes only; {@link verifyRecordSignatureV1} checks a signature.\n *\n * # Assumptions\n *\n * - None: every value is validated here.\n */\nexport function buildRecordEnvelopeV1(fields: RecordEnvelopeFields): Uint8Array {\n if (!isValidRecordEnvelopeFields(fields)) {\n throw new Error(\"record envelope: a field is outside sink-format §9.1\");\n }\n return encodeEnvelope(RECORD_ENVELOPE_DOMAIN, [\n fields.chainId,\n fields.entryId,\n fields.entryType,\n fields.globalSeq,\n fields.previousHash,\n fields.timestamp,\n fields.contentHash,\n fields.signingKeyId,\n ]);\n}\n\n/** domain ‖ 0x00 ‖ field(1, v1) ‖ field(2, v2) ‖ … with field(t, v) = t ‖ u32be(len v) ‖ v. */\nfunction encodeEnvelope(domainText: string, fieldValues: readonly string[]): Uint8Array {\n const enc = new TextEncoder();\n const values = fieldValues.map((v) => enc.encode(v));\n const domain = enc.encode(domainText);\n\n let size = domain.length + 1;\n for (const v of values) size += 5 + v.length;\n const out = new Uint8Array(size);\n const view = new DataView(out.buffer);\n out.set(domain, 0);\n let at = domain.length;\n out[at++] = 0x00;\n values.forEach((v, i) => {\n out[at++] = i + 1;\n view.setUint32(at, v.length, false);\n at += 4;\n out.set(v, at);\n at += v.length;\n });\n return out;\n}\n\n/**\n * Verify a pure ML-DSA-65 signature with an EMPTY context.\n *\n * # Description\n *\n * FIPS 204 pure mode (not HashML-DSA), context of zero bytes, as proof signs\n * checkpoints (format-spec §9.5) and records (sink-format §9.1). A signature\n * made with a non-empty context, or with HashML-DSA, does not verify.\n *\n * # Inputs\n *\n * - publicKey: raw 1952-byte ML-DSA-65 public key\n * - message: the exact signed bytes\n * - signature: raw 3309-byte signature\n *\n * # Outputs\n *\n * - boolean: true only when the signature verifies. Never throws: a wrong\n * size or a library error is false.\n *\n * # Example\n *\n * if (!verifyMLDSA65Pure(pk, envelope, sig)) { ... }\n *\n * # Limitations\n *\n * - Does not resolve key ids; the caller matches the key to its id.\n *\n * # Assumptions\n *\n * - `@noble/post-quantum` 0.5: `verify(sig, msg, publicKey, { context })`\n * builds the pure-mode message `0x00 ‖ len(ctx) ‖ ctx ‖ msg`.\n */\nexport function verifyMLDSA65Pure(\n publicKey: Uint8Array,\n message: Uint8Array,\n signature: Uint8Array\n): boolean {\n return verifyMLDSA65PureWithContext(publicKey, message, signature, EMPTY_CONTEXT);\n}\n\n/**\n * Verify a pure ML-DSA-65 signature made with a given FIPS 204 context.\n *\n * # Description\n *\n * FIPS 204 pure mode (not HashML-DSA) with context `ctx` (0 to 255 bytes):\n * the signed message is `0x00 ‖ len(ctx) ‖ ctx ‖ message`. A signature made\n * with any other context, or none, does not verify. proof uses\n * `aleutian.proof.anchor.v7` for v7 anchors (format-spec §9.5) and\n * `aleutian.proof.record.v2` for record.v2 signatures (sink-format §9.1).\n *\n * # Inputs\n *\n * - publicKey: raw 1952-byte ML-DSA-65 public key\n * - message: the exact signed bytes\n * - signature: raw 3309-byte signature\n * - context: the context bytes (the caller chooses it from the declared\n * version, never from the signature)\n *\n * # Outputs\n *\n * - boolean: true only when the signature verifies. Never throws.\n *\n * # Example\n *\n * verifyMLDSA65PureWithContext(pk, envelope, sig, utf8(\"aleutian.proof.record.v2\"));\n *\n * # Limitations\n *\n * - Does not resolve key ids.\n *\n * # Assumptions\n *\n * - `@noble/post-quantum` 0.5's `{ context }` option.\n */\nexport function verifyMLDSA65PureWithContext(\n publicKey: Uint8Array,\n message: Uint8Array,\n signature: Uint8Array,\n context: Uint8Array\n): boolean {\n if (publicKey.length !== MLDSA65_PUBLIC_KEY_SIZE) return false;\n if (signature.length !== MLDSA65_SIGNATURE_SIZE) return false;\n if (!(context instanceof Uint8Array) || context.length > 255) return false;\n try {\n return ml_dsa65.verify(signature, message, publicKey, { context });\n } catch {\n return false;\n }\n}\n\n/**\n * Verify a record signature over the `record.v1` envelope of `fields`.\n *\n * # Description\n *\n * Builds the envelope from the stored values and verifies the signature (pure\n * ML-DSA-65, empty context). False when no envelope can be built.\n *\n * # Inputs\n *\n * - publicKey: raw 1952-byte ML-DSA-65 public key, whose key id the caller\n * has checked equals `fields.signingKeyId`\n * - fields: the eight envelope values\n * - signature: raw 3309-byte signature\n *\n * # Outputs\n *\n * - boolean: whether the signature verifies. Never throws.\n *\n * # Example\n *\n * const ok = verifyRecordSignatureV1(pk, fields, sig);\n *\n * # Limitations\n *\n * - Does not check that `publicKey` has id `fields.signingKeyId`.\n *\n * # Assumptions\n *\n * - The caller decided the key is trusted for records.\n */\nexport function verifyRecordSignatureV1(\n publicKey: Uint8Array,\n fields: RecordEnvelopeFields,\n signature: Uint8Array\n): boolean {\n if (!isValidRecordEnvelopeFields(fields)) return false;\n return verifyMLDSA65Pure(publicKey, buildRecordEnvelopeV1(fields), signature);\n}\n\n// =============================================================================\n// record.v2 (sink-format §9.1): a record signature over a chain-format-v4 entry\n// =============================================================================\n\n/** The record.v2 envelope's domain string; a 0x00 byte follows it. */\nexport const RECORD_ENVELOPE_DOMAIN_V2 = \"aleutian.proof.record.v2\";\n\n/**\n * The ML-DSA context a record.v2 signature is made with (sink-format §9.1).\n * record.v1 uses the empty context.\n */\nexport const RECORD_SIGNATURE_CONTEXT_V2 = \"aleutian.proof.record.v2\";\n\nconst CONTEXT_V2 = new TextEncoder().encode(RECORD_SIGNATURE_CONTEXT_V2);\n\n/** The nine values a record.v2 signature covers: record.v1's eight and the leaf hash. */\nexport interface RecordEnvelopeFieldsV2 extends RecordEnvelopeFields {\n /** The entry's leaf hash (format-spec §2.0): 128 lowercase hex. */\n readonly leafHash: string;\n}\n\n/** Whether every value is inside sink-format §9.1's table, leaf hash included. */\nexport function isValidRecordEnvelopeFieldsV2(f: RecordEnvelopeFieldsV2): boolean {\n return isValidRecordEnvelopeFields(f) && typeof f.leafHash === \"string\" && HEX_128.test(f.leafHash);\n}\n\n/**\n * Build the exact bytes a record.v2 signature covers (sink-format §9.1).\n *\n * # Description\n *\n * `\"aleutian.proof.record.v2\" 0x00`, then fields 0x01-0x08 as record.v1\n * (chain id, entry id, entry type, global seq, previous hash, timestamp,\n * content hash, signing key id), then 0x09 the leaf hash. Signing the leaf\n * hash binds the salt, which the content hash alone does not. Values are the\n * stored strings, never re-formatted.\n *\n * # Inputs\n *\n * - fields: the nine envelope values\n *\n * # Outputs\n *\n * - Uint8Array: the envelope bytes\n * - Error: thrown, with a fixed message, when a value is outside the table\n *\n * # Example\n *\n * const envelope = buildRecordEnvelopeV2({ ...fieldsV1, leafHash });\n *\n * # Limitations\n *\n * - Builds bytes only; {@link verifyRecordSignatureV2} checks a signature.\n *\n * # Assumptions\n *\n * - None: every value is validated here.\n */\nexport function buildRecordEnvelopeV2(fields: RecordEnvelopeFieldsV2): Uint8Array {\n if (!isValidRecordEnvelopeFieldsV2(fields)) {\n throw new Error(\"record envelope: a field is outside sink-format §9.1\");\n }\n return encodeEnvelope(RECORD_ENVELOPE_DOMAIN_V2, [\n fields.chainId,\n fields.entryId,\n fields.entryType,\n fields.globalSeq,\n fields.previousHash,\n fields.timestamp,\n fields.contentHash,\n fields.signingKeyId,\n fields.leafHash,\n ]);\n}\n\n/**\n * Verify a record signature over the record.v2 envelope of `fields`.\n *\n * # Description\n *\n * Builds the v2 envelope and verifies the signature as pure ML-DSA-65 with the\n * context `aleutian.proof.record.v2`. A record.v1 signature, or one made with\n * the empty or another context, does not verify. False when no envelope can\n * be built.\n *\n * # Inputs\n *\n * - publicKey: raw 1952-byte ML-DSA-65 public key, whose key id the caller\n * has checked equals `fields.signingKeyId`\n * - fields: the nine envelope values\n * - signature: raw 3309-byte signature\n *\n * # Outputs\n *\n * - boolean: whether the signature verifies. Never throws.\n *\n * # Example\n *\n * const ok = verifyRecordSignatureV2(pk, fields, sig);\n *\n * # Limitations\n *\n * - Does not check that `publicKey` has id `fields.signingKeyId`.\n *\n * # Assumptions\n *\n * - The caller decided the key is trusted for records.\n */\nexport function verifyRecordSignatureV2(\n publicKey: Uint8Array,\n fields: RecordEnvelopeFieldsV2,\n signature: Uint8Array\n): boolean {\n if (!isValidRecordEnvelopeFieldsV2(fields)) return false;\n return verifyMLDSA65PureWithContext(publicKey, buildRecordEnvelopeV2(fields), signature, CONTEXT_V2);\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Verifier for proof's sink export bundles, `aleutian.proof.bundle.v1` and\n * `aleutian.proof.bundle.v2`.\n *\n * Written from `proof/docs/bundle-format.md` (normative, revision 4: §1-§15 for\n * v1, §16's deltas for v2) and what it references (format-spec §2.0, §2.1, §3,\n * §4, §8, §9; sink-format §1, §2, §4.1, §9), independently of proof's code.\n * Section numbers below are bundle-format's unless stated otherwise.\n *\n * Dispatch is on the bundle's declared `format` only. v1: chain hash v3, v6\n * checkpoints, record.v1 (empty ML-DSA context). v2: chain format v4 (leaf\n * hash, then chain hash), v7 checkpoints (context `aleutian.proof.anchor.v7`),\n * record.v2 (context `aleutian.proof.record.v2`). Both give the same result.\n *\n * Trust is the verifier's (§6): the caller supplies checkpoint keys and record\n * keys; a bundle never adds a key. The result is §9's, a closed set that every\n * implementation produces identically.\n *\n * NO-LEAK RULE (§10): nothing here puts a bundle value into an error message.\n * The parser reports no positions and no input; every error this module throws\n * has a fixed message.\n *\n * The bundle is read in one streaming pass (`proofBundleReader.ts`), so memory\n * on hostile input stays bounded by the largest readable bundle (§5's value\n * limit). Hashing is synchronous (`proofBundleHashes.ts`).\n *\n * Browser-safe: WebCrypto, `@noble/hashes` and `@noble/post-quantum` only, no\n * Node APIs, and no embedded key fixtures (`keys.ts` is not imported).\n */\n\nimport {\n ANCHOR_SIGNATURE_CONTEXT_V7,\n canonicalizeAnchorV6,\n canonicalizeAnchorV7,\n} from \"./anchorCanonical.js\";\nimport {\n anchorChainHashV7Sync,\n SEED_ANCHOR_HASH,\n SEED_ANCHOR_ID,\n} from \"./anchorChainHash.js\";\nimport { chainHashV4Sync, leafHashV4Sync } from \"./chainV4.js\";\nimport { decodeCanonicalBase64 } from \"./canonicalBase64.js\";\nimport { hexToUint8Array } from \"./hash.js\";\nimport { keyIdMLDSA65, MLDSA65_PUBLIC_KEY_SIZE } from \"./keyId.js\";\nimport {\n BUNDLE_FORMAT_V1,\n BUNDLE_FORMAT_V2,\n BUNDLE_MAX_DEPTH,\n readProofBundle,\n type BundleChain,\n type BundleEntry,\n type BundleFormatVersion,\n} from \"./proofBundleReader.js\";\nimport {\n anchorChainHashSync,\n chainHashV3Sync,\n openCommitmentSync,\n sha512HexSync,\n} from \"./proofBundleHashes.js\";\nimport {\n buildRecordEnvelopeV1,\n buildRecordEnvelopeV2,\n RECORD_SIGNATURE_CONTEXT_V2,\n verifyMLDSA65Pure,\n verifyMLDSA65PureWithContext,\n} from \"./recordEnvelope.js\";\nimport {\n HEX_128,\n HEX_32,\n HEX_64,\n isGlobalSeq,\n isSinkTimestamp,\n SINK_CHAIN_ID,\n SINK_ENTRY_ID,\n} from \"./sinkShapes.js\";\nimport { JsonNumber, JsonObject, parseStrictJson, type JsonValue } from \"./strictJson.js\";\n\n// =============================================================================\n// Result types (§9)\n// =============================================================================\n\n/** The result id. A consumer MUST refuse any other (§9.4). */\nexport const PROOF_BUNDLE_RESULT_ID = \"aleutian.proof.bundle-result.v1\";\n\n/** The v1 bundle format string (§4.1). */\nexport const PROOF_BUNDLE_FORMAT = BUNDLE_FORMAT_V1;\n\n/**\n * The v2 bundle format string (§16): chain format v4 entries, v7 checkpoints,\n * record.v2 signatures. Verified with the same result as v1.\n */\nexport const PROOF_BUNDLE_FORMAT_V2 = BUNDLE_FORMAT_V2;\n\n/**\n * Why a bundle is unreadable (§9.1). Precedence: too-large (size), json,\n * too-large (values), duplicate-key, format, structure, too-large (counts).\n */\nexport type ProofBundleUnreadableReason =\n | \"too-large\"\n | \"json\"\n | \"duplicate-key\"\n | \"format\"\n | \"structure\";\n\n/** A verdict (§1). */\nexport type ProofBundleVerdict = \"ok\" | \"unauthenticated\" | \"failed\";\n\n/** Whether a trust dimension was checked (§6). */\nexport type ProofBundleTrustState = \"checked\" | \"not_checked\";\n\n/** A chain's erasure state (§7.9). */\nexport type ProofBundleErasureState = \"none\" | \"recorded\" | \"anchored\" | \"signed\";\n\n/** The complete v1 list of problem codes (§12). */\nexport type ProofBundleProblemCode =\n | \"duplicate-chain\"\n | \"invalid-chain-id\"\n | \"field-shape\"\n | \"duplicate-entry-id\"\n | \"first-entry\"\n | \"sequence\"\n | \"link\"\n | \"chain-hash\"\n | \"entry-type\"\n | \"erasure-invalid\"\n | \"after-erasure\"\n | \"erased-event-disclosed\"\n | \"modified\"\n | \"checkpoint-malformed\"\n | \"checkpoint-subject\"\n | \"checkpoint-sequence\"\n | \"checkpoint-overreach\"\n | \"checkpoint-binding\"\n | \"checkpoint-unknown-key\"\n | \"checkpoint-bad-signature\"\n | \"unsigned\"\n | \"malformed-signature\"\n | \"unknown-key\"\n | \"bad-signature\";\n\n/** One problem code with its count and lowest index (§9.2). */\nexport interface ProofBundleProblem {\n readonly code: ProofBundleProblemCode;\n readonly count: number;\n /** The lowest index; null only for `invalid-chain-id`. */\n readonly first: number | null;\n}\n\n/** A chain's counts (§9.2). Every count is always present. */\nexport interface ProofBundleChainCounts {\n readonly entries: number;\n readonly events: number;\n readonly erasures: number;\n readonly opened: number;\n readonly committed: number;\n readonly erased: number;\n readonly checkpoints: number;\n readonly unanchored: number;\n readonly authenticated: number;\n readonly unauthenticated: number;\n readonly checkpoint_authenticated: number;\n readonly record_authenticated: number;\n readonly record_signatures_present: number;\n}\n\n/** One chain's result (§9.2). */\nexport interface ProofBundleChainResult {\n readonly verdict: ProofBundleVerdict;\n readonly erasure: ProofBundleErasureState;\n readonly counts: ProofBundleChainCounts;\n /** Sorted by `code` in byte order. */\n readonly problems: ProofBundleProblem[];\n}\n\n/** An unreadable bundle (§9.1). */\nexport interface ProofBundleUnreadableResult {\n readonly result: typeof PROOF_BUNDLE_RESULT_ID;\n readonly readable: false;\n readonly reason: ProofBundleUnreadableReason;\n}\n\n/** A readable bundle (§9.2). */\nexport interface ProofBundleReadableResult {\n readonly result: typeof PROOF_BUNDLE_RESULT_ID;\n readonly readable: true;\n readonly checkpoint_trust: ProofBundleTrustState;\n readonly record_trust: ProofBundleTrustState;\n readonly verdict: ProofBundleVerdict;\n /** Sorted by `code` in byte order. */\n readonly bundle_problems: ProofBundleProblem[];\n /** Keyed by chain id, or `#<i>` for an invalid or duplicated id (§9.3). */\n readonly chains: Record<string, ProofBundleChainResult>;\n}\n\n/** The §9 result. */\nexport type ProofBundleResult = ProofBundleUnreadableResult | ProofBundleReadableResult;\n\n/** The verifier's trust (§6): raw 1952-byte ML-DSA-65 public keys. */\nexport interface ProofBundleTrust {\n /** Keys trusted for checkpoints. Empty: the dimension is not checked. */\n readonly checkpointKeys: readonly Uint8Array[];\n /** Keys trusted for record signatures. Empty: the dimension is not checked. */\n readonly recordKeys: readonly Uint8Array[];\n}\n\n/** The §5 limits. */\nexport interface ProofBundleLimits {\n readonly bundleBytes: number;\n /** JSON values in a v1 bundle, at every depth, the top-level value included. */\n readonly values: number;\n /**\n * JSON values in a v2 bundle (§16 §5: 17,000,000). When absent, `values`\n * applies to both formats.\n */\n readonly valuesV2?: number;\n readonly chains: number;\n readonly entries: number;\n readonly checkpoints: number;\n readonly checkpointTextBytes: number;\n}\n\n/** The normative limits (§5). Every implementation MUST accept a bundle within them. */\nexport const PROOF_BUNDLE_LIMITS: ProofBundleLimits = Object.freeze({\n bundleBytes: 256 * 1024 * 1024,\n values: 15_000_000,\n valuesV2: 17_000_000,\n chains: 100_000,\n entries: 1_000_000,\n checkpoints: 100_000,\n checkpointTextBytes: 1024 * 1024,\n});\n\n/** Nesting depth limit (§3, §5). */\nconst MAX_DEPTH = BUNDLE_MAX_DEPTH;\n\n/** Thrown only for a caller error (bad trust keys) or a bug; never names a bundle value. */\nexport class ProofBundleVerifierError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ProofBundleVerifierError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\n// =============================================================================\n// Checkpoint text (§4.4)\n// =============================================================================\n\ninterface Checkpoint {\n readonly anchorId: string;\n readonly chainHash: string;\n readonly createdAtMs: bigint;\n readonly entryCount: number;\n readonly previousAnchorId: string;\n readonly startEntryId: string;\n readonly endEntryId: string;\n readonly signature: Uint8Array;\n readonly signingKeyId: string;\n readonly subject: string;\n readonly verifiedThrough: bigint;\n}\n\n/** Whether an object has exactly the required members. */\nfunction hasExactMembers(obj: JsonObject, required: readonly string[]): boolean {\n if (obj.members.size !== required.length) return false;\n for (const name of required) if (!obj.members.has(name)) return false;\n return true;\n}\n\n/** A member that must be a string; undefined when it is not. */\nfunction str(obj: JsonObject, name: string): string | undefined {\n const v = obj.members.get(name);\n return typeof v === \"string\" ? v : undefined;\n}\n\n/** A two-string object (`range`), or null on any violation. */\nfunction stringPair(\n v: JsonValue | undefined,\n a: string,\n b: string\n): [string, string] | null {\n if (!(v instanceof JsonObject) || !hasExactMembers(v, [a, b])) return null;\n const x = str(v, a);\n const y = str(v, b);\n return x === undefined || y === undefined ? null : [x, y];\n}\n\nconst CHECKPOINT_MEMBERS = [\n \"version\",\n \"anchor_id\",\n \"chain_hash\",\n \"created_at_ms\",\n \"entry_count\",\n \"previous_anchor_id\",\n \"range\",\n \"signature\",\n \"signing_key_id\",\n \"subject\",\n \"verified_through\",\n] as const;\nconst CHECKPOINT_NUMBER = /^(0|[1-9][0-9]*)$/;\nconst MAX_SAFE = BigInt(Number.MAX_SAFE_INTEGER);\nconst MLDSA65_SIGNATURE_SIZE = 3309;\n\n/** A checkpoint number (§3): `0|[1-9][0-9]*`, at most 2⁵³−1; null otherwise. */\nfunction checkpointNumber(v: JsonValue | undefined): bigint | null {\n if (!(v instanceof JsonNumber) || !CHECKPOINT_NUMBER.test(v.text)) return null;\n const n = BigInt(v.text);\n return n <= MAX_SAFE ? n : null;\n}\n\n/** A non-empty string without `|` (anchor ids, subject). */\nfunction pipeFree(s: string | undefined): s is string {\n return s !== undefined && s !== \"\" && !s.includes(\"|\");\n}\n\n/** Step a of §7.6: the text satisfies §3 and §4.4, or null. */\nfunction parseCheckpoint(text: string, limits: ProofBundleLimits): Checkpoint | null {\n // The text came out of the strict parser, so it holds no lone surrogate and\n // encodes to UTF-8 exactly.\n const bytes = new TextEncoder().encode(text);\n if (bytes.length > limits.checkpointTextBytes) return null;\n const parsed = parseStrictJson(bytes, MAX_DEPTH);\n if (!parsed.ok || parsed.duplicateKey) return null;\n const obj = parsed.value;\n if (!(obj instanceof JsonObject) || !hasExactMembers(obj, CHECKPOINT_MEMBERS))\n return null;\n\n const version = checkpointNumber(obj.members.get(\"version\"));\n const createdAtMs = checkpointNumber(obj.members.get(\"created_at_ms\"));\n const entryCount = checkpointNumber(obj.members.get(\"entry_count\"));\n const verifiedThrough = checkpointNumber(obj.members.get(\"verified_through\"));\n if (version !== 6n || createdAtMs === null) return null;\n if (entryCount === null || entryCount < 1n) return null;\n if (verifiedThrough === null || verifiedThrough < 1n) return null;\n\n const anchorId = str(obj, \"anchor_id\");\n const previousAnchorId = str(obj, \"previous_anchor_id\");\n const subject = str(obj, \"subject\");\n if (!pipeFree(anchorId) || !pipeFree(previousAnchorId) || !pipeFree(subject))\n return null;\n\n const chainHash = str(obj, \"chain_hash\");\n const signingKeyId = str(obj, \"signing_key_id\");\n if (chainHash === undefined || !HEX_128.test(chainHash)) return null;\n if (signingKeyId === undefined || !HEX_32.test(signingKeyId)) return null;\n\n const signatureText = str(obj, \"signature\");\n const signature =\n signatureText === undefined ? null : decodeCanonicalBase64(signatureText);\n if (signature === null || signature.length !== MLDSA65_SIGNATURE_SIZE) return null;\n\n const range = stringPair(obj.members.get(\"range\"), \"start_entry_id\", \"end_entry_id\");\n if (range === null || !SINK_ENTRY_ID.test(range[0]) || !SINK_ENTRY_ID.test(range[1]))\n return null;\n\n return {\n anchorId,\n chainHash,\n createdAtMs,\n entryCount: Number(entryCount),\n previousAnchorId,\n startEntryId: range[0],\n endEntryId: range[1],\n signature,\n signingKeyId,\n subject,\n verifiedThrough,\n };\n}\n\n/** The v6 canonical bytes a checkpoint signature covers (format-spec §9.2). */\nfunction checkpointCanonicalBytes(cp: Checkpoint): Uint8Array {\n const canonical = canonicalizeAnchorV6({\n version: 6,\n anchorId: cp.anchorId,\n subject: cp.subject,\n chainHash: cp.chainHash,\n range: { startEntryId: cp.startEntryId, endEntryId: cp.endEntryId },\n entryCount: BigInt(cp.entryCount),\n signature: \"\",\n signingKeyId: cp.signingKeyId,\n createdAtMs: cp.createdAtMs,\n previousAnchorId: cp.previousAnchorId,\n verifiedThrough: cp.verifiedThrough,\n });\n return new TextEncoder().encode(canonical);\n}\n\n// =============================================================================\n// v2 checkpoint text (§16 §4.4): a v7 anchor\n// =============================================================================\n\ninterface CheckpointV7 {\n readonly anchorId: string;\n readonly chainHash: string;\n readonly createdAtMs: bigint;\n readonly entryCount: bigint;\n readonly endSeq: string;\n readonly previousAnchorHash: string;\n readonly previousAnchorId: string;\n readonly signature: Uint8Array;\n readonly signingKeyId: string;\n readonly subject: string;\n}\n\nconst CHECKPOINT_V7_MEMBERS = [\n \"version\",\n \"anchor_id\",\n \"chain_hash\",\n \"created_at_ms\",\n \"entry_count\",\n \"previous_anchor_hash\",\n \"previous_anchor_id\",\n \"range\",\n \"signature\",\n \"signing_key_id\",\n \"subject\",\n] as const;\n\nconst ANCHOR_CONTEXT_V7 = new TextEncoder().encode(ANCHOR_SIGNATURE_CONTEXT_V7);\nconst RECORD_CONTEXT_V2 = new TextEncoder().encode(RECORD_SIGNATURE_CONTEXT_V2);\n\n/** Step a of §7.6 for v2: the text satisfies §3 and §16 §4.4, or null. */\nfunction parseCheckpointV7(text: string, limits: ProofBundleLimits): CheckpointV7 | null {\n const bytes = new TextEncoder().encode(text);\n if (bytes.length > limits.checkpointTextBytes) return null;\n const parsed = parseStrictJson(bytes, MAX_DEPTH);\n if (!parsed.ok || parsed.duplicateKey) return null;\n const obj = parsed.value;\n if (!(obj instanceof JsonObject) || !hasExactMembers(obj, CHECKPOINT_V7_MEMBERS))\n return null;\n\n // Numbers in v7 checkpoint text are only version and created_at_ms (§16 §3).\n const version = checkpointNumber(obj.members.get(\"version\"));\n const createdAtMs = checkpointNumber(obj.members.get(\"created_at_ms\"));\n if (version !== 7n || createdAtMs === null) return null;\n\n // entry_count and the range are decimal STRINGS (format-spec §2.1's grammar),\n // compared as integers.\n const entryCountText = str(obj, \"entry_count\");\n if (entryCountText === undefined || !isGlobalSeq(entryCountText)) return null;\n const entryCount = BigInt(entryCountText);\n if (entryCount < 1n) return null;\n const range = stringPair(obj.members.get(\"range\"), \"start_seq\", \"end_seq\");\n if (range === null || !isGlobalSeq(range[0]) || !isGlobalSeq(range[1])) return null;\n if (range[0] !== \"0\" || entryCount !== BigInt(range[1]) + 1n) return null;\n\n const anchorId = str(obj, \"anchor_id\");\n const previousAnchorId = str(obj, \"previous_anchor_id\");\n const subject = str(obj, \"subject\");\n if (!pipeFree(anchorId) || !pipeFree(previousAnchorId) || !pipeFree(subject))\n return null;\n\n const chainHash = str(obj, \"chain_hash\");\n const previousAnchorHash = str(obj, \"previous_anchor_hash\");\n const signingKeyId = str(obj, \"signing_key_id\");\n if (chainHash === undefined || !HEX_128.test(chainHash)) return null;\n if (previousAnchorHash === undefined || !HEX_128.test(previousAnchorHash)) return null;\n if (signingKeyId === undefined || !HEX_32.test(signingKeyId)) return null;\n // format-spec §9.3: the seed id exactly when the seed hash.\n if ((previousAnchorId === SEED_ANCHOR_ID) !== (previousAnchorHash === SEED_ANCHOR_HASH))\n return null;\n\n const signatureText = str(obj, \"signature\");\n const signature =\n signatureText === undefined ? null : decodeCanonicalBase64(signatureText);\n if (signature === null || signature.length !== MLDSA65_SIGNATURE_SIZE) return null;\n\n return {\n anchorId,\n chainHash,\n createdAtMs,\n entryCount,\n endSeq: range[1],\n previousAnchorHash,\n previousAnchorId,\n signature,\n signingKeyId,\n subject,\n };\n}\n\n/** The v7 canonical bytes a v2 checkpoint signature covers (format-spec §9.2). */\nfunction checkpointCanonicalBytesV7(cp: CheckpointV7): Uint8Array {\n const canonical = canonicalizeAnchorV7({\n version: 7,\n anchorId: cp.anchorId,\n subject: cp.subject,\n chainHash: cp.chainHash,\n range: { startEntryId: \"\", endEntryId: \"\", startSeq: 0n, endSeq: BigInt(cp.endSeq) },\n entryCount: cp.entryCount,\n signature: \"\",\n signingKeyId: cp.signingKeyId,\n createdAtMs: cp.createdAtMs,\n previousAnchorId: cp.previousAnchorId,\n previousAnchorHash: cp.previousAnchorHash,\n });\n return new TextEncoder().encode(canonical);\n}\n\n// =============================================================================\n// Chain checks (§7)\n// =============================================================================\n\n/** Problem codes with counts and lowest indexes. */\nclass ProblemSet {\n private readonly byCode = new Map<\n ProofBundleProblemCode,\n { count: number; first: number | null }\n >();\n\n add(code: ProofBundleProblemCode, index: number | null): void {\n const p = this.byCode.get(code);\n if (p === undefined) {\n this.byCode.set(code, { count: 1, first: index });\n } else {\n p.count++;\n if (index !== null && (p.first === null || index < p.first)) p.first = index;\n }\n }\n\n get empty(): boolean {\n return this.byCode.size === 0;\n }\n\n /** Sorted by code in byte order (codes are ASCII, so UTF-16 order is byte order). */\n list(): ProofBundleProblem[] {\n return [...this.byCode.entries()]\n .sort(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))\n .map(([code, p]) => ({ code, count: p.count, first: p.first }));\n }\n}\n\nconst ERASURE_DOMAIN = \"aleutian.sink.erasure.v1:\";\n\n/** EH (§7.3): the erasure hash for the position after an entry of `globalSeq`. */\nfunction erasureHash(previousGlobalSeq: string): string {\n // sink-format §4.1: the record, built (never parsed) from the stored string.\n const record =\n '{\"erased\":\"every earlier event on this chain\",\"through_global_seq\":\"' +\n previousGlobalSeq +\n '\"}';\n return sha512HexSync(ERASURE_DOMAIN + record);\n}\n\n/** §4.3's `disclosed` shape: canonical base64 of 1–65,536 bytes, and a 64-hex nonce. */\nfunction disclosedInShape(d: NonNullable<BundleEntry[\"disclosed\"]>): boolean {\n if (!HEX_64.test(d.nonce)) return false;\n // 65,536 bytes is 87,384 base64 characters; refuse longer text unread.\n if (d.content.length > 87_384) return false;\n const content = decodeCanonicalBase64(d.content);\n return content !== null && content.length >= 1 && content.length <= 65_536;\n}\n\n/**\n * The well-formedness of §7.1.3: the six hashed members in shape, and in v2\n * (§16 §4.3) `salt` and `leaf_hash` too.\n */\nfunction isWellFormed(e: BundleEntry, format: BundleFormatVersion): boolean {\n if (format === 2 && !(HEX_64.test(e.salt ?? \"\") && HEX_128.test(e.leafHash ?? \"\"))) {\n return false;\n }\n return (\n SINK_ENTRY_ID.test(e.entryId) &&\n isGlobalSeq(e.globalSeq) &&\n (e.previousHash === \"\" || HEX_128.test(e.previousHash)) &&\n isSinkTimestamp(e.timestamp) &&\n HEX_128.test(e.contentHash) &&\n HEX_128.test(e.chainHash)\n );\n}\n\ninterface TrustKeys {\n readonly checkpoint: ReadonlyMap<string, Uint8Array>;\n readonly record: ReadonlyMap<string, Uint8Array>;\n}\n\n/**\n * §7.2 step 3: whether a well-formed entry's hashes recompute. v1: chain hash\n * v3. v2 (§16 §7.2): the leaf hash v4 over the stored id, type, content hash\n * and salt, then chain hash v4 over the stored leaf hash.\n */\nfunction hashesRecompute(e: BundleEntry, format: BundleFormatVersion): boolean {\n if (format === 1) {\n return chainHashV3Sync(e.previousHash, e.globalSeq, e.timestamp, e.contentHash) === e.chainHash;\n }\n const leafHash = e.leafHash!;\n if (leafHashV4Sync(e.entryId, e.entryType, e.contentHash, e.salt!) !== leafHash) return false;\n return chainHashV4Sync(e.previousHash, e.globalSeq, e.timestamp, leafHash) === e.chainHash;\n}\n\n/** One step of §7.6 failed: its problem code. */\ntype CheckpointStep =\n | \"checkpoint-malformed\"\n | \"checkpoint-subject\"\n | \"checkpoint-sequence\"\n | \"checkpoint-overreach\"\n | \"checkpoint-binding\"\n | \"checkpoint-unknown-key\"\n | \"checkpoint-bad-signature\";\n\n/** The state the next checkpoint of a series is judged against (§7.6). */\ninterface SeriesHead {\n readonly anchorId: string;\n readonly anchorHash: string;\n readonly count: bigint;\n}\n\n/** §16 §7.6: one v7 checkpoint's first failing step, or the head it establishes. */\nfunction checkCheckpointV7(\n text: string,\n head: SeriesHead,\n ctx: {\n readonly chainId: string;\n readonly chainIdValid: boolean;\n readonly entries: readonly BundleEntry[];\n readonly firstMalformed: number;\n readonly trust: TrustKeys;\n readonly limits: ProofBundleLimits;\n }\n): CheckpointStep | SeriesHead {\n const n = BigInt(ctx.entries.length);\n const cp = parseCheckpointV7(text, ctx.limits);\n if (cp === null) return \"checkpoint-malformed\"; // a\n if (!ctx.chainIdValid || cp.subject !== ctx.chainId) return \"checkpoint-subject\"; // b\n if (\n cp.previousAnchorId !== head.anchorId ||\n cp.previousAnchorHash !== head.anchorHash ||\n cp.entryCount <= head.count\n ) {\n return \"checkpoint-sequence\"; // c\n }\n if (cp.entryCount > n) return \"checkpoint-overreach\"; // d\n // e: entries 0 … entry_count−1 all well-formed, and the v7 anchor chain hash\n // over previous_anchor_hash, the chain id, \"0\", end_seq, and the stored chain\n // hash of entry end_seq (= entry_count − 1: §7.5 covers by index).\n if (cp.entryCount > BigInt(ctx.firstMalformed)) return \"checkpoint-binding\";\n const tip = ctx.entries[Number(cp.entryCount) - 1]!;\n const expected = anchorChainHashV7Sync(\n cp.previousAnchorHash,\n ctx.chainId,\n \"0\",\n cp.endSeq,\n tip.chainHash\n );\n if (cp.chainHash !== expected) return \"checkpoint-binding\";\n if (ctx.trust.checkpoint.size > 0) {\n const key = ctx.trust.checkpoint.get(cp.signingKeyId);\n if (key === undefined) return \"checkpoint-unknown-key\"; // f\n // g: pure ML-DSA-65, context aleutian.proof.anchor.v7, v7 canonical bytes.\n if (\n !verifyMLDSA65PureWithContext(\n key,\n checkpointCanonicalBytesV7(cp),\n cp.signature,\n ANCHOR_CONTEXT_V7\n )\n ) {\n return \"checkpoint-bad-signature\";\n }\n }\n return { anchorId: cp.anchorId, anchorHash: cp.chainHash, count: cp.entryCount };\n}\n\nfunction verifyChain(\n chain: BundleChain,\n trust: TrustKeys,\n limits: ProofBundleLimits,\n format: BundleFormatVersion\n): ProofBundleChainResult {\n const { chainId, entries } = chain;\n const n = entries.length;\n const problems = new ProblemSet();\n const checkpointTrust = trust.checkpoint.size > 0;\n const recordTrust = trust.record.size > 0;\n\n // §7.1 Shape.\n const chainIdValid = SINK_CHAIN_ID.test(chainId);\n if (!chainIdValid) problems.add(\"invalid-chain-id\", null);\n\n const wellFormed: boolean[] = [];\n const disclosedBad: boolean[] = [];\n const seenIds = new Set<string>();\n for (let i = 0; i < n; i++) {\n const e = entries[i]!;\n const wf = isWellFormed(e, format);\n const dBad =\n e.disclosed !== undefined &&\n (e.entryType !== \"sink.event\" || !disclosedInShape(e.disclosed));\n wellFormed.push(wf);\n disclosedBad.push(dBad);\n if (!wf || dBad) problems.add(\"field-shape\", i);\n if (seenIds.has(e.entryId)) problems.add(\"duplicate-entry-id\", i);\n if (wf) seenIds.add(e.entryId);\n }\n\n // §7.2 Links, and §7.3 erasure positions.\n const holdsErasureHash: boolean[] = new Array<boolean>(n).fill(false);\n let lastErasure = -1;\n for (let i = 0; i < n; i++) {\n if (!wellFormed[i]) continue;\n const e = entries[i]!;\n if (i === 0) {\n if (e.globalSeq !== \"0\" || e.previousHash !== \"\") problems.add(\"first-entry\", i);\n } else if (wellFormed[i - 1]) {\n const prev = entries[i - 1]!;\n if (BigInt(e.globalSeq) !== BigInt(prev.globalSeq) + 1n)\n problems.add(\"sequence\", i);\n if (e.previousHash !== prev.chainHash) problems.add(\"link\", i);\n if (e.contentHash === erasureHash(prev.globalSeq)) {\n holdsErasureHash[i] = true;\n lastErasure = i;\n }\n }\n if (!hashesRecompute(e, format)) problems.add(\"chain-hash\", i);\n }\n\n // §7.4 Entries.\n const E = lastErasure;\n let events = 0;\n let erasures = 0;\n let opened = 0;\n let committed = 0;\n let erased = 0;\n const genuineErasure: boolean[] = new Array<boolean>(n).fill(false);\n for (let i = 0; i < n; i++) {\n const e = entries[i]!;\n if (e.entryType === \"sink.event\") events++;\n if (!wellFormed[i]) continue;\n if (E >= 0 && i > E) {\n problems.add(\"after-erasure\", i);\n continue;\n }\n if (disclosedBad[i]) continue; // its field-shape is its outcome (§7.1.3)\n if (holdsErasureHash[i]) {\n if (e.entryType === \"sink.erasure\") {\n genuineErasure[i] = true;\n erasures++;\n } else {\n problems.add(\"erasure-invalid\", i);\n }\n } else if (e.entryType === \"sink.erasure\") {\n problems.add(\"erasure-invalid\", i);\n } else if (e.entryType === \"sink.event\") {\n if (i < E) {\n if (e.disclosed === undefined) erased++;\n else problems.add(\"erased-event-disclosed\", i);\n } else if (e.disclosed === undefined) {\n committed++;\n } else {\n const nonce = hexToUint8Array(e.disclosed.nonce);\n const content = decodeCanonicalBase64(e.disclosed.content)!;\n if (openCommitmentSync(nonce, content, e.contentHash)) opened++;\n else problems.add(\"modified\", i);\n }\n } else {\n problems.add(\"entry-type\", i);\n }\n }\n\n // §7.6 Checkpoints. The first failing step ends the series. Step e needs\n // entries 0..count-1 well-formed: count <= the first malformed index.\n const malformedAt = wellFormed.indexOf(false);\n const firstMalformed = malformedAt === -1 ? n : malformedAt;\n let passedCheckpoints = 0;\n let covered = 0;\n let prevAnchorId = SEED_ANCHOR_ID;\n let prevAnchorHash = SEED_ANCHOR_HASH;\n let prevCount = 0;\n if (format === 2) {\n let head: SeriesHead = { anchorId: SEED_ANCHOR_ID, anchorHash: SEED_ANCHOR_HASH, count: 0n };\n for (let k = 0; k < chain.checkpoints.length; k++) {\n const step = checkCheckpointV7(chain.checkpoints[k]!, head, {\n chainId,\n chainIdValid,\n entries,\n firstMalformed,\n trust,\n limits,\n });\n if (typeof step === \"string\") {\n problems.add(step, k);\n break;\n }\n head = step;\n passedCheckpoints++;\n covered = Number(step.count);\n }\n }\n for (let k = 0; format === 1 && k < chain.checkpoints.length; k++) {\n const cp = parseCheckpoint(chain.checkpoints[k]!, limits);\n if (cp === null) {\n problems.add(\"checkpoint-malformed\", k);\n break;\n }\n if (!chainIdValid || cp.subject !== chainId) {\n problems.add(\"checkpoint-subject\", k);\n break;\n }\n if (\n cp.previousAnchorId !== prevAnchorId ||\n cp.entryCount < 1 ||\n cp.entryCount <= prevCount\n ) {\n problems.add(\"checkpoint-sequence\", k);\n break;\n }\n if (cp.entryCount > n) {\n problems.add(\"checkpoint-overreach\", k);\n break;\n }\n const count = cp.entryCount;\n let bound = count <= firstMalformed;\n if (bound) {\n const first = entries[0]!;\n const tip = entries[count - 1]!;\n bound =\n cp.startEntryId === first.entryId &&\n cp.endEntryId === tip.entryId &&\n cp.chainHash ===\n anchorChainHashSync(\n prevAnchorHash,\n chainId,\n cp.startEntryId,\n cp.endEntryId,\n tip.chainHash\n );\n }\n if (!bound) {\n problems.add(\"checkpoint-binding\", k);\n break;\n }\n if (checkpointTrust) {\n const key = trust.checkpoint.get(cp.signingKeyId);\n if (key === undefined) {\n problems.add(\"checkpoint-unknown-key\", k);\n break;\n }\n if (!verifyMLDSA65Pure(key, checkpointCanonicalBytes(cp), cp.signature)) {\n problems.add(\"checkpoint-bad-signature\", k);\n break;\n }\n }\n passedCheckpoints++;\n covered = count;\n prevAnchorId = cp.anchorId;\n prevAnchorHash = cp.chainHash;\n prevCount = count;\n }\n\n // §7.7 Record signatures, and §7.8 authentication.\n let recordSignaturesPresent = 0;\n const recordAuthenticated: boolean[] = new Array<boolean>(n).fill(false);\n for (let i = 0; i < n; i++) {\n const e = entries[i]!;\n const rs = e.recordSignature;\n if (rs !== undefined) recordSignaturesPresent++;\n if (!recordTrust) continue;\n if (rs === undefined) {\n problems.add(\"unsigned\", i);\n continue;\n }\n const signature = HEX_32.test(rs.keyId) ? decodeCanonicalBase64(rs.signature) : null;\n if (signature === null || signature.length !== MLDSA65_SIGNATURE_SIZE) {\n problems.add(\"malformed-signature\", i);\n continue;\n }\n const key = trust.record.get(rs.keyId);\n if (key === undefined) {\n problems.add(\"unknown-key\", i);\n continue;\n }\n const envelopeBuildable =\n wellFormed[i] &&\n chainIdValid &&\n (e.entryType === \"sink.event\" || e.entryType === \"sink.erasure\") &&\n (e.previousHash === \"\") === (e.globalSeq === \"0\");\n if (!envelopeBuildable) {\n problems.add(\"bad-signature\", i);\n continue;\n }\n const fields = {\n chainId,\n entryId: e.entryId,\n entryType: e.entryType,\n globalSeq: e.globalSeq,\n previousHash: e.previousHash,\n timestamp: e.timestamp,\n contentHash: e.contentHash,\n signingKeyId: rs.keyId,\n };\n // v1: record.v1, empty context. v2 (§16 §7.7): record.v2 with the stored\n // leaf_hash as field 0x09, context aleutian.proof.record.v2.\n const verified =\n format === 1\n ? verifyMLDSA65Pure(key, buildRecordEnvelopeV1(fields), signature)\n : verifyMLDSA65PureWithContext(\n key,\n buildRecordEnvelopeV2({ ...fields, leafHash: e.leafHash! }),\n signature,\n RECORD_CONTEXT_V2\n );\n if (verified) recordAuthenticated[i] = true;\n else problems.add(\"bad-signature\", i);\n }\n\n let authenticated = 0;\n let checkpointAuthenticated = 0;\n let recordAuthenticatedCount = 0;\n const checkpointAuthenticatedAt = (i: number): boolean =>\n checkpointTrust && wellFormed[i] === true && i < covered;\n for (let i = 0; i < n; i++) {\n const byCheckpoint = checkpointAuthenticatedAt(i);\n const byRecord = recordAuthenticated[i] === true;\n if (byCheckpoint) checkpointAuthenticated++;\n if (byRecord) recordAuthenticatedCount++;\n if (byCheckpoint || byRecord) authenticated++;\n }\n\n // §7.9 Erasure state.\n let erasure: ProofBundleErasureState = \"none\";\n if (E >= 0 && genuineErasure[E]) {\n if (problems.empty && checkpointAuthenticatedAt(E)) erasure = \"anchored\";\n else if (problems.empty && recordAuthenticated[E]) erasure = \"signed\";\n else erasure = \"recorded\";\n }\n\n // §7.10 Verdict.\n const unauthenticated = n - authenticated;\n const verdict: ProofBundleVerdict = !problems.empty\n ? \"failed\"\n : unauthenticated > 0\n ? \"unauthenticated\"\n : \"ok\";\n\n return {\n verdict,\n erasure,\n counts: {\n entries: n,\n events,\n erasures,\n opened,\n committed,\n erased,\n checkpoints: passedCheckpoints,\n unanchored: n - covered,\n authenticated,\n unauthenticated,\n checkpoint_authenticated: checkpointAuthenticated,\n record_authenticated: recordAuthenticatedCount,\n record_signatures_present: recordSignaturesPresent,\n },\n problems: problems.list(),\n };\n}\n\n// =============================================================================\n// Public API\n// =============================================================================\n\n/** The caller's trust, held to its declared shape (the API boundary). */\nfunction checkTrustShape(trust: ProofBundleTrust): void {\n const t = trust as unknown;\n if (\n typeof t !== \"object\" ||\n t === null ||\n !Array.isArray((t as ProofBundleTrust).checkpointKeys) ||\n !Array.isArray((t as ProofBundleTrust).recordKeys)\n ) {\n throw new ProofBundleVerifierError(\n \"trust must be an object with checkpointKeys and recordKeys arrays of Uint8Array\"\n );\n }\n}\n\nasync function keyMap(\n keys: readonly Uint8Array[],\n role: string\n): Promise<Map<string, Uint8Array>> {\n const map = new Map<string, Uint8Array>();\n for (const key of keys) {\n if (!(key instanceof Uint8Array) || key.length !== MLDSA65_PUBLIC_KEY_SIZE) {\n throw new ProofBundleVerifierError(\n `${role} trust: every key must be a raw ${MLDSA65_PUBLIC_KEY_SIZE}-byte ML-DSA-65 public key`\n );\n }\n map.set(await keyIdMLDSA65(key), key);\n }\n return map;\n}\n\n/**\n * Verify a bundle under limits other than §5's. For tests only: a verifier\n * MUST accept every bundle within §5's limits, so production code calls\n * {@link verifyProofBundle}.\n *\n * @internal\n */\nexport async function verifyProofBundleWithLimits(\n bundle: Uint8Array,\n trust: ProofBundleTrust,\n limits: ProofBundleLimits\n): Promise<ProofBundleResult> {\n if (!(bundle instanceof Uint8Array)) {\n throw new ProofBundleVerifierError(\"bundle must be a Uint8Array\");\n }\n checkTrustShape(trust);\n const keys: TrustKeys = {\n checkpoint: await keyMap(trust.checkpointKeys, \"checkpoint\"),\n record: await keyMap(trust.recordKeys, \"record\"),\n };\n\n const read = readProofBundle(bundle, limits);\n if (!read.ok)\n return { result: PROOF_BUNDLE_RESULT_ID, readable: false, reason: read.reason };\n const chains = read.chains;\n\n // §8 Bundle-level checks: duplicate chain ids, compared as strings.\n const occurrences = new Map<string, number>();\n for (const c of chains)\n occurrences.set(c.chainId, (occurrences.get(c.chainId) ?? 0) + 1);\n const bundleProblems = new ProblemSet();\n const seen = new Set<string>();\n chains.forEach((c, i) => {\n if (seen.has(c.chainId)) bundleProblems.add(\"duplicate-chain\", i);\n seen.add(c.chainId);\n });\n\n const results: Record<string, ProofBundleChainResult> = {};\n let anyFailed = false;\n let anyUnauthenticated = false;\n for (let i = 0; i < chains.length; i++) {\n const c = chains[i]!;\n const r = verifyChain(c, keys, limits, read.format);\n const keyedById = SINK_CHAIN_ID.test(c.chainId) && occurrences.get(c.chainId) === 1;\n results[keyedById ? c.chainId : `#${i}`] = r;\n if (r.verdict === \"failed\") anyFailed = true;\n if (r.verdict === \"unauthenticated\") anyUnauthenticated = true;\n }\n\n const verdict: ProofBundleVerdict =\n anyFailed || !bundleProblems.empty\n ? \"failed\"\n : anyUnauthenticated || chains.length === 0\n ? \"unauthenticated\"\n : \"ok\";\n\n return {\n result: PROOF_BUNDLE_RESULT_ID,\n readable: true,\n checkpoint_trust: keys.checkpoint.size > 0 ? \"checked\" : \"not_checked\",\n record_trust: keys.record.size > 0 ? \"checked\" : \"not_checked\",\n verdict,\n bundle_problems: bundleProblems.list(),\n chains: results,\n };\n}\n\n/**\n * Verify an `aleutian.proof.bundle.v1` or `aleutian.proof.bundle.v2` bundle.\n *\n * # Description\n *\n * Applies bundle-format §3–§9 to the bundle bytes under the caller's trust and\n * returns the §9 result: either unreadable with its lowest-numbered reason, or\n * readable with both trust dimensions, the bundle verdict, bundle problems and\n * a result per chain. A dimension is checked exactly when its key set is\n * non-empty.\n *\n * # Inputs\n *\n * - bundle: the bundle file's exact bytes\n * - trust: raw 1952-byte ML-DSA-65 public keys trusted for checkpoints and\n * for record signatures (see `parseProofPublicKeyFile` for key files)\n *\n * # Outputs\n *\n * - ProofBundleResult: the §9 result. An unreadable or failing bundle is a\n * result, never an exception.\n * - ProofBundleVerifierError: thrown only when `bundle` is not a Uint8Array,\n * `trust` is not an object with two arrays, or a trust key is not a\n * 1952-byte Uint8Array. The message names no bundle value.\n *\n * # Example\n *\n * const result = await verifyProofBundle(bytes, {\n * checkpointKeys: [checkpointKey],\n * recordKeys: [],\n * });\n * if (result.readable && result.verdict === \"ok\") { ... }\n *\n * # Limitations\n *\n * - Holds the bundle and its parsed chains in memory (at most 256 MiB of\n * input and 15,000,000 JSON values for v1, 17,000,000 for v2, §5, §16);\n * hostile input is refused without\n * building more than a readable bundle would.\n * - A passing bundle proves only what §1 says: not that it holds every\n * chain, not that a chain is complete to its end, and nothing against a\n * writer that controls every key the verifier trusts.\n *\n * # Assumptions\n *\n * - WebCrypto (`crypto.subtle`) is available (Node ≥ 19, modern browsers).\n * - The caller chose the trust keys out of band; a bundle never adds a key.\n */\nexport function verifyProofBundle(\n bundle: Uint8Array,\n trust: ProofBundleTrust\n): Promise<ProofBundleResult> {\n return verifyProofBundleWithLimits(bundle, trust, PROOF_BUNDLE_LIMITS);\n}\n\n/**\n * The key ids present in both trust sets (§6: allowed, but one key for both\n * roles means one compromise forges both, so a verifier SHOULD warn).\n *\n * # Description\n *\n * Computes each key's id (format-spec §9.6) and returns those in both sets,\n * sorted.\n *\n * # Inputs\n *\n * - trust: the two key sets\n *\n * # Outputs\n *\n * - string[]: key ids trusted for both checkpoints and records\n * - ProofBundleVerifierError: thrown when `trust` is not an object with two\n * arrays, or a key is not a 1952-byte Uint8Array\n *\n * # Example\n *\n * for (const id of await keysTrustedForBothRoles(trust)) warn(id);\n *\n * # Limitations\n *\n * - Compares key ids, which name keys exactly (SHA-512 based).\n *\n * # Assumptions\n *\n * - None.\n */\nexport async function keysTrustedForBothRoles(\n trust: ProofBundleTrust\n): Promise<string[]> {\n checkTrustShape(trust);\n const checkpoint = await keyMap(trust.checkpointKeys, \"checkpoint\");\n const record = await keyMap(trust.recordKeys, \"record\");\n return [...checkpoint.keys()].filter((id) => record.has(id)).sort();\n}\n","// Copyright 2026 Aleutian AI\n// SPDX-License-Identifier: Apache-2.0\n\n/**\n * Trust key files for proof bundles (bundle-format §6).\n *\n * A key file is PEM: EXACTLY one block, label `PUBLIC KEY`, no headers, a\n * canonical base64 body, and nothing but whitespace after it. The block holds\n * exactly the RFC 9881 SubjectPublicKeyInfo DER of a 1952-byte ML-DSA-65 key:\n * the same bytes its key id hashes (format-spec §9.6). That is what\n * `proof keygen` and `proof sink init` write. Anything else is refused.\n *\n * Browser-safe: this parses bytes; reading the file is the caller's job.\n */\n\nimport { decodeCanonicalBase64 } from \"./canonicalBase64.js\";\nimport { mldsa65Spki, MLDSA65_PUBLIC_KEY_SIZE } from \"./keyId.js\";\n\n/** Thrown for any key file that is not exactly what §6 allows. */\nexport class ProofKeyFileError extends Error {\n constructor(message: string) {\n super(message);\n this.name = \"ProofKeyFileError\";\n Object.setPrototypeOf(this, new.target.prototype);\n }\n}\n\nconst BEGIN = \"-----BEGIN PUBLIC KEY-----\";\nconst END = \"-----END PUBLIC KEY-----\";\n// RFC 9881 SPKI of a 1952-byte key: 4-byte SEQUENCE header, 13-byte\n// AlgorithmIdentifier, 5-byte BIT STRING header, the key.\nconst SPKI_SIZE = 4 + 13 + 5 + MLDSA65_PUBLIC_KEY_SIZE;\nconst WHITESPACE_ONLY = /^[ \\t\\r\\n]*$/;\nconst BODY_LINE = /^[A-Za-z0-9+/=]+$/;\n\nfunction isAscii(bytes: Uint8Array): boolean {\n for (const b of bytes) if (b > 0x7f) return false;\n return true;\n}\n\n/**\n * Parse a trust key file into a raw ML-DSA-65 public key.\n *\n * # Description\n *\n * Accepts one PEM block labelled `PUBLIC KEY`, optionally surrounded by\n * whitespace, whose body lines (ending in LF or CRLF) join to canonical base64\n * of exactly the RFC 9881 SPKI DER of a 1952-byte ML-DSA-65 key. Returns the\n * raw 1952-byte key.\n *\n * # Inputs\n *\n * - bytes: the whole key file\n *\n * # Outputs\n *\n * - Uint8Array: the raw 1952-byte public key\n * - ProofKeyFileError: thrown, with a fixed message that quotes nothing from\n * the file, for any other file\n *\n * # Example\n *\n * const pk = parseProofPublicKeyFile(await readFile(\"checkpoint.pub\"));\n *\n * # Limitations\n *\n * - ML-DSA-65 only. Text before the block is refused (only whitespace may\n * surround it).\n *\n * # Assumptions\n *\n * - None.\n */\nexport function parseProofPublicKeyFile(bytes: Uint8Array): Uint8Array {\n if (!isAscii(bytes)) throw new ProofKeyFileError(\"key file: not an ASCII PEM file\");\n let text = \"\";\n for (const b of bytes) text += String.fromCharCode(b);\n\n const begin = text.indexOf(BEGIN);\n if (begin < 0 || !WHITESPACE_ONLY.test(text.slice(0, begin))) {\n throw new ProofKeyFileError(\n \"key file: not exactly one PEM block labelled PUBLIC KEY\"\n );\n }\n const afterBegin = begin + BEGIN.length;\n const end = text.indexOf(END, afterBegin);\n if (end < 0) throw new ProofKeyFileError(\"key file: PEM block not terminated\");\n if (!WHITESPACE_ONLY.test(text.slice(end + END.length))) {\n throw new ProofKeyFileError(\n \"key file: something other than whitespace after the PEM block\"\n );\n }\n\n // Between the markers: a line break, then body lines each ending in a line\n // break. Anything else (a header, a blank line, stray spaces) is refused.\n const inner = text.slice(afterBegin, end);\n const lines = inner.split(\"\\n\");\n if (\n lines.length < 3 ||\n (lines[0] !== \"\" && lines[0] !== \"\\r\") ||\n lines[lines.length - 1] !== \"\"\n ) {\n throw new ProofKeyFileError(\"key file: malformed PEM body\");\n }\n let body = \"\";\n for (const raw of lines.slice(1, -1)) {\n const line = raw.endsWith(\"\\r\") ? raw.slice(0, -1) : raw;\n if (!BODY_LINE.test(line))\n throw new ProofKeyFileError(\"key file: malformed PEM body\");\n body += line;\n }\n\n const der = decodeCanonicalBase64(body);\n if (der === null) throw new ProofKeyFileError(\"key file: body is not canonical base64\");\n if (der.length !== SPKI_SIZE) {\n throw new ProofKeyFileError(\"key file: not the SPKI of an ML-DSA-65 public key\");\n }\n const key = der.slice(SPKI_SIZE - MLDSA65_PUBLIC_KEY_SIZE);\n const expected = mldsa65Spki(key);\n for (let i = 0; i < SPKI_SIZE; i++) {\n if (der[i] !== expected[i]) {\n throw new ProofKeyFileError(\"key file: not the SPKI of an ML-DSA-65 public key\");\n }\n }\n return key;\n}\n"]}